diff options
author | Susan Franklin | 2008-04-24 21:01:05 +0000 |
---|---|---|
committer | Susan Franklin | 2008-04-24 21:01:05 +0000 |
commit | 4d8a6529516307c9b1a866c239c54c1678bc5d80 (patch) | |
tree | e6e7d7404e2a4c49000a974420739e59875c0571 | |
parent | 64978dd20ec2d36a21fb5d703cd96e6b2b5ceb97 (diff) | |
download | rt.equinox.p2-4d8a6529516307c9b1a866c239c54c1678bc5d80.tar.gz rt.equinox.p2-4d8a6529516307c9b1a866c239c54c1678bc5d80.tar.xz rt.equinox.p2-4d8a6529516307c9b1a866c239c54c1678bc5d80.zip |
Bug 224445 - [ui] Available IU view should use check box selection model
8 files changed, 403 insertions, 40 deletions
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml index b855ce1eb..6beb9c1b9 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml @@ -49,7 +49,7 @@ id="org.eclipse.equinox.internal.p2.ui.sdk.RepositoryPropertyPage"> <enabledWhen> <adapt - type="org.eclipse.equinox.internal.provisional.p2.ui.model.RepositoryElement"> + type="org.eclipse.equinox.internal.provisional.p2.ui.model.IRepositoryElement"> </adapt> </enabledWhen> </page> diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/UpdateAndInstallDialog.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/UpdateAndInstallDialog.java index c0df793cf..1bef4c984 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/UpdateAndInstallDialog.java +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/UpdateAndInstallDialog.java @@ -39,6 +39,7 @@ import org.eclipse.jface.window.SameShellProvider; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.dnd.*; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.GC; @@ -58,6 +59,8 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi private static final int DEFAULT_HEIGHT = 240; private static final int DEFAULT_WIDTH = 300; private static final int CHAR_INDENT = 5; + private static final int SITE_COLUMN_WIDTH_IN_DLUS = 300; + private static final int OTHER_COLUMN_WIDTH_IN_DLUS = 200; private static final int VERTICAL_MARGIN_DLU = 2; private static final int DEFAULT_VIEW_TYPE = AvailableIUViewQueryContext.VIEW_BY_REPO; private static final int INDEX_INSTALLED = 0; @@ -172,7 +175,7 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi // Set widgets according to query context showInstalledCheckbox.setSelection(!queryContext.getHideAlreadyInstalled()); showLatestVersionsCheckbox.setSelection(queryContext.getShowLatestVersionsOnly()); - + updateTreeColumns(); } private void createTabFolder(Composite parent) { @@ -331,7 +334,7 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi composite.setLayout(layout); // Now the available group - availableIUGroup = new AvailableIUGroup(composite, ProvSDKUIActivator.getDefault().getQueryProvider(), JFaceResources.getDialogFont(), new ProvisioningContext(), queryContext, new AvailableIUPatternFilter(ProvUI.getIUColumnConfig()), ProvUI.getIUColumnConfig(), this); + availableIUGroup = new AvailableIUGroup(composite, ProvSDKUIActivator.getDefault().getQueryProvider(), JFaceResources.getDialogFont(), new ProvisioningContext(), queryContext, new AvailableIUPatternFilter(ProvUI.getIUColumnConfig()), ProvUI.getIUColumnConfig(), this, true); // Vertical buttons Composite vButtonBar = (Composite) createAvailableIUsVerticalButtonBar(composite); @@ -339,7 +342,9 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi data.verticalIndent = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_BAR_HEIGHT); vButtonBar.setLayoutData(data); - // Must be done after buttons are created so that the buttons can + // Selection listeners must be registered on both the normal selection + // events and the check mark events. Must be done after buttons + // are created so that the buttons can // register and receive their selection notifications before us. availableIUGroup.getStructuredViewer().addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { @@ -347,6 +352,12 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi } }); + availableIUGroup.getCheckMappingSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + validateAvailableIUButtons(); + } + }); + // We might need to adjust the content of this viewer according to installation // changes. We want to be very selective about refreshing. profileListener = new StructuredViewerProvisioningListener(availableIUGroup.getStructuredViewer(), StructuredViewerProvisioningListener.PROV_EVENT_PROFILE, ProvSDKUIActivator.getDefault().getQueryProvider()) { @@ -438,10 +449,11 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi // Add the buttons to the button bar. installButton = createVerticalButton(composite, ProvUI.INSTALL_COMMAND_LABEL, false); - IAction installAction = new InstallAction(availableIUGroup.getStructuredViewer(), profileId, null, ProvPolicies.getDefault(), getShell()); + IAction installAction = new InstallAction(availableIUGroup.getCheckMappingSelectionProvider(), profileId, null, ProvPolicies.getDefault(), getShell()); installButton.setData(BUTTONACTION, installAction); availablePropButton = createVerticalButton(composite, ProvSDKMessages.UpdateAndInstallDialog_Properties, false); + // We use the viewer selection for properties, not the check marks IAction propertiesAction = new PropertyDialogAction(new SameShellProvider(parent.getShell()), availableIUGroup.getStructuredViewer()); availablePropButton.setData(BUTTONACTION, propertiesAction); @@ -476,18 +488,35 @@ public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvi } void updateAvailableViewState() { - Composite parent = availableIUGroup.getComposite().getParent(); - parent.setRedraw(false); + if (availableIUGroup.getTree() == null || availableIUGroup.getTree().isDisposed()) + return; + final Composite parent = availableIUGroup.getComposite().getParent(); validateAvailableIUButtons(); availableIUGroup.setUseBoldFontForFilteredItems(queryContext.getViewType() != AvailableIUViewQueryContext.VIEW_FLAT); - queryContext.setShowLatestVersionsOnly(showLatestVersionsCheckbox.getSelection()); - if (showInstalledCheckbox.getSelection()) - queryContext.showAlreadyInstalled(); - else - queryContext.hideAlreadyInstalled(profileId); - availableIUGroup.setQueryContext(queryContext); - parent.layout(true); - parent.setRedraw(true); + + BusyIndicator.showWhile(display, new Runnable() { + public void run() { + parent.setRedraw(false); + updateTreeColumns(); + queryContext.setShowLatestVersionsOnly(showLatestVersionsCheckbox.getSelection()); + if (showInstalledCheckbox.getSelection()) + queryContext.showAlreadyInstalled(); + else + queryContext.hideAlreadyInstalled(profileId); + availableIUGroup.setQueryContext(queryContext); + parent.layout(true); + parent.setRedraw(true); + } + }); + } + + void updateTreeColumns() { + if (availableIUGroup.getTree() == null || availableIUGroup.getTree().isDisposed()) + return; + TreeColumn[] columns = availableIUGroup.getTree().getColumns(); + if (columns.length > 0) + columns[0].setWidth(convertHorizontalDLUsToPixels(queryContext.getViewType() == AvailableIUViewQueryContext.VIEW_BY_REPO ? SITE_COLUMN_WIDTH_IN_DLUS : OTHER_COLUMN_WIDTH_IN_DLUS)); + } void validateAvailableIUButtons() { diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/provisional/p2/ui/sdk/RepositoryManipulationDialog.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/provisional/p2/ui/sdk/RepositoryManipulationDialog.java index 2e26846fd..3ddc30973 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/provisional/p2/ui/sdk/RepositoryManipulationDialog.java +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/provisional/p2/ui/sdk/RepositoryManipulationDialog.java @@ -89,6 +89,7 @@ public class RepositoryManipulationDialog extends TrayDialog { setTableColumns(table); contentProvider = new RepositoryContentProvider(ProvSDKUIActivator.getDefault().getQueryProvider()); repositoryViewer.setComparer(new ProvElementComparer()); + repositoryViewer.setComparator(new ViewerComparator()); repositoryViewer.setContentProvider(contentProvider); repositoryViewer.setLabelProvider(new ProvElementLabelProvider()); diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ContainerCheckedTreeViewer.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ContainerCheckedTreeViewer.java new file mode 100644 index 000000000..eb21c28fd --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ContainerCheckedTreeViewer.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.ui.dialogs; + +import java.util.ArrayList; +import org.eclipse.equinox.internal.provisional.p2.ui.query.QueriedElement; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.*; + +/** + * CheckboxTreeViewer with special behaviour of the checked / gray state on + * container (non-leaf) nodes: + * Copied from org.eclipse.ui.dialogs + * Altered so that checking a parent will expand it when we know it's a long + * running operation to get the children. + * + * The modified method is doCheckStateChanged() + */ +public class ContainerCheckedTreeViewer extends CheckboxTreeViewer { + + /** + * Constructor for ContainerCheckedTreeViewer. + * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite) + */ + public ContainerCheckedTreeViewer(Composite parent) { + super(parent); + initViewer(); + } + + /** + * Constructor for ContainerCheckedTreeViewer. + * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite,int) + */ + public ContainerCheckedTreeViewer(Composite parent, int style) { + super(parent, style); + initViewer(); + } + + /** + * Constructor for ContainerCheckedTreeViewer. + * @see CheckboxTreeViewer#CheckboxTreeViewer(Tree) + */ + public ContainerCheckedTreeViewer(Tree tree) { + super(tree); + initViewer(); + } + + private void initViewer() { + setUseHashlookup(true); + addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + doCheckStateChanged(event.getElement()); + } + }); + addTreeListener(new ITreeViewerListener() { + public void treeCollapsed(TreeExpansionEvent event) { + } + + public void treeExpanded(TreeExpansionEvent event) { + Widget item = findItem(event.getElement()); + if (item instanceof TreeItem) { + initializeItem((TreeItem) item); + } + } + }); + } + + /** + * Update element after a checkstate change. + * @param element + */ + protected void doCheckStateChanged(Object element) { + Widget item = findItem(element); + if (item instanceof TreeItem) { + TreeItem treeItem = (TreeItem) item; + treeItem.setGrayed(false); + // BEGIN MODIFICATION OF COPIED CLASS + if (element instanceof QueriedElement && treeItem.getChecked()) { + if (!((QueriedElement) element).hasQueryable()) { + // We have checked an element that will take some time + // to get its children. Use this opportunity to auto-expand + // the tree so that the check mark is not misleading. Don't + // update the check state because it will just be a pending + // placeholder. + expandToLevel(element, 1); + return; + } + } + // END MODIFICATION OF COPIED CLASS + updateChildrenItems(treeItem); + updateParentItems(treeItem.getParentItem()); + } + } + + /** + * The item has expanded. Updates the checked state of its children. + */ + private void initializeItem(TreeItem item) { + if (item.getChecked() && !item.getGrayed()) { + updateChildrenItems(item); + } + } + + /** + * Updates the check state of all created children + */ + private void updateChildrenItems(TreeItem parent) { + Item[] children = getChildren(parent); + boolean state = parent.getChecked(); + for (int i = 0; i < children.length; i++) { + TreeItem curr = (TreeItem) children[i]; + if (curr.getData() != null && ((curr.getChecked() != state) || curr.getGrayed())) { + curr.setChecked(state); + curr.setGrayed(false); + updateChildrenItems(curr); + } + } + } + + /** + * Updates the check / gray state of all parent items + */ + private void updateParentItems(TreeItem item) { + if (item != null) { + Item[] children = getChildren(item); + boolean containsChecked = false; + boolean containsUnchecked = false; + for (int i = 0; i < children.length; i++) { + TreeItem curr = (TreeItem) children[i]; + containsChecked |= curr.getChecked(); + containsUnchecked |= (!curr.getChecked() || curr.getGrayed()); + } + item.setChecked(containsChecked); + item.setGrayed(containsChecked && containsUnchecked); + updateParentItems(item.getParentItem()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICheckable#setChecked(java.lang.Object, boolean) + */ + public boolean setChecked(Object element, boolean state) { + if (super.setChecked(element, state)) { + doCheckStateChanged(element); + return true; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.CheckboxTreeViewer#setCheckedElements(java.lang.Object[]) + */ + public void setCheckedElements(Object[] elements) { + super.setCheckedElements(elements); + for (int i = 0; i < elements.length; i++) { + doCheckStateChanged(elements[i]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpanded(org.eclipse.swt.widgets.Item, boolean) + */ + protected void setExpanded(Item item, boolean expand) { + super.setExpanded(item, expand); + if (expand && item instanceof TreeItem) { + initializeItem((TreeItem) item); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.CheckboxTreeViewer#getCheckedElements() + */ + public Object[] getCheckedElements() { + Object[] checked = super.getCheckedElements(); + // add all items that are children of a checked node but not created yet + ArrayList result = new ArrayList(); + for (int i = 0; i < checked.length; i++) { + Object curr = checked[i]; + result.add(curr); + Widget item = findItem(curr); + if (item != null) { + Item[] children = getChildren(item); + // check if contains the dummy node + if (children.length == 1 && children[0].getData() == null) { + // not yet created + collectChildren(curr, result); + } + } + } + return result.toArray(); + } + + /** + * Recursively add the filtered children of element to the result. + * @param element + * @param result + */ + private void collectChildren(Object element, ArrayList result) { + Object[] filteredChildren = getFilteredChildren(element); + for (int i = 0; i < filteredChildren.length; i++) { + Object curr = filteredChildren[i]; + result.add(curr); + collectChildren(curr, result); + } + } + +} diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/DeferredFetchFilteredTree.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/DeferredFetchFilteredTree.java index fd89beda4..00e2dda1b 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/DeferredFetchFilteredTree.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/DeferredFetchFilteredTree.java @@ -9,6 +9,7 @@ import org.eclipse.equinox.internal.provisional.p2.ui.viewers.DeferredQueryConte import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; @@ -21,8 +22,9 @@ import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.progress.WorkbenchJob; /** - * FilteredTree extension that provides a hook for menu creation, - * and forces synchronous fetching of the tree when the first + * FilteredTree extension that creates a check box tree, + * provides a hook for menu creation, and forces synchronous + * fetching of the tree when the first * filtering is performed. * * @since 3.4 @@ -38,12 +40,14 @@ public class DeferredFetchFilteredTree extends FilteredTree { PatternFilter patternFilter; IViewMenuProvider viewMenuProvider; DeferredQueryContentProvider contentProvider; + boolean useCheckBoxTree = false; - public DeferredFetchFilteredTree(Composite parent, int treeStyle, PatternFilter filter, final IViewMenuProvider viewMenuProvider, Display display) { + public DeferredFetchFilteredTree(Composite parent, int treeStyle, PatternFilter filter, final IViewMenuProvider viewMenuProvider, Display display, boolean useCheckBoxViewer) { super(parent); this.display = display; this.viewMenuProvider = viewMenuProvider; this.patternFilter = filter; + this.useCheckBoxTree = useCheckBoxViewer; init(treeStyle, filter); } @@ -61,6 +65,12 @@ public class DeferredFetchFilteredTree extends FilteredTree { } } + protected TreeViewer doCreateTreeViewer(Composite composite, int style) { + if (useCheckBoxTree) + return new ContainerCheckedTreeViewer(composite, style); + return super.doCreateTreeViewer(composite, style); + } + protected Composite createFilterControls(Composite filterParent) { super.createFilterControls(filterParent); Object layout = filterParent.getLayout(); diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/StructuredIUGroup.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/StructuredIUGroup.java index ddc3d76b8..3357da221 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/StructuredIUGroup.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/StructuredIUGroup.java @@ -37,7 +37,7 @@ public abstract class StructuredIUGroup { private IQueryProvider queryProvider; private ProvisioningContext context; private FontMetrics fm; - private StructuredViewer viewer; + protected StructuredViewer viewer; private Composite composite; /** diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/actions/InstallAction.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/actions/InstallAction.java index 08827fbc7..8762a4a02 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/actions/InstallAction.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/actions/InstallAction.java @@ -11,6 +11,7 @@ package org.eclipse.equinox.internal.provisional.p2.ui.actions; +import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.internal.p2.ui.ProvUIMessages; @@ -68,14 +69,12 @@ public class InstallAction extends ProfileModificationAction { protected boolean isEnabledFor(Object[] selectionArray) { if (selectionArray.length < 1) return false; + Set children = new HashSet(); for (int i = 0; i < selectionArray.length; i++) { - Set children = ElementUtils.getIUs(selectionArray[i]); - if (children.isEmpty()) - return false; + children.addAll(ElementUtils.getIUs(selectionArray[i])); } - return true; - + return !children.isEmpty(); } protected String getTaskName() { diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/AvailableIUGroup.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/AvailableIUGroup.java index 53ce08b4e..059e42cdc 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/AvailableIUGroup.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/AvailableIUGroup.java @@ -11,6 +11,9 @@ package org.eclipse.equinox.internal.provisional.p2.ui.dialogs; import java.net.URL; +import java.util.*; +import java.util.List; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.equinox.internal.p2.ui.ProvUIActivator; import org.eclipse.equinox.internal.p2.ui.ProvUIMessages; import org.eclipse.equinox.internal.p2.ui.dialogs.DeferredFetchFilteredTree; @@ -48,6 +51,99 @@ import org.eclipse.ui.statushandlers.StatusManager; */ public class AvailableIUGroup extends StructuredIUGroup { + class CheckSelectionProvider implements ISelectionProvider, ICheckStateListener { + + CheckboxTreeViewer checkboxViewer; + private ListenerList listeners = new ListenerList(); + List checkedNotGrayed; + + CheckSelectionProvider(CheckboxTreeViewer v) { + this.checkboxViewer = v; + v.addCheckStateListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + listeners.add(listener); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() + */ + public ISelection getSelection() { + return new IStructuredSelection() { + public Object getFirstElement() { + if (size() == 0) + return null; + return toList().get(0); + } + + public Iterator iterator() { + return toList().iterator(); + } + + public int size() { + return toList().size(); + } + + public Object[] toArray() { + return toList().toArray(); + } + + public List toList() { + return getCheckedNotGrayed(); + } + + public boolean isEmpty() { + return toList().isEmpty(); + } + + }; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + listeners.remove(listener); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) + */ + public void setSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + checkboxViewer.setCheckedElements(((IStructuredSelection) selection).toArray()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) + */ + public void checkStateChanged(CheckStateChangedEvent event) { + final Object[] listenerArray = listeners.getListeners(); + checkedNotGrayed = null; + SelectionChangedEvent selectionEvent = new SelectionChangedEvent(this, this.getSelection()); + for (int i = 0; i < listenerArray.length; i++) { + ((ISelectionChangedListener) listenerArray[i]).selectionChanged(selectionEvent); + } + } + + List getCheckedNotGrayed() { + if (checkedNotGrayed == null) { + Object[] checked = checkboxViewer.getCheckedElements(); + checkedNotGrayed = new ArrayList(checked.length); + for (int i = 0; i < checked.length; i++) + if (!checkboxViewer.getGrayed(checked[i])) + checkedNotGrayed.add(checked[i]); + } + return checkedNotGrayed; + + } + } + QueryContext queryContext; // We restrict the type of the filter used because PatternFilter does // unnecessary accesses of children that cause problems with the deferred @@ -55,16 +151,18 @@ public class AvailableIUGroup extends StructuredIUGroup { AvailableIUPatternFilter filter; private IViewMenuProvider menuProvider; private boolean useBold = false; + private boolean useCheckboxes = false; private IUDetailsLabelProvider labelProvider; private Display display; boolean ignoreEvent = false; DeferredFetchFilteredTree filteredTree; IUColumnConfig[] columnConfig; private int refreshRepoFlags = IMetadataRepositoryManager.REPOSITORIES_NON_SYSTEM; + ISelectionProvider selectionProvider; /** * Create a group that represents the available IU's but does not use any of the - * view menu or filtering capabilities. + * view menu or check box capabilities. * * @param parent the parent composite for the group * @param queryProvider the query provider that defines the queries used @@ -75,7 +173,7 @@ public class AvailableIUGroup extends StructuredIUGroup { * including information about which repositories should be used. */ public AvailableIUGroup(final Composite parent, IQueryProvider queryProvider, Font font, ProvisioningContext context) { - this(parent, queryProvider, font, context, null, null, ProvUI.getIUColumnConfig(), null); + this(parent, queryProvider, font, context, null, null, ProvUI.getIUColumnConfig(), null, false); } /** @@ -96,13 +194,17 @@ public class AvailableIUGroup extends StructuredIUGroup { * will be used. * @param menuProvider the IMenuProvider that fills the view menu. If <code>null</code>, * then there is no view menu shown. + * @param useCheckboxes a boolean indicating whether a checkbox selection model should be + * used. If <code>true</code>, a check box selection model will be used and the group's + * implementation of ISelectionProvider will use the checks as the selection. */ - public AvailableIUGroup(final Composite parent, IQueryProvider queryProvider, Font font, ProvisioningContext context, QueryContext queryContext, AvailableIUPatternFilter filter, IUColumnConfig[] columnConfig, IViewMenuProvider menuProvider) { + public AvailableIUGroup(final Composite parent, IQueryProvider queryProvider, Font font, ProvisioningContext context, QueryContext queryContext, AvailableIUPatternFilter filter, IUColumnConfig[] columnConfig, IViewMenuProvider menuProvider, boolean useCheckboxes) { super(parent, queryProvider, font, context); this.display = parent.getDisplay(); this.queryContext = queryContext; this.filter = filter; this.menuProvider = menuProvider; + this.useCheckboxes = useCheckboxes; if (columnConfig == null) this.columnConfig = ProvUI.getIUColumnConfig(); else @@ -116,8 +218,12 @@ public class AvailableIUGroup extends StructuredIUGroup { protected StructuredViewer createViewer(Composite parent) { // Table of available IU's - filteredTree = new DeferredFetchFilteredTree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, filter, menuProvider, parent.getDisplay()); + filteredTree = new DeferredFetchFilteredTree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, filter, menuProvider, parent.getDisplay(), useCheckboxes); final TreeViewer availableIUViewer = filteredTree.getViewer(); + if (availableIUViewer instanceof CheckboxTreeViewer) + selectionProvider = new CheckSelectionProvider((CheckboxTreeViewer) availableIUViewer); + else + selectionProvider = availableIUViewer; labelProvider = new IUDetailsLabelProvider(filteredTree, columnConfig, getShell()); labelProvider.setUseBoldFontForFilteredItems(useBold); @@ -191,13 +297,13 @@ public class AvailableIUGroup extends StructuredIUGroup { */ public void setQueryContext(QueryContext context) { this.queryContext = context; - if (getStructuredViewer() == null) + if (viewer == null) return; - Object input = getStructuredViewer().getInput(); + Object input = viewer.getInput(); if (input instanceof QueriedElement) { ((QueriedElement) input).setQueryContext(context); - getStructuredViewer().refresh(); + viewer.refresh(); } } @@ -241,9 +347,9 @@ public class AvailableIUGroup extends StructuredIUGroup { } public Tree getTree() { - if (getStructuredViewer() == null) + if (viewer == null) return null; - return ((TreeViewer) getStructuredViewer()).getTree(); + return ((TreeViewer) viewer).getTree(); } /** @@ -257,9 +363,8 @@ public class AvailableIUGroup extends StructuredIUGroup { else op = new RefreshMetadataRepositoriesOperation(ProvUIMessages.AvailableIUGroup_RefreshOperationLabel, urls); ProvisioningOperationRunner.schedule(op, getShell(), StatusManager.SHOW | StatusManager.LOG); - StructuredViewer v = getStructuredViewer(); - if (v != null && !v.getControl().isDisposed()) - v.setInput(getNewInput()); + if (viewer != null && !viewer.getControl().isDisposed()) + viewer.setInput(getNewInput()); } /* @@ -279,19 +384,19 @@ public class AvailableIUGroup extends StructuredIUGroup { } display.asyncExec(new Runnable() { public void run() { - final TreeViewer viewer = filteredTree.getViewer(); + final TreeViewer treeViewer = filteredTree.getViewer(); IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench.isClosing()) return; - viewer.refresh(); - final Tree tree = viewer.getTree(); + treeViewer.refresh(); + final Tree tree = treeViewer.getTree(); if (tree != null && !tree.isDisposed()) { TreeItem[] items = tree.getItems(); for (int i = 0; i < items.length; i++) { if (items[i].getData() instanceof IRepositoryElement) { URL url = ((IRepositoryElement) items[i].getData()).getLocation(); if (url.toExternalForm().equals(location.toExternalForm())) { - viewer.expandToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS); + treeViewer.expandToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS); tree.select(items[i]); return; } @@ -301,4 +406,8 @@ public class AvailableIUGroup extends StructuredIUGroup { } }); } + + public ISelectionProvider getCheckMappingSelectionProvider() { + return selectionProvider; + } } |