001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
011: * font should be activated and used by other components.
012: *******************************************************************************/package org.eclipse.ui.dialogs;
013:
014: import org.eclipse.core.filesystem.IFileStore;
015: import org.eclipse.core.resources.IContainer;
016: import org.eclipse.core.resources.IPathVariableManager;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.resources.IWorkspace;
019: import org.eclipse.core.resources.ResourcesPlugin;
020: import org.eclipse.core.runtime.IPath;
021: import org.eclipse.core.runtime.IStatus;
022: import org.eclipse.core.runtime.Path;
023: import org.eclipse.jface.dialogs.IDialogConstants;
024: import org.eclipse.jface.wizard.WizardPage;
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.events.ModifyEvent;
027: import org.eclipse.swt.events.ModifyListener;
028: import org.eclipse.swt.events.SelectionAdapter;
029: import org.eclipse.swt.events.SelectionEvent;
030: import org.eclipse.swt.events.SelectionListener;
031: import org.eclipse.swt.graphics.Font;
032: import org.eclipse.swt.layout.GridData;
033: import org.eclipse.swt.layout.GridLayout;
034: import org.eclipse.swt.widgets.Button;
035: import org.eclipse.swt.widgets.Composite;
036: import org.eclipse.swt.widgets.DirectoryDialog;
037: import org.eclipse.swt.widgets.FileDialog;
038: import org.eclipse.swt.widgets.Label;
039: import org.eclipse.swt.widgets.Text;
040: import org.eclipse.ui.PlatformUI;
041: import org.eclipse.ui.ide.dialogs.PathVariableSelectionDialog;
042: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
043: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
044: import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
045: import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
046:
047: /**
048: * Standard resource link page for a wizard that creates a file or
049: * folder resource.
050: * <p>
051: * This class may be instantiated; it is not intended to be subclassed.
052: * </p>
053: * @since 2.1
054: */
055: public class WizardNewLinkPage extends WizardPage {
056: private String initialLinkTarget;
057:
058: private int type;
059:
060: private boolean createLink = false;
061:
062: private IContainer container;
063:
064: // widgets
065: private Text linkTargetField;
066:
067: private Button browseButton;
068:
069: private Button variablesButton;
070:
071: /**
072: * Creates a new resource link wizard page.
073: *
074: * @param pageName the name of the page
075: * @param type specifies the type of resource to link to.
076: * <code>IResource.FILE</code> or <code>IResource.FOLDER</code>
077: */
078: public WizardNewLinkPage(String pageName, int type) {
079: super (pageName);
080: this .type = type;
081: setPageComplete(true);
082: }
083:
084: /* (non-Javadoc)
085: * Method declared on IDialogPage.
086: */
087: public void createControl(Composite parent) {
088: Font font = parent.getFont();
089: initializeDialogUnits(parent);
090: // top level group
091: Composite topLevel = new Composite(parent, SWT.NONE);
092: GridLayout layout = new GridLayout();
093: layout.numColumns = 3;
094: topLevel.setLayout(layout);
095: topLevel.setLayoutData(new GridData(
096: GridData.VERTICAL_ALIGN_FILL
097: | GridData.HORIZONTAL_ALIGN_FILL));
098: topLevel.setFont(font);
099: PlatformUI.getWorkbench().getHelpSystem().setHelp(topLevel,
100: IIDEHelpContextIds.NEW_LINK_WIZARD_PAGE);
101:
102: final Button createLinkButton = new Button(topLevel, SWT.CHECK);
103: if (type == IResource.FILE) {
104: createLinkButton
105: .setText(IDEWorkbenchMessages.WizardNewLinkPage_linkFileButton);
106: } else {
107: createLinkButton
108: .setText(IDEWorkbenchMessages.WizardNewLinkPage_linkFolderButton);
109: }
110: createLinkButton.setSelection(createLink);
111: GridData data = new GridData();
112: data.horizontalSpan = 3;
113: createLinkButton.setLayoutData(data);
114: createLinkButton.setFont(font);
115: SelectionListener listener = new SelectionAdapter() {
116: public void widgetSelected(SelectionEvent e) {
117: createLink = createLinkButton.getSelection();
118: browseButton.setEnabled(createLink);
119: variablesButton.setEnabled(createLink);
120: linkTargetField.setEnabled(createLink);
121: setPageComplete(validatePage());
122: }
123: };
124: createLinkButton.addSelectionListener(listener);
125:
126: createLinkLocationGroup(topLevel, createLink);
127: validatePage();
128:
129: setErrorMessage(null);
130: setMessage(null);
131: setControl(topLevel);
132: }
133:
134: /**
135: * Creates the link target location widgets.
136: *
137: * @param locationGroup the parent composite
138: * @param enabled sets the initial enabled state of the widgets
139: */
140: private void createLinkLocationGroup(Composite locationGroup,
141: boolean enabled) {
142: Font font = locationGroup.getFont();
143: Label fill = new Label(locationGroup, SWT.NONE);
144: GridData data = new GridData();
145: Button button = new Button(locationGroup, SWT.CHECK);
146: data.widthHint = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
147: button.dispose();
148: fill.setLayoutData(data);
149:
150: // link target location entry field
151: linkTargetField = new Text(locationGroup, SWT.BORDER);
152: data = new GridData(GridData.FILL_HORIZONTAL);
153: linkTargetField.setLayoutData(data);
154: linkTargetField.setFont(font);
155: linkTargetField.setEnabled(enabled);
156: linkTargetField.addModifyListener(new ModifyListener() {
157: public void modifyText(ModifyEvent e) {
158: setPageComplete(validatePage());
159: }
160: });
161: if (initialLinkTarget != null) {
162: linkTargetField.setText(initialLinkTarget);
163: }
164:
165: // browse button
166: browseButton = new Button(locationGroup, SWT.PUSH);
167: setButtonLayoutData(browseButton);
168: browseButton.setFont(font);
169: browseButton
170: .setText(IDEWorkbenchMessages.WizardNewLinkPage_browseButton);
171: browseButton.addSelectionListener(new SelectionAdapter() {
172: public void widgetSelected(SelectionEvent event) {
173: handleLinkTargetBrowseButtonPressed();
174: }
175: });
176: browseButton.setEnabled(enabled);
177:
178: fill = new Label(locationGroup, SWT.NONE);
179: data = new GridData();
180: data.horizontalSpan = 2;
181: fill.setLayoutData(data);
182:
183: // variables button
184: variablesButton = new Button(locationGroup, SWT.PUSH);
185: setButtonLayoutData(variablesButton);
186: variablesButton.setFont(font);
187: variablesButton
188: .setText(IDEWorkbenchMessages.WizardNewLinkPage_variablesButton);
189: variablesButton.addSelectionListener(new SelectionAdapter() {
190: public void widgetSelected(SelectionEvent event) {
191: handleVariablesButtonPressed();
192: }
193: });
194: variablesButton.setEnabled(enabled);
195: }
196:
197: /**
198: * Returns the link target location entered by the user.
199: *
200: * @return the link target location entered by the user. null if the user
201: * choose not to create a link.
202: */
203: public String getLinkTarget() {
204: if (createLink && linkTargetField != null
205: && linkTargetField.isDisposed() == false) {
206: return linkTargetField.getText();
207: }
208: return null;
209: }
210:
211: /**
212: * Opens a file or directory browser depending on the link type.
213: */
214: private void handleLinkTargetBrowseButtonPressed() {
215: String linkTargetName = linkTargetField.getText();
216: String selection = null;
217: IFileStore store = null;
218: if (linkTargetName.length() > 0) {
219: store = IDEResourceInfoUtils.getFileStore(linkTargetName);
220: if (store == null || !store.fetchInfo().exists()) {
221: store = null;
222: }
223: }
224: if (type == IResource.FILE) {
225: FileDialog dialog = new FileDialog(getShell());
226: if (store != null) {
227: if (store.fetchInfo().isDirectory()) {
228: dialog.setFilterPath(linkTargetName);
229: } else {
230: dialog.setFileName(linkTargetName);
231: }
232: }
233: selection = dialog.open();
234: } else {
235: DirectoryDialog dialog = new DirectoryDialog(getShell());
236: if (store != null) {
237: if (!store.fetchInfo().isDirectory()) {
238: linkTargetName = store.getParent().getName();
239: }
240: if (linkTargetName != null) {
241: dialog.setFilterPath(linkTargetName);
242: }
243: }
244: dialog
245: .setMessage(IDEWorkbenchMessages.WizardNewLinkPage_targetSelectionLabel);
246: selection = dialog.open();
247: }
248: if (selection != null) {
249: linkTargetField.setText(selection);
250: }
251: }
252:
253: /**
254: * Opens a path variable selection dialog
255: */
256: private void handleVariablesButtonPressed() {
257: PathVariableSelectionDialog dialog = new PathVariableSelectionDialog(
258: getShell(), type);
259:
260: if (dialog.open() == IDialogConstants.OK_ID) {
261: String[] variableNames = (String[]) dialog.getResult();
262:
263: if (variableNames != null) {
264: IPathVariableManager pathVariableManager = ResourcesPlugin
265: .getWorkspace().getPathVariableManager();
266: IPath path = pathVariableManager
267: .getValue(variableNames[0]);
268:
269: if (path != null) {
270: linkTargetField.setText(path.toOSString());
271: }
272: }
273: }
274: }
275:
276: /**
277: * Sets the container to use for link validation.
278: * This should be the parent of the new resource that is being
279: * linked.
280: *
281: * @param container the container to use for link validation.
282: */
283: public void setContainer(IContainer container) {
284: this .container = container;
285: }
286:
287: /**
288: * Sets the value of the link target field
289: *
290: * @param target the value of the link target field
291: */
292: public void setLinkTarget(String target) {
293: initialLinkTarget = target;
294: if (linkTargetField != null
295: && linkTargetField.isDisposed() == false) {
296: linkTargetField.setText(target);
297: }
298: }
299:
300: /**
301: * Validates the type of the given file against the link type specified
302: * during page creation.
303: *
304: * @param linkTargetStore file to validate
305: * @return boolean <code>true</code> if the link target type is valid
306: * and <code>false</code> otherwise.
307: */
308: private boolean validateFileType(IFileStore linkTargetStore) {
309: boolean valid = true;
310:
311: if (type == IResource.FILE
312: && linkTargetStore.fetchInfo().isDirectory()) {
313: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNotFile);
314: valid = false;
315: } else if (type == IResource.FOLDER
316: && !linkTargetStore.fetchInfo().isDirectory()) {
317: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNotFolder);
318: valid = false;
319: }
320: return valid;
321: }
322:
323: /**
324: * Validates the name of the link target
325: *
326: * @param linkTargetName link target name to validate
327: * @return boolean <code>true</code> if the link target name is valid
328: * and <code>false</code> otherwise.
329: */
330: private boolean validateLinkTargetName(String linkTargetName) {
331: boolean valid = true;
332:
333: if ("".equals(linkTargetName)) {//$NON-NLS-1$
334: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetEmpty);
335: valid = false;
336: } else {
337: IPath path = new Path("");//$NON-NLS-1$
338: if (path.isValidPath(linkTargetName) == false) {
339: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetInvalid);
340: valid = false;
341: }
342: }
343: return valid;
344: }
345:
346: /**
347: * Returns whether this page's controls currently all contain valid
348: * values.
349: *
350: * @return <code>true</code> if all controls are valid, and
351: * <code>false</code> if at least one is invalid
352: */
353: private boolean validatePage() {
354: boolean valid = true;
355: IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
356:
357: if (createLink) {
358: String linkTargetName = linkTargetField.getText();
359:
360: valid = validateLinkTargetName(linkTargetName);
361: if (valid) {
362: IFileStore linkTargetFile = IDEResourceInfoUtils
363: .getFileStore(linkTargetName);
364: if (linkTargetFile == null
365: || !linkTargetFile.fetchInfo().exists()) {
366: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetNonExistent);
367: valid = false;
368: } else {
369: IStatus locationStatus = workspace
370: .validateLinkLocation(container, new Path(
371: linkTargetName));
372:
373: if (locationStatus.isOK() == false) {
374: setErrorMessage(IDEWorkbenchMessages.WizardNewLinkPage_linkTargetLocationInvalid);
375: valid = false;
376: } else {
377: valid = validateFileType(linkTargetFile);
378: }
379: }
380: }
381: }
382: // Avoid draw flicker by clearing error message
383: // if all is valid.
384: if (valid) {
385: setMessage(null);
386: setErrorMessage(null);
387: }
388: return valid;
389: }
390: }
|