Java tutorial
/* * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" * which accompanies this distribution, and is available * at the URL "http://www.eclipse.org/legal/epl-v10.html". * * Initial Contributors: * Nokia Corporation - initial contribution. * * Contributors: * * Description: * */ package com.nokia.sdt.uidesigner.ui; import com.nokia.sdt.datamodel.adapter.IComponentInstance; import com.nokia.sdt.editor.*; import com.nokia.sdt.uidesigner.ui.editparts.*; import com.nokia.sdt.uidesigner.ui.utils.Adapters; import com.nokia.sdt.uidesigner.ui.utils.EditorUtils; import com.nokia.cpp.internal.api.utils.core.Logging; import org.eclipse.core.runtime.*; import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.*; import org.eclipse.jface.viewers.*; import org.eclipse.ui.*; import java.util.*; /** * SelectionManager * * <li>A selection provider that will unify the selections of both * GraphicalViewers so as to provide a single selection from the EditorPart. * <li>Also, a SelectionSynchronizer implementation that allows selection * setting from other sources besides viewers. * <li>Handles left over selections from editor reload operation. */ public class SelectionManager implements ISelectionManager { private IDesignerEditor editor; private ListenerList selectionChangedListeners = new ListenerList(ListenerList.IDENTITY); private IPartService partService; private IPartListener partListener; private List leftoverSelectedNames; private Set savedComponentEditors = new HashSet(); private List partsWithVisibleScrollbars = new ArrayList(); private ISelection currentSelection; private List viewers = new ArrayList(); private boolean isDispatching; class PartListener implements IPartListener { private IDesignerEditor editor; public PartListener(IDesignerEditor editor) { this.editor = editor; } public void partActivated(IWorkbenchPart part) { if (part.equals(editor.getAdapter(IWorkbenchPart.class))) { if (leftoverSelectedNames != null) { setSelectionFromNames(leftoverSelectedNames); leftoverSelectedNames = null; } } } public void partBroughtToTop(IWorkbenchPart part) { } public void partClosed(IWorkbenchPart part) { } public void partDeactivated(IWorkbenchPart part) { } public void partOpened(IWorkbenchPart part) { if (!part.equals(editor)) return; getLeftoverSelectedNames(); } } public SelectionManager(IDesignerEditor editor, IPartService partService) { this.editor = editor; this.partService = partService; partListener = new PartListener(editor); partService.addPartListener(partListener); } public void dispose() { partService.removePartListener(partListener); editor = null; selectionChangedListeners.clear(); viewers.clear(); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.add(listener); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.remove(listener); } private boolean editPartListContainsModel(List<EditPart> editPartList, Object model) { for (EditPart editPart : editPartList) { if (editPart.getModel().equals(model)) return true; } return false; } private void addUniqueSelectedPartsFromViewer(List<EditPart> selectedEditParts, EditPartViewer viewer) { if (viewer != null) { for (EditPart editPart : getPrunedEditParts(viewer.getSelectedEditParts())) { if (!editPartListContainsModel(selectedEditParts, editPart.getModel())) { selectedEditParts.add(editPart); } } } } private void addModelsFromViewer(Collection<EObject> selectedObjects, EditPartViewer viewer) { if (viewer != null) { for (EditPart editPart : getPrunedEditParts(viewer.getSelectedEditParts())) { selectedObjects.add((EObject) editPart.getModel()); } } } private boolean containsLayoutObjects(Collection<EObject> selectedObjects) { for (EObject object : selectedObjects) { if (Adapters.getLayoutObject(object) != null && EditorUtils.findTransientObject(object) == null) return true; } return false; } private boolean containsOutlineOnlyObjects(Collection<EObject> selectedObjects) { for (EObject object : selectedObjects) { if (Adapters.getLayoutObject(object) == null && !EditorUtils.isNonLayoutObject(object, null)) return true; } return false; } private Collection<EditPart> getPrunedEditParts(Collection<EditPart> parts) { // we remove content parts because they are not actual model objects // also remove the transient edit parts, so the selection will contain the non-layout part List<EditPart> prunedParts = new ArrayList<EditPart>(); for (EditPart editPart : parts) { if (editPart.getModel() != null && !editPart.getModel().equals(editor.getModelObject()) && !(editPart instanceof TransientObjectEditPart)) prunedParts.add(editPart); } return prunedParts; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() */ public ISelection getSelection() { if (currentSelection != null) return currentSelection; // create a new list of edit parts from the various viewers. // favor upper viewer parts to outline part to allow alignment and matching actions to work. // However, avoid mixing outline with graphical parts - some GEF actions throw NPEs. // So if there are outline-only objects in the selection, use only outline parts List<EditPart> selectedEditParts = new ArrayList(); boolean useGraphicalViewers = false; EditPartViewer outlineViewer = this.editor.getOutlineViewer(); if (outlineViewer != null) { Set<EObject> selectedObjects = new HashSet(); addModelsFromViewer(selectedObjects, outlineViewer); if (selectedObjects.isEmpty()) return currentSelection = StructuredSelection.EMPTY; if (containsOutlineOnlyObjects(selectedObjects)) addUniqueSelectedPartsFromViewer(selectedEditParts, outlineViewer); else useGraphicalViewers = true; } else useGraphicalViewers = true; if (useGraphicalViewers) { addUniqueSelectedPartsFromViewer(selectedEditParts, this.editor.getUpperGraphicalViewer()); addUniqueSelectedPartsFromViewer(selectedEditParts, this.editor.getLowerGraphicalViewer()); } // prune the list to not include contents or transient parts List selection = new ArrayList(); for (EditPart editPart : selectedEditParts) { selection.add(editPart); } return currentSelection = new StructuredSelection(selection); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) */ public void setSelection(ISelection newSelection) { syncSelection(null, newSelection); } public void addViewer(EditPartViewer viewer) { viewer.addSelectionChangedListener(this); viewers.add(viewer); } public void removeViewer(EditPartViewer viewer) { viewer.removeSelectionChangedListener(this); viewers.remove(viewer); } protected EditPart getViewerEditPart(EditPartViewer viewer, Object model) { if (model == null) return null; Object temp = viewer.getEditPartRegistry().get(model); EditPart newPart = null; if (temp != null) { newPart = (EditPart) temp; } return newPart; } private void syncSelection(EditPartViewer source, ISelection selection) { if (editor.getUpperGraphicalViewer() == null) return; determineTransientMode(selection); adviseEditors(selection); resetContainerScrollbarsVisibility(selection); isDispatching = true; if (source instanceof org.eclipse.gef.ui.parts.TreeViewer) { // tree viewer => all others EditorUtils.setDisplayModelSelectedObjects(editor.getDisplayModel(), getModelObjectsFromSelection(selection)); setViewerSelection(editor.getUpperGraphicalViewer(), selection); setViewerSelection(editor.getLowerGraphicalViewer(), selection); } else if (editor.getUpperGraphicalViewer().equals(source)) { // if upper, sel => tree; null => lower setViewerSelection(editor.getOutlineViewer(), selection); setViewerSelection(editor.getLowerGraphicalViewer(), selection); } else if ((source != null) && source.equals(editor.getLowerGraphicalViewer())) { // if lower, sel => tree; null => upper setViewerSelection(editor.getOutlineViewer(), selection); setViewerSelection(editor.getUpperGraphicalViewer(), selection); } else if (source == null) { // if null source, set all setViewerSelection(editor.getUpperGraphicalViewer(), selection); setViewerSelection(editor.getLowerGraphicalViewer(), selection); setViewerSelection(editor.getOutlineViewer(), selection); } isDispatching = false; if (source != null) revealSelectionInViewer(source, selection); // tell the rest of the world fireSelectionChanged(getSelection()); } private List getViewerSelection(EditPartViewer viewer, ISelection selection) { if ((viewer == null) || (viewer.getControl() == null)) return null; ArrayList result = new ArrayList(); for (Iterator iter = ((IStructuredSelection) selection).iterator(); iter.hasNext();) { EditPart part = getViewerEditPart(viewer, getObjectFromSelected(iter.next())); if (part != null) result.add(part); } return result; } private void setViewerSelection(EditPartViewer viewer, ISelection selection) { if (viewer == null) return; List selectedParts = getViewerSelection(viewer, selection); if ((selectedParts != null) && (!selectedParts.isEmpty())) { viewer.setSelection(new StructuredSelection(selectedParts)); if (selectedParts.size() > 0) { viewer.reveal((EditPart) selectedParts.get(selectedParts.size() - 1)); } } else { viewer.setSelection(StructuredSelection.EMPTY); } } public void revealSelectionInViewer(EditPartViewer viewer, ISelection selection) { List selectedParts = getViewerSelection(viewer, selection); if ((selectedParts != null) && (!selectedParts.isEmpty())) { if (selectedParts.size() > 0) { for (Iterator<EditPart> iter = selectedParts.iterator(); iter.hasNext();) { EditPart part = iter.next(); if (part.getModel() instanceof EObject) { viewer.reveal(part); break; } } } } } public void selectionChanged(SelectionChangedEvent event) { currentSelection = null; if (isDispatching) return; // this synchronizes between viewers EditPartViewer source = (EditPartViewer) event.getSelectionProvider(); ISelection selection = event.getSelection(); syncSelection(source, selection); } private void determineTransientMode(ISelection selection) { List selectedObjects = getModelObjectsFromSelection(selection); if (selectedObjects.isEmpty() || containsLayoutObjects(selectedObjects)) editor.setLayoutMode(); // if all objects belong to the same transient root, set to transient, else set to layout // set to transient mode, else set to layout mode EObject transientRoot = null; boolean makeTransient = false; for (Iterator iter = selectedObjects.iterator(); iter.hasNext();) { EObject object = (EObject) iter.next(); if (transientRoot == null) { transientRoot = EditorUtils.findTransientObject(object); } makeTransient = EditorUtils.isSameObjectOrChild(transientRoot, object); } if (makeTransient) { Object prevRoot = editor.getTransientRootObject(); if ((prevRoot != null) && !transientRoot.equals(prevRoot)) editor.setLayoutMode(); editor.setTransientMode(transientRoot); } else editor.setLayoutMode(); } private List getModelObjectsFromSelection(ISelection selection) { List selectedObjects = new ArrayList(); for (Iterator iter = ((StructuredSelection) selection).toList().iterator(); iter.hasNext();) { EObject object = getObjectFromSelected(iter.next()); if (object != null) selectedObjects.add(object); } return selectedObjects; } private void adviseEditors(ISelection selection) { Set newComponentEditors = new HashSet(); // add new editors from selection for (Iterator iter = ((StructuredSelection) selection).iterator(); iter.hasNext();) { EObject object = getObjectFromSelected(iter.next()); if (object != null) { IComponentEditor componentEditor = Adapters.getComponentEditor(object); if (componentEditor != null) newComponentEditors.add(componentEditor); } } // advise saved editors that are not in the new set to exit edit mode for (Iterator iter = savedComponentEditors.iterator(); iter.hasNext();) { IComponentEditor componentEditor = (IComponentEditor) iter.next(); if (!newComponentEditors.contains(componentEditor)) componentEditor.endEditing(); } // advise new component editors that are not in the saved set to enter edit mode for (Iterator iter = newComponentEditors.iterator(); iter.hasNext();) { IComponentEditor componentEditor = (IComponentEditor) iter.next(); if (!savedComponentEditors.contains(componentEditor)) componentEditor.beginEditing(editor); } // replace the saved component editors with the new set savedComponentEditors = newComponentEditors; } private void setContainerScrollbarsVisible(EditPart selectedPart, boolean visible) { if (!(selectedPart instanceof ModelObjectEditPart)) return; if (selectedPart instanceof LayoutContainerEditPart) { ((LayoutContainerEditPart) selectedPart).setScrollbarsVisible(visible); if (visible) partsWithVisibleScrollbars.add(selectedPart); } setContainerScrollbarsVisible(selectedPart.getParent(), visible); } private void resetContainerScrollbarsVisibility(ISelection selection) { for (Iterator iter = partsWithVisibleScrollbars.iterator(); iter.hasNext();) { EditPart part = (EditPart) iter.next(); setContainerScrollbarsVisible(part, false); } partsWithVisibleScrollbars.clear(); GraphicalViewer upperGraphicalViewer = editor.getUpperGraphicalViewer(); for (Iterator iter = ((StructuredSelection) selection).iterator(); iter.hasNext();) { EObject object = getObjectFromSelected(iter.next()); if (object != null) { EditPart part = getPart(upperGraphicalViewer, object); setContainerScrollbarsVisible(part, true); } } } private void fireSelectionChanged(ISelection selection) { Object[] listeners = selectionChangedListeners.getListeners(); selection = getSelection(); for (int i = 0; i < listeners.length; ++i) { ((ISelectionChangedListener) listeners[i]).selectionChanged(new SelectionChangedEvent(this, selection)); } } private EditPart getPart(EditPartViewer viewer, Object object) { if (object == null) return null; Object temp = viewer.getEditPartRegistry().get(object); EditPart newPart = null; if (temp != null) { newPart = (EditPart) temp; } return newPart; } public void setSelectionFromNames(List objectNames) { List parts = new ArrayList(); for (Iterator iter = objectNames.iterator(); iter.hasNext();) { EObject object = this.editor.getDataModel().findByNameProperty(iter.next().toString()); EditPart part = getPart(this.editor.getUpperGraphicalViewer(), object); if (part != null) parts.add(part); else if (this.editor.getLowerGraphicalViewer() != null) { part = getPart(this.editor.getLowerGraphicalViewer(), object); if (part != null) parts.add(part); } } setSelection(new StructuredSelection(parts)); } public void getLeftoverSelectedNames() { try { IDesignerDataModelEditor ddme = (IDesignerDataModelEditor) editor .getAdapter(IDesignerDataModelEditor.class); QualifiedName key = new QualifiedName(UIDesignerPlugin.getDefault().toString(), ddme.getPartName()); leftoverSelectedNames = (List) editor.getDataModelResource().getSessionProperty(key); editor.getDataModelResource().setSessionProperty(key, null); } catch (CoreException e) { IStatus status = Logging.newStatus(UIDesignerPlugin.getDefault(), e); Logging.log(UIDesignerPlugin.getDefault(), status); } } public void reloadSelection() { getLeftoverSelectedNames(); if (leftoverSelectedNames != null) { setSelectionFromNames(leftoverSelectedNames); leftoverSelectedNames = null; } } public List getSelectedModelNames() { ISelection sel = getSelection(); if (!(sel instanceof IStructuredSelection)) return null; List objectNames = new ArrayList(); IStructuredSelection selection = (IStructuredSelection) sel; for (Iterator iter = selection.iterator(); iter.hasNext();) { EObject object = getObjectFromSelected(iter.next()); if (object != null) { IComponentInstance instance = Adapters.getComponentInstance(object); objectNames.add(instance.getName()); } } return objectNames; } public boolean isComponentEditing() { return !savedComponentEditors.isEmpty(); } public void setSync(boolean sync) { isDispatching = !sync; } private EObject getObjectFromSelected(Object object) { if (object instanceof EditPart) { object = ((EditPart) object).getModel(); } if (object instanceof EObject) return (EObject) object; return null; } }