/*******************************************************************************
* Copyright (c) 2011, 2012 Wind River Systems, Inc. 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:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.internal.cdt.ui.commands;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.cdt.debug.ui.IPinProvider;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
import org.eclipse.tcf.internal.debug.ui.model.TCFNode;
import org.eclipse.tcf.internal.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tcf.internal.debug.ui.model.TCFNodeStackFrame;
import org.eclipse.tcf.services.IRunControl;
import org.eclipse.tcf.util.TCFDataCache;
import org.eclipse.tcf.util.TCFTask;
import org.eclipse.ui.IWorkbenchPart;
@SuppressWarnings("restriction")
public class TCFPinViewCommand implements IPinProvider {
private final TCFModel model;
private final ArrayList<PinnedView> list = new ArrayList<PinnedView>();
private class PinnedView implements IPinElementHandle {
@SuppressWarnings("unused")
private final IPinModelListener listener;
@SuppressWarnings("unused")
private final IWorkbenchPart part;
private final TCFNode node;
private final IPresentationContext ctx;
final IRunControl.RunControlListener rc_listener = new IRunControl.RunControlListener() {
public void contextAdded(IRunControl.RunControlContext[] contexts) {
}
public void contextChanged(IRunControl.RunControlContext[] contexts) {
for (IRunControl.RunControlContext ctx : contexts) {
if (node.getID().equals(ctx.getID())) updateLabel();
}
}
public void contextRemoved(String[] context_ids) {
for (String id : context_ids) {
if (node.getID().equals(id)) updateLabel();
}
}
public void contextSuspended(String id, String pc, String reason, Map<String, Object> params) {
if (node.getID().equals(id)) updateLabel();
}
public void contextResumed(String id) {
if (node.getID().equals(id)) updateLabel();
}
public void containerSuspended(String context, String pc, String reason, Map<String, Object> params, String[] suspended_ids) {
for (String id : suspended_ids) {
if (node.getID().equals(id)) updateLabel();
}
}
public void containerResumed(String[] context_ids) {
for (String id : context_ids) {
if (node.getID().equals(id)) updateLabel();
}
}
public void contextException(String id, String msg) {
if (node.getID().equals(id)) updateLabel();
}
};
PinnedView(IWorkbenchPart part, TCFNode node, IPinModelListener listener) {
this.part = part;
this.node = node;
this.listener = listener;
ctx = new PresentationContext(TCFModel.ID_PINNED_VIEW, part);
IRunControl rc = model.getChannel().getRemoteService(IRunControl.class);
if (rc != null) rc.addListener(rc_listener);
}
void updateLabel() {
// TODO: CDT does not support label update
/*
model.getDisplay().asyncExec(new Runnable() {
public void run() {
listener.modelChanged(new StructuredSelection(node));
}
});
*/
}
void dispose() {
IRunControl rc = model.getChannel().getRemoteService(IRunControl.class);
if (rc != null) rc.removeListener(rc_listener);
}
public Object getDebugContext() {
return node;
}
public String getLabel() {
return new TCFTask<String>() {
public void run() {
model.update(new ILabelUpdate[]{ new ILabelUpdate() {
String text;
public IPresentationContext getPresentationContext() {
return ctx;
}
public Object getElement() {
return node;
}
public TreePath getElementPath() {
return null;
}
public Object getViewerInput() {
return null;
}
public void setStatus(IStatus status) {
}
public IStatus getStatus() {
return null;
}
public void done() {
done_update(text);
}
public void cancel() {
}
public boolean isCanceled() {
return false;
}
public String[] getColumnIds() {
return null;
}
public void setLabel(String text, int columnIndex) {
if (columnIndex == 0) this.text = text;
}
public void setFontData(FontData fontData, int columnIndex) {
}
public void setImageDescriptor(ImageDescriptor image, int columnIndex) {
}
public void setForeground(RGB foreground, int columnIndex) {
}
public void setBackground(RGB background, int columnIndex) {
}
}});
}
private void done_update(String text) {
if (text == null) text = node.getID();
done(text);
}
}.getE();
}
public IPinElementColorDescriptor getPinElementColorDescriptor() {
return null;
}
}
public TCFPinViewCommand(TCFModel model) {
this.model = model;
}
public boolean isPinnable(IWorkbenchPart part, final Object obj) {
if (obj instanceof TCFNode) {
try {
final String id = part.getSite().getId();
return new TCFTask<Boolean>(model.getChannel()) {
public void run() {
boolean mem = false;
boolean vars = false;
if (obj instanceof TCFNodeExecContext) {
TCFNodeExecContext node = (TCFNodeExecContext)obj;
TCFDataCache<IRunControl.RunControlContext> ctx_cache = node.getRunContext();
if (!ctx_cache.validate(this)) return;
IRunControl.RunControlContext ctx_data = ctx_cache.getData();
if (ctx_data != null) {
vars = ctx_data.hasState();
mem = vars || ctx_data.getProcessID() != null;
}
}
if (obj instanceof TCFNodeStackFrame) {
vars = true;
mem = true;
}
if (IDebugUIConstants.ID_REGISTER_VIEW.equals(id)) done(mem);
else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(id)) done(vars);
else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(id)) done(mem);
else done(false);
}
}.getE();
}
catch (Throwable x) {
return false;
}
}
return false;
}
public IPinElementHandle pin(final IWorkbenchPart part, Object obj, final IPinModelListener listener) {
if (obj instanceof TCFNode) {
final TCFNode node = (TCFNode)obj;
return new TCFTask<IPinElementHandle>() {
public void run() {
PinnedView p = new PinnedView(part, node, listener);
model.setPin(part, node);
list.add(p);
done(p);
}
}.getE();
}
return null;
}
public void unpin(final IWorkbenchPart part, final IPinElementHandle handle) {
new TCFTask<Object>() {
public void run() {
model.setPin(part, null);
if (list.remove(handle)) {
((PinnedView)handle).dispose();
}
done(null);
}
};
}
public boolean isPinnedTo(Object obj, final IPinElementHandle handle) {
if (obj instanceof TCFNode) {
return new TCFTask<Boolean>() {
public void run() {
done(list.contains(handle));
}
}.getE();
}
return false;
}
}