001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 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: *******************************************************************************/package org.eclipse.jdt.internal.ui.jarpackager;
011:
012: import org.eclipse.core.resources.IFile;
013: import org.eclipse.core.resources.IResource;
014: import org.eclipse.core.resources.IWorkspace;
015: import org.eclipse.core.resources.ResourcesPlugin;
016: import org.eclipse.core.runtime.IPath;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Path;
019:
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.events.SelectionAdapter;
022: import org.eclipse.swt.events.SelectionEvent;
023: import org.eclipse.swt.layout.GridData;
024: import org.eclipse.swt.layout.GridLayout;
025: import org.eclipse.swt.widgets.Button;
026: import org.eclipse.swt.widgets.Composite;
027: import org.eclipse.swt.widgets.Event;
028: import org.eclipse.swt.widgets.Label;
029: import org.eclipse.swt.widgets.Listener;
030: import org.eclipse.swt.widgets.Text;
031:
032: import org.eclipse.jface.dialogs.Dialog;
033: import org.eclipse.jface.dialogs.IDialogSettings;
034: import org.eclipse.jface.resource.JFaceResources;
035: import org.eclipse.jface.window.Window;
036: import org.eclipse.jface.wizard.IWizardPage;
037: import org.eclipse.jface.wizard.WizardPage;
038:
039: import org.eclipse.ui.dialogs.SaveAsDialog;
040: import org.eclipse.ui.PlatformUI;
041:
042: import org.eclipse.jdt.internal.corext.util.Messages;
043:
044: import org.eclipse.jdt.ui.jarpackager.JarPackageData;
045:
046: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
047: import org.eclipse.jdt.internal.ui.JavaPlugin;
048:
049: import org.eclipse.jdt.internal.ui.util.SWTUtil;
050:
051: /**
052: * Page 2 of the JAR Package wizard
053: */
054: class JarOptionsPage extends WizardPage implements
055: IJarPackageWizardPage {
056:
057: // Untyped listener
058: private class UntypedListener implements Listener {
059: /*
060: * Implements method from Listener
061: */
062: public void handleEvent(Event e) {
063: if (getControl() == null)
064: return;
065: update();
066: }
067: }
068:
069: private JarPackageData fJarPackage;
070:
071: // widgets
072: private Button fExportErrorsCheckbox;
073: private Button fExportWarningsCheckbox;
074: private Button fUseSourceFoldersCheckbox;
075: private Composite fDescriptionFileGroup;
076: private Button fSaveDescriptionCheckbox;
077: private Label fDescriptionFileLabel;
078: private Text fDescriptionFileText;
079: private Button fDescriptionFileBrowseButton;
080: private Button fBuildIfNeededCheckbox;
081:
082: // dialog store id constants
083: private final static String PAGE_NAME = "jarOptionsWizardPage"; //$NON-NLS-1$
084:
085: private final static String STORE_EXPORT_WARNINGS = PAGE_NAME
086: + ".EXPORT_WARNINGS"; //$NON-NLS-1$
087: private final static String STORE_EXPORT_ERRORS = PAGE_NAME
088: + ".EXPORT_ERRORS"; //$NON-NLS-1$
089: private final static String STORE_SAVE_DESCRIPTION = PAGE_NAME
090: + ".SAVE_DESCRIPTION"; //$NON-NLS-1$
091: private final static String STORE_DESCRIPTION_LOCATION = PAGE_NAME
092: + ".DESCRIPTION_LOCATION"; //$NON-NLS-1$
093: private final static String STORE_USE_SRC_FOLDERS = PAGE_NAME
094: + ".STORE_USE_SRC_FOLDERS"; //$NON-NLS-1$
095: private final static String STORE_BUILD_IF_NEEDED = PAGE_NAME
096: + ".BUILD_IF_NEEDED"; //$NON-NLS-1$
097:
098: /**
099: * Create an instance of this class
100: */
101: public JarOptionsPage(JarPackageData jarPackage) {
102: super (PAGE_NAME);
103: setTitle(JarPackagerMessages.JarOptionsPage_title);
104: setDescription(JarPackagerMessages.JarOptionsPage_description);
105: fJarPackage = jarPackage;
106: }
107:
108: /*
109: * Method declared on IDialogPage.
110: */
111: public void createControl(Composite parent) {
112: Composite composite = new Composite(parent, SWT.NULL);
113: composite.setLayout(new GridLayout());
114: composite.setLayoutData(new GridData(
115: GridData.VERTICAL_ALIGN_FILL
116: | GridData.HORIZONTAL_ALIGN_FILL));
117:
118: createOptionsGroup(composite);
119:
120: restoreWidgetValues();
121: setControl(composite);
122: update();
123:
124: Dialog.applyDialogFont(composite);
125: PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
126: IJavaHelpContextIds.JAROPTIONS_WIZARD_PAGE);
127: }
128:
129: /**
130: * Create the export options specification widgets.
131: *
132: * @param parent org.eclipse.swt.widgets.Composite
133: */
134: protected void createOptionsGroup(Composite parent) {
135:
136: initializeDialogUnits(parent);
137:
138: Composite optionsGroup = new Composite(parent, SWT.NONE);
139: GridLayout layout = new GridLayout();
140: layout.marginHeight = 0;
141: optionsGroup.setLayout(layout);
142:
143: createLabel(
144: optionsGroup,
145: JarPackagerMessages.JarOptionsPage_howTreatProblems_label,
146: false);
147:
148: UntypedListener selectionListener = new UntypedListener();
149:
150: fExportErrorsCheckbox = new Button(optionsGroup, SWT.CHECK
151: | SWT.LEFT);
152: fExportErrorsCheckbox
153: .setText(JarPackagerMessages.JarOptionsPage_exportErrors_text);
154: fExportErrorsCheckbox.addListener(SWT.Selection,
155: selectionListener);
156:
157: fExportWarningsCheckbox = new Button(optionsGroup, SWT.CHECK
158: | SWT.LEFT);
159: fExportWarningsCheckbox
160: .setText(JarPackagerMessages.JarOptionsPage_exportWarnings_text);
161: fExportWarningsCheckbox.addListener(SWT.Selection,
162: selectionListener);
163:
164: createSpacer(optionsGroup);
165:
166: fUseSourceFoldersCheckbox = new Button(optionsGroup, SWT.CHECK
167: | SWT.LEFT);
168: fUseSourceFoldersCheckbox
169: .setText(JarPackagerMessages.JarOptionsPage_useSourceFoldersHierarchy);
170: fUseSourceFoldersCheckbox.addListener(SWT.Selection,
171: selectionListener);
172: fUseSourceFoldersCheckbox.setEnabled(fJarPackage
173: .areJavaFilesExported()
174: && !fJarPackage.areGeneratedFilesExported());
175:
176: createSpacer(optionsGroup);
177:
178: fBuildIfNeededCheckbox = new Button(optionsGroup, SWT.CHECK
179: | SWT.LEFT);
180: fBuildIfNeededCheckbox
181: .setText(JarPackagerMessages.JarOptionsPage_buildIfNeeded);
182: fBuildIfNeededCheckbox.addListener(SWT.Selection,
183: selectionListener);
184:
185: createSpacer(optionsGroup);
186:
187: fSaveDescriptionCheckbox = new Button(optionsGroup, SWT.CHECK
188: | SWT.LEFT);
189: fSaveDescriptionCheckbox
190: .setText(JarPackagerMessages.JarOptionsPage_saveDescription_text);
191: fSaveDescriptionCheckbox.addListener(SWT.Selection,
192: selectionListener);
193: createDescriptionFileGroup(parent);
194: }
195:
196: /**
197: * Persists resource specification control setting that are to be restored
198: * in the next instance of this page. Subclasses wishing to persist
199: * settings for their controls should extend the hook method
200: * <code>internalSaveWidgetValues</code>.
201: */
202: public final void saveWidgetValues() {
203: // update directory names history
204: IDialogSettings settings = getDialogSettings();
205: if (settings != null) {
206: settings.put(STORE_EXPORT_WARNINGS, fJarPackage
207: .exportWarnings());
208: settings.put(STORE_EXPORT_ERRORS, fJarPackage
209: .areErrorsExported());
210: settings.put(STORE_USE_SRC_FOLDERS, fJarPackage
211: .useSourceFolderHierarchy());
212: settings.put(STORE_BUILD_IF_NEEDED, fJarPackage
213: .isBuildingIfNeeded());
214: settings.put(STORE_SAVE_DESCRIPTION, fJarPackage
215: .isDescriptionSaved());
216: settings.put(STORE_DESCRIPTION_LOCATION, fJarPackage
217: .getDescriptionLocation().toString());
218: }
219: // Allow subclasses to save values
220: internalSaveWidgetValues();
221: }
222:
223: /**
224: * Hook method for subclasses to persist their settings.
225: */
226: protected void internalSaveWidgetValues() {
227: }
228:
229: /**
230: * Hook method for restoring widget values to the values that they held
231: * last time this wizard was used to completion.
232: */
233: protected void restoreWidgetValues() {
234: if (!((JarPackageWizard) getWizard())
235: .isInitializingFromJarPackage())
236: initializeJarPackage();
237:
238: fExportWarningsCheckbox.setSelection(fJarPackage
239: .exportWarnings());
240: fExportErrorsCheckbox.setSelection(fJarPackage
241: .areErrorsExported());
242: fBuildIfNeededCheckbox.setSelection(fJarPackage
243: .isBuildingIfNeeded());
244: fUseSourceFoldersCheckbox.setSelection(fJarPackage
245: .useSourceFolderHierarchy());
246: fSaveDescriptionCheckbox.setSelection(fJarPackage
247: .isDescriptionSaved());
248: fDescriptionFileText.setText(fJarPackage
249: .getDescriptionLocation().toString());
250: }
251:
252: /**
253: * Initializes the JAR package from last used wizard page values.
254: */
255: protected void initializeJarPackage() {
256: IDialogSettings settings = getDialogSettings();
257: if (settings != null) {
258: fJarPackage.setExportWarnings(settings
259: .getBoolean(STORE_EXPORT_WARNINGS));
260: fJarPackage.setExportErrors(settings
261: .getBoolean(STORE_EXPORT_ERRORS));
262: fJarPackage.setUseSourceFolderHierarchy(settings
263: .getBoolean(STORE_USE_SRC_FOLDERS));
264: fJarPackage.setSaveDescription(false); // bug 15877
265: String pathStr = settings.get(STORE_DESCRIPTION_LOCATION);
266: if (pathStr == null)
267: pathStr = ""; //$NON-NLS-1$
268: fJarPackage.setDescriptionLocation(new Path(pathStr));
269: if (settings.get(STORE_BUILD_IF_NEEDED) != null)
270: fJarPackage.setBuildIfNeeded(settings
271: .getBoolean(STORE_BUILD_IF_NEEDED));
272: }
273: }
274:
275: private void update() {
276: updateModel();
277: updateWidgetEnablements();
278: updatePageCompletion();
279: }
280:
281: /**
282: * Stores the widget values in the JAR package.
283: */
284: protected void updateModel() {
285: if (getControl() == null)
286: return;
287: fJarPackage.setExportWarnings(fExportWarningsCheckbox
288: .getSelection());
289: fJarPackage.setExportErrors(fExportErrorsCheckbox
290: .getSelection());
291: fJarPackage.setBuildIfNeeded(fBuildIfNeededCheckbox
292: .getSelection());
293: fJarPackage.setSaveDescription(fSaveDescriptionCheckbox
294: .getSelection());
295: fJarPackage.setDescriptionLocation(new Path(
296: fDescriptionFileText.getText()));
297: fJarPackage
298: .setUseSourceFolderHierarchy(fUseSourceFoldersCheckbox
299: .getSelection());
300: }
301:
302: /**
303: * Open an appropriate destination browser so that the user can specify a source
304: * to import from
305: */
306: protected void handleDescriptionFileBrowseButtonPressed() {
307: SaveAsDialog dialog = new SaveAsDialog(getContainer()
308: .getShell());
309: dialog.create();
310: dialog.getShell().setText(
311: JarPackagerMessages.JarOptionsPage_saveAsDialog_title);
312: dialog
313: .setMessage(JarPackagerMessages.JarOptionsPage_saveAsDialog_message);
314: dialog.setOriginalFile(createFileHandle(fJarPackage
315: .getDescriptionLocation()));
316: if (dialog.open() == Window.OK) {
317: IPath path = dialog.getResult();
318: path = path.removeFileExtension().addFileExtension(
319: JarPackagerUtil.DESCRIPTION_EXTENSION);
320: fDescriptionFileText.setText(path.toString());
321: }
322: }
323:
324: /**
325: * Updates the enablements of this page's controls. Subclasses may extend.
326: */
327: protected void updateWidgetEnablements() {
328: boolean saveDescription = fSaveDescriptionCheckbox
329: .getSelection();
330: fDescriptionFileGroup.setEnabled(saveDescription);
331: fDescriptionFileBrowseButton.setEnabled(saveDescription);
332: fDescriptionFileText.setEnabled(saveDescription);
333: fDescriptionFileLabel.setEnabled(saveDescription);
334:
335: boolean exportClassFiles = fJarPackage.areClassFilesExported()
336: && !fJarPackage.areOutputFoldersExported();
337: fExportWarningsCheckbox.setEnabled(exportClassFiles);
338: fExportErrorsCheckbox.setEnabled(exportClassFiles);
339:
340: boolean isAutobuilding = ResourcesPlugin.getWorkspace()
341: .isAutoBuilding();
342: fBuildIfNeededCheckbox.setEnabled(exportClassFiles
343: && !isAutobuilding);
344:
345: fUseSourceFoldersCheckbox.setEnabled(fJarPackage
346: .areJavaFilesExported()
347: && !fJarPackage.areGeneratedFilesExported());
348: }
349:
350: /*
351: * Implements method from IJarPackageWizardPage
352: */
353: public boolean isPageComplete() {
354: if (fJarPackage.isDescriptionSaved()) {
355: if (fJarPackage.getDescriptionLocation().toString()
356: .length() == 0) {
357: setErrorMessage(null);
358: return false;
359: }
360: IPath location = fJarPackage.getDescriptionLocation();
361: if (!location.toString().startsWith("/")) { //$NON-NLS-1$
362: setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionMustBeAbsolute);
363: return false;
364: }
365: IResource resource = findResource(location);
366: if (resource != null
367: && resource.getType() != IResource.FILE) {
368: setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionMustNotBeExistingContainer);
369: return false;
370: }
371: resource = findResource(location.removeLastSegments(1));
372: if (resource == null
373: || resource.getType() == IResource.FILE) {
374: setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionContainerDoesNotExist);
375: return false;
376: }
377: String fileExtension = fJarPackage.getDescriptionLocation()
378: .getFileExtension();
379: if (fileExtension == null
380: || !fileExtension
381: .equals(JarPackagerUtil.DESCRIPTION_EXTENSION)) {
382: setErrorMessage(Messages
383: .format(
384: JarPackagerMessages.JarOptionsPage_error_invalidDescriptionExtension,
385: JarPackagerUtil.DESCRIPTION_EXTENSION));
386: return false;
387: }
388: }
389: setErrorMessage(null);
390: return true;
391: }
392:
393: public boolean canFlipToNextPage() {
394: return fJarPackage.areGeneratedFilesExported()
395: && super .canFlipToNextPage();
396: }
397:
398: /*
399: * Overrides method from WizardDataTransferPage
400: */
401: protected void createDescriptionFileGroup(Composite parent) {
402: // destination specification group
403: fDescriptionFileGroup = new Composite(parent, SWT.NONE);
404: GridLayout layout = new GridLayout();
405: layout.numColumns = 3;
406: fDescriptionFileGroup.setLayout(layout);
407: fDescriptionFileGroup.setLayoutData(new GridData(
408: GridData.HORIZONTAL_ALIGN_FILL
409: | GridData.VERTICAL_ALIGN_FILL
410: | GridData.GRAB_HORIZONTAL));
411:
412: fDescriptionFileLabel = new Label(fDescriptionFileGroup,
413: SWT.NONE);
414: fDescriptionFileLabel
415: .setText(JarPackagerMessages.JarOptionsPage_descriptionFile_label);
416:
417: // destination name entry field
418: fDescriptionFileText = new Text(fDescriptionFileGroup,
419: SWT.SINGLE | SWT.BORDER);
420: fDescriptionFileText.addListener(SWT.Modify,
421: new UntypedListener());
422: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
423: | GridData.GRAB_HORIZONTAL);
424: data.widthHint = convertWidthInCharsToPixels(40);
425: fDescriptionFileText.setLayoutData(data);
426:
427: // destination browse button
428: fDescriptionFileBrowseButton = new Button(
429: fDescriptionFileGroup, SWT.PUSH);
430: fDescriptionFileBrowseButton
431: .setText(JarPackagerMessages.JarOptionsPage_browseButton_text);
432: fDescriptionFileBrowseButton.setLayoutData(new GridData(
433: GridData.HORIZONTAL_ALIGN_FILL));
434: SWTUtil.setButtonDimensionHint(fDescriptionFileBrowseButton);
435: fDescriptionFileBrowseButton
436: .addSelectionListener(new SelectionAdapter() {
437: public void widgetSelected(SelectionEvent e) {
438: handleDescriptionFileBrowseButtonPressed();
439: }
440: });
441: }
442:
443: /**
444: * Creates a file resource handle for the file with the given workspace path.
445: * This method does not create the file resource; this is the responsibility
446: * of <code>createFile</code>.
447: *
448: * @param filePath the path of the file resource to create a handle for
449: * @return the new file resource handle
450: */
451: protected IFile createFileHandle(IPath filePath) {
452: if (filePath.isValidPath(filePath.toString())
453: && filePath.segmentCount() >= 2)
454: return JavaPlugin.getWorkspace().getRoot()
455: .getFile(filePath);
456: else
457: return null;
458: }
459:
460: /*
461: * Method declared on IWizardPage.
462: */
463: public void setPreviousPage(IWizardPage page) {
464: super .setPreviousPage(page);
465: updateWidgetEnablements();
466: if (getControl() != null)
467: updatePageCompletion();
468: }
469:
470: /*
471: * Implements method from IJarPackageWizardPage.
472: */
473: public void finish() {
474: saveWidgetValues();
475: }
476:
477: /**
478: * Creates a new label with a bold font.
479: *
480: * @param parent the parent control
481: * @param text the label text
482: * @return the new label control
483: */
484: protected Label createLabel(Composite parent, String text,
485: boolean bold) {
486: Label label = new Label(parent, SWT.NONE);
487: if (bold)
488: label.setFont(JFaceResources.getBannerFont());
489: label.setText(text);
490: GridData data = new GridData();
491: data.verticalAlignment = GridData.FILL;
492: data.horizontalAlignment = GridData.FILL;
493: label.setLayoutData(data);
494: return label;
495: }
496:
497: /**
498: * Creates a horizontal spacer line that fills the width of its container.
499: *
500: * @param parent the parent control
501: */
502: protected void createSpacer(Composite parent) {
503: Label spacer = new Label(parent, SWT.NONE);
504: GridData data = new GridData();
505: data.horizontalAlignment = GridData.FILL;
506: data.verticalAlignment = GridData.BEGINNING;
507: spacer.setLayoutData(data);
508: }
509:
510: /**
511: * Determine if the page is complete and update the page appropriately.
512: */
513: protected void updatePageCompletion() {
514: boolean pageComplete = isPageComplete();
515: setPageComplete(pageComplete);
516: if (pageComplete) {
517: setErrorMessage(null);
518: }
519: }
520:
521: /**
522: * Returns the resource for the specified path.
523: *
524: * @param path the path for which the resource should be returned
525: * @return the resource specified by the path or <code>null</code>
526: */
527: protected IResource findResource(IPath path) {
528: IWorkspace workspace = JavaPlugin.getWorkspace();
529: IStatus result = workspace.validatePath(path.toString(),
530: IResource.ROOT | IResource.PROJECT | IResource.FOLDER
531: | IResource.FILE);
532: if (result.isOK() && workspace.getRoot().exists(path))
533: return workspace.getRoot().findMember(path);
534: return null;
535: }
536: }
|