| /******************************************************************************* |
| * Copyright (c) 2010 SAP AG, Walldorf. |
| * 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: |
| * SAP AG - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.platform.discovery.ui.internal.selector;
|
|
|
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreePath; |
| import org.eclipse.jface.viewers.TreeSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.platform.discovery.core.internal.selectors.IItemSelector; |
| import org.eclipse.platform.discovery.runtime.api.IDestinationsProvider; |
| import org.eclipse.platform.discovery.runtime.api.ISearchDestination; |
| import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IDestinationCategoryDescription; |
| import org.eclipse.platform.discovery.ui.internal.plugin.DiscoveryUIMessages; |
| import org.eclipse.platform.discovery.ui.internal.view.IGetControlObject; |
| import org.eclipse.platform.discovery.ui.internal.view.SearchConsoleView; |
| import org.eclipse.platform.discovery.ui.internal.view.impl.DestinationsContentProvider; |
| import org.eclipse.platform.discovery.ui.internal.view.impl.DestinationsLabelProvider; |
| import org.eclipse.platform.discovery.util.internal.property.IPropertyAttributeListener; |
| import org.eclipse.platform.discovery.util.internal.property.Property; |
| import org.eclipse.platform.discovery.util.internal.property.PropertyAttributeChangedEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.FormAttachment; |
| import org.eclipse.swt.layout.FormData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
|
|
|
|
| /**
|
| * The UI component for selecting search destinations
|
| *
|
| * @author Danail Branekov
|
| *
|
| */
|
| public abstract class SearchDestinationsSelector implements IItemSelector<ISearchDestination, IDestinationCategoryDescription>, IGetControlObject<Control>
|
| {
|
| private final TreeViewer destinationsTreeViewer;
|
| private final Property<IStructuredSelection> lastKnownSelection;
|
|
|
| public SearchDestinationsSelector(final Composite parent, final FormToolkit formToolkit, final int secondColumnPosition, final Control topNeighbourControl)
|
| {
|
| lastKnownSelection = new Property<IStructuredSelection>();
|
| lastKnownSelection.set(new StructuredSelection());
|
| lastKnownSelection.registerValueListener(new SelectionChangedListener(), false);
|
|
|
| Label destinationLabel = new Label(parent, SWT.FLAT);
|
| destinationLabel.setText(DiscoveryUIMessages.SEARCH_IN_LIST_VIEWER_LABEL);
|
|
|
| final FormData labelSearchedInFormData = new FormData();
|
| labelSearchedInFormData.left = new FormAttachment(0, SearchConsoleView.UI_IN_CONTROL_SPACING);
|
| labelSearchedInFormData.top = new FormAttachment(topNeighbourControl, SearchConsoleView.UI_IN_CONTROL_SPACING);
|
| destinationLabel.setLayoutData(labelSearchedInFormData);
|
|
|
| destinationsTreeViewer = createDestinationsTreeViewer(parent);
|
| formToolkit.adapt(destinationsTreeViewer.getControl(), true, true);
|
| final FormData searchInFormData = new FormData();
|
| searchInFormData.top = new FormAttachment(topNeighbourControl, SearchConsoleView.UI_IN_CONTROL_SPACING);
|
| searchInFormData.left = new FormAttachment(0, secondColumnPosition + 2*SearchConsoleView.UI_IN_CONTROL_SPACING);
|
| searchInFormData.right = new FormAttachment(100, -SearchConsoleView.UI_IN_CONTROL_SPACING);
|
| searchInFormData.height = Math.max(destinationsTreeViewer.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y, treeViewerMinHeight());
|
| destinationsTreeViewer.getControl().setLayoutData(searchInFormData);
|
| }
|
|
|
| public ISearchDestination getSelectedItem()
|
| {
|
| final Object selectedObject = ((IStructuredSelection) destinationsTreeViewer.getSelection()).getFirstElement();
|
| if (selectedObject instanceof IDestinationCategoryDescription)
|
| {
|
| return null;
|
| }
|
|
|
| return (ISearchDestination) selectedObject;
|
| }
|
|
|
| private TreeViewer createDestinationsTreeViewer(final Composite parent)
|
| {
|
| final TreeViewer viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
|
| viewer.setContentProvider(new DestinationsContentProvider()
|
| {
|
| @Override
|
| protected List<ISearchDestination> getSearchDestinationsForCategory(final IDestinationCategoryDescription category)
|
| {
|
| final List<ISearchDestination> result = new ArrayList<ISearchDestination>();
|
| for(IDestinationsProvider destinationsProvider : getDestinationProvidersForCategory(category))
|
| {
|
| result.addAll(getSearchDestinations(category, destinationsProvider));
|
| }
|
|
|
| return result;
|
| }
|
| });
|
| viewer.setLabelProvider(new DestinationsLabelProvider());
|
| viewer.addSelectionChangedListener(new ISelectionChangedListener()
|
| {
|
| @Override
|
| public void selectionChanged(final SelectionChangedEvent event)
|
| {
|
| // filter out empty selection events - registered listeners have to be notified, but the selection property needs to remain unchanged
|
| // Also, empty selection can happen only via API - the user is not capable of delesecting everything
|
| if(event.getSelection().isEmpty())
|
| {
|
| handleSelectionChange(null);
|
| return;
|
| }
|
| lastKnownSelection.set((IStructuredSelection) event.getSelection());
|
| }
|
| });
|
|
|
| return viewer;
|
| }
|
|
|
|
|
| @Override
|
| public Control getControl() {
|
| return destinationsTreeViewer.getControl();
|
| }
|
| |
| @Override
|
| public void setInput(List<IDestinationCategoryDescription> input)
|
| {
|
| updateInternal(input);
|
| }
|
|
|
| @SuppressWarnings("unchecked")
|
| public void update()
|
| {
|
| updateInternal((List<IDestinationCategoryDescription>) destinationsTreeViewer.getInput());
|
| }
|
|
|
| private void updateInternal(final List<IDestinationCategoryDescription> input)
|
| {
|
| destinationsTreeViewer.setInput(input);
|
| refreshAndExpandTreeViewer(destinationsTreeViewer);
|
| if(!input.isEmpty())
|
| {
|
| restoreLastKnownSelection(destinationsTreeViewer);
|
| }
|
|
|
| if (input.size() == 1)
|
| {
|
| final Set<ISearchDestination> result = new HashSet<ISearchDestination>();
|
| for(IDestinationsProvider destinationsProvider : getDestinationProvidersForCategory(input.iterator().next()))
|
| {
|
| result.addAll(getSearchDestinations(input.iterator().next(), destinationsProvider));
|
| }
|
| if (result.size() == 1)
|
| {
|
| destinationsTreeViewer.setSelection(new StructuredSelection(result.iterator().next()));
|
| }
|
| }
|
| }
|
|
|
| private void refreshAndExpandTreeViewer(TreeViewer viewer)
|
| {
|
| viewer.refresh();
|
| viewer.expandAll();
|
| }
|
|
|
| /**
|
| * Restores the last known selection
|
| */
|
| private void restoreLastKnownSelection(final TreeViewer viewer)
|
| {
|
| viewer.setSelection(lastKnownSelection.get(), true);
|
| lastKnownSelection.set((IStructuredSelection)viewer.getSelection());
|
| }
|
|
|
| public void setEnabled(boolean enabled)
|
| {
|
| destinationsTreeViewer.getControl().setEnabled(enabled);
|
| }
|
|
|
| @Override
|
| public boolean isEnabled()
|
| {
|
| return destinationsTreeViewer.getControl().isEnabled();
|
| }
|
|
|
| /**
|
| * Retrieves a set of destination providers which are capable of providing destinations for the category specified
|
| *
|
| * @param category
|
| * the destination category
|
| * @return a set of destination provider descriptions
|
| */
|
| protected abstract Set<IDestinationsProvider> getDestinationProvidersForCategory(final IDestinationCategoryDescription category);
|
|
|
| /**
|
| * Retrieves a list of search destinations which are relevant to the destination category and destination provider specified
|
| *
|
| * @param category
|
| * the destination category
|
| * @param destinationsProvider
|
| * the destinations provider
|
| * @return a set of search destinations
|
| */
|
| protected abstract List<ISearchDestination> getSearchDestinations(final IDestinationCategoryDescription category,
|
| final IDestinationsProvider destinationsProvider);
|
|
|
| private class SelectionChangedListener implements IPropertyAttributeListener<IStructuredSelection>
|
| {
|
| @Override
|
| public void attributeChanged(final PropertyAttributeChangedEvent<IStructuredSelection> event)
|
| {
|
| final IStructuredSelection selection = event.getNewAttribute();
|
| if (selection.isEmpty() || !(selection.getFirstElement() instanceof ISearchDestination))
|
| {
|
| handleSelectionChange(null);
|
| return;
|
| }
|
|
|
| handleSelectionChange((ISearchDestination)selection.getFirstElement());
|
| }
|
| }
|
|
|
| protected int treeViewerMinHeight()
|
| {
|
| // TODO: Maybe take a percentage of screen size!?
|
| return 80;
|
| } |
| |
| public IDestinationCategoryDescription getActiveDestinationCategory() { |
| IStructuredSelection selection = lastKnownSelection.get(); |
| |
| if(!(selection instanceof TreeSelection)) { |
| //this means initial empty selection |
| return null; |
| } |
| |
| TreeSelection treeSelection = (TreeSelection) selection; |
| |
| Object selectedElement = treeSelection.getFirstElement(); |
| if (selectedElement instanceof IDestinationCategoryDescription) { |
| return (IDestinationCategoryDescription)selectedElement; |
| } |
| |
| if(selectedElement instanceof ISearchDestination) { |
| TreePath pathToSelected = treeSelection.getPathsFor(selectedElement)[0]; |
| assert pathToSelected.getFirstSegment() instanceof IDestinationCategoryDescription; |
| return (IDestinationCategoryDescription) pathToSelected.getFirstSegment() ; |
| } |
| |
| return null; |
| }
|
| }
|