| /******************************************************************************* |
| * Copyright (c) 2012 Rushan R. Gilmullin 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: |
| * Rushan R. Gilmullin - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.osbp.vaaclipse.emf; |
| |
| import javax.annotation.PostConstruct; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| |
| import org.eclipse.e4.core.contexts.Active; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.di.annotations.Optional; |
| import org.eclipse.e4.core.services.events.IEventBroker; |
| import org.eclipse.e4.ui.model.application.ui.MUIElement; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; |
| import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; |
| import org.eclipse.e4.ui.workbench.UIEvents; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.osbp.vaaclipse.emf.api.view.IConstants; |
| import org.eclipse.osbp.vaadin.emf.api.EmfModelElementClickEvent; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventHandler; |
| import org.eclipse.osbp.vaaclipse.publicapi.events.IWidgetModelAssociations; |
| import org.eclipse.osbp.vaaclipse.publicapi.events.VaaclipseUiEvents; |
| |
| import com.vaadin.event.LayoutEvents; |
| import com.vaadin.ui.AbstractOrderedLayout; |
| import com.vaadin.ui.Component; |
| |
| @SuppressWarnings("serial") |
| public class ModeledUiClickController implements |
| LayoutEvents.LayoutClickListener, EventHandler { |
| |
| @Inject |
| private IEclipseContext context; |
| |
| @Inject |
| private IEventBroker eventBroker; |
| |
| private boolean enabled; |
| |
| private AbstractOrderedLayout content; |
| |
| @PostConstruct |
| protected void setup() { |
| } |
| |
| @Inject |
| protected void activate(@Active @Optional MTrimmedWindow window) { |
| if (content != null) { |
| return; |
| } |
| |
| if (window != null) { |
| content = (AbstractOrderedLayout) window.getContext().get( |
| "rootLayoutClickNotifier"); |
| } |
| |
| if (content != null) { |
| setEnabled(true); |
| } |
| } |
| |
| public void setEnabled(boolean value) { |
| if (content == null) { |
| return; |
| } |
| this.enabled = value; |
| if (enabled) { |
| content.addLayoutClickListener(this); |
| |
| // e4 ui model |
| eventBroker.subscribe( |
| UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT, this); |
| eventBroker.subscribe(UIEvents.Item.TOPIC_SELECTED, this); |
| eventBroker.subscribe(VaaclipseUiEvents.Item.TOPIC_EXECUTED, this); |
| |
| } else { |
| if (content != null) { |
| content.removeLayoutClickListener(this); |
| content = null; |
| } |
| |
| eventBroker.unsubscribe(this); |
| } |
| } |
| |
| public boolean isEnabled() { |
| return enabled; |
| } |
| |
| @Override |
| public void layoutClick(LayoutEvents.LayoutClickEvent event) { |
| Component clickedUI = event.getClickedComponent(); |
| EObject clickedModel = context.get(IWidgetModelAssociations.class) |
| .getElement(clickedUI); |
| |
| if (clickedModel == null) { |
| return; |
| } |
| |
| // if designer parts where clicked, then do not send event |
| if (!isDesignerPart(clickedModel)) { |
| eventBroker.send(IConstants.TOPIC__ELEMENT_CLICKED, |
| new EmfModelElementClickEvent(clickedUI, |
| (EObject) clickedModel)); |
| } |
| } |
| |
| @PreDestroy |
| protected void destroy() { |
| if (isEnabled()) { |
| setEnabled(false); |
| } |
| context = null; |
| eventBroker = null; |
| content = null; |
| } |
| |
| @Override |
| public void handleEvent(Event event) { |
| |
| // if a perspective was selected, we need to send a layoutclick event |
| // |
| if (event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MPerspectiveStack) { |
| // events from e4 application model |
| // |
| String type = (String) event.getProperty(UIEvents.EventTags.TYPE); |
| if (UIEvents.EventTypes.SET.equals(type) |
| && event.getProperty(UIEvents.EventTags.ATTNAME).equals( |
| "selectedElement")) { |
| MUIElement newValue = (MUIElement) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| // if designer parts where clicked, then do not send event |
| if (!isDesignerPart((EObject) newValue)) { |
| Object widget = context.get(IWidgetModelAssociations.class) |
| .getWidget((EObject) newValue); |
| eventBroker.send(IConstants.TOPIC__ELEMENT_CLICKED, |
| new EmfModelElementClickEvent(widget, |
| (EObject) newValue)); |
| } |
| } |
| } else if (event.getTopic().endsWith( |
| VaaclipseUiEvents.Item.TOPIC_EXECUTED)) { |
| // events from e4 application model -> executed items |
| // |
| MUIElement item = (MUIElement) event.getProperty(IEventBroker.DATA); |
| // if designer parts where clicked, then do not send event |
| if (!isDesignerPart((EObject) item)) { |
| Object widget = context.get(IWidgetModelAssociations.class) |
| .getWidget((EObject) item); |
| eventBroker.send(IConstants.TOPIC__ELEMENT_CLICKED, |
| new EmfModelElementClickEvent(widget, (EObject) item)); |
| } |
| } |
| } |
| |
| /** |
| * Check if the model or its parent up to part or sashContainer have the tag |
| * "designerPart". |
| * |
| * @param element |
| * @return |
| */ |
| private boolean isDesignerPart(EObject element) { |
| if (element == null) { |
| return false; |
| } |
| |
| if (!(element instanceof MUIElement)) { |
| return false; |
| } |
| |
| MUIElement uiElement = (MUIElement) element; |
| if (element instanceof MPart || element instanceof MPartSashContainer) { |
| // do not check parents |
| return uiElement.getTags().contains(IConstants.TAG__DESIGNER_PARTS); |
| } |
| if (uiElement.getTags().contains(IConstants.TAG__DESIGNER_PARTS)) { |
| // it is designer part |
| return false; |
| } else { |
| // check up the parent until part or sashcontainer reached |
| EObject parent = ((EObject) element).eContainer(); |
| return isDesignerPart(parent); |
| } |
| } |
| } |