/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * * 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: * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.infra.hyperlink.ui; import java.util.Collection; import java.util.Iterator; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.papyrus.infra.core.editor.BackboneException; import org.eclipse.papyrus.infra.core.editorsfactory.IPageIconsRegistry; import org.eclipse.papyrus.infra.core.editorsfactory.IPageIconsRegistryExtended; import org.eclipse.papyrus.infra.core.editorsfactory.PageIconsRegistry; import org.eclipse.papyrus.infra.core.extension.NotFoundException; import org.eclipse.papyrus.infra.core.extension.commands.CreationCommandDescriptor; import org.eclipse.papyrus.infra.core.extension.commands.CreationCommandRegistry; import org.eclipse.papyrus.infra.core.extension.commands.ICreationCommand; import org.eclipse.papyrus.infra.core.extension.commands.ICreationCommandRegistry; import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageMngr; import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.core.utils.DiResourceSet; import org.eclipse.papyrus.infra.core.utils.EditorUtils; import org.eclipse.papyrus.infra.emf.providers.strategy.SemanticEMFContentProvider; import org.eclipse.papyrus.infra.emf.utils.EMFHelper; import org.eclipse.papyrus.infra.hyperlink.helper.AbstractHyperLinkEditorHelper; import org.eclipse.papyrus.infra.hyperlink.object.HyperLinkEditor; import org.eclipse.papyrus.infra.hyperlink.util.EditorListContentProvider; import org.eclipse.papyrus.infra.hyperlink.util.HyperLinkEditorHelpersRegistrationUtil; import org.eclipse.papyrus.infra.table.instance.papyrustableinstance.PapyrusTableInstance; import org.eclipse.papyrus.views.modelexplorer.DecoratingLabelProviderWTooltips; import org.eclipse.papyrus.views.modelexplorer.MoDiscoLabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; //TODO remove this dependency //TODO : remove the table dependencies public class EditorLookForEditorShell extends AbstractLookForEditorShell { /** The adapter factory. */ protected AdapterFactory adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); /** The selected diagram. */ protected Object selectedEditor; /** * Gets the selected editor. * * @return the selectedEditor */ protected Object getSelectedEditor() { return selectedEditor; } /** * Sets the selected editor * * @param selectedEditor * the selectedEditor to set */ protected void setSelectedEditor(Object selectedEditor) { this.selectedEditor = selectedEditor; } /** The model. */ protected EObject model; /** The diagram menu button. */ protected Menu diagramMenuButton; /** The diagram list tree viewer. */ protected TreeViewer diagramListTreeViewer; /** The tree viewer. */ protected TreeViewer treeViewer; /** * The listener interface for receiving diagramCreate events. The class that * is interested in processing a diagramCreate event implements this * interface, and the object created with that class is registered with a * component using the component's <code>addDiagramCreateListener<code> method. When * the diagramCreate event occurs, that object's appropriate * method is invoked. * * @see DiagramCreateEvent */ public class DiagramCreateListener extends SelectionAdapter { /** The command descriptor. */ private final CreationCommandDescriptor commandDescriptor; /** The container. */ private EObject container; /** The i creation command registry. */ private final ICreationCommandRegistry iCreationCommandRegistry; /** * {@inheritedDoc}. * * @param e * the e */ @Override public void widgetSelected(SelectionEvent e) { try { EObject elt = (EObject)((IStructuredSelection)treeViewer.getSelection()).getFirstElement(); setContainer(elt); ServicesRegistry servicesRegistry = EditorUtils.getServiceRegistry(); DiResourceSet diResourceSet = servicesRegistry.getService(DiResourceSet.class); ICreationCommand creationCommand = iCreationCommandRegistry.getCommand(commandDescriptor.getCommandId()); creationCommand.createDiagram(diResourceSet, container, null); // refresh several filtered tree getDiagramfilteredTree().getViewer().setInput(null); getDiagramfilteredTree().getViewer().setInput(""); //$NON-NLS-1$ getModeFilteredTree().getViewer().setInput(null); getModeFilteredTree().getViewer().setInput(model.eResource()); } catch (NotFoundException ex) { ex.printStackTrace(); } catch (BackboneException ex) { ex.printStackTrace(); } catch (ServiceException ex) { ex.printStackTrace(); } } /** * Instantiates a new diagram create listener. * * @param commandDescriptor * the command descriptor * @param backboneContext * the backbone context * @param container * the container * @param iCreationCommandRegistry * the i creation command registry */ public DiagramCreateListener(CreationCommandDescriptor commandDescriptor, EObject container, ICreationCommandRegistry iCreationCommandRegistry) { super(); this.commandDescriptor = commandDescriptor; this.container = container; this.iCreationCommandRegistry = iCreationCommandRegistry; } /** * Sets the container. * * @param container * the new container */ public void setContainer(EObject container) { this.container = container; } } /** * Instantiates a new editor look for diagram. * * @param editorFactoryRegistry * the editor factory registry * @param amodel * the amodel */ public EditorLookForEditorShell(IPageIconsRegistry editorFactoryRegistry, EObject amodel) { super(); this.model = amodel; // create the shell createLookforShell(); // intall tree with uml element treeViewer = getModeFilteredTree().getViewer(); treeViewer.setUseHashlookup(true); // treeViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory) { // // @Override // public Image getImage(Object object) { // //TODO //// if(object instanceof PapyrusTableInstance) { //// return editorRegistry.getEditorIcon((object)); //// } else { //// return super.getImage(object); //// } // Image im = super.getImage(object); // return im; //// return null; // } // }); ILabelProvider labelProvider = new LocalLabelProvider(); treeViewer.setLabelProvider(labelProvider); //treeViewer.setContentProvider(new CustomAdapterFactoryContentProvider(adapterFactory)); treeViewer.setContentProvider(new SemanticEMFContentProvider(new EObject[]{ amodel })); // treeViewer.setContentProvider(new CustomizableModelContentProvider()); //treeViewer.setInput(model.eResource()); treeViewer.setInput(EditorUtils.getServiceRegistry()); // install diagramlist diagramListTreeViewer = getDiagramfilteredTree().getViewer(); diagramListTreeViewer.setUseHashlookup(true); // fill list of diagram //TODO //diagramListTreeViewer.setLabelProvider(new ObjectLabelProvider(null)); //we can't reuse the same instance of the label provider see bug 385599: [Hyperlink] We can't select the diagram/table for referencing them labelProvider = new LocalLabelProvider(); diagramListTreeViewer.setLabelProvider(labelProvider); diagramListTreeViewer.setContentProvider(new EditorListContentProvider()); diagramListTreeViewer.setInput(" "); //$NON-NLS-1$ // add listner on the new button to display menu for each diagram diagramMenuButton = new Menu(getNewDiagrambutton()); getNewDiagrambutton().setMenu(diagramMenuButton); CreationCommandRegistry commandRegistry = CreationCommandRegistry.getInstance(org.eclipse.papyrus.infra.core.Activator.PLUGIN_ID); for(CreationCommandDescriptor desc : commandRegistry.getCommandDescriptors()) { MenuItem menuItem = new MenuItem(diagramMenuButton, SWT.PUSH); menuItem.addSelectionListener(new DiagramCreateListener(desc, null, commandRegistry)); menuItem.setText(desc.getLabel()); } getNewDiagrambutton().addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { diagramMenuButton.setVisible(true); } }); // add listener to remove diagram getRemoveDiagrambutton().addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { @Override public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { IStructuredSelection iSelection = (IStructuredSelection)getModeFilteredTree().getViewer().getSelection(); Iterator iterator = iSelection.iterator(); while(iterator.hasNext()) { IPageMngr pageMngr = EditorUtils.getIPageMngr(); pageMngr.removePage(iterator.next()); } getDiagramfilteredTree().getViewer().setInput(null); getDiagramfilteredTree().getViewer().setInput(""); //$NON-NLS-1$ getModeFilteredTree().getViewer().setInput(null); getModeFilteredTree().getViewer().setInput(model.eResource()); } }); // add listener to keep the selected diagram in the list for the model // view getModeFilteredTree().getViewer().addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { Object selection = ((IStructuredSelection)getModeFilteredTree().getViewer().getSelection()).getFirstElement(); refresh(selection); } }); // add listener to keep in mind the selected diagram in the list for the // view of digram list getDiagramfilteredTree().getViewer().addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { Object selection = ((IStructuredSelection)getDiagramfilteredTree().getViewer().getSelection()).getFirstElement(); refresh(selection); } }); // add listener for the button ok, keep the selected diagram getOKbutton().addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { getLookforShell().close(); } public void widgetDefaultSelected(SelectionEvent e) { } }); // add listener for the button cancel, remove the value of the selected // diagram getCancelbutton().addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { setSelectedEditor(null); getLookforShell().close(); } public void widgetDefaultSelected(SelectionEvent e) { } }); } /** * Open the shell */ public void open() { Display display = Display.getCurrent(); getLookforShell().pack(); // getLookforShell().setSize(700, 500); // code use to wait for an action from the user getLookforShell().pack(); // getLookforShell().setBounds(500, 500, 500, 300); getLookforShell().open(); while(!getLookforShell().isDisposed()) { if(!display.readAndDispatch()) { display.sleep(); } } } protected void refresh(Object selectedElement) { selectedElement = EMFHelper.getEObject(selectedElement); Button but = getOKbutton(); if(isAValidEditor(selectedElement)) { but = getOKbutton(); but.setEnabled(true); selectedEditor = selectedElement; } else { but.setEnabled(false); selectedEditor = null; } } protected boolean isAValidEditor(final Object object) { Collection<AbstractHyperLinkEditorHelper> helpers = HyperLinkEditorHelpersRegistrationUtil.INSTANCE.getAllRegisteredHyperLinkEditorHelper(); for(AbstractHyperLinkEditorHelper current : helpers) { HyperLinkEditor editor = current.getHyperLinkObjectFor(object); if(editor != null) { return true; } } return false; } //TODO delete this class to remove the PapyrusTable dependencies! private class LocalLabelProvider extends DecoratingLabelProviderWTooltips { public LocalLabelProvider() { super(new MoDiscoLabelProvider()); } /** * Return the EditorRegistry for nested editor descriptors. Subclass should * implements this method in order to return the registry associated to the * extension point namespace. * * @return the EditorRegistry for nested editor descriptors * FIXME : use a deprecated method */ protected IPageIconsRegistry createEditorRegistry() { try { return EditorUtils.getServiceRegistry().getService(IPageIconsRegistry.class); } catch (ServiceException e) { // Not found, return an empty one which return null for each // request. return new PageIconsRegistry(); } } /** * the icon registry */ private IPageIconsRegistry editorRegistry; /** * Get the EditorRegistry used to create editor instances. This default * implementation return the singleton eINSTANCE. This method can be * subclassed to return another registry. * * @return the singleton eINSTANCE of editor registry */ protected IPageIconsRegistryExtended getEditorRegistry() { if(editorRegistry == null) { editorRegistry = createEditorRegistry(); } if(!(editorRegistry instanceof IPageIconsRegistryExtended)) { throw new RuntimeException("The editor registry do not implement IPageIconsRegistryExtended");////$NON-NLS-1$ } return (IPageIconsRegistryExtended)editorRegistry; } @Override public String getText(Object element) { if(element instanceof PapyrusTableInstance) { return ((PapyrusTableInstance)element).getName(); } return super.getText(element); } @Override public Image getImage(Object element) { if(element instanceof PapyrusTableInstance) { return getEditorRegistry().getEditorIcon(element); } return super.getImage(element); } } }