/******************************************************************************* * Copyright (c) 2000, 2015 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 * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog * font should be activated and used by other components. *******************************************************************************/ package org.eclipse.ui.dialogs; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IPathVariableManager; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; 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.DirectoryDialog; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.dialogs.PathVariableSelectionDialog; import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; import org.eclipse.ui.internal.ide.IIDEHelpContextIds; import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils; /** * Standard resource link page for a wizard that creates a file or * folder resource. * <p> * This class may be instantiated; it is not intended to be subclassed. * </p> * @since 2.1 * @noextend This class is not intended to be subclassed by clients. */ public class WizardNewLinkPage extends WizardPage { private String initialLinkTarget; private int type; private boolean createLink = false; private IContainer container; // widgets private Text linkTargetField; private Button browseButton; private Button variablesButton; /** * Creates a new resource link wizard page. * * @param pageName the name of the page * @param type specifies the type of resource to link to. * <code>IResource.FILE</code> or <code>IResource.FOLDER</code> */ public WizardNewLinkPage(String pageName, int type) { super(pageName); this.type = type; setPageComplete(true); } @Override public void createControl(Composite parent) { Font font = parent.getFont(); initializeDialogUnits(parent); // top level group Composite topLevel = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 3; topLevel.setLayout(layout); topLevel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); topLevel.setFont(font); PlatformUI.getWorkbench().getHelpSystem().setHelp(topLevel, IIDEHelpContextIds.NEW_LINK_WIZARD_PAGE); final Button createLinkButton = new Button(topLevel, SWT.CHECK); if (type == IResource.FILE) { createLinkButton.setText(IDEWorkbenchMessages.WizardNewLinkPage_linkFileButton); } else { createLinkButton.setText(IDEWorkbenchMessages.WizardNewLinkPage_linkFolderButton); } createLinkButton.setSelection(createLink); GridData data = new GridData(); data.horizontalSpan = 3; createLinkButton.setLayoutData(data); createLinkButton.setFont(font); SelectionListener listener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { createLink = createLinkButton.getSelection(); browseButton.setEnabled(createLink); variablesButton.setEnabled(createLink); linkTargetField.setEnabled(createLink); setPageComplete(validatePage()); } }; createLinkButton.addSelectionListener(listener); createLinkLocationGroup(topLevel, createLink); validatePage(); setErrorMessage(null); setMessage(null); setControl(topLevel); } /** * Creates the link target location widgets. * * @param locationGroup the parent composite * @param enabled sets the initial enabled state of the widgets */ private void createLinkLocationGroup(Composite locationGroup, boolean enabled) { Font font = locationGroup.getFont(); Label fill = new Label(locationGroup, SWT.NONE); GridData data = new GridData(); Button button = new Button(locationGroup, SWT.CHECK); data.widthHint = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; button.dispose(); fill.setLayoutData(data); // link target location entry field linkTargetField = new Text(locationGroup, SWT.BORDER); data = new GridData(GridData.FILL_HORIZONTAL); linkTargetField.setLayoutData(data); linkTargetField.setFont(font); linkTargetField.setEnabled(enabled); linkTargetField.addModifyListener(e -> setPageComplete(validatePage())); if (initialLinkTarget != null) { linkTargetField.setText(initialLinkTarget); } // browse button browseButton = new Button(locationGroup, SWT.PUSH); setButtonLayoutData(browseButton); browseButton.setFont(font); browseButton.setText(IDEWorkbenchMessages.WizardNewLinkPage_browseButton); browseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { handleLinkTargetBrowseButtonPressed(); } }); browseButton.setEnabled(enabled); fill = new Label(locationGroup, SWT.NONE); data = new GridData(); data.horizontalSpan = 2; fill.setLayoutData(data); // variables button variablesButton = new Button(locationGroup, SWT.PUSH); setButtonLayoutData(variablesButton); variablesButton.setFont(font); variablesButton.setText(IDEWorkbenchMessages.WizardNewLinkPage_variablesButton); variablesButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { handleVariablesButtonPressed(); } }); variablesButton.setEnabled(enabled); } /** * Returns the link target location entered by the user. * * @return the link target location entered by the user. null if the user * choose not to create a link. */ public String getLinkTarget() { if (createLink && linkTargetField != null && linkTargetField.isDisposed() == false) { return linkTargetField.getText(); } return null; } /** * Opens a file or directory browser depending on the link type. */ private void handleLinkTargetBrowseButtonPressed() { String linkTargetName = linkTargetField.getText(); String selection = null; IFileStore store = null; if (linkTargetName.length() > 0) { store = IDEResourceInfoUtils.getFileStore(linkTargetName); if (store == null || !store.fetchInfo().exists()) { store = null; } } if (type == IResource.FILE) { FileDialog dialog = new FileDialog(getShell(), SWT.SHEET); if (store != null) { if (store.fetchInfo().isDirectory()) { dialog.setFilterPath(linkTargetName); } else { dialog.setFileName(linkTargetName); } } selection = dialog.open(); } else { DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SHEET); if (store != null) { if (!store.fetchInfo().isDirectory()) { linkTargetName = store.getParent().getName(); } if (linkTargetName != null) { dialog.setFilterPath(linkTargetName); } } dialog.setMessage(IDEWorkbenchMessages.WizardNewLinkPage_targetSelectionLabel); selection = dialog.open(); } if (selection != null) { linkTargetField.setText(selection); } } /** * Opens a path variable selection dialog */ private void handleVariablesButtonPressed() { PathVariableSelectionDialog dialog = new PathVariableSelectionDialog( getShell(), type); if (dialog.open() == IDialogConstants.OK_ID) { String[] variableNames = (String[]) dialog.getResult(); if (variableNames != null) { IPathVariableManager pathVariableManager = ResourcesPlugin .getWorkspace().getPathVariableManager(); IPath path = pathVariableManager.getValue(variableNames[0]); if (path != null) { linkTargetField.setText(path.toOSString()); } } } } /** * Sets the container to use for link validation. * This should be the parent of the new resource that is being * linked. * * @param container the container to use for link validation. */ public void setContainer(IContainer container) { this.container = container; } /** * Sets the value of the link target field * * @param target the value of the link target field */ public void setLinkTarget(String target) { initialLinkTarget = target; if (linkTargetField != null && linkTargetField.isDisposed() == false) { linkTargetField.setText(target); } } /** * Validates the type of the given file against the link type specified * during page creation. * * @param linkTargetStore file to validate * @return boolean <code>true</code> if the link target type is valid * and <code>false</code> otherwise. */ private boolean validateFileType(IFileStore linkTargetStore) { boolean valid = true; if (type == IResource.FILE && linkTargetStore.fetchInfo().isDirectory()) { setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNotFile); valid = false; } else if (type == IResource.FOLDER && !linkTargetStore.fetchInfo().isDirectory()) { setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNotFolder); valid = false; } return valid; } /** * Validates the name of the link target * * @param linkTargetName link target name to validate * @return boolean <code>true</code> if the link target name is valid * and <code>false</code> otherwise. */ private boolean validateLinkTargetName(String linkTargetName) { boolean valid = true; if ("".equals(linkTargetName)) {//$NON-NLS-1$ setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetEmpty); valid = false; } else { IPath path = new Path("");//$NON-NLS-1$ if (path.isValidPath(linkTargetName) == false) { setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetInvalid); valid = false; } } return valid; } /** * Returns whether this page's controls currently all contain valid * values. * * @return <code>true</code> if all controls are valid, and * <code>false</code> if at least one is invalid */ private boolean validatePage() { boolean valid = true; IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace(); if (createLink) { String linkTargetName = linkTargetField.getText(); valid = validateLinkTargetName(linkTargetName); if (valid) { IFileStore linkTargetFile = IDEResourceInfoUtils.getFileStore(linkTargetName); if (linkTargetFile == null || !linkTargetFile.fetchInfo().exists()) { setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNonExistent); valid = false; } else { IStatus locationStatus = workspace.validateLinkLocation( container, new Path(linkTargetName)); if (locationStatus.isOK() == false) { setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetLocationInvalid); valid = false; } else { valid = validateFileType(linkTargetFile); } } } } // Avoid draw flicker by clearing error message // if all is valid. if (valid) { setMessage(null); setErrorMessage(null); } return valid; } }