| /* |
| * Copyright (c) 2015-2017 Ed Merks (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * Ed Merks - initial API and implementation |
| */ |
| package org.eclipse.oomph.setup.presentation; |
| |
| import org.eclipse.oomph.internal.ui.UIPlugin; |
| import org.eclipse.oomph.preferences.PreferenceNode; |
| import org.eclipse.oomph.preferences.PreferencesFactory; |
| import org.eclipse.oomph.preferences.Property; |
| import org.eclipse.oomph.preferences.util.PreferencesUtil; |
| import org.eclipse.oomph.setup.CompoundTask; |
| import org.eclipse.oomph.setup.PreferenceTask; |
| import org.eclipse.oomph.setup.SetupTask; |
| import org.eclipse.oomph.setup.ui.recorder.RecorderTransaction; |
| import org.eclipse.oomph.setup.util.SetupUtil; |
| import org.eclipse.oomph.setup.util.StringExpander; |
| import org.eclipse.oomph.util.IORuntimeException; |
| import org.eclipse.oomph.util.Pair; |
| import org.eclipse.oomph.util.PropertiesUtil; |
| |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.util.AbstractTreeIterator; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.edit.provider.ItemProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| |
| import org.eclipse.core.resources.ProjectScope; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.preferences.ConfigurationScope; |
| import org.eclipse.core.runtime.preferences.DefaultScope; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor; |
| import org.eclipse.core.runtime.preferences.IPreferencesService; |
| import org.eclipse.core.runtime.preferences.IScopeContext; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.ToolBar; |
| import org.eclipse.swt.widgets.ToolItem; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.dialogs.FilteredTree; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| |
| import org.osgi.service.prefs.BackingStoreException; |
| import org.osgi.service.prefs.Preferences; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * @author Ed Merks |
| */ |
| public class PreferenceCaptureDialog extends Dialog |
| { |
| private static final URI INSTANCE_URI = URI.createURI("//" + PreferencesUtil.INSTANCE_NODE); //$NON-NLS-1$ |
| |
| protected ILabelProvider labelProvider; |
| |
| protected FilteringAdapterFactoryContentProvider availablePreferencesContentProvider; |
| |
| protected FilteringAdapterFactoryContentProvider selectedPreferencesContentProvider; |
| |
| protected Set<Object> included = new HashSet<Object>(); |
| |
| protected boolean fromEclipsePreferenceFile; |
| |
| /** |
| * @since 2.6 |
| */ |
| public PreferenceCaptureDialog(Shell parent, AdapterFactory adapterFactory, boolean fromEclipsePreferenceFile) |
| { |
| super(parent); |
| |
| setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); |
| |
| this.fromEclipsePreferenceFile = fromEclipsePreferenceFile; |
| |
| labelProvider = new AdapterFactoryLabelProvider(adapterFactory); |
| availablePreferencesContentProvider = new FilteringAdapterFactoryContentProvider(adapterFactory, false); |
| selectedPreferencesContentProvider = new FilteringAdapterFactoryContentProvider(adapterFactory, true); |
| } |
| |
| @Override |
| protected void configureShell(Shell shell) |
| { |
| super.configureShell(shell); |
| shell.setText(fromEclipsePreferenceFile ? Messages.PreferenceCaptureDialog_shellText_importPrefs : Messages.PreferenceCaptureDialog_shellText_capturePrefs); |
| shell.setImage(SetupEditorPlugin.INSTANCE.getSWTImage(fromEclipsePreferenceFile ? "preference_importer" : "preference_picker")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| @Override |
| protected IDialogSettings getDialogBoundsSettings() |
| { |
| return SetupEditorPlugin.INSTANCE.getDialogSettings(fromEclipsePreferenceFile ? "PreferenceImport" : "PreferenceCapture"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| protected List<?> getAvailablePreferences() |
| { |
| PreferenceNode rootPreferenceNode = PreferencesUtil.getRootPreferenceNode(Collections.unmodifiableSet(new LinkedHashSet<String>( |
| Arrays.asList(new String[] { PreferencesUtil.BUNDLE_DEFAULTS_NODE, PreferencesUtil.DEFAULT_NODE, PreferencesUtil.INSTANCE_NODE }))), false); |
| |
| Map<URI, Pair<String, String>> preferences = new HashMap<URI, Pair<String, String>>(); |
| for (PreferenceNode preferenceNode : rootPreferenceNode.getChildren()) |
| { |
| traverse(preferences, preferenceNode); |
| } |
| |
| return RecorderTransaction.record(preferences); |
| } |
| |
| protected void traverse(Map<URI, Pair<String, String>> preferences, PreferenceNode preferenceNode) |
| { |
| for (PreferenceNode childPreferenceNode : preferenceNode.getChildren()) |
| { |
| traverse(preferences, childPreferenceNode); |
| } |
| |
| for (Property property : preferenceNode.getProperties()) |
| { |
| preferences.put(INSTANCE_URI.appendSegments(property.getRelativePath().segments()), new Pair<String, String>(null, property.getValue())); |
| } |
| } |
| |
| @Override |
| protected Control createDialogArea(Composite parent) |
| { |
| final ItemProvider input = new ItemProvider(); |
| |
| Composite contents = (Composite)super.createDialogArea(parent); |
| |
| GridLayout contentsGridLayout = (GridLayout)contents.getLayout(); |
| contentsGridLayout.numColumns = 3; |
| |
| GridData contentsGridData = (GridData)contents.getLayoutData(); |
| contentsGridData.horizontalAlignment = SWT.FILL; |
| contentsGridData.verticalAlignment = SWT.FILL; |
| |
| Text preferenceFileText = null; |
| |
| if (fromEclipsePreferenceFile) |
| { |
| Group preferenceFileGroup = new Group(contents, SWT.NONE); |
| preferenceFileGroup.setText(Messages.PreferenceCaptureDialog_preferenceFileGroup_text); |
| preferenceFileGroup.setLayout(new GridLayout(2, false)); |
| preferenceFileGroup.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 3, 1)); |
| |
| final Text finalPreferenceFileText = preferenceFileText = new Text(preferenceFileGroup, SWT.BORDER); |
| preferenceFileText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 1, 1)); |
| |
| Button preferenceFileBrowseButton = new Button(preferenceFileGroup, SWT.PUSH); |
| preferenceFileBrowseButton.setText(Messages.PreferenceCaptureDialog_preferenceFileBrowseButton_text); |
| preferenceFileBrowseButton.addSelectionListener(new SelectionAdapter() |
| { |
| @Override |
| public void widgetSelected(SelectionEvent e) |
| { |
| FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.MULTI); |
| dialog.setFilterExtensions(new String[] { "*.epf" }); //$NON-NLS-1$ |
| String result = dialog.open(); |
| if (result != null) |
| { |
| finalPreferenceFileText.setText(result); |
| } |
| } |
| }); |
| } |
| |
| Group filterGroupComposite = new Group(contents, SWT.NONE); |
| filterGroupComposite.setText(Messages.PreferenceCaptureDialog_filterGroup_text); |
| filterGroupComposite.setLayout(new GridLayout(1, false)); |
| filterGroupComposite.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 3, 1)); |
| |
| Composite availablePreferencesComposite = new Composite(contents, SWT.NONE); |
| { |
| GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); |
| data.horizontalAlignment = SWT.END; |
| availablePreferencesComposite.setLayoutData(data); |
| |
| GridLayout layout = new GridLayout(); |
| data.horizontalAlignment = SWT.FILL; |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| layout.numColumns = 1; |
| availablePreferencesComposite.setLayout(layout); |
| } |
| |
| Label availablePreferencesLabel = new Label(availablePreferencesComposite, SWT.NONE); |
| availablePreferencesLabel.setText(Messages.PreferenceCaptureDialog_availablePreferencesLabel); |
| GridData availablePreferencesLabelGridData = new GridData(); |
| availablePreferencesLabelGridData.verticalAlignment = SWT.FILL; |
| availablePreferencesLabelGridData.horizontalAlignment = SWT.FILL; |
| availablePreferencesLabel.setLayoutData(availablePreferencesLabelGridData); |
| |
| PatternFilter filter = new PatternFilter(); |
| filter.setIncludeLeadingWildcard(true); |
| final FilteredTree availablePreferencesTree = new PreferenceFilteredTree(availablePreferencesComposite, SWT.MULTI | SWT.BORDER, filter); |
| GridData availablePreferencesTreeGridData = new GridData(); |
| availablePreferencesTreeGridData.widthHint = Display.getCurrent().getBounds().width / 5; |
| availablePreferencesTreeGridData.heightHint = Display.getCurrent().getBounds().height / 3; |
| availablePreferencesTreeGridData.verticalAlignment = SWT.FILL; |
| availablePreferencesTreeGridData.horizontalAlignment = SWT.FILL; |
| availablePreferencesTreeGridData.grabExcessHorizontalSpace = true; |
| availablePreferencesTreeGridData.grabExcessVerticalSpace = true; |
| availablePreferencesTree.setLayoutData(availablePreferencesTreeGridData); |
| |
| Control filterControl = availablePreferencesTree.getChildren()[0]; |
| filterControl.setParent(filterGroupComposite); |
| filterControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| final TreeViewer availablePreferencesTreeViewer = availablePreferencesTree.getViewer(); |
| availablePreferencesTreeViewer.setContentProvider(availablePreferencesContentProvider); |
| availablePreferencesTreeViewer.setLabelProvider(labelProvider); |
| if (!fromEclipsePreferenceFile) |
| { |
| input.getChildren().addAll(getAvailablePreferences()); |
| } |
| |
| availablePreferencesTreeViewer.setInput(input); |
| |
| Composite controlButtons = new Composite(contents, SWT.NONE); |
| GridData controlButtonsGridData = new GridData(); |
| controlButtonsGridData.verticalAlignment = SWT.FILL; |
| controlButtonsGridData.horizontalAlignment = SWT.FILL; |
| controlButtons.setLayoutData(controlButtonsGridData); |
| |
| GridLayout controlsButtonGridLayout = new GridLayout(); |
| controlButtons.setLayout(controlsButtonGridLayout); |
| |
| new Label(controlButtons, SWT.NONE); |
| |
| final Button addButton = new Button(controlButtons, SWT.PUSH); |
| addButton.setText(Messages.PreferenceCaptureDialog_addButton_text); |
| GridData addButtonGridData = new GridData(); |
| addButtonGridData.verticalAlignment = SWT.FILL; |
| addButtonGridData.horizontalAlignment = SWT.FILL; |
| addButton.setLayoutData(addButtonGridData); |
| |
| final Button removeButton = new Button(controlButtons, SWT.PUSH); |
| removeButton.setText(Messages.PreferenceCaptureDialog_removeButton_text); |
| GridData removeButtonGridData = new GridData(); |
| removeButtonGridData.verticalAlignment = SWT.FILL; |
| removeButtonGridData.horizontalAlignment = SWT.FILL; |
| removeButton.setLayoutData(removeButtonGridData); |
| |
| Label spaceLabel = new Label(controlButtons, SWT.NONE); |
| GridData spaceLabelGridData = new GridData(); |
| spaceLabelGridData.verticalSpan = 2; |
| spaceLabel.setLayoutData(spaceLabelGridData); |
| |
| Composite selectedPreferencesComposite = new Composite(contents, SWT.NONE); |
| { |
| GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); |
| data.horizontalAlignment = SWT.END; |
| selectedPreferencesComposite.setLayoutData(data); |
| |
| GridLayout layout = new GridLayout(); |
| data.horizontalAlignment = SWT.FILL; |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| layout.numColumns = 1; |
| selectedPreferencesComposite.setLayout(layout); |
| } |
| |
| Label selectedPreferencesLabel = new Label(selectedPreferencesComposite, SWT.NONE); |
| selectedPreferencesLabel.setText(Messages.PreferenceCaptureDialog_selectedPreferencesLabel); |
| GridData selectedPreferencesLabelGridData = new GridData(); |
| selectedPreferencesLabelGridData.horizontalSpan = 2; |
| selectedPreferencesLabelGridData.horizontalAlignment = SWT.FILL; |
| selectedPreferencesLabelGridData.verticalAlignment = SWT.FILL; |
| selectedPreferencesLabel.setLayoutData(selectedPreferencesLabelGridData); |
| |
| final Tree selectedPreferencesTree = new Tree(selectedPreferencesComposite, SWT.MULTI | SWT.BORDER); |
| GridData selectedPreferencesTreeGridData = new GridData(); |
| selectedPreferencesTreeGridData.widthHint = Display.getCurrent().getBounds().width / 5; |
| selectedPreferencesTreeGridData.heightHint = Display.getCurrent().getBounds().height / 3; |
| selectedPreferencesTreeGridData.verticalAlignment = SWT.FILL; |
| selectedPreferencesTreeGridData.horizontalAlignment = SWT.FILL; |
| selectedPreferencesTreeGridData.grabExcessHorizontalSpace = true; |
| selectedPreferencesTreeGridData.grabExcessVerticalSpace = true; |
| selectedPreferencesTree.setLayoutData(selectedPreferencesTreeGridData); |
| |
| final TreeViewer selectedPreferencesTreeViewer = new TreeViewer(selectedPreferencesTree); |
| selectedPreferencesTreeViewer.setContentProvider(selectedPreferencesContentProvider); |
| selectedPreferencesTreeViewer.setLabelProvider(labelProvider); |
| selectedPreferencesTreeViewer.setInput(input); |
| |
| availablePreferencesTreeViewer.addDoubleClickListener(new IDoubleClickListener() |
| { |
| public void doubleClick(DoubleClickEvent event) |
| { |
| if (addButton.isEnabled()) |
| { |
| addButton.notifyListeners(SWT.Selection, null); |
| } |
| } |
| }); |
| |
| selectedPreferencesTreeViewer.addDoubleClickListener(new IDoubleClickListener() |
| { |
| public void doubleClick(DoubleClickEvent event) |
| { |
| if (removeButton.isEnabled()) |
| { |
| removeButton.notifyListeners(SWT.Selection, null); |
| } |
| } |
| }); |
| |
| addButton.addSelectionListener(new FilteringSelectionAdapter(selectedPreferencesTreeViewer, availablePreferencesTreeViewer, input, true)); |
| removeButton.addSelectionListener(new FilteringSelectionAdapter(selectedPreferencesTreeViewer, availablePreferencesTreeViewer, input, false)); |
| |
| if (preferenceFileText != null) |
| { |
| preferenceFileText.addModifyListener(new ModifyListener() |
| { |
| public void modifyText(ModifyEvent e) |
| { |
| included.clear(); |
| EList<Object> children = input.getChildren(); |
| children.clear(); |
| |
| try |
| { |
| Map<URI, Pair<String, String>> preferences = new HashMap<URI, Pair<String, String>>(); |
| Map<String, String> loadProperties = PropertiesUtil.loadProperties(new File(((Text)e.widget).getText())); |
| for (Map.Entry<String, String> entry : loadProperties.entrySet()) |
| { |
| String key = entry.getKey(); |
| if (key.startsWith("/")) //$NON-NLS-1$ |
| { |
| preferences.put(PreferencesFactory.eINSTANCE.createURI(key), new Pair<String, String>(null, entry.getValue())); |
| } |
| } |
| |
| List<SetupTask> availablePreferences = RecorderTransaction.record(preferences); |
| children.addAll(availablePreferences); |
| } |
| catch (IORuntimeException ex) |
| { |
| children.add(new ItemProvider(ex.getMessage(), UIPlugin.INSTANCE.getImage("error"))); //$NON-NLS-1$ |
| } |
| |
| availablePreferencesTreeViewer.refresh(); |
| selectedPreferencesTreeViewer.refresh(); |
| } |
| }); |
| } |
| |
| return contents; |
| } |
| |
| @Override |
| public boolean close() |
| { |
| availablePreferencesContentProvider.dispose(); |
| selectedPreferencesContentProvider.dispose(); |
| return super.close(); |
| } |
| |
| public Map<URI, Pair<String, String>> getResult() |
| { |
| Map<URI, Pair<String, String>> result = new HashMap<URI, Pair<String, String>>(); |
| for (Object object : included) |
| { |
| PreferenceTask preferenceTask = (PreferenceTask)object; |
| new StringExpander() |
| { |
| @Override |
| protected String resolve(String key) |
| { |
| return null; |
| } |
| |
| @Override |
| protected boolean isUnexpanded(String key) |
| { |
| return false; |
| } |
| |
| @Override |
| protected String filter(String value, String filterName) |
| { |
| return null; |
| } |
| }; |
| |
| String escapedValue = preferenceTask.getValue(); |
| String actualValue = SetupUtil.descape(escapedValue); |
| result.put(PreferencesFactory.eINSTANCE.createURI(preferenceTask.getKey()), new Pair<String, String>(null, actualValue)); |
| } |
| |
| return result; |
| } |
| |
| /** |
| * @author Ed Merks |
| */ |
| private class FilteringSelectionAdapter extends SelectionAdapter |
| { |
| private final TreeViewer selectedPreferencesTreeViewer; |
| |
| private final TreeViewer availablePreferencesTreeViewer; |
| |
| private final ItemProvider input; |
| |
| private boolean add; |
| |
| private FilteringSelectionAdapter(TreeViewer selectedPreferencesTreeViewer, TreeViewer availablePreferencesTreeViewer, ItemProvider input, boolean add) |
| { |
| this.selectedPreferencesTreeViewer = selectedPreferencesTreeViewer; |
| this.availablePreferencesTreeViewer = availablePreferencesTreeViewer; |
| this.input = input; |
| this.add = add; |
| } |
| |
| @Override |
| public void widgetSelected(SelectionEvent event) |
| { |
| IStructuredSelection selection = (IStructuredSelection)(add ? availablePreferencesTreeViewer : selectedPreferencesTreeViewer).getSelection(); |
| List<Object> newSelection = new ArrayList<Object>(); |
| |
| for (Object object : selection.toArray()) |
| { |
| Object[] children = (add ? availablePreferencesContentProvider : selectedPreferencesContentProvider).getChildren(object); |
| if (children.length != 0) |
| { |
| List<Object> choices = Arrays.asList(children); |
| newSelection.addAll(choices); |
| } |
| else |
| { |
| newSelection.add(object); |
| } |
| } |
| |
| Set<Object> nonCandidates = new HashSet<Object>(newSelection); |
| Object candidate = null; |
| Object bestCandidate = null; |
| |
| for (TreeIterator<Object> it = (add ? availablePreferencesContentProvider : selectedPreferencesContentProvider).getAllContents(input, false); it |
| .hasNext();) |
| { |
| candidate = it.next(); |
| if (nonCandidates.remove(candidate)) |
| { |
| if (!(bestCandidate instanceof PreferenceTask)) |
| { |
| bestCandidate = null; |
| } |
| } |
| else |
| { |
| if (!(candidate instanceof CompoundTask)) |
| { |
| bestCandidate = candidate; |
| } |
| |
| if (nonCandidates.isEmpty()) |
| { |
| break; |
| } |
| } |
| } |
| |
| if (add) |
| { |
| included.addAll(newSelection); |
| } |
| else |
| { |
| included.removeAll(newSelection); |
| } |
| |
| for (Object object : input.getChildren()) |
| { |
| if (object instanceof CompoundTask) |
| { |
| CompoundTask compoundTask = (CompoundTask)object; |
| EList<SetupTask> setupTasks = compoundTask.getSetupTasks(); |
| if (newSelection.containsAll(setupTasks)) |
| { |
| newSelection.removeAll(setupTasks); |
| newSelection.add(compoundTask); |
| } |
| } |
| } |
| |
| selectedPreferencesTreeViewer.refresh(); |
| availablePreferencesTreeViewer.refresh(); |
| |
| (add ? selectedPreferencesTreeViewer : availablePreferencesTreeViewer).setSelection(new StructuredSelection(newSelection)); |
| |
| if (bestCandidate == null && candidate != null) |
| { |
| bestCandidate = candidate; |
| } |
| |
| if (bestCandidate != null) |
| { |
| (add ? availablePreferencesTreeViewer : selectedPreferencesTreeViewer).setSelection(new StructuredSelection(bestCandidate)); |
| } |
| } |
| } |
| |
| /** |
| * @author Ed Merks |
| */ |
| private final class FilteringAdapterFactoryContentProvider extends AdapterFactoryContentProvider |
| { |
| private boolean include; |
| |
| private FilteringAdapterFactoryContentProvider(AdapterFactory adapterFactory, boolean include) |
| { |
| super(adapterFactory); |
| this.include = include; |
| } |
| |
| public TreeIterator<Object> getAllContents(Object object, boolean includeRoot) |
| { |
| return new AbstractTreeIterator<Object>(object, includeRoot) |
| { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| protected Iterator<? extends Object> getChildren(Object object) |
| { |
| return Arrays.asList(object instanceof ItemProvider ? FilteringAdapterFactoryContentProvider.this.getElements(object) |
| : FilteringAdapterFactoryContentProvider.this.getChildren(object)).iterator(); |
| } |
| }; |
| } |
| |
| @Override |
| public Object[] getElements(Object object) |
| { |
| List<Object> elements = ((ItemProvider)object).getChildren(); |
| List<Object> result = new ArrayList<Object>(); |
| |
| for (Object element : elements) |
| { |
| if (include) |
| { |
| for (Object child : getChildren(element)) |
| { |
| if (included.contains(child)) |
| { |
| result.add(element); |
| break; |
| } |
| } |
| } |
| else if (element instanceof ItemProvider) |
| { |
| result.add(element); |
| } |
| else if (!included.containsAll(Arrays.asList(getChildren(element)))) |
| { |
| result.add(element); |
| } |
| } |
| |
| return result.toArray(); |
| } |
| |
| @Override |
| public Object[] getChildren(Object object) |
| { |
| Object[] children = super.getChildren(object); |
| List<Object> result = new ArrayList<Object>(); |
| |
| for (Object child : children) |
| { |
| if (included.contains(child) == include) |
| { |
| result.add(child); |
| } |
| } |
| |
| return result.toArray(); |
| } |
| } |
| |
| /** |
| * A filtered tree for displaying preferences, with an additional filter to suppress preferences set to their default value. |
| * |
| * @author Adrian Price <aprice@tibco.com> |
| */ |
| private static final class PreferenceFilteredTree extends FilteredTree |
| { |
| private static final IScopeContext DUMMY_CONFIGURATION_SCOPE = new DummyScope(ConfigurationScope.SCOPE); |
| |
| private static final IScopeContext DUMMY_DEFAULT_SCOPE = new DummyScope(DefaultScope.SCOPE); |
| |
| private static final IScopeContext DUMMY_INSTANCE_SCOPE = new DummyScope(InstanceScope.SCOPE); |
| |
| private static final IEclipsePreferences DUMMY_PREFERENCES = new DummyPreferences(); |
| |
| private static final IScopeContext DUMMY_PROJECT_SCOPE = new DummyScope(ProjectScope.SCOPE); |
| |
| private ToolItem defaultsToolItem; |
| |
| @SuppressWarnings("deprecation") |
| public PreferenceFilteredTree(Composite parent, int treeStyle, PatternFilter filter) |
| { |
| super(parent, treeStyle, filter, true); |
| } |
| |
| @Override |
| protected Composite createFilterControls(Composite parent) |
| { |
| ((GridLayout)parent.getLayout()).numColumns = 3; |
| Composite filters = super.createFilterControls(parent); |
| |
| ToolBar toolBar = new ToolBar(parent, SWT.FLAT | SWT.HORIZONTAL); |
| defaultsToolItem = new ToolItem(toolBar, SWT.CHECK); |
| defaultsToolItem.setImage(SetupEditorPlugin.INSTANCE.getSWTImage("filter_advanced_properties")); //$NON-NLS-1$ |
| defaultsToolItem.setToolTipText(Messages.PreferenceCaptureDialog_defaultsToolItem_tooltip); |
| defaultsToolItem.addSelectionListener(new SelectionAdapter() |
| { |
| @Override |
| public void widgetSelected(SelectionEvent e) |
| { |
| treeViewer.refresh(); |
| } |
| }); |
| |
| return filters; |
| } |
| |
| @Override |
| protected Control createTreeControl(Composite parent, int style) |
| { |
| Control treeControl = super.createTreeControl(parent, style); |
| treeViewer.addFilter(new ViewerFilter() |
| { |
| |
| private final IPreferencesService preferencesService = Platform.getPreferencesService(); |
| |
| private final IScopeContext[] defaultContexts = new IScopeContext[] { DUMMY_PROJECT_SCOPE, DUMMY_INSTANCE_SCOPE, DUMMY_CONFIGURATION_SCOPE, |
| DefaultScope.INSTANCE }; |
| |
| private final IScopeContext[] preferenceContexts = new IScopeContext[] { DUMMY_PROJECT_SCOPE, DUMMY_INSTANCE_SCOPE, DUMMY_CONFIGURATION_SCOPE, |
| DUMMY_DEFAULT_SCOPE }; |
| |
| private final Map<PreferenceTask, Boolean> selected = new HashMap<PreferenceTask, Boolean>(); |
| |
| @Override |
| public boolean select(Viewer viewer, Object parentElement, Object element) |
| { |
| if (!defaultsToolItem.getSelection()) |
| { |
| return true; |
| } |
| |
| if (element instanceof CompoundTask) |
| { |
| CompoundTask compoundTask = (CompoundTask)element; |
| EList<SetupTask> setupTasks = compoundTask.getSetupTasks(); |
| for (Object child : getPatternFilter().filter(viewer, compoundTask, setupTasks.toArray())) |
| { |
| if (select(viewer, compoundTask, child)) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| if (element instanceof PreferenceTask) |
| { |
| Boolean result = selected.get(element); |
| if (result != null) |
| { |
| return result; |
| } |
| |
| PreferenceTask preferenceTask = (PreferenceTask)element; |
| String preferencePath = preferenceTask.getKey(); |
| int index = preferencePath.indexOf('/', 1); |
| String scope = preferencePath.substring(1, index); |
| String keyWithoutScope = preferencePath.substring(index + 1); |
| index = keyWithoutScope.indexOf('/', 0); |
| String qualifier = keyWithoutScope.substring(0, index); |
| String key = keyWithoutScope.substring(index + 1); |
| |
| // NOTE: this hideous mess is necessary because IPreferencesService.getString(...) doesn't do what it says on the tin. |
| // That is, it effectively IGNORES the contexts parameter and searches ALL scopes regardless of which ones were supplied. |
| // So it's impossible to obtain the instance, configuration or default preference value by respectively passing just |
| // InstanceScope.INSTANCE, ConfiguurationScope.INSTANCE or DefaultScope.INSTANCE - hence the need for the dummy scopes. |
| IScopeContext instanceScope = DUMMY_INSTANCE_SCOPE; |
| IScopeContext configurationScope = DUMMY_CONFIGURATION_SCOPE; |
| if (InstanceScope.SCOPE.equals(scope)) |
| { |
| instanceScope = InstanceScope.INSTANCE; |
| } |
| else if (ConfigurationScope.SCOPE.equals(scope)) |
| { |
| configurationScope = ConfigurationScope.INSTANCE; |
| } |
| preferenceContexts[1] = instanceScope; |
| preferenceContexts[2] = configurationScope; |
| String defaultValue = preferencesService.getString(qualifier, key, null, defaultContexts); |
| String preferenceValue = preferencesService.getString(qualifier, key, null, preferenceContexts); |
| boolean isSelected = !(preferenceValue == null || preferenceValue.equals(defaultValue)); |
| selected.put(preferenceTask, isSelected); |
| return isSelected; |
| } |
| |
| return true; |
| } |
| }); |
| return treeControl; |
| } |
| |
| /** |
| * @author Adrian Price |
| */ |
| private static final class DummyPreferences implements IEclipsePreferences |
| { |
| public String absolutePath() |
| { |
| return null; |
| } |
| |
| public void accept(IPreferenceNodeVisitor visitor) throws BackingStoreException |
| { |
| } |
| |
| public void addNodeChangeListener(INodeChangeListener listener) |
| { |
| } |
| |
| public void addPreferenceChangeListener(IPreferenceChangeListener listener) |
| { |
| } |
| |
| public String[] childrenNames() throws BackingStoreException |
| { |
| return null; |
| } |
| |
| public void clear() throws BackingStoreException |
| { |
| } |
| |
| public void flush() throws BackingStoreException |
| { |
| } |
| |
| public String get(String key, String def) |
| { |
| return def; |
| } |
| |
| public boolean getBoolean(String key, boolean def) |
| { |
| return def; |
| } |
| |
| public byte[] getByteArray(String key, byte[] def) |
| { |
| return def; |
| } |
| |
| public double getDouble(String key, double def) |
| { |
| return def; |
| } |
| |
| public float getFloat(String key, float def) |
| { |
| return def; |
| } |
| |
| public int getInt(String key, int def) |
| { |
| return def; |
| } |
| |
| public long getLong(String key, long def) |
| { |
| return def; |
| } |
| |
| public String[] keys() throws BackingStoreException |
| { |
| return null; |
| } |
| |
| public String name() |
| { |
| return null; |
| } |
| |
| public Preferences node(String path) |
| { |
| return this; |
| } |
| |
| public boolean nodeExists(String pathName) throws BackingStoreException |
| { |
| return false; |
| } |
| |
| public Preferences parent() |
| { |
| return null; |
| } |
| |
| public void put(String key, String value) |
| { |
| } |
| |
| public void putBoolean(String key, boolean value) |
| { |
| } |
| |
| public void putByteArray(String key, byte[] value) |
| { |
| } |
| |
| public void putDouble(String key, double value) |
| { |
| } |
| |
| public void putFloat(String key, float value) |
| { |
| } |
| |
| public void putInt(String key, int value) |
| { |
| } |
| |
| public void putLong(String key, long value) |
| { |
| } |
| |
| public void remove(String key) |
| { |
| } |
| |
| public void removeNode() throws BackingStoreException |
| { |
| } |
| |
| public void removeNodeChangeListener(INodeChangeListener listener) |
| { |
| } |
| |
| public void removePreferenceChangeListener(IPreferenceChangeListener listener) |
| { |
| } |
| |
| public void sync() throws BackingStoreException |
| { |
| } |
| } |
| |
| /** |
| * @author Adrian Price |
| */ |
| private static final class DummyScope implements IScopeContext |
| { |
| private final String name; |
| |
| public DummyScope(String name) |
| { |
| this.name = name; |
| } |
| |
| public IPath getLocation() |
| { |
| return null; |
| } |
| |
| public String getName() |
| { |
| return name; |
| } |
| |
| public IEclipsePreferences getNode(String qualifier) |
| { |
| return DUMMY_PREFERENCES; |
| } |
| } |
| } |
| } |