1 /*******************************************************************************
2  * Copyright (c) 2000, 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.team.internal.ccvs.ui.tags;
15 
16 import java.lang.reflect.InvocationTargetException;
17 import java.util.*;
18 import java.util.List;
19 
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.jface.dialogs.*;
23 import org.eclipse.jface.dialogs.Dialog;
24 import org.eclipse.jface.viewers.*;
25 import org.eclipse.osgi.util.NLS;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.events.*;
28 import org.eclipse.swt.graphics.Point;
29 import org.eclipse.swt.graphics.Rectangle;
30 import org.eclipse.swt.layout.GridData;
31 import org.eclipse.swt.layout.GridLayout;
32 import org.eclipse.swt.widgets.*;
33 import org.eclipse.team.core.TeamException;
34 import org.eclipse.team.internal.ccvs.core.*;
35 import org.eclipse.team.internal.ccvs.ui.*;
36 import org.eclipse.team.internal.ccvs.ui.Policy;
37 import org.eclipse.team.internal.ccvs.ui.model.RemoteContentProvider;
38 import org.eclipse.team.internal.ccvs.ui.repo.NewDateTagAction;
39 import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager;
40 import org.eclipse.team.internal.ccvs.ui.tags.TagSourceWorkbenchAdapter.ProjectElementComparator;
41 import org.eclipse.ui.PlatformUI;
42 import org.eclipse.ui.model.WorkbenchContentProvider;
43 import org.eclipse.ui.model.WorkbenchLabelProvider;
44 
45 /**
46  * Allows configuration of the CVS tags that are shown within the workbench.
47  */
48 public class TagConfigurationDialog extends TrayDialog {
49 
50 	// show the resource contained within the roots
51 	private TreeViewer cvsResourceTree;
52 
53 	// shows the tags found on the selected resources
54 	private CheckboxTableViewer cvsTagTree;
55 
56 	// shows the defined tags for the given root
57 	private TreeViewer cvsDefinedTagsTree;
58 
59 	// remember the root element in the defined tags tree
60 	private TagSourceWorkbenchAdapter cvsDefinedTagsRootElement;
61 
62 	// list of auto-refresh files
63 	private org.eclipse.swt.widgets.List autoRefreshFileList;
64 
65 	// enable selecting auto-refresh files
66 	private boolean allowSettingAutoRefreshFiles = true;
67 
68 	// preference keys
69 	private final String ALLOWREFRESH_WIDTH_KEY = "AllowRefreshWidth"; //$NON-NLS-1$
70 	private final String ALLOWREFRESH_HEIGHT_KEY = "AllowRefreshHeight"; //$NON-NLS-1$
71 	private final String NOREFRESH_WIDTH_KEY = "NoRefreshWidth"; //$NON-NLS-1$
72 	private final String NOREFRESH_HEIGHT_KEY = "NoRefreshHeight"; //$NON-NLS-1$
73 
74 	// buttons
75 	private Button addSelectedTagsButton;
76 	private Button addSelectedFilesButton;
77 	private Button removeFileButton;
78 	private Button removeTagButton;
79 
80 	// dialogs settings that are persistent between workbench sessions
81 	private IDialogSettings settings;
82 
83 	private final TagSource tagSource;
84 
85 	private final TagSourceWrapper wrappedTagSource;
86 
87 	class FileComparator extends ViewerComparator {
88 		@Override
compare(Viewer viewer, Object e1, Object e2)89 		public int compare(Viewer viewer, Object e1, Object e2) {
90 			boolean oneIsFile = e1 instanceof CVSFileElement;
91 			boolean twoIsFile = e2 instanceof CVSFileElement;
92 			if (oneIsFile != twoIsFile) {
93 				return oneIsFile ? 1 : -1;
94 			}
95 			return super.compare(viewer, e1, e2);
96 		}
97 	}
98 
99 	/*
100 	 * Create a tag source that cahces the added and removed tags
101 	 * so that the changes can be propogated to the repository
102 	 * manager when OK is pressed
103 	 */
104 	class TagSourceWrapper extends TagSource {
105 
106 		private final TagSource tagSource;
107 		private final List<CVSTag> branches = new ArrayList<>();
108 		private final List<CVSTag> versions = new ArrayList<>();
109 		private final List<CVSTag> dates = new ArrayList<>();
110 
TagSourceWrapper(TagSource tagSource)111 		public TagSourceWrapper(TagSource tagSource) {
112 			this.tagSource = tagSource;
113 			branches.addAll(Arrays.asList(tagSource.getTags(CVSTag.BRANCH)));
114 			versions.addAll(Arrays.asList(tagSource.getTags(CVSTag.VERSION)));
115 			dates.addAll(Arrays.asList(tagSource.getTags(CVSTag.DATE)));
116 		}
117 
118 		@Override
getTags(int type)119 		public CVSTag[] getTags(int type) {
120 			if (type == CVSTag.HEAD || type == BASE) {
121 				return super.getTags(type);
122 			}
123 			List<CVSTag> list = getTagList(type);
124 			if (list != null)
125 				return list.toArray(new CVSTag[list.size()]);
126 			return tagSource.getTags(type);
127 		}
128 
getTagList(int type)129 		private List<CVSTag> getTagList(int type) {
130 			switch (type) {
131 			case CVSTag.VERSION:
132 				return versions;
133 			case CVSTag.BRANCH:
134 				return branches;
135 			case CVSTag.DATE:
136 				return dates;
137 		}
138 			return null;
139 		}
140 
141 		@Override
refresh(boolean bestEffort, IProgressMonitor monitor)142 		public CVSTag[] refresh(boolean bestEffort, IProgressMonitor monitor) throws TeamException {
143 			// The wrapper is never refreshed
144 			return new CVSTag[0];
145 		}
146 
147 		@Override
getLocation()148 		public ICVSRepositoryLocation getLocation() {
149 			return tagSource.getLocation();
150 		}
151 
152 		@Override
getShortDescription()153 		public String getShortDescription() {
154 			return tagSource.getShortDescription();
155 		}
156 
remove(CVSTag[] tags)157 		public void remove(CVSTag[] tags) {
158 			for (CVSTag tag : tags) {
159 				List list = getTagList(tag.getType());
160 				if (list != null)
161 					list.remove(tag);
162 			}
163 		}
164 
add(CVSTag[] tags)165 		public void add(CVSTag[] tags) {
166 			for (CVSTag tag : tags) {
167 				List<CVSTag> list = getTagList(tag.getType());
168 				if (list != null)
169 					list.add(tag);
170 			}
171 		}
172 
removeAll()173 		public void removeAll() {
174 			versions.clear();
175 			branches.clear();
176 			dates.clear();
177 		}
178 
179 		/**
180 		 * Remember the state that has been accumulated
181 		 * @param monitor
182 		 * @throws CVSException
183 		 */
commit(IProgressMonitor monitor)184 		public void commit(IProgressMonitor monitor) throws CVSException {
185 			tagSource.commit(getTags(new int[] { CVSTag.VERSION, CVSTag.BRANCH, CVSTag.DATE }), true /* replace */, monitor);
186 		}
187 
188 		@Override
commit(CVSTag[] tags, boolean replace, IProgressMonitor monitor)189 		public void commit(CVSTag[] tags, boolean replace, IProgressMonitor monitor) throws CVSException {
190 			// Not invoked
191 		}
192 
193 		@Override
getCVSResources()194 		public ICVSResource[] getCVSResources() {
195 			return tagSource.getCVSResources();
196 		}
197 	}
198 
TagConfigurationDialog(Shell shell, TagSource tagSource)199 	public TagConfigurationDialog(Shell shell, TagSource tagSource) {
200 		super(shell);
201 		this.tagSource = tagSource;
202 		wrappedTagSource = new TagSourceWrapper(tagSource);
203 		setShellStyle(SWT.CLOSE|SWT.RESIZE|SWT.APPLICATION_MODAL);
204 		allowSettingAutoRefreshFiles = getSingleFolder(tagSource, false) != null;
205 		IDialogSettings workbenchSettings = CVSUIPlugin.getPlugin().getDialogSettings();
206 		this.settings = workbenchSettings.getSection("TagConfigurationDialog");//$NON-NLS-1$
207 		if (settings == null) {
208 			this.settings = workbenchSettings.addNewSection("TagConfigurationDialog");//$NON-NLS-1$
209 		}
210 	}
211 
212 	@Override
configureShell(Shell newShell)213 	protected void configureShell(Shell newShell) {
214 		super.configureShell(newShell);
215 		newShell.setText(NLS.bind(CVSUIMessages.TagConfigurationDialog_1, new String[] { tagSource.getShortDescription() }));
216 	}
217 
218 	@Override
createDialogArea(Composite parent)219 	protected Control createDialogArea(Composite parent) {
220 		Composite shell = new Composite(parent, SWT.NONE);
221 		GridData data = new GridData (GridData.FILL_BOTH);
222 		shell.setLayoutData(data);
223 		GridLayout gridLayout = new GridLayout();
224 		gridLayout.numColumns = 2;
225 		gridLayout.makeColumnsEqualWidth = true;
226 		gridLayout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
227 		gridLayout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
228 		shell.setLayout (gridLayout);
229 
230 		Composite comp = new Composite(shell, SWT.NULL);
231 		gridLayout = new GridLayout();
232 		gridLayout.numColumns = 1;
233 		gridLayout.marginWidth = 0;
234 		gridLayout.marginHeight = 0;
235 		comp.setLayout(gridLayout);
236 		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
237 
238 		Label cvsResourceTreeLabel = new Label(comp, SWT.NONE);
239 		cvsResourceTreeLabel.setText(CVSUIMessages.TagConfigurationDialog_5);
240 		data = new GridData();
241 		data.horizontalSpan = 1;
242 		cvsResourceTreeLabel.setLayoutData(data);
243 
244 		Tree tree = new Tree(comp, SWT.BORDER | SWT.MULTI);
245 		cvsResourceTree = new TreeViewer (tree);
246 		cvsResourceTree.setContentProvider(new RemoteContentProvider());
247 		cvsResourceTree.setLabelProvider(new WorkbenchLabelProvider());
248 		data = new GridData (GridData.FILL_BOTH);
249 		data.heightHint = 150;
250 		data.horizontalSpan = 1;
251 		cvsResourceTree.getTree().setLayoutData(data);
252 		cvsResourceTree.setComparator(new FileComparator());
253 		cvsResourceTree.setInput(TagSourceResourceAdapter.getViewerInput(tagSource));
254 		cvsResourceTree.addSelectionChangedListener(event -> {
255 			updateShownTags();
256 			updateEnablements();
257 		});
258 
259 		comp = new Composite(shell, SWT.NULL);
260 		gridLayout = new GridLayout();
261 		gridLayout.numColumns = 1;
262 		gridLayout.marginWidth = 0;
263 		gridLayout.marginHeight = 0;
264 		comp.setLayout(gridLayout);
265 		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
266 
267 		Label cvsTagTreeLabel = new Label(comp, SWT.NONE);
268 		cvsTagTreeLabel.setText(CVSUIMessages.TagConfigurationDialog_6);
269 		data = new GridData();
270 		data.horizontalSpan = 1;
271 		cvsTagTreeLabel.setLayoutData(data);
272 
273 		final Table table = new Table(comp, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.CHECK);
274 		data = new GridData(GridData.FILL_BOTH);
275 		data.heightHint = 150;
276 		data.horizontalSpan = 1;
277 		table.setLayoutData(data);
278 		cvsTagTree = new CheckboxTableViewer(table);
279 		cvsTagTree.setContentProvider(new WorkbenchContentProvider());
280 		cvsTagTree.setLabelProvider(new WorkbenchLabelProvider());
281 		cvsTagTree.addSelectionChangedListener(event -> updateEnablements());
282 
283 		Composite selectComp = new Composite(comp, SWT.NONE);
284 		GridLayout selectLayout = new GridLayout(2, true);
285 		selectLayout.marginHeight = selectLayout.marginWidth = 0;
286 		selectComp.setLayout(selectLayout);
287 		selectComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
288 		Button selectAllButton = new Button(selectComp, SWT.PUSH);
289 		selectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
290 		selectAllButton.setText(CVSUIMessages.ReleaseCommentDialog_selectAll);
291 		selectAllButton.addSelectionListener(new SelectionAdapter() {
292 			@Override
293 			public void widgetSelected(SelectionEvent e) {
294 				int nItems = table.getItemCount();
295 				for (int j=0; j<nItems; j++)
296 					table.getItem(j).setChecked(true);
297 			}
298 		});
299 		Button deselectAllButton = new Button(selectComp, SWT.PUSH);
300 		deselectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
301 		deselectAllButton.setText(CVSUIMessages.ReleaseCommentDialog_deselectAll);
302 		deselectAllButton.addSelectionListener(new SelectionAdapter() {
303 			@Override
304 			public void widgetSelected(SelectionEvent e) {
305 				int nItems = table.getItemCount();
306 				for (int j=0; j<nItems; j++)
307 					table.getItem(j).setChecked(false);
308 			}
309 		});
310 
311 		cvsTagTree.setComparator(new ViewerComparator() {
312 			@Override
313 			public int compare(Viewer viewer, Object e1, Object e2) {
314 				if (!(e1 instanceof TagElement) || !(e2 instanceof TagElement)) return super.compare(viewer, e1, e2);
315 				CVSTag tag1 = ((TagElement)e1).getTag();
316 				CVSTag tag2 = ((TagElement)e2).getTag();
317 				int type1 = tag1.getType();
318 				int type2 = tag2.getType();
319 				if (type1 != type2) {
320 					return  type1 - type2;
321 				}
322 				// Sort in reverse order so larger numbered versions are at the top
323 				return -tag1.compareTo(tag2);
324 			}
325 		});
326 
327 		Composite rememberedTags = new Composite(shell, SWT.NONE);
328 		data = new GridData (GridData.FILL_BOTH);
329 		data.horizontalSpan = 2;
330 		rememberedTags.setLayoutData(data);
331 		gridLayout = new GridLayout();
332 		gridLayout.numColumns = 2;
333 		gridLayout.marginHeight = 0;
334 		gridLayout.marginWidth = 0;
335 		rememberedTags.setLayout (gridLayout);
336 
337 		Label rememberedTagsLabel = new Label (rememberedTags, SWT.NONE);
338 		rememberedTagsLabel.setText (CVSUIMessages.TagConfigurationDialog_7);
339 		data = new GridData ();
340 		data.horizontalSpan = 2;
341 		rememberedTagsLabel.setLayoutData (data);
342 
343 		tree = new Tree(rememberedTags, SWT.BORDER | SWT.MULTI);
344 		cvsDefinedTagsTree = new TreeViewer (tree);
345 		cvsDefinedTagsTree.setContentProvider(new WorkbenchContentProvider());
346 		cvsDefinedTagsTree.setLabelProvider(new WorkbenchLabelProvider());
347 		data = new GridData (GridData.FILL_BOTH);
348 		data.heightHint = 100;
349 		data.horizontalAlignment = GridData.FILL;
350 		data.grabExcessHorizontalSpace = true;
351 		cvsDefinedTagsTree.getTree().setLayoutData(data);
352 		cvsDefinedTagsRootElement = new TagSourceWorkbenchAdapter(wrappedTagSource, TagSourceWorkbenchAdapter.INCLUDE_BRANCHES | TagSourceWorkbenchAdapter.INCLUDE_VERSIONS |TagSourceWorkbenchAdapter.INCLUDE_DATES);
353 		cvsDefinedTagsTree.setInput(cvsDefinedTagsRootElement);
354 		cvsDefinedTagsTree.addSelectionChangedListener(event -> updateEnablements());
355 		cvsDefinedTagsTree.setComparator(new ProjectElementComparator());
356 
357 		Composite buttonComposite = new Composite(rememberedTags, SWT.NONE);
358 		data = new GridData ();
359 		data.verticalAlignment = GridData.BEGINNING;
360 		buttonComposite.setLayoutData(data);
361 		gridLayout = new GridLayout();
362 		gridLayout.marginHeight = 0;
363 		gridLayout.marginWidth = 0;
364 		buttonComposite.setLayout (gridLayout);
365 
366 		addSelectedTagsButton = new Button (buttonComposite, SWT.PUSH);
367 		addSelectedTagsButton.setText (CVSUIMessages.TagConfigurationDialog_8);
368 		data = getStandardButtonData(addSelectedTagsButton);
369 		data.horizontalAlignment = GridData.FILL;
370 		addSelectedTagsButton.setLayoutData(data);
371 		addSelectedTagsButton.addListener(SWT.Selection, event -> {
372 			rememberCheckedTags();
373 			updateShownTags();
374 			updateEnablements();
375 		});
376 		Button addDatesButton = new Button(buttonComposite, SWT.PUSH);
377 		addDatesButton.setText(CVSUIMessages.TagConfigurationDialog_0);
378 		data = getStandardButtonData(addDatesButton);
379 		data.horizontalAlignment = GridData.FILL;
380 		addDatesButton.setLayoutData(data);
381 		addDatesButton.addListener(SWT.Selection, event -> {
382 			CVSTag dateTag = NewDateTagAction.getDateTag(getShell(), tagSource.getLocation());
383 			addDateTagsSelected(dateTag);
384 			updateShownTags();
385 			updateEnablements();
386 		});
387 		removeTagButton = new Button (buttonComposite, SWT.PUSH);
388 		removeTagButton.setText (CVSUIMessages.TagConfigurationDialog_9);
389 		data = getStandardButtonData(removeTagButton);
390 		data.horizontalAlignment = GridData.FILL;
391 		removeTagButton.setLayoutData(data);
392 		removeTagButton.addListener(SWT.Selection, event -> {
393 			deleteSelected();
394 			updateShownTags();
395 			updateEnablements();
396 		});
397 
398 		Button removeAllTags = new Button (buttonComposite, SWT.PUSH);
399 		removeAllTags.setText (CVSUIMessages.TagConfigurationDialog_10);
400 		data = getStandardButtonData(removeAllTags);
401 		data.horizontalAlignment = GridData.FILL;
402 		removeAllTags.setLayoutData(data);
403 		removeAllTags.addListener(SWT.Selection, event -> {
404 			removeAllKnownTags();
405 			updateShownTags();
406 			updateEnablements();
407 		});
408 
409 		if(allowSettingAutoRefreshFiles) {
410 			Label explanation = new Label(rememberedTags, SWT.WRAP);
411 			explanation.setText(CVSUIMessages.TagConfigurationDialog_11);
412 			data = new GridData ();
413 			data.horizontalSpan = 2;
414 			//data.widthHint = 300;
415 			explanation.setLayoutData(data);
416 
417 			autoRefreshFileList = new org.eclipse.swt.widgets.List(rememberedTags, SWT.BORDER | SWT.MULTI);
418 			data = new GridData ();
419 			data.heightHint = 45;
420 			data.horizontalAlignment = GridData.FILL;
421 			data.grabExcessHorizontalSpace = true;
422 			autoRefreshFileList.setLayoutData(data);
423 			try {
424 				autoRefreshFileList.setItems(CVSUIPlugin.getPlugin().getRepositoryManager().getAutoRefreshFiles(getSingleFolder(tagSource, false)));
425 			} catch (CVSException e) {
426 				autoRefreshFileList.setItems(new String[0]);
427 				CVSUIPlugin.log(e);
428 			}
429 			autoRefreshFileList.addSelectionListener(new SelectionListener() {
430 				@Override
431 				public void widgetSelected(SelectionEvent e) {
432 					updateEnablements();
433 				}
434 				@Override
435 				public void widgetDefaultSelected(SelectionEvent e) {
436 					updateEnablements();
437 				}
438 			});
439 
440 			Composite buttonComposite2 = new Composite(rememberedTags, SWT.NONE);
441 			data = new GridData ();
442 			data.verticalAlignment = GridData.BEGINNING;
443 			buttonComposite2.setLayoutData(data);
444 			gridLayout = new GridLayout();
445 			gridLayout.marginHeight = 0;
446 			gridLayout.marginWidth = 0;
447 			buttonComposite2.setLayout (gridLayout);
448 
449 			addSelectedFilesButton = new Button (buttonComposite2, SWT.PUSH);
450 			addSelectedFilesButton.setText (CVSUIMessages.TagConfigurationDialog_12);
451 			data = getStandardButtonData(addSelectedFilesButton);
452 			data.horizontalAlignment = GridData.FILL;
453 			addSelectedFilesButton.setLayoutData(data);
454 			addSelectedFilesButton.addListener(SWT.Selection, event -> addSelectionToAutoRefreshList());
455 
456 			removeFileButton = new Button (buttonComposite2, SWT.PUSH);
457 			removeFileButton.setText (CVSUIMessages.TagConfigurationDialog_13);
458 			data = getStandardButtonData(removeFileButton);
459 			data.horizontalAlignment = GridData.FILL;
460 			removeFileButton.setLayoutData(data);
461 			removeFileButton.addListener(SWT.Selection, event -> {
462 				String[] selected = autoRefreshFileList.getSelection();
463 				for (String s : selected) {
464 					autoRefreshFileList.remove(s);
465 					autoRefreshFileList.setFocus();
466 				}
467 			});
468 			PlatformUI.getWorkbench().getHelpSystem().setHelp(autoRefreshFileList, IHelpContextIds.TAG_CONFIGURATION_REFRESHLIST);
469 		}
470 
471 		Label seperator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
472 		data = new GridData (GridData.FILL_BOTH);
473 		data.horizontalSpan = 2;
474 		seperator.setLayoutData(data);
475 
476 		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IHelpContextIds.TAG_CONFIGURATION_OVERVIEW);
477 
478 		updateEnablements();
479 		Dialog.applyDialogFont(parent);
480 		return shell;
481 	}
482 
updateShownTags()483 	private void updateShownTags() {
484 		final CVSFileElement[] filesSelection = getSelectedFiles();
485 		final Set<CVSTag> tags = new HashSet<>();
486 		if(filesSelection.length!=0) {
487 			try {
488 				CVSUIPlugin.runWithProgress(getShell(), true /*cancelable*/, monitor -> {
489 					monitor.beginTask(CVSUIMessages.TagConfigurationDialog_22, filesSelection.length);
490 					try {
491 						for (CVSFileElement f : filesSelection) {
492 							ICVSFile file = f.getCVSFile();
493 							tags.addAll(Arrays.asList(getTagsFor(file, Policy.subMonitorFor(monitor, 1))));
494 						}
495 					} catch (TeamException e) {
496 						// ignore the exception
497 					} finally {
498 						monitor.done();
499 					}
500 				});
501 			} catch (InterruptedException e) {
502 				// operation cancelled
503 			} catch (InvocationTargetException e) {
504 				// can't happen since we're ignoring all possible exceptions
505 			}
506 			cvsTagTree.getTable().removeAll();
507 			for (Iterator it = tags.iterator(); it.hasNext();) {
508 				CVSTag tag = (CVSTag) it.next();
509 				List<CVSTag> knownTags = new ArrayList<>();
510 				knownTags.addAll(Arrays.asList(wrappedTagSource.getTags(new int[] { CVSTag.VERSION, CVSTag.BRANCH, CVSTag.DATE })));
511 				if(!knownTags.contains(tag)) {
512 					TagElement tagElem = new TagElement(tag);
513 					cvsTagTree.add(tagElem);
514 					cvsTagTree.setChecked(tagElem, true);
515 				}
516 			}
517 		}
518 	}
519 
getSelectedFiles()520 	private CVSFileElement[] getSelectedFiles() {
521 		IStructuredSelection selection = cvsResourceTree.getStructuredSelection();
522 		if (!selection.isEmpty()) {
523 			final List<CVSFileElement> filesSelection = new ArrayList<>();
524 			Iterator it = selection.iterator();
525 			while(it.hasNext()) {
526 				Object o = it.next();
527 				if(o instanceof CVSFileElement) {
528 					filesSelection.add((CVSFileElement) o);
529 				}
530 			}
531 			return filesSelection.toArray(new CVSFileElement[filesSelection.size()]);
532 		}
533 		return new CVSFileElement[0];
534 	}
535 
addSelectionToAutoRefreshList()536 	private void addSelectionToAutoRefreshList() {
537 		IStructuredSelection selection = cvsResourceTree.getStructuredSelection();
538 		if (!selection.isEmpty()) {
539 			final List<CVSFileElement> filesSelection = new ArrayList<>();
540 			Iterator it = selection.iterator();
541 			while(it.hasNext()) {
542 				Object o = it.next();
543 				if(o instanceof CVSFileElement) {
544 					filesSelection.add((CVSFileElement) o);
545 				}
546 			}
547 			if(!filesSelection.isEmpty()) {
548 				for (it = filesSelection.iterator(); it.hasNext();) {
549 					try {
550 						ICVSFile file = ((CVSFileElement)it.next()).getCVSFile();
551 						ICVSFolder fileParent = file.getParent();
552 						String filePath = new Path(null, fileParent.getFolderSyncInfo().getRepository())
553 							.append(file.getRelativePath(fileParent)).toString();
554 						if(autoRefreshFileList.indexOf(filePath)==-1) {
555 							autoRefreshFileList.add(filePath);
556 						}
557 					} catch(CVSException e) {
558 						CVSUIPlugin.openError(getShell(), null, null, e);
559 					}
560 				}
561 			}
562 		}
563 	}
564 
getTagsFor(ICVSFile file, IProgressMonitor monitor)565 	private CVSTag[] getTagsFor(ICVSFile file, IProgressMonitor monitor) throws TeamException {
566 		return SingleFileTagSource.fetchTagsFor(file, monitor);
567 	}
568 
rememberCheckedTags()569 	private void rememberCheckedTags() {
570 		Object[] checked = cvsTagTree.getCheckedElements();
571 		List<CVSTag> tagsToAdd = new ArrayList<>();
572 		for (Object c : checked) {
573 			CVSTag tag = ((TagElement) c).getTag();
574 			tagsToAdd.add(tag);
575 		}
576 		if (!tagsToAdd.isEmpty()) {
577 			wrappedTagSource.add(tagsToAdd.toArray(new CVSTag[tagsToAdd.size()]));
578 			cvsDefinedTagsTree.refresh();
579 		}
580 	}
581 
deleteSelected()582 	private void deleteSelected() {
583 		IStructuredSelection selection = cvsDefinedTagsTree.getStructuredSelection();
584 		List<CVSTag> tagsToRemove = new ArrayList<>();
585 		if (!selection.isEmpty()) {
586 			Iterator it = selection.iterator();
587 			while(it.hasNext()) {
588 				Object o = it.next();
589 				if(o instanceof TagElement) {
590 					CVSTag tag = ((TagElement)o).getTag();
591 					tagsToRemove.add(tag);
592 				}
593 			}
594 		}
595 		if (!tagsToRemove.isEmpty()) {
596 			wrappedTagSource.remove(tagsToRemove.toArray(new CVSTag[tagsToRemove.size()]));
597 			cvsDefinedTagsTree.refresh();
598 			cvsDefinedTagsTree.getTree().setFocus();
599 		}
600 	}
addDateTagsSelected(CVSTag tag)601 	private void addDateTagsSelected(CVSTag tag){
602 		if(tag == null) return;
603 		List<CVSTag> knownTags = new ArrayList<>();
604 		knownTags.addAll(Arrays.asList(wrappedTagSource.getTags(CVSTag.DATE)));
605 		if(!knownTags.contains( tag)){
606 			wrappedTagSource.add(new CVSTag[] { tag });
607 			cvsDefinedTagsTree.refresh();
608 			cvsDefinedTagsTree.getTree().setFocus();
609 		}
610 	}
isTagSelectedInKnownTagTree()611 	private boolean isTagSelectedInKnownTagTree() {
612 		IStructuredSelection selection = cvsDefinedTagsTree.getStructuredSelection();
613 		if (!selection.isEmpty()) {
614 			Iterator it = selection.iterator();
615 			while(it.hasNext()) {
616 				Object o = it.next();
617 				if(o instanceof TagElement) {
618 					return true;
619 				}
620 			}
621 		}
622 		return false;
623 	}
624 
removeAllKnownTags()625 	private void removeAllKnownTags() {
626 		wrappedTagSource.removeAll();
627 		cvsDefinedTagsTree.refresh();
628 	}
629 
updateEnablements()630 	private void updateEnablements() {
631 		// add checked tags
632 		Object[] checked = cvsTagTree.getCheckedElements();
633 		addSelectedTagsButton.setEnabled(checked.length!=0?true:false);
634 
635 		// Remove known tags
636 		removeTagButton.setEnabled(isTagSelectedInKnownTagTree()?true:false);
637 
638 		if(allowSettingAutoRefreshFiles) {
639 			// add selected files
640 			addSelectedFilesButton.setEnabled(getSelectedFiles().length!=0?true:false);
641 
642 			// remove auto refresh files
643 			removeFileButton.setEnabled(autoRefreshFileList.getSelection().length!=0?true:false);
644 		}
645 	}
646 
647 	@Override
okPressed()648 	protected void okPressed() {
649 		try {
650 			// save auto refresh file names
651 			if(allowSettingAutoRefreshFiles) {
652 				RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager();
653 				manager.setAutoRefreshFiles(getSingleFolder(tagSource, false), autoRefreshFileList.getItems());
654 			}
655 
656 			wrappedTagSource.commit(null);
657 
658 			super.okPressed();
659 		} catch (CVSException e) {
660 			CVSUIPlugin.openError(getShell(), null, null, e);
661 		}
662 	}
663 
getSingleFolder(TagSource tagSource, boolean bestEffort)664 	protected ICVSFolder getSingleFolder(TagSource tagSource, boolean bestEffort) {
665 		if (!bestEffort && tagSource instanceof MultiFolderTagSource)
666 			return null;
667 		if (tagSource instanceof SingleFolderTagSource)
668 			return ((SingleFolderTagSource)tagSource).getFolder();
669 		return null;
670 	}
671 
672 	@Override
getInitialSize()673 	protected Point getInitialSize() {
674 		int width, height;
675 		if(allowSettingAutoRefreshFiles) {
676 			try {
677 				height = settings.getInt(ALLOWREFRESH_HEIGHT_KEY);
678 				width = settings.getInt(ALLOWREFRESH_WIDTH_KEY);
679 			} catch(NumberFormatException e) {
680 				return super.getInitialSize();
681 			}
682 		} else {
683 			try {
684 				height = settings.getInt(NOREFRESH_HEIGHT_KEY);
685 				width = settings.getInt(NOREFRESH_WIDTH_KEY);
686 			} catch(NumberFormatException e) {
687 				return super.getInitialSize();
688 			}
689 		}
690 		return new Point(width, height);
691 	}
692 
693 	@Override
cancelPressed()694 	protected void cancelPressed() {
695 		super.cancelPressed();
696 	}
697 
getStandardButtonData(Button button)698 	private GridData getStandardButtonData(Button button) {
699 		GridData data = new GridData();
700 		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
701 		//don't crop labels with large font
702 		//int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
703 		//data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
704 		return data;
705 	}
706 
707 	@Override
close()708 	public boolean close() {
709 		// Close the tray so we only remember the size without the tray
710 		if (getTray() != null)
711 			closeTray();
712 		Rectangle bounds = getShell().getBounds();
713 		if(allowSettingAutoRefreshFiles) {
714 			settings.put(ALLOWREFRESH_HEIGHT_KEY, bounds.height);
715 			settings.put(ALLOWREFRESH_WIDTH_KEY, bounds.width);
716 		} else {
717 			settings.put(NOREFRESH_HEIGHT_KEY, bounds.height);
718 			settings.put(NOREFRESH_WIDTH_KEY, bounds.width);
719 		}
720 		return super.close();
721 	}
722 }
723