package no.playtrd.ui; import java.util.Dictionary; import java.util.EventObject; import java.util.Hashtable; import java.util.logging.Level; import java.util.logging.Logger; import no.playtrd.services.IPositionService; import no.playtrd.v10.playtrd.ObjectPosition; import no.playtrd.v10.playtrd.Playtrd; import no.playtrd.v10.playtrd.PlaytrdPackage; import no.playtrd.v10.playtrd.PositionService; import no.playtrd.v10.playtrd.Positioned; import no.playtrd.v10.playtrd.Service; import no.playtrd.v10.playtrd.impl.PlaytrdFactoryImpl; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CommandStackListener; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.eclipse.ui.views.properties.PropertySheetPage; import org.jscience.geography.coordinates.LatLong; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import swingxmap.IPositionProvider; import swingxmap.MapViewContent; public class PositionServiceMapView extends ViewPart implements IAdaptable, IPositionService, ISelectionProvider, CommandStackListener, ISelectionChangedListener { private Logger log = Logger.getLogger(Activator.getDefault().getBundle().getSymbolicName()); private MapViewContent mapViewContent; public final static String playtrdSourceUri = "http://playtrd.no/v10/playtrd.ecore"; private MultiAdapter positionsAdapter = new MultiAdapter() { public void notifyChanged(Notification msg) { mapViewContent.updatePositions(); } }; private int addPositions(EObject eObject, int level) { ObjectPosition position = null; if (eObject instanceof ObjectPosition) { position = (ObjectPosition)eObject; } else if (eObject instanceof Positioned) { position = findObjectPosition((Positioned)eObject); } int count = 0; if (position != null) { count++; mapViewContent.addPosition(new ObjectPositionProvider((ObjectPosition)position) { public void setPosition(double latitude, double longitude) { PositionServiceMapView.this.setPosition(getObjectPosition(), latitude, longitude); } }); positionsAdapter.addTarget(position); } else if (level != 0) { for (EObject child: eObject.eContents()) { count += addPositions(child, level - 1); } } return count; } private ObjectPosition findObjectPosition(Positioned positioned) { EObject eObject = positioned; while (eObject != null) { if (eObject instanceof Playtrd) { for (Service service: ((Playtrd)eObject).getServices()) { if (service instanceof PositionService) { return findObjectPosition((PositionService)service, positioned); } } } eObject = eObject.eContainer(); } return null; } private ObjectPosition findObjectPosition(PositionService positionService, Positioned positioned) { for (ObjectPosition objectPosition: positionService.getObjectPositions()) { if (objectPosition.getPositioned() == positioned) { return objectPosition; } } return null; } private IEditingDomainProvider editingDomainProvider = null; public void setEditingDomainProvider(IEditingDomainProvider editingDomainProvider) { if (this.editingDomainProvider != null) { this.editingDomainProvider.getEditingDomain().getCommandStack().removeCommandStackListener(this); } this.editingDomainProvider = editingDomainProvider; if (this.editingDomainProvider != null) { this.editingDomainProvider.getEditingDomain().getCommandStack().addCommandStackListener(this); } } public void commandStackChanged(EventObject event) { viewComposite.getDisplay().asyncExec(new Runnable() { public void run() { if (propertySheetPage != null && (! propertySheetPage.getControl().isDisposed())) { propertySheetPage.refresh(); } } }); } private void setPosition(EObject eObject, double lat, double lng) { EAttribute positionAttr = PlaytrdPackage.eINSTANCE.getObjectPosition_GlobePosition(); LatLong position = PlaytrdFactoryImpl.createLatLong(lat, lng); if (editingDomainProvider != null) { EditingDomain editingDomain = editingDomainProvider.getEditingDomain(); Command command = new SetCommand(editingDomain, eObject, positionAttr, position); if (command.canExecute()) { editingDomain.getCommandStack().execute(command); } } else { eObject.eSet(positionAttr, position); } } private ServiceRegistration serviceRegistration = null; private Dictionary<String, Object> serviceProperties = new Hashtable<String, Object>(); { serviceProperties.put("viewId", "no.playtrd.ui.PositionServiceMapView"); } private TreeViewer viewer; private PropertySheetPage propertySheetPage; private ComposedAdapterFactory adapterFactory; private Composite viewComposite; protected void handleActivated(IWorkbenchPart part) { if (part instanceof IEditingDomainProvider) { setEditingDomainProvider((IEditingDomainProvider)part); } } public void createPartControl(final Composite parent) { viewComposite = parent; getSite().setSelectionProvider(this); BundleContext context = Activator.getDefault().getBundle().getBundleContext(); serviceRegistration = context.registerService(IPositionService.class.getName(), this, serviceProperties); mapViewContent = new MapViewContent() { protected void updateStatus(final String status) { super.updateStatus(status); parent.getDisplay().asyncExec(new Runnable() { public void run() { getViewSite().getActionBars().getStatusLineManager().setMessage(status); } }); } }; SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL); mapViewContent.createControls(sashForm); adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new EcoreItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); Composite treeParent = new Composite(sashForm, SWT.BORDER); treeParent.setLayout(new FillLayout()); Tree tree = new Tree(treeParent, SWT.SINGLE); viewer = new TreeViewer(tree); viewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory)); viewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); // viewer.setInput(); // viewer.setSelection(new StructuredSelection(), true); // new AdapterFactoryTreeEditor(selectionViewer.getTree(), adapterFactory); sashForm.setWeights(new int[]{70, 30}); viewer.addSelectionChangedListener(this); } public void dispose() { if (serviceRegistration != null) { serviceRegistration.unregister(); } super.dispose(); } public void setFocus() { mapViewContent.setFocus(); } public void handleService(PositionService positionService, IEditingDomainProvider editingDomainProvider) { setEditingDomainProvider(editingDomainProvider); positionsAdapter.clearTargets(); mapViewContent.clearPositions(); viewer.setInput(positionService); int count = addPositions(positionService, -1); log.log(Level.INFO, "Service activated with " + count + " positions"); mapViewContent.updatePositions(); } // public Object getAdapter(Class key) { if (key.equals(IPropertySheetPage.class)) { return getPropertySheetPage(); } return super.getAdapter(key); } public IPropertySheetPage getPropertySheetPage() { if (propertySheetPage == null){ propertySheetPage = new PropertySheetPage(); propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory)); } return propertySheetPage; } // delegate selection to viewer public void addSelectionChangedListener(ISelectionChangedListener listener) { viewer.addSelectionChangedListener(listener); } public ISelection getSelection() { return viewer.getSelection(); } public void removeSelectionChangedListener(ISelectionChangedListener listener) { viewer.removeSelectionChangedListener(listener); } public void setSelection(ISelection selection) { viewer.setSelection(selection); } public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection && ((IStructuredSelection)selection).getFirstElement() instanceof ObjectPosition) { ObjectPosition objectPosition = (ObjectPosition)((IStructuredSelection)selection).getFirstElement(); for (IPositionProvider positionProvider: mapViewContent) { if (positionProvider instanceof ObjectPositionProvider && (((ObjectPositionProvider)positionProvider).getObjectPosition() == objectPosition)) { mapViewContent.setSelectedPosition(positionProvider); } } } } }