/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.e4.ui.parts;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedDeque;
import javax.inject.Inject;
import javax.inject.Named;
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.di.UIEventTopic;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.widgets.Composite;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.e4.ui.actions.IE4UIConstants;
import org.whole.lang.e4.ui.actions.ResumeAction;
import org.whole.lang.e4.ui.actions.BreakpointsDisableAction;
import org.whole.lang.e4.ui.actions.TerminateAction;
import org.whole.lang.e4.ui.jobs.ExecutionState;
import org.whole.lang.model.IEntity;
import org.whole.lang.ui.actions.IUpdatableAction;
import org.whole.lang.ui.editparts.IEntityPart;
import org.whole.lang.ui.editpolicies.SuspensionFeedbackEditPolicy;
import org.whole.lang.ui.util.SuspensionKind;
import org.whole.lang.ui.viewers.IEntityPartViewer;
import org.whole.lang.util.EntityUtils;
/**
* @author Enrico Persiani
*/
public class E4DebugGraphicalPart extends E4GraphicalPart {
protected Deque<ExecutionState> executions = new ConcurrentLinkedDeque<>();
public SuspensionKind getSuspensionKind() {
ExecutionState execution = executions.peek();
return execution != null ? execution.getSuspensionKind() : SuspensionKind.NONE;
}
protected void updateUI() {
updateActions();
IEventBroker eventBroker = context.get(IEventBroker.class);
ExecutionState execution = executions.peek();
if (execution != null) {
final IEntity sourceEntity = execution.getSourceEntity();
IEntity contents = EntityUtils.getCompoundRoot(sourceEntity);
getViewer().setContents(contents);
getViewer().setInteractive(contents, false, true, false);
context.get(UISynchronize.class).asyncExec(new Runnable() {
@Override
public void run() {
IEntity adaptee = sourceEntity.wGetAdaptee(false);
IEntityPart sourceEntityPart = getViewer().getEditPartRegistry().get(adaptee);
sourceEntityPart.installEditPolicy(SuspensionFeedbackEditPolicy.SUSPENSION_FEEDBACK_ROLE,
new SuspensionFeedbackEditPolicy(getSuspensionKind(), execution.getThrowable()));
getViewer().reveal(sourceEntity);
}
});
eventBroker.post(IE4UIConstants.TOPIC_UPDATE_VARIABLES, execution.getVariablesModel());
} else {
getViewer().setEntityContents(createDefaultContents());
eventBroker.post(IE4UIConstants.TOPIC_UPDATE_VARIABLES, null);
}
}
protected void pushExecution(ExecutionState execution) {
executions.push(execution);
updateUI();
}
protected ExecutionState popExecution() {
ExecutionState execution = executions.removeFirst();
updateUI();
return execution;
}
@Override
protected IEntityPartViewer createEntityViewer(Composite parent) {
IEntityPartViewer viewer = super.createEntityViewer(parent);
viewer.setOperationExecutable(false);
return viewer;
}
@Inject
void setSelection(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) IBindingManager bm) {
if (bm == null || bm.wGetValue("viewer") != getViewer())
return;
//TODO
}
@Inject
@Optional
private void getNotified(@UIEventTopic(IE4UIConstants.TOPIC_UPDATE_DEBUG) ExecutionState execution) {
pushExecution(execution);
}
@Override
protected void restoreState() {
super.restoreState();
if (!part.getPersistedState().containsKey("debug#breakpointsEnabled"))
part.getPersistedState().put("debug#breakpointsEnabled", Boolean.toString(true));
}
public void doBreakpointsDisable(boolean disable) {
part.getPersistedState().put("debug#breakpointsEnabled", Boolean.toString(!disable));
}
public void doResume() {
popExecution().resume();
}
public void doTerminate() {
popExecution().terminate();
}
protected Set<IUpdatableAction> actions = new HashSet<IUpdatableAction>();
protected void updateActions() {
for (IUpdatableAction action : actions)
action.update();
}
protected BreakpointsDisableAction breakpointsDisableAction;
public IAction getBreakpoiontsDisableAction(IEclipseContext context) {
if (breakpointsDisableAction == null)
actions.add(breakpointsDisableAction = new BreakpointsDisableAction(context, this));
return breakpointsDisableAction;
}
protected ResumeAction resumeAction;
public IAction getResumeAction(IEclipseContext context) {
if (resumeAction == null)
actions.add(resumeAction = new ResumeAction(context, this));
return resumeAction;
}
protected TerminateAction terminateAction;
public IAction getTerminateAction(IEclipseContext context) {
if (terminateAction == null)
actions.add(terminateAction = new TerminateAction(context, this));
return terminateAction;
}
}