com.intellij.debugger.ui.EvaluationDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.debugger.ui.EvaluationDialog.java

Source

/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.intellij.debugger.ui;

import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.tree.TreeModel;

import org.jetbrains.annotations.Nullable;
import com.intellij.CommonBundle;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.actions.DebuggerActions;
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerContextListener;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.ui.impl.ValueNodeDnD;
import com.intellij.debugger.ui.impl.WatchDebuggerTree;
import com.intellij.debugger.ui.impl.WatchPanel;
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.EvaluationDescriptor;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPopupMenu;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiElement;
import com.intellij.xdebugger.XDebuggerBundle;

public abstract class EvaluationDialog extends DialogWrapper {
    private final MyEvaluationPanel myEvaluationPanel;
    private final Project myProject;
    private final DebuggerContextListener myContextListener;
    private final DebuggerEditorImpl myEditor;
    private final List<Runnable> myDisposeRunnables = new ArrayList<Runnable>();

    public EvaluationDialog(Project project, TextWithImports text) {
        super(project, true);
        myProject = project;
        setModal(false);
        setCancelButtonText(CommonBundle.message("button.close"));
        setOKButtonText(DebuggerBundle.message("button.evaluate"));

        myEvaluationPanel = new MyEvaluationPanel(myProject);

        myEditor = createEditor(DefaultCodeFragmentFactory.getInstance());

        setDebuggerContext(getDebuggerContext());
        initDialogData(text);

        myContextListener = new DebuggerContextListener() {
            @Override
            public void changeEvent(DebuggerContextImpl newContext, int event) {
                boolean close = true;
                for (DebuggerSession session : DebuggerManagerEx.getInstanceEx(myProject).getSessions()) {
                    if (!session.isStopped()) {
                        close = false;
                        break;
                    }
                }

                if (close) {
                    close(CANCEL_EXIT_CODE);
                } else {
                    setDebuggerContext(newContext);
                }
            }
        };
        DebuggerManagerEx.getInstanceEx(myProject).getContextManager().addListener(myContextListener);

        setHorizontalStretch(1f);
        setVerticalStretch(1f);
    }

    @Override
    protected void doOKAction() {
        if (isOKActionEnabled()) {
            doEvaluate();
        }
    }

    protected void doEvaluate() {
        if (myEditor == null || myEvaluationPanel == null) {
            return;
        }

        myEvaluationPanel.clear();
        TextWithImports codeToEvaluate = getCodeToEvaluate();
        if (codeToEvaluate == null) {
            return;
        }
        try {
            setOKActionEnabled(false);
            NodeDescriptorImpl descriptor = myEvaluationPanel.getWatchTree().addWatch(codeToEvaluate, "result")
                    .getDescriptor();
            if (descriptor instanceof EvaluationDescriptor) {
                final EvaluationDescriptor evalDescriptor = (EvaluationDescriptor) descriptor;
                evalDescriptor.setCodeFragmentFactory(myEditor.getCurrentFactory());
            }
            myEvaluationPanel.getWatchTree().rebuild(getDebuggerContext());
            descriptor.myIsExpanded = true;
        } finally {
            setOKActionEnabled(true);
        }
        getEditor().addRecent(getCodeToEvaluate());

        final DebuggerSession session = myEvaluationPanel.getContextManager().getContext().getDebuggerSession();
        if (session != null) {
            session.refresh(true);
        }
    }

    @Nullable
    protected TextWithImports getCodeToEvaluate() {
        TextWithImports text = getEditor().getText();
        String s = text.getText();
        if (s != null) {
            s = s.trim();
        }
        if ("".equals(s)) {
            return null;
        }
        return text;
    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        return myEditor.getPreferredFocusedComponent();
    }

    @Override
    protected String getDimensionServiceKey() {
        return "#com.intellij.debugger.ui.EvaluationDialog2";
    }

    protected void addDisposeRunnable(Runnable runnable) {
        myDisposeRunnables.add(runnable);
    }

    @Override
    public void dispose() {
        for (Runnable runnable : myDisposeRunnables) {
            runnable.run();
        }
        myDisposeRunnables.clear();
        myEditor.dispose();
        DebuggerManagerEx.getInstanceEx(myProject).getContextManager().removeListener(myContextListener);
        myEvaluationPanel.dispose();
        super.dispose();
    }

    protected class MyEvaluationPanel extends WatchPanel {
        public MyEvaluationPanel(final Project project) {
            super(project, (DebuggerManagerEx.getInstanceEx(project)).getContextManager());
            final WatchDebuggerTree watchTree = getWatchTree();
            final AnAction setValueAction = ActionManager.getInstance().getAction(DebuggerActions.SET_VALUE);
            setValueAction.registerCustomShortcutSet(
                    new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), watchTree);
            registerDisposable(new Disposable() {
                @Override
                public void dispose() {
                    setValueAction.unregisterCustomShortcutSet(watchTree);
                }
            });
            setUpdateEnabled(true);
            getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.results"));
            new ValueNodeDnD(myTree, project);
        }

        @Override
        protected ActionPopupMenu createPopupMenu() {
            ActionGroup group = (ActionGroup) ActionManager.getInstance()
                    .getAction(DebuggerActions.EVALUATION_DIALOG_POPUP);
            return ActionManager.getInstance().createActionPopupMenu(DebuggerActions.EVALUATION_DIALOG_POPUP,
                    group);
        }

        @Override
        protected void changeEvent(DebuggerContextImpl newContext, int event) {
            if (event == DebuggerSession.EVENT_REFRESH || event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY) {
                // in order not to spoil the evaluation result do not re-evaluate the tree
                final TreeModel treeModel = getTree().getModel();
                updateTree(treeModel, (DebuggerTreeNodeImpl) treeModel.getRoot());
            }
        }

        private void updateTree(final TreeModel model, final DebuggerTreeNodeImpl node) {
            if (node == null) {
                return;
            }
            if (node.getDescriptor().myIsExpanded) {
                final int count = model.getChildCount(node);
                for (int idx = 0; idx < count; idx++) {
                    final DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl) model.getChild(node, idx);
                    updateTree(model, child);
                }
            }
            node.labelChanged();
        }
    }

    protected void setDebuggerContext(DebuggerContextImpl context) {
        final PsiElement contextElement = PositionUtil.getContextElement(context);
        myEditor.setContext(contextElement);
    }

    protected PsiElement getContext() {
        return myEditor.getContext();
    }

    protected void initDialogData(TextWithImports text) {
        getEditor().setText(text);
        myEvaluationPanel.clear();
    }

    public DebuggerContextImpl getDebuggerContext() {
        return DebuggerManagerEx.getInstanceEx(myProject).getContext();
    }

    public DebuggerEditorImpl getEditor() {
        return myEditor;
    }

    protected abstract DebuggerEditorImpl createEditor(final CodeFragmentFactory factory);

    protected MyEvaluationPanel getEvaluationPanel() {
        return myEvaluationPanel;
    }

    public Project getProject() {
        return myProject;
    }

}