/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.debug.ui.internal.view; import com.google.dart.tools.debug.core.util.IDartDebugVariable; import com.google.dart.tools.internal.corext.refactoring.util.ReflectionUtils; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.internal.util.SWTUtil; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.internal.ui.views.variables.AvailableLogicalStructuresAction; import org.eclipse.debug.internal.ui.views.variables.VariablesView; import org.eclipse.debug.internal.ui.views.variables.details.AvailableDetailPanesAction; import org.eclipse.debug.internal.ui.views.variables.details.DetailPaneProxy; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IWorkbenchActionConstants; /** * This custom subclass of the debugger VariablesView allows us to customize the actions that the * view exposes, and override some visibility behavior that is necessary to embed this view in other * views. */ @SuppressWarnings("restriction") public class DartVariablesView extends VariablesView { private boolean visible; private TreeModelViewer treeViewer; private IPreferenceStore preferences; private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { doPropertyChange(event); } }; /** * Create a new DartVariablesView instance. */ public DartVariablesView() { } @Override public void becomesHidden() { visible = false; super.becomesHidden(); } @Override public void becomesVisible() { visible = true; super.becomesVisible(); } @Override public TreeModelViewer createViewer(Composite parent) { preferences = DartToolsPlugin.getDefault().getCombinedPreferenceStore(); final TreeModelViewer treeViewer = (TreeModelViewer) super.createViewer(parent); this.treeViewer = treeViewer; treeViewer.getTree().setBackgroundMode(SWT.INHERIT_FORCE); treeViewer.getTree().addListener(SWT.EraseItem, new Listener() { @Override public void handleEvent(Event event) { SWTUtil.eraseSelection(event, treeViewer.getTree(), getPreferences()); } }); SWTUtil.bindJFaceResourcesFontToControl(treeViewer.getTree()); updateColors(); return treeViewer; } @Override public void dispose() { if (propertyChangeListener != null) { getPreferences().removePropertyChangeListener(propertyChangeListener); propertyChangeListener = null; } super.dispose(); } @Override public boolean isVisible() { return visible; } @Override public void refreshDetailPaneContents() { super.refreshDetailPaneContents(); SWTUtil.setColors(getDetailsText(), getPreferences()); getDetailsText().setEditable(false); } @Override public void setSelectionProvider(ISelectionProvider provider) { // Overridden to do nothing. This prevents a nasty class cast exception. // See https://code.google.com/p/dart/issues/detail?id=2008. } @Override public void viewerUpdatesComplete() { super.viewerUpdatesComplete(); // If the first element is an exception, select it. // Because the viewer uses a lazy content provider, there is no happy, clean // way of getting the contents of the viewer. TreeModelViewer viewer = (TreeModelViewer) getViewer(); Tree tree = viewer.getTree(); int itemCount = tree.getItemCount(); if (itemCount > 0) { TreeItem item = tree.getItem(0); Object data = item.getData(); if (data instanceof IDartDebugVariable) { IDartDebugVariable var = (IDartDebugVariable) data; if (var.isThrownException()) { viewer.setSelection(new StructuredSelection(var)); } } } } @Override protected void configureToolBar(IToolBarManager tbm) { // tbm.add(new Separator(this.getClass().getName())); // tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP)); // // //tbm.add(getAction("ShowTypeNames")); //$NON-NLS-1$ // tbm.add(getAction("ToggleContentProviders")); //$NON-NLS-1$ // //tbm.add(getAction("CollapseAll")); //$NON-NLS-1$ } @Override protected void fillContextMenu(IMenuManager menu) { menu.add(new Separator(IDebugUIConstants.EMPTY_VARIABLE_GROUP)); menu.add(new Separator(IDebugUIConstants.VARIABLE_GROUP)); menu.add(new Separator()); IAction action = new AvailableLogicalStructuresAction(this); if (action.isEnabled()) { menu.add(action); } action = new AvailableDetailPanesAction(this); if (isDetailPaneVisible() && action.isEnabled()) { menu.add(action); } menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP)); menu.add(new Separator(IDebugUIConstants.EMPTY_NAVIGATION_GROUP)); menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } @Override protected int[] getLastSashWeights() { return new int[] {12, 4}; } protected void updateColors() { IPreferenceStore prefs = getPreferences(); StyledText detailsText = getDetailsText(); SWTUtil.setColors(treeViewer.getTree(), prefs); SWTUtil.setColors(detailsText, prefs); } private void doPropertyChange(PropertyChangeEvent event) { SWTUtil.runUI(new Runnable() { @Override public void run() { updateColors(); treeViewer.refresh(false); } }); } private StyledText getDetailsText() { // Warning: fragile code! DetailPaneProxy detailProxy = ReflectionUtils.getFieldObject(this, "fDetailPane"); StyledText text = ReflectionUtils.getFieldObject(detailProxy, "fCurrentControl"); return text; } private IPreferenceStore getPreferences() { return preferences; } }