1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package org.eclipse.jdt.internal.ui.javadocexport;
15 import java.lang.reflect.InvocationTargetException;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.ModifyEvent;
25 import org.eclipse.swt.events.ModifyListener;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Group;
34 import org.eclipse.swt.widgets.Shell;
35 import org.eclipse.swt.widgets.Text;
37 import org.eclipse.core.runtime.CoreException;
38 import org.eclipse.core.runtime.IPath;
39 import org.eclipse.core.runtime.IProgressMonitor;
40 import org.eclipse.core.runtime.IStatus;
42 import org.eclipse.core.resources.IProject;
43 import org.eclipse.core.resources.IWorkspaceRunnable;
45 import org.eclipse.jface.dialogs.Dialog;
46 import org.eclipse.jface.dialogs.StatusDialog;
47 import org.eclipse.jface.viewers.ViewerComparator;
48 import org.eclipse.jface.window.Window;
50 import org.eclipse.ui.PlatformUI;
52 import org.eclipse.jdt.core.IClasspathEntry;
53 import org.eclipse.jdt.core.IJavaProject;
54 import org.eclipse.jdt.core.JavaCore;
56 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
57 import org.eclipse.jdt.launching.JavaRuntime;
59 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
60 import org.eclipse.jdt.internal.ui.JavaPlugin;
61 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
62 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
63 import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
64 import org.eclipse.jdt.internal.ui.preferences.JavadocConfigurationBlock;
65 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
66 import org.eclipse.jdt.internal.ui.util.SWTUtil;
67 import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
68 import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
69 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
70 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
71 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
72 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
73 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
75 public class JavadocStandardWizardPage extends JavadocWizardPage {
78 private final int STYLESHEETSTATUS= 1;
79 private final int LINK_REFERENCES= 2;
81 private JavadocOptionsManager fStore;
82 private Composite fUpperComposite;
84 private Group fBasicOptionsGroup;
85 private Group fTagsGroup;
87 private Button fTitleButton;
88 private Text fTitleText;
89 private Text fStyleSheetText;
90 private FlaggedButton fDeprecatedList;
91 private FlaggedButton fDeprecatedCheck;
92 private FlaggedButton fIndexCheck;
93 private FlaggedButton fSeperatedIndexCheck;
94 private Button fStyleSheetBrowseButton;
95 private Button fStyleSheetButton;
97 private CheckedListDialogField<JavadocLinkRef> fListDialogField;
99 private StatusInfo fStyleSheetStatus;
100 private StatusInfo fLinkRefStatus;
102 private ArrayList<FlaggedButton> fButtonsList;
103 private JavadocTreeWizardPage fFirstPage;
106 public JavadocStandardWizardPage(String pageName, JavadocTreeWizardPage firstPage, JavadocOptionsManager store) {
108 fFirstPage= firstPage;
109 setDescription(JavadocExportMessages.JavadocStandardWizardPage_description);
112 fButtonsList= new ArrayList<FlaggedButton>();
113 fStyleSheetStatus= new StatusInfo();
114 fLinkRefStatus= new StatusInfo();
117 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
119 public void createControl(Composite parent) {
121 initializeDialogUnits(parent);
123 fUpperComposite= new Composite(parent, SWT.NONE);
124 fUpperComposite.setFont(parent.getFont());
125 fUpperComposite.setLayoutData(createGridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL, 1, 0));
127 GridLayout layout= createGridLayout(4);
128 layout.marginHeight= 0;
129 fUpperComposite.setLayout(layout);
131 createBasicOptionsGroup(fUpperComposite);
132 createTagOptionsGroup(fUpperComposite);
133 createListDialogField(fUpperComposite);
134 createStyleSheetGroup(fUpperComposite);
136 setControl(fUpperComposite);
137 Dialog.applyDialogFont(fUpperComposite);
138 PlatformUI.getWorkbench().getHelpSystem().setHelp(fUpperComposite, IJavaHelpContextIds.JAVADOC_STANDARD_PAGE);
140 private void createBasicOptionsGroup(Composite composite) {
142 fTitleButton= createButton(composite, SWT.CHECK, JavadocExportMessages.JavadocStandardWizardPage_titlebutton_label, createGridData(1));
143 fTitleText= createText(composite, SWT.SINGLE | SWT.BORDER, null, createGridData(GridData.FILL_HORIZONTAL, 3, 0));
144 SWTUtil.setAccessibilityText(fTitleText, JavadocExportMessages.JavadocStandardWizardPage_titlebutton_description);
146 String text= fStore.getTitle();
147 if (!text.equals("")) { //$NON-NLS-1$
148 fTitleText.setText(text);
149 fTitleButton.setSelection(true);
151 fTitleText.setEnabled(false);
153 fBasicOptionsGroup= new Group(composite, SWT.SHADOW_ETCHED_IN);
154 fBasicOptionsGroup.setLayout(createGridLayout(1));
155 fBasicOptionsGroup.setLayoutData(createGridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL, 2, 0));
156 fBasicOptionsGroup.setText(JavadocExportMessages.JavadocStandardWizardPage_basicgroup_label);
158 new FlaggedButton(fBasicOptionsGroup, JavadocExportMessages.JavadocStandardWizardPage_usebutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.USE, true);
159 new FlaggedButton(fBasicOptionsGroup, JavadocExportMessages.JavadocStandardWizardPage_hierarchybutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.NOTREE, false);
160 new FlaggedButton(fBasicOptionsGroup, JavadocExportMessages.JavadocStandardWizardPage_navigartorbutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.NONAVBAR, false);
162 fIndexCheck= new FlaggedButton(fBasicOptionsGroup, JavadocExportMessages.JavadocStandardWizardPage_indexbutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.NOINDEX, false);
164 fSeperatedIndexCheck= new FlaggedButton(fBasicOptionsGroup, JavadocExportMessages.JavadocStandardWizardPage_seperateindexbutton_label, createGridData(GridData.GRAB_HORIZONTAL, 1, convertWidthInCharsToPixels(3)), fStore.SPLITINDEX, true);
165 fSeperatedIndexCheck.getButton().setEnabled(fIndexCheck.getButton().getSelection());
167 fIndexCheck.getButton().addSelectionListener(new ToggleSelectionAdapter(new Control[] { fSeperatedIndexCheck.getButton()}));
168 fTitleButton.addSelectionListener(new ToggleSelectionAdapter(new Control[] { fTitleText }));
172 private void createTagOptionsGroup(Composite composite) {
173 fTagsGroup= new Group(composite, SWT.SHADOW_ETCHED_IN);
174 fTagsGroup.setLayout(createGridLayout(1));
175 fTagsGroup.setLayoutData(createGridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL, 2, 0));
176 fTagsGroup.setText(JavadocExportMessages.JavadocStandardWizardPage_tagsgroup_label);
178 new FlaggedButton(fTagsGroup, JavadocExportMessages.JavadocStandardWizardPage_authorbutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.AUTHOR, true);
179 new FlaggedButton(fTagsGroup, JavadocExportMessages.JavadocStandardWizardPage_versionbutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.VERSION, true);
180 fDeprecatedCheck= new FlaggedButton(fTagsGroup, JavadocExportMessages.JavadocStandardWizardPage_deprecatedbutton_label, new GridData(GridData.FILL_HORIZONTAL), fStore.NODEPRECATED, false);
181 fDeprecatedList= new FlaggedButton(fTagsGroup, JavadocExportMessages.JavadocStandardWizardPage_deprecatedlistbutton_label, createGridData(GridData.FILL_HORIZONTAL, 1, convertWidthInCharsToPixels(3)), fStore.NODEPRECATEDLIST, false);
182 fDeprecatedList.getButton().setEnabled(fDeprecatedCheck.getButton().getSelection());
184 fDeprecatedCheck.getButton().addSelectionListener(new ToggleSelectionAdapter(new Control[] { fDeprecatedList.getButton()}));
185 } //end createTagOptionsGroup
187 private void createStyleSheetGroup(Composite composite) {
188 Composite c= new Composite(composite, SWT.NONE);
189 c.setLayout(createGridLayout(3));
190 c.setLayoutData(createGridData(GridData.FILL_HORIZONTAL, 4, 0));
191 ((GridLayout) c.getLayout()).marginWidth= 0;
193 fStyleSheetButton= createButton(c, SWT.CHECK, JavadocExportMessages.JavadocStandardWizardPage_stylesheettext_label, createGridData(1));
194 fStyleSheetText= createText(c, SWT.SINGLE | SWT.BORDER, null, createGridData(GridData.FILL_HORIZONTAL, 1, 0));
195 SWTUtil.setAccessibilityText(fStyleSheetText, JavadocExportMessages.JavadocStandardWizardPage_stylesheettext_description);
196 //there really aught to be a way to specify this
197 ((GridData) fStyleSheetText.getLayoutData()).widthHint= 200;
198 fStyleSheetBrowseButton= createButton(c, SWT.PUSH, JavadocExportMessages.JavadocStandardWizardPage_stylesheetbrowsebutton_label, createGridData(GridData.HORIZONTAL_ALIGN_END, 1, 0));
199 SWTUtil.setButtonDimensionHint(fStyleSheetBrowseButton);
201 String str= fStore.getStyleSheet();
202 if (str.equals("")) { //$NON-NLS-1$
204 fStyleSheetText.setEnabled(false);
205 fStyleSheetBrowseButton.setEnabled(false);
207 fStyleSheetButton.setSelection(true);
208 fStyleSheetText.setText(str);
212 fStyleSheetButton.addSelectionListener(new ToggleSelectionAdapter(new Control[] { fStyleSheetText, fStyleSheetBrowseButton }) {
214 public void validate() {
215 doValidation(STYLESHEETSTATUS);
219 fStyleSheetText.addModifyListener(new ModifyListener() {
220 public void modifyText(ModifyEvent e) {
221 doValidation(STYLESHEETSTATUS);
225 fStyleSheetBrowseButton.addSelectionListener(new SelectionAdapter() {
227 public void widgetSelected(SelectionEvent event) {
228 handleFileBrowseButtonPressed(fStyleSheetText, new String[] { "*.css" }, JavadocExportMessages.JavadocSpecificsWizardPage_stylesheetbrowsedialog_title); //$NON-NLS-1$
234 private void createListDialogField(Composite composite) {
235 Composite c= new Composite(composite, SWT.NONE);
236 c.setFont(composite.getFont());
237 c.setLayout(createGridLayout(3));
238 c.setLayoutData(createGridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL, 4, 0));
239 ((GridLayout) c.getLayout()).marginWidth= 0;
241 String[] buttonlabels= new String[] { JavadocExportMessages.JavadocStandardWizardPage_selectallbutton_label, JavadocExportMessages.JavadocStandardWizardPage_clearallbutton_label, JavadocExportMessages.JavadocStandardWizardPage_configurebutton_label};
243 JavadocLinkDialogLabelProvider labelProvider= new JavadocLinkDialogLabelProvider();
245 ListAdapter adapter= new ListAdapter();
247 fListDialogField= new CheckedListDialogField<JavadocLinkRef>(adapter, buttonlabels, labelProvider);
248 fListDialogField.setDialogFieldListener(adapter);
249 fListDialogField.setCheckAllButtonIndex(0);
250 fListDialogField.setUncheckAllButtonIndex(1);
251 fListDialogField.setViewerComparator(new ViewerComparator());
253 createLabel(c, SWT.NONE, JavadocExportMessages.JavadocStandardWizardPage_referencedclasses_label, createGridData(GridData.HORIZONTAL_ALIGN_BEGINNING, 4, 0));
254 fListDialogField.doFillIntoGrid(c, 3);
256 LayoutUtil.setHorizontalGrabbing(fListDialogField.getListControl(null));
258 fListDialogField.enableButton(2, false);
261 private List<JavadocLinkRef> getCheckedReferences(JavadocLinkRef[] referencesClasses) {
262 List<JavadocLinkRef> checkedElements= new ArrayList<JavadocLinkRef>();
264 String hrefs[]= fStore.getHRefs();
265 if (hrefs.length > 0) {
266 HashSet<String> set= new HashSet<String>();
267 for (int i= 0; i < hrefs.length; i++) {
270 for (int i = 0; i < referencesClasses.length; i++) {
271 JavadocLinkRef curr= referencesClasses[i];
272 URL url= curr.getURL();
273 if (url != null && set.contains(url.toExternalForm())) {
274 checkedElements.add(curr);
278 return checkedElements;
284 * Returns IJavaProjects and IPaths that will be on the classpath
285 * @param checkedProjects the list of checked projects
286 * @return all IJavaProjects and IPaths that will be on the classpath
288 private JavadocLinkRef[] getReferencedElements(IJavaProject[] checkedProjects) {
289 HashSet<JavadocLinkRef> result= new HashSet<JavadocLinkRef>();
290 for (int i= 0; i < checkedProjects.length; i++) {
291 IJavaProject project= checkedProjects[i];
293 collectReferencedElements(project, result);
294 } catch (CoreException e) {
299 return result.toArray(new JavadocLinkRef[result.size()]);
302 private void collectReferencedElements(IJavaProject project, HashSet<JavadocLinkRef> result) throws CoreException {
303 IRuntimeClasspathEntry[] unresolved = JavaRuntime.computeUnresolvedRuntimeClasspath(project);
304 for (int i= 0; i < unresolved.length; i++) {
305 IRuntimeClasspathEntry curr= unresolved[i];
306 if (curr.getType() == IRuntimeClasspathEntry.PROJECT) {
307 result.add(new JavadocLinkRef(JavaCore.create((IProject) curr.getResource())));
309 IRuntimeClasspathEntry[] entries= JavaRuntime.resolveRuntimeClasspathEntry(curr, project);
310 for (int k = 0; k < entries.length; k++) {
311 IRuntimeClasspathEntry entry= entries[k];
312 if (entry.getType() == IRuntimeClasspathEntry.PROJECT) {
313 result.add(new JavadocLinkRef(JavaCore.create((IProject) entry.getResource())));
314 } else if (entry.getType() == IRuntimeClasspathEntry.ARCHIVE) {
315 IClasspathEntry classpathEntry= entry.getClasspathEntry();
316 if (classpathEntry != null) {
317 IPath containerPath= null;
318 if (curr.getType() == IRuntimeClasspathEntry.CONTAINER) {
319 containerPath= curr.getPath();
321 result.add(new JavadocLinkRef(containerPath, classpathEntry, project));
329 final void doValidation(int VALIDATE) {
331 case STYLESHEETSTATUS :
332 fStyleSheetStatus= new StatusInfo();
333 if (fStyleSheetButton.getSelection()) {
334 String filename= fStyleSheetText.getText();
335 if (filename.length() == 0) {
336 fStyleSheetStatus.setError(JavadocExportMessages.JavadocSpecificsWizardPage_overviewnotfound_error);
338 File file= new File(filename);
339 String ext= filename.substring(filename.lastIndexOf('.') + 1);
340 if (!file.isFile()) {
341 fStyleSheetStatus.setError(JavadocExportMessages.JavadocStandardWizardPage_stylesheetnopath_error);
342 } else if (!ext.equalsIgnoreCase("css")) { //$NON-NLS-1$
343 fStyleSheetStatus.setError(JavadocExportMessages.JavadocStandardWizardPage_stylesheetnotcss_error);
348 case LINK_REFERENCES:
349 fLinkRefStatus= new StatusInfo();
350 List<JavadocLinkRef> list= fListDialogField.getCheckedElements();
351 for (int i= 0; i < list.size(); i++) {
352 JavadocLinkRef curr= list.get(i);
353 URL url= curr.getURL();
355 fLinkRefStatus.setWarning(JavadocExportMessages.JavadocStandardWizardPage_nolinkref_error);
357 } else if ("jar".equals(url.getProtocol())) { //$NON-NLS-1$
358 fLinkRefStatus.setWarning(JavadocExportMessages.JavadocStandardWizardPage_nojarlinkref_error);
365 updateStatus(findMostSevereStatus());
369 private IStatus findMostSevereStatus() {
370 return StatusUtil.getMostSevere(new IStatus[] { fStyleSheetStatus, fLinkRefStatus });
373 public void updateStore() {
375 if (fTitleButton.getSelection())
376 fStore.setTitle(fTitleText.getText());
378 fStore.setTitle(""); //$NON-NLS-1$
380 //don't store the buttons if they are not enabled
381 //this will change when there is a single page aimed at the standard doclet
383 Object[] buttons= fButtonsList.toArray();
384 for (int i= 0; i < buttons.length; i++) {
385 FlaggedButton button= (FlaggedButton) buttons[i];
386 if (button.getButton().getEnabled())
387 fStore.setBoolean(button.getFlag(), !(button.getButton().getSelection() ^ button.show()));
389 fStore.setBoolean(button.getFlag(), false == button.show());
393 if (fStyleSheetText.getEnabled())
394 fStore.setStyleSheet(fStyleSheetText.getText());
396 fStore.setStyleSheet(""); //$NON-NLS-1$
398 fStore.setHRefs(getHRefs());
401 private String[] getHRefs() {
402 HashSet<String> res= new HashSet<String>();
403 List<JavadocLinkRef> checked= fListDialogField.getCheckedElements();
404 for (Iterator<JavadocLinkRef> iterator= checked.iterator(); iterator.hasNext();) {
405 JavadocLinkRef element= iterator.next();
406 URL url= element.getURL();
408 res.add(url.toExternalForm());
411 return res.toArray(new String[res.size()]);
417 public void setVisible(boolean visible) {
418 super.setVisible(visible);
420 doValidation(STYLESHEETSTATUS);
421 updateHRefList(fFirstPage.getCheckedProjects());
428 * Method will refresh the list of referenced libraries and projects
429 * depended on the projects or elements of projects selected in the
430 * TreeViewer on the JavadocTreeWizardPage.
431 * @param checkedProjects the list of checked projects
433 private void updateHRefList(IJavaProject[] checkedProjects) {
434 JavadocLinkRef[] res= getReferencedElements(checkedProjects);
435 fListDialogField.setElements(Arrays.asList(res));
437 List<JavadocLinkRef> checked= getCheckedReferences(res);
438 fListDialogField.setCheckedElements(checked);
442 updateStatus(new StatusInfo());
445 protected class FlaggedButton {
447 private Button fButton;
448 private String fFlag;
449 private boolean fShowFlag;
451 public FlaggedButton(Composite composite, String message, GridData gridData, String flag, boolean show) {
454 fButton= createButton(composite, SWT.CHECK, message, gridData);
455 fButtonsList.add(this);
459 public Button getButton() {
463 public String getFlag() {
466 public boolean show() {
470 private void setButtonSettings() {
472 fButton.setSelection(!(fStore.getBoolean(fFlag) ^ fShowFlag));
475 } //end class FlaggesButton
477 private class ListAdapter implements IListAdapter<JavadocLinkRef>, IDialogFieldListener {
480 * @see IListAdapter#customButtonPressed(ListDialogField, int)
482 public void customButtonPressed(ListDialogField<JavadocLinkRef> field, int index) {
484 doEditButtonPressed();
488 * @see IListAdapter#selectionChanged(ListDialogField)
490 public void selectionChanged(ListDialogField<JavadocLinkRef> field) {
491 List<JavadocLinkRef> selection= fListDialogField.getSelectedElements();
492 if (selection.size() != 1) {
493 fListDialogField.enableButton(2, false);
495 fListDialogField.enableButton(2, true);
499 public void doubleClicked(ListDialogField<JavadocLinkRef> field) {
500 doEditButtonPressed();
503 public void dialogFieldChanged(DialogField field) {
504 doValidation(LINK_REFERENCES);
510 * Method doEditButtonPressed.
512 private void doEditButtonPressed() {
514 List<JavadocLinkRef> selected= fListDialogField.getSelectedElements();
515 if (selected.isEmpty()) {
518 JavadocLinkRef obj= selected.get(0);
520 JavadocPropertyDialog jdialog= new JavadocPropertyDialog(getShell(), obj);
521 if (jdialog.open() == Window.OK) {
522 fListDialogField.refresh();
528 private class JavadocPropertyDialog extends StatusDialog implements IStatusChangeListener {
530 private JavadocConfigurationBlock fJavadocConfigurationBlock;
531 private JavadocLinkRef fElement;
533 public JavadocPropertyDialog(Shell parent, JavadocLinkRef selection) {
535 setTitle(JavadocExportMessages.JavadocStandardWizardPage_javadocpropertydialog_title);
538 URL initialLocation= selection.getURL();
539 fJavadocConfigurationBlock= new JavadocConfigurationBlock(parent, this, initialLocation, selection.isProjectRef());
543 protected Control createDialogArea(Composite parent) {
544 Composite composite= (Composite) super.createDialogArea(parent);
545 Control inner= fJavadocConfigurationBlock.createContents(composite);
546 inner.setLayoutData(new GridData(GridData.FILL_BOTH));
547 applyDialogFont(composite);
551 public void statusChanged(IStatus status) {
552 updateStatus(status);
557 * @see Dialog#okPressed()
560 protected void okPressed() {
562 IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
563 public void run(IProgressMonitor monitor) throws CoreException {
564 URL javadocLocation= fJavadocConfigurationBlock.getJavadocLocation();
565 fElement.setURL(javadocLocation, monitor);
568 PlatformUI.getWorkbench().getProgressService().run(true, true, new WorkbenchRunnableAdapter(runnable));
570 } catch (InvocationTargetException e) {
571 String title= JavadocExportMessages.JavadocStandardWizardPage_configurecontainer_error_title;
572 String message= JavadocExportMessages.JavadocStandardWizardPage_configurecontainer_error_message;
573 ExceptionHandler.handle(e, getShell(), title, message);
574 } catch (InterruptedException e) {
578 fListDialogField.refresh();
579 doValidation(LINK_REFERENCES);
584 * @see org.eclipse.jface.window.Window#configureShell(Shell)
587 protected void configureShell(Shell newShell) {
588 super.configureShell(newShell);
589 PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.JAVADOC_PROPERTY_DIALOG);