blob: 96a7ab364d19e6aac384a493a53e7e502851a451 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* 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:
* Pierre Allard,
* Regent L'Archeveque,
* Olivier L. Larouche - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.core.invocator.ui.parts;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.emf.ui.parts.AbstractEObjectSelectionPart;
import org.eclipse.apogy.core.invocator.AbstractProgramRuntime;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFactory;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage;
import org.eclipse.apogy.core.invocator.OperationCall;
import org.eclipse.apogy.core.invocator.OperationCallsListProgramRuntime;
import org.eclipse.apogy.core.invocator.Program;
import org.eclipse.apogy.core.invocator.ProgramRuntimeState;
import org.eclipse.apogy.core.invocator.ui.ApogyCoreInvocatorUIRCPConstants;
import org.eclipse.apogy.core.invocator.ui.ProgramUIFactoriesRegistry;
import org.eclipse.apogy.core.invocator.ui.ProgramUIFactory;
import org.eclipse.apogy.core.invocator.ui.composites.OperationCallsListComposite;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.ISelectionListener;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
public class ProgramPart extends AbstractEObjectSelectionPart implements org.eclipse.ui.ISelectionListener {
List<AbstractProgramRuntime> runtimes;
private Adapter runtimeAdapter;
@Inject
private IEventBroker broker;
private Program selectedProgram = null;
private Composite top;
@Override
protected void createContentComposite(Composite parent, int style) {
this.top = new Composite(parent, SWT.NONE);
this.top.setLayout(new FillLayout());
}
@Override
protected void setCompositeContents(EObject eObject) {
if (this.runtimes != null) {
for (AbstractProgramRuntime runtime : this.runtimes) {
runtime.eAdapters().remove(getRuntimeAdapter());
}
}
this.runtimes.clear();
// Remove previous composite child.
if (!this.top.isDisposed()) {
for (Control control : this.top.getChildren()) {
if (!control.isDisposed())
control.dispose();
}
}
if (eObject instanceof Program) {
this.selectedProgram = (Program) eObject;
ProgramUIFactory programUIFactory = ProgramUIFactoriesRegistry.INSTANCE
.getFactory(this.selectedProgram.eClass());
if (programUIFactory != null) {
programUIFactory.createProgramComposite(this.top, (Program) eObject, this);
/** Creates the runtimesList if null. */
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getProgramRuntimesList() == null) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(
ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession(),
ApogyCoreInvocatorPackage.Literals.INVOCATOR_SESSION__PROGRAM_RUNTIMES_LIST,
ApogyCoreInvocatorFactory.eINSTANCE.createProgramRuntimesList());
}
/** Gets the current runtimes. */
for (AbstractProgramRuntime runtime : ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession()
.getProgramRuntimesList().getProgramRuntimes()) {
if (runtime.getProgram() == eObject) {
newRuntime(runtime);
}
}
/** To trigger a notify changed to display colors. */
if (!this.runtimes.isEmpty()) {
AbstractProgramRuntime runtime = this.runtimes.get(this.runtimes.size() - 1);
ApogyCommonTransactionFacade.INSTANCE.basicSet(runtime,
ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, runtime.getState());
}
} else {
setEObject(null);
}
} else {
this.selectedProgram = null;
}
this.top.layout();
}
@Override
protected HashMap<String, ISelectionListener> getSelectionProvidersIdsToSelectionListeners() {
HashMap<String, ISelectionListener> selectionProvidersIdsToSelectionListeners = new HashMap<String, ISelectionListener>();
selectionProvidersIdsToSelectionListeners
.put(ApogyCoreInvocatorUIRCPConstants.PART__SCRIPT_BASED_PROGRAMS_LIST__ID, this.DEFAULT_LISTENER);
return selectionProvidersIdsToSelectionListeners;
}
@Override
public void userPostConstruct(MPart mPart) {
this.runtimes = new ArrayList<AbstractProgramRuntime>();
super.userPostConstruct(mPart);
}
public void newRuntime(AbstractProgramRuntime runtime) {
this.runtimes.add(runtime);
runtime.eAdapters().add(getRuntimeAdapter());
}
public List<AbstractProgramRuntime> getRuntimes() {
return this.runtimes;
}
public Program getSelectedProgram() {
return this.selectedProgram;
}
private Adapter getRuntimeAdapter() {
if (this.runtimeAdapter == null) {
this.runtimeAdapter = new AdapterImpl() {
@SuppressWarnings("unchecked")
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() == ProgramPart.this.runtimes.get(ProgramPart.this.runtimes.size() - 1)) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
/**
* If the feature changed is the state of the runtime
*/
if (msg.getFeature() == ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE) {
/** Update the part */
ProgramPart.this.broker.send(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC,
UIEvents.ALL_ELEMENT_ID);
/** If the state is terminated */
if (msg.getNewValue() == ProgramRuntimeState.TERMINATED) {
if (getActualComposite() instanceof OperationCallsListComposite) {
/** Set background colors */
((OperationCallsListComposite) getActualComposite())
.setBackgroudColor(Collections.EMPTY_MAP);
}
/**
* Remove the adapter and remove the runtime from the list
*/
AbstractProgramRuntime runtime = (AbstractProgramRuntime) msg.getNotifier();
runtime.eAdapters().remove(this);
ProgramPart.this.runtimes.remove(runtime);
}
}
/** To update the colors */
if (getActualComposite() instanceof OperationCallsListComposite) {
OperationCallsListComposite composite = (OperationCallsListComposite) getActualComposite();
if (msg.getFeature() == ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE
|| msg.getFeature() == ApogyCoreInvocatorPackage.Literals.OPERATION_CALLS_LIST_PROGRAM_RUNTIME__INDEX_CURRENTLY_EXECUTED
|| msg.getFeature() == ApogyCoreInvocatorPackage.Literals.OPERATION_CALLS_LIST_PROGRAM_RUNTIME__INDEX_LAST_EXECUTED) {
Map<OperationCall, Integer> map = new HashMap<>();
OperationCallsListProgramRuntime runtime = (OperationCallsListProgramRuntime) msg
.getNotifier();
EList<OperationCall> opsCall = composite.getOperationCallsList()
.getOperationCalls();
/** If the runtime is running */
if (runtime.getState() == ProgramRuntimeState.RUNNING
|| runtime.getState() == ProgramRuntimeState.RUNNING_SUSPENDED
|| runtime.getState() == ProgramRuntimeState.RUNNING_TERMINATED) {
if (runtime.getIndexCurrentlyExecuted() != -1) {
/**
* Set the currently executed opCall background green
*/
map.put(opsCall.get(runtime.getIndexCurrentlyExecuted()),
SWT.COLOR_GREEN);
}
}
/**
* Otherwise, if the runtime is suspended
*/
else if (runtime.getState() == ProgramRuntimeState.SUSPENDED) {
if (runtime.getIndexLastExecuted() != -1
&& runtime.getIndexLastExecuted() + 1 != opsCall.size()) {
/**
* Set the next executed opCall background yellow
*/
map.put(opsCall.get(runtime.getIndexLastExecuted() + 1),
SWT.COLOR_YELLOW);
}
}
composite.setBackgroudColor(map);
}
}
}
});
}
}
};
}
return this.runtimeAdapter;
}
@Override
public void userPreDestroy(MPart mPart) {
if (this.runtimes != null) {
for (AbstractProgramRuntime runtime : this.runtimes) {
runtime.eAdapters().remove(getRuntimeAdapter());
}
}
super.userPreDestroy(mPart);
}
@Override
public void selectionChanged(IWorkbenchPart arg0, ISelection selection) {
if (selection instanceof IStructuredSelection) {
IStructuredSelection iStructuredSelection = (IStructuredSelection) selection;
this.selectionService.setSelection(iStructuredSelection.getFirstElement());
}
}
}