1 /*******************************************************************************
2  * Copyright (c) 2013, 2018 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.pde.api.tools.ui.internal.wizards;
15 
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.HashSet;
19 
20 import org.eclipse.core.resources.IProject;
21 import org.eclipse.core.runtime.IAdaptable;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.jdt.core.JavaCore;
26 import org.eclipse.jface.dialogs.IDialogSettings;
27 import org.eclipse.jface.dialogs.IMessageProvider;
28 import org.eclipse.jface.viewers.ArrayContentProvider;
29 import org.eclipse.jface.viewers.CheckboxTableViewer;
30 import org.eclipse.jface.viewers.ISelection;
31 import org.eclipse.jface.viewers.ISelectionProvider;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.jface.viewers.ViewerComparator;
34 import org.eclipse.jface.wizard.IWizardPage;
35 import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
36 import org.eclipse.pde.api.tools.internal.util.Util;
37 import org.eclipse.pde.api.tools.ui.internal.ApiUIPlugin;
38 import org.eclipse.pde.api.tools.ui.internal.IApiToolsHelpContextIds;
39 import org.eclipse.pde.api.tools.ui.internal.SWTFactory;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.events.KeyListener;
42 import org.eclipse.swt.events.SelectionListener;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.widgets.Button;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Table;
47 import org.eclipse.swt.widgets.TableItem;
48 import org.eclipse.swt.widgets.Text;
49 import org.eclipse.ui.IWorkbenchPage;
50 import org.eclipse.ui.IWorkbenchPart;
51 import org.eclipse.ui.IWorkbenchSite;
52 import org.eclipse.ui.IWorkbenchWindow;
53 import org.eclipse.ui.PlatformUI;
54 import org.eclipse.ui.model.WorkbenchLabelProvider;
55 import org.eclipse.ui.progress.WorkbenchJob;
56 
57 /**
58  * The wizard page for performing the conversion
59  *
60  * @since 1.0.500
61  */
62 public class JavadocConversionPage extends UserInputWizardPage {
63 
64 	/**
65 	 * Job for updating the filtering on the table viewer
66 	 */
67 	class UpdateJob extends WorkbenchJob {
68 
69 		private String pattern = null;
70 
71 		/**
72 		 * Constructor
73 		 */
UpdateJob()74 		public UpdateJob() {
75 			super(WizardMessages.ApiToolingSetupWizardPage_filter_update_job);
76 			setSystem(true);
77 		}
78 
79 		/**
80 		 * Sets the current text filter to use
81 		 *
82 		 * @param filter
83 		 */
setFilter(String pattern)84 		public synchronized void setFilter(String pattern) {
85 			this.pattern = pattern;
86 		}
87 
88 		@Override
runInUIThread(IProgressMonitor monitor)89 		public IStatus runInUIThread(IProgressMonitor monitor) {
90 			if (tableviewer != null) {
91 				try {
92 					tableviewer.getTable().setRedraw(false);
93 					synchronized (this) {
94 						filter.setPattern(pattern + '*');
95 					}
96 					tableviewer.refresh(true);
97 					tableviewer.setCheckedElements(checkedset.toArray());
98 				} finally {
99 					tableviewer.getTable().setRedraw(true);
100 				}
101 			}
102 			return Status.OK_STATUS;
103 		}
104 
105 	}
106 
107 	private static final String SETTINGS_SECTION = "JavadocTagConversionWizardPage"; //$NON-NLS-1$
108 	private static final String SETTINGS_REMOVE_TAGS = "remove_tags"; //$NON-NLS-1$
109 
110 	Button removetags = null;
111 	CheckboxTableViewer tableviewer = null;
112 	HashSet<Object> checkedset = new HashSet<>();
113 	UpdateJob updatejob = new UpdateJob();
114 	StringFilter filter = new StringFilter();
115 	private Text checkcount = null;
116 
117 	/**
118 	 * Constructor
119 	 *
120 	 * @param name
121 	 */
JavadocConversionPage()122 	public JavadocConversionPage() {
123 		super(WizardMessages.JavadocConversionWizard_0);
124 		setTitle(WizardMessages.JavadocConversionWizard_0);
125 		setDescription(WizardMessages.JavadocConversionPage_convert_tags_to_annotations_description);
126 	}
127 
128 	@Override
createControl(Composite parent)129 	public void createControl(Composite parent) {
130 		Composite comp = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_BOTH);
131 		setControl(comp);
132 		PlatformUI.getWorkbench().getHelpSystem().setHelp(comp, IApiToolsHelpContextIds.JAVADOC_CONVERSION_WIZARD_PAGE);
133 		SWTFactory.createWrapLabel(comp, WizardMessages.JavadocConversionPage_select_pjs_to_convert, 1, 100);
134 		SWTFactory.createVerticalSpacer(comp, 1);
135 		SWTFactory.createWrapLabel(comp, WizardMessages.ApiToolingSetupWizardPage_6, 1, 50);
136 
137 		final Text text = SWTFactory.createText(comp, SWT.BORDER, 1);
138 		text.addModifyListener(e -> {
139 			updatejob.setFilter(text.getText().trim());
140 			updatejob.cancel();
141 			updatejob.schedule();
142 		});
143 		text.addKeyListener(KeyListener.keyPressedAdapter(e -> {
144 			if (e.keyCode == SWT.ARROW_DOWN) {
145 				if (tableviewer != null) {
146 					tableviewer.getTable().setFocus();
147 				}
148 			}
149 		}));
150 
151 		SWTFactory.createWrapLabel(comp, WizardMessages.UpdateJavadocTagsWizardPage_8, 1, 50);
152 
153 		Table table = new Table(comp, SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK | SWT.MULTI);
154 		GridData gd = new GridData(GridData.FILL_BOTH);
155 		gd.heightHint = 150;
156 		table.setLayoutData(gd);
157 		tableviewer = new CheckboxTableViewer(table);
158 		tableviewer.setLabelProvider(new WorkbenchLabelProvider());
159 		tableviewer.setContentProvider(ArrayContentProvider.getInstance());
160 		IProject[] input = Util.getApiProjectsMinSourceLevel(JavaCore.VERSION_1_5);
161 		if (input == null) {
162 			setMessage(WizardMessages.JavadocConversionPage_0, IMessageProvider.WARNING);
163 		} else {
164 			tableviewer.setInput(input);
165 		}
166 		tableviewer.setComparator(new ViewerComparator());
167 		tableviewer.addFilter(filter);
168 		tableviewer.addCheckStateListener(event -> {
169 			if (event.getChecked()) {
170 				checkedset.add(event.getElement());
171 			} else {
172 				checkedset.remove(event.getElement());
173 			}
174 			setPageComplete(pageValid());
175 		});
176 		Composite bcomp = SWTFactory.createComposite(comp, 3, 1, GridData.FILL_HORIZONTAL | GridData.END, 0, 0);
177 		Button button = SWTFactory.createPushButton(bcomp, WizardMessages.UpdateJavadocTagsWizardPage_10, null);
178 		button.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
179 			tableviewer.setAllChecked(true);
180 			checkedset.addAll(Arrays.asList(tableviewer.getCheckedElements()));
181 			setPageComplete(pageValid());
182 		}));
183 		button = SWTFactory.createPushButton(bcomp, WizardMessages.UpdateJavadocTagsWizardPage_11, null);
184 		button.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
185 			tableviewer.setAllChecked(false);
186 			TableItem[] items = tableviewer.getTable().getItems();
187 			for (TableItem item : items) {
188 				checkedset.remove(item.getData());
189 			}
190 			setPageComplete(pageValid());
191 		}));
192 
193 		checkcount = SWTFactory.createText(bcomp, SWT.FLAT | SWT.READ_ONLY, 1, GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
194 		checkcount.setBackground(bcomp.getBackground());
195 
196 		Object[] selected = getWorkbenchSelection();
197 		if (selected.length > 0) {
198 			tableviewer.setCheckedElements(selected);
199 			checkedset.addAll(Arrays.asList(selected));
200 		}
201 		setPageComplete(tableviewer.getCheckedElements().length > 0);
202 
203 		SWTFactory.createVerticalSpacer(comp, 1);
204 		removetags = SWTFactory.createCheckButton(comp, WizardMessages.JavadocConversionPage_delete_tags_during_conversion, null, true, 1);
205 
206 		IDialogSettings settings = ApiUIPlugin.getDefault().getDialogSettings().getSection(SETTINGS_SECTION);
207 		if (settings != null) {
208 			removetags.setSelection(settings.getBoolean(SETTINGS_REMOVE_TAGS));
209 		}
210 	}
211 
212 	/**
213 	 * @return if the page is valid or not, this method also sets error messages
214 	 */
pageValid()215 	protected boolean pageValid() {
216 		if (checkedset.size() < 1) {
217 			setErrorMessage(WizardMessages.UpdateJavadocTagsWizardPage_12);
218 			return false;
219 		}
220 		setErrorMessage(null);
221 		return true;
222 	}
223 
224 	/**
225 	 * Called by the {@link ApiToolingSetupWizard} when finishing the wizard
226 	 *
227 	 * @return true if the page finished normally, false otherwise
228 	 */
finish()229 	public boolean finish() {
230 		IDialogSettings settings = ApiUIPlugin.getDefault().getDialogSettings().addNewSection(SETTINGS_SECTION);
231 		settings.put(SETTINGS_REMOVE_TAGS, removetags.getSelection());
232 		return true;
233 	}
234 
235 	@Override
getNextPage()236 	public IWizardPage getNextPage() {
237 		// always have to collect changes again in the event the user goes back
238 		// and forth,
239 		// as a change cannot ever have more than one parent - EVER
240 		JavadocConversionRefactoring refactoring = (JavadocConversionRefactoring) getRefactoring();
241 		HashSet<IProject> projects = new HashSet<>();
242 		for (Object object : checkedset) {
243 			IProject current = (IProject) object;
244 			projects.add(current);
245 		}
246 		refactoring.setProjects(projects);
247 		refactoring.setRemoveTags(removetags.getSelection());
248 		IWizardPage page = super.getNextPage();
249 		if (page != null) {
250 			page.setDescription(WizardMessages.JavadocConversionPage_changes_required_for_conversion);
251 		}
252 		return page;
253 	}
254 
255 	@Override
performFinish()256 	protected boolean performFinish() {
257 		// always have to collect changes again in the event the user goes back
258 		// and forth,
259 		// as a change cannot ever have more than one parent - EVER
260 		JavadocConversionRefactoring refactoring = (JavadocConversionRefactoring) getRefactoring();
261 		HashSet<IProject> projects = new HashSet<>();
262 		for (Object object : checkedset) {
263 			IProject current = (IProject) object;
264 			projects.add(current);
265 		}
266 		refactoring.setProjects(projects);
267 		refactoring.setRemoveTags(removetags.getSelection());
268 		return super.performFinish();
269 	}
270 
271 	/**
272 	 * @return the current selection from the workbench as an array of objects
273 	 */
getWorkbenchSelection()274 	protected Object[] getWorkbenchSelection() {
275 		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
276 		if (window != null) {
277 			IWorkbenchPage page = window.getActivePage();
278 			if (page != null) {
279 				IWorkbenchPart part = page.getActivePart();
280 				if (part != null) {
281 					IWorkbenchSite site = part.getSite();
282 					if (site != null) {
283 						ISelectionProvider provider = site.getSelectionProvider();
284 						if (provider != null) {
285 							ISelection selection = provider.getSelection();
286 							if (selection instanceof IStructuredSelection) {
287 								Object[] jps = ((IStructuredSelection) provider.getSelection()).toArray();
288 								ArrayList<IProject> pjs = new ArrayList<>();
289 								for (Object jp : jps) {
290 									if (jp instanceof IAdaptable) {
291 										IAdaptable adapt = (IAdaptable) jp;
292 										IProject pj = adapt.getAdapter(IProject.class);
293 										if (Util.isApiProject(pj)) {
294 											pjs.add(pj);
295 										}
296 									}
297 								}
298 								return pjs.toArray();
299 							}
300 						}
301 					}
302 				}
303 			}
304 		}
305 		return new Object[0];
306 	}
307 }
308