// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package net.sourceforge.eclipsejetty.launch.util;
import java.io.File;
import java.util.List;
import net.sourceforge.eclipsejetty.JettyPluginUtils;
import net.sourceforge.eclipsejetty.Messages;
import net.sourceforge.eclipsejetty.util.Result;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.debug.ui.StringVariableSelectionDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
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.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
public class JettyLaunchUI
{
/**
* Creates a label
*
* @param parent the parent composite
* @param text the text of the label
* @param widthHint the width, <0 to fill up the space
* @param horizontalAlignment the horizontal alignment of the text
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the label
*/
public static Label createLabel(Composite parent, String text, int widthHint, int horizontalAlignment,
int horizontalSpan, int verticalSpan)
{
Label label = new Label(parent, SWT.NONE);
GridData gridData =
new GridData(SWT.FILL, (verticalSpan <= 1) ? SWT.CENTER : SWT.TOP, widthHint < 0, false, horizontalSpan,
verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
label.setLayoutData(gridData);
label.setText(text);
label.setAlignment(horizontalAlignment);
return label;
}
/**
* Creates a label with an image
*
* @param parent the parent composite
* @param image the image
* @param widthHint the width, <0 to fill up the space
* @param horizontalAlignment the horizontal alignment
* @param verticalAlignment the vertical alignment
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the label with an image
*/
public static Label createImage(Composite parent, Image image, int widthHint, int horizontalAlignment,
int verticalAlignment, int horizontalSpan, int verticalSpan)
{
Label label = new Label(parent, SWT.NONE);
GridData gridData =
new GridData(horizontalAlignment, verticalAlignment, false, false, horizontalSpan, verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
label.setAlignment(horizontalAlignment);
label.setLayoutData(gridData);
label.setImage(image);
return label;
}
/**
* Creates an hint.
*
* @param parent the parent composite
* @param text the text of the hint
* @param widthHint the width, <0 to fill up the space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the label
*/
public static Label createHint(Composite parent, String text, int widthHint, int horizontalSpan, int verticalSpan)
{
Label label = createLabel(parent, text, widthHint, SWT.LEFT, horizontalSpan, verticalSpan);
label.setAlignment(SWT.RIGHT);
setItalicFont(parent.getDisplay(), label);
return label;
}
/**
* Creates a link
*
* @param parent the parent composite
* @param style the type
* @param text the text
* @param horizontalAlignment the horizontal alignment of the text
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param listener the listener
* @return the link
*/
public static Link createLink(Composite parent, int style, String text, int horizontalAlignment,
int horizontalSpan, int verticalSpan, Listener listener)
{
Link link = new Link(parent, style);
GridData gridData = new GridData(horizontalAlignment, SWT.CENTER, false, false, horizontalSpan, verticalSpan);
link.setLayoutData(gridData);
if (text != null)
{
link.setText(text);
}
if (listener != null)
{
link.addListener(SWT.Selection, listener);
}
setItalicFont(parent.getDisplay(), link);
return link;
}
/**
* Create a button.
*
* @param parent the parent composite
* @param style the style
* @param text the text of the button
* @param toolTip the tool tip of the button
* @param widthHint the width, <0 to fill up the space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param selectionListeners listeners to be notified on action
* @return the button
*/
public static Button createButton(Composite parent, int style, String text, String toolTip, int widthHint,
int horizontalSpan, int verticalSpan, SelectionListener... selectionListeners)
{
return createButton(parent, style, null, text, toolTip, widthHint, horizontalSpan, verticalSpan,
selectionListeners);
}
/**
* Create a button.
*
* @param parent the parent composite
* @param style the style
* @param image the image
* @param toolTip the tool tip of the button
* @param widthHint the width, <0 to fill up the space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param selectionListeners listeners to be notified on action
* @return the button
*/
public static Button createButton(Composite parent, int style, Image image, String toolTip, int widthHint,
int horizontalSpan, int verticalSpan, SelectionListener... selectionListeners)
{
return createButton(parent, style, image, null, toolTip, widthHint, horizontalSpan, verticalSpan,
selectionListeners);
}
/**
* Create a button.
*
* @param parent the parent composite
* @param style the style
* @param image the image
* @param text the text of the button
* @param toolTip the tool tip of the button
* @param widthHint the width, <0 to fill up the space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param selectionListeners listeners to be notified on action
* @return the button
*/
public static Button createButton(Composite parent, int style, Image image, String text, String toolTip,
int widthHint, int horizontalSpan, int verticalSpan, SelectionListener... selectionListeners)
{
Button button = new Button(parent, style);
GridData gridData =
new GridData((widthHint < 0) ? SWT.FILL : SWT.LEFT, (verticalSpan <= 1) ? SWT.CENTER : SWT.TOP,
widthHint < 0, false, horizontalSpan, verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
button.setLayoutData(gridData);
if (text != null)
{
button.setText(text);
}
if (toolTip != null)
{
button.setToolTipText(toolTip);
}
if (image != null)
{
button.setImage(image);
}
if (selectionListeners != null)
{
for (SelectionListener selectionListener : selectionListeners)
{
button.addSelectionListener(selectionListener);
}
}
return button;
}
/**
* Creates a text component
*
* @param parent the parent composite
* @param style the style
* @param toolTip the tool tip
* @param widthHint the width, <0 to fill up the space
* @param heightHint the height, <0 to ignore
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param selectionListeners listeners to be notified on action
* @return the component
*/
public static Text createText(Composite parent, int style, String toolTip, int widthHint, int heightHint,
int horizontalSpan, int verticalSpan, ModifyListener... modifyListeners)
{
Text text = new Text(parent, style);
GridData gridData =
new GridData((widthHint < 0) ? SWT.FILL : SWT.LEFT, (verticalSpan <= 1) ? SWT.CENTER : SWT.TOP,
widthHint < 0, false, horizontalSpan, verticalSpan);
if (toolTip != null)
{
text.setToolTipText(toolTip);
}
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
if (heightHint >= 0)
{
gridData.heightHint = heightHint;
}
text.setLayoutData(gridData);
if (modifyListeners != null)
{
for (ModifyListener modifyListener : modifyListeners)
{
text.addModifyListener(modifyListener);
}
}
return text;
}
/**
* Creates a spinner
*
* @param parent the parent composite
* @param style the style
* @param toolTip the tool tip
* @param widthHint the width, <0 to fill up the space
* @param heightHint the height, <0 to ignore
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param selectionListeners listeners to be notified on action
* @return the component
*/
public static Spinner createSpinner(Composite parent, int style, String toolTip, int widthHint, int heightHint,
int horizontalSpan, int verticalSpan, ModifyListener... modifyListeners)
{
Spinner spinner = new Spinner(parent, style);
GridData gridData =
new GridData((widthHint < 0) ? SWT.FILL : SWT.LEFT, (verticalSpan <= 1) ? SWT.CENTER : SWT.TOP,
widthHint < 0, false, horizontalSpan, verticalSpan);
if (toolTip != null)
{
spinner.setToolTipText(toolTip);
}
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
if (heightHint >= 0)
{
gridData.heightHint = heightHint;
}
spinner.setLayoutData(gridData);
if (modifyListeners != null)
{
for (ModifyListener modifyListener : modifyListeners)
{
spinner.addModifyListener(modifyListener);
}
}
return spinner;
}
/**
* Creates a titled group
*
* @param parent the parent composite
* @param title the title
* @param columns the number of columns
* @param widthHint the width, <0 to fill up the space
* @param grabVerticalSpace true to grab all vertical space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the group
*/
public static Group createGroup(Composite parent, String title, int columns, int widthHint,
boolean grabVerticalSpace, int horizontalSpan, int verticalSpan)
{
Group group = new Group(parent, SWT.NONE);
group.setLayout(new GridLayout(columns, false));
GridData gridData =
new GridData((widthHint < 0) ? SWT.FILL : SWT.LEFT, (verticalSpan <= 1) ? SWT.FILL : SWT.TOP,
widthHint < 0, grabVerticalSpace, horizontalSpan, verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
group.setLayoutData(gridData);
group.setText(title);
return group;
}
/**
* Creates the main tab composite
*
* @param parent the parent
* @param columns the number of columns
* @param equalWidth true, to make columns equals in width
* @return the composite;
*/
public static Composite createTabComposite(Composite parent, int columns, boolean equalWidth)
{
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(columns, equalWidth));
return composite;
}
/**
* Creates a composite without label and without border (slight margin)
*
* @param parent the parent composite
* @param style the type
* @param columns the number of columns
* @param widthHint the width, <0 to fill up the space
* @param grabVerticalSpace true to grab all vertical space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the composite
*/
public static Composite createTopComposite(Composite parent, int style, int columns, int widthHint,
boolean grabVerticalSpace, int horizontalSpan, int verticalSpan)
{
GridLayout layout = new GridLayout(columns, false);
layout.marginHeight = 8;
layout.marginWidth = 8;
return createComposite(parent, style, widthHint, grabVerticalSpace, horizontalSpan, verticalSpan, layout);
}
/**
* Create a composite, usually used for button bars (no margin)
*
* @param parent the parent composite
* @param style the type
* @param columns the number of columns
* @param widthHint the width, <0 to fill up the space
* @param grabVerticalSpace true to grab all vertical space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @return the composite
*/
public static Composite createComposite(Composite parent, int style, int columns, int widthHint,
boolean grabVerticalSpace, int horizontalSpan, int verticalSpan)
{
GridLayout layout = new GridLayout(columns, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
return createComposite(parent, style, widthHint, grabVerticalSpace, horizontalSpan, verticalSpan, layout);
}
/**
* Create a composite, using the specified layout
*
* @param parent the parent composite
* @param style the type
* @param widthHint the width, <0 to fill up the space
* @param grabVerticalSpace true to grab all vertical space
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param layout the layout
* @return the composite
*/
private static Composite createComposite(Composite parent, int style, int widthHint, boolean grabVerticalSpace,
int horizontalSpan, int verticalSpan, GridLayout layout)
{
Composite composite = new Composite(parent, style);
composite.setLayout(layout);
GridData gridData =
new GridData((widthHint < 0) ? SWT.FILL : SWT.LEFT, (verticalSpan <= 1) ? SWT.FILL : SWT.TOP,
widthHint < 0, grabVerticalSpace, horizontalSpan, verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
composite.setLayoutData(gridData);
return composite;
}
/**
* Creates a table
*
* @param parent the parent composite
* @param style the type
* @param widthHint the width, <0 to fill up the space
* @param heightHint the minimum height, <0 to ignore
* @param horizontalSpan the horizontal span
* @param verticalSpan the vertical span
* @param titles the column titles
* @return the table
*/
public static Table createTable(Composite parent, int style, int widthHint, int heightHint, int horizontalSpan,
int verticalSpan, String... titles)
{
Table table = new Table(parent, style);
table.setLinesVisible(false);
table.setHeaderVisible(true);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, widthHint < 0, true, horizontalSpan, verticalSpan);
if (widthHint >= 0)
{
gridData.widthHint = widthHint;
}
if (heightHint >= 0)
{
gridData.minimumHeight = heightHint;
}
table.setLayoutData(gridData);
for (String title : titles)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText(title);
}
return table;
}
/**
* Shows a dialog to select a file from the workspace
*
* @param shell the shell
* @param project the project
* @param title the title
* @param message the message
* @param path the initial path
* @return the result, null if canceled
*/
public static String chooseWorkspaceFile(Shell shell, IProject project, String title, String message, String path)
{
path = JettyPluginUtils.resolveVariables(path);
ElementTreeSelectionDialog dialog =
new ElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new BaseWorkbenchContentProvider());
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
if ((path != null) && (path.length() > 0))
{
dialog.setInitialSelection(path);
}
dialog.setAllowMultiple(false);
dialog.open();
Object[] results = dialog.getResult();
if ((results != null) && (results.length > 0) && (results[0] instanceof IFile))
{
IFile file = (IFile) results[0];
return JettyPluginUtils.toRelativePath(project, file.getFullPath().toString());
}
return null;
}
/**
* Shows a dialog to select a folder from the workspace
*
* @param project the project
* @param shell the shell
* @param title the title
* @param message the message
* @param path the initial path
* @return the result, null if canceled
*/
public static String chooseWorkspaceDirectory(Shell shell, IProject project, String title, String message,
String path)
{
path = JettyPluginUtils.resolveVariables(path);
ContainerSelectionDialog dialog = new ContainerSelectionDialog(shell, project, false, message);
dialog.setTitle(title);
if (project != null)
{
dialog.setInitialSelections(new Object[]{path});
}
dialog.showClosedProjects(false);
dialog.open();
Object[] results = dialog.getResult();
if ((results != null) && (results.length > 0) && (results[0] instanceof IPath))
{
IPath folder = (IPath) results[0];
return JettyPluginUtils.toRelativePath(project, folder.toString());
}
return null;
}
/**
* Shows a dialog to select a folder from the file system
*
* @param shell the shell
* @param text the title
* @param message the message
* @param path the inital path
* @return the folder, null if canceled
*/
public static String chooseExternalDirectory(Shell shell, String text, String message, String path)
{
path = JettyPluginUtils.resolveVariables(path);
DirectoryDialog dialog = new DirectoryDialog(shell, SWT.OPEN);
dialog.setText(text);
dialog.setMessage(message);
dialog.setFilterPath(path);
return dialog.open();
}
/**
* Shows a dialog to select a file from the file system
*
* @param shell the shell
* @param path the initial path
* @param text the title
* @param filter an array of filter options
* @return the selected file, null if canceled
*/
public static String chooseExternalFile(Shell shell, String path, String text, String... filter)
{
path = JettyPluginUtils.resolveVariables(path);
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setText(text);
if (path != null)
{
File file = new File(path);
dialog.setFileName(file.getName());
dialog.setFilterPath(file.getParent());
}
dialog.setFilterExtensions(filter);
return dialog.open();
}
/**
* Shows a dialog to select or define a variable
*
* @param shell the shell
* @param textComponent the text component to be filled
*/
public static void chooseVariable(Shell shell, Text textComponent)
{
StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(shell);
if (Window.OK == dialog.open())
{
Object[] results = dialog.getResult();
for (int i = results.length - 1; i >= 0; i -= 1)
{
String placeholder = "${" + ((IStringVariable) results[i]).getName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$
int position = textComponent.getCaretPosition();
String text = textComponent.getText();
if (position <= 0)
{
text = placeholder + text;
}
else if (position >= text.length())
{
text = text + placeholder;
}
else
{
text = text.substring(0, position) + placeholder + text.substring(position);
}
textComponent.setText(text);
}
}
}
/**
* Searches for the web app directory.
*
* @param shell the shell
* @param project the project
* @param path the current path, may be null
* @return the web app directory
* @throws CoreException on occasion
*/
public static String chooseWebAppDir(final Shell shell, final IProject project, final String path)
throws CoreException
{
final List<IPath> paths = JettyLaunchUtils.findWebappDirs(project, Integer.MAX_VALUE);
if (paths.size() == 0)
{
Display.getCurrent().syncExec(new Runnable()
{
public void run()
{
MessageDialog.openError(Display.getCurrent().getActiveShell(),
Messages.configTab_webAppScanFailedTitle,
String.format(Messages.configTab_webAppScanFailedMessage, project.getName()));
}
});
return chooseWorkspaceDirectory(shell, project, Messages.configTab_webAppBrowseTitle,
Messages.configTab_webAppBrowseMessage, path);
}
else if (paths.size() > 1)
{
return chooseWebAppDir(shell, project, paths, path);
}
return JettyPluginUtils.toRelativePath(project, paths.get(0).toString());
}
/**
* Choose one webApp directory from a list of directories. Show a user selection on cancel
*
* @param shell the shell
* @param project the project
* @param paths the paths
* @param path the path for the file selection
* @return the selected directory, null if none was selected
* @throws CoreException on occasion
*/
public static String chooseWebAppDir(final Shell shell, final IProject project, final List<IPath> paths,
final String path) throws CoreException
{
final Result<String> result = new Result<String>();
Display.getCurrent().syncExec(new Runnable()
{
public void run()
{
ElementListSelectionDialog dialog =
new ElementListSelectionDialog(Display.getCurrent().getActiveShell(), new WebAppPathLabelProvider());
String[] elements = JettyLaunchUtils.toStringArray(paths);
for (int i = 0; i < elements.length; i += 1)
{
elements[i] = JettyPluginUtils.toRelativePath(project, elements[i]);
}
dialog.setElements(elements);
dialog.setTitle("Choose WebApp Directory");
dialog
.setMessage("There are multiple folders, that may act as Web Application directory.\nPlease choose one:");
dialog.setMultipleSelection(false);
if (dialog.open() != Window.OK)
{
result.setResult(chooseWorkspaceDirectory(shell, project, Messages.configTab_webAppBrowseTitle,
Messages.configTab_webAppBrowseMessage, path));
return;
}
result.setResult((String) dialog.getResult()[0]);
}
});
return result.getResult();
}
private static void setItalicFont(Display display, Control control)
{
FontData[] fontData = control.getFont().getFontData();
for (FontData element : fontData)
{
element.setStyle(SWT.ITALIC);
}
final Font italicFont = new Font(display, fontData);
control.setFont(italicFont);
control.addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
italicFont.dispose();
}
});
}
}