/*
 * 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.actions;

import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.evaluation.expression.Modifier;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.ui.impl.watch.*;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;

public class EditSourceAction extends DebuggerAction{
  public void actionPerformed(AnActionEvent e) {
    final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());

    if(project == null) return;

    final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext());
    final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext());
    if(debuggerContext != null && selectedNode != null) {
      debuggerContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
          public void threadAction() {
            final SourcePosition sourcePosition = getSourcePosition(selectedNode, debuggerContext);
            if (sourcePosition != null) {
              sourcePosition.navigate(true);
            }
          }
        });
    }
  }

  private SourcePosition getSourcePosition(DebuggerTreeNodeImpl selectedNode, DebuggerContextImpl debuggerContext) {
    DebuggerTreeNodeImpl node = selectedNode;
    final DebuggerContextImpl context = debuggerContext;

    if(node == null) return null;
    if(context == null) return null;

    final Project project = context.getProject();

    final DebuggerSession debuggerSession = context.getDebuggerSession();

    if(debuggerSession == null) return null;

    NodeDescriptorImpl nodeDescriptor = node.getDescriptor();
    if(nodeDescriptor instanceof WatchItemDescriptor) {
      Modifier modifier = ((WatchItemDescriptor)nodeDescriptor).getModifier();

      if(modifier == null) return null;

      nodeDescriptor = (NodeDescriptorImpl)modifier.getInspectItem(project);
    }

    final NodeDescriptorImpl nodeDescriptor1 = nodeDescriptor;
    return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
      public SourcePosition compute() {
        if (nodeDescriptor1 instanceof FieldDescriptorImpl && debuggerSession != null) {
          return ((FieldDescriptorImpl)nodeDescriptor1).getSourcePosition(project, context);
        }
        if (nodeDescriptor1 instanceof LocalVariableDescriptorImpl && debuggerSession != null) {
          return ((LocalVariableDescriptorImpl)nodeDescriptor1).getSourcePosition(project, context);
        }
        return null;
      }
    });
  }

  public void update(AnActionEvent e) {
    final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());

    final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext());
    final DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext());

    final Presentation presentation = e.getPresentation();

    presentation.setEnabled(true);

    //if user used shortcut actionPerformed is called immediately after update
    //we not disable presentation here to allow actionPerform work
    DebuggerInvocationUtil.invokeLater(project, new Runnable() {
      public void run() {
        presentation.setEnabled(false);
      }
    });

    if(debuggerContext != null && debuggerContext.getDebugProcess() != null) {
      debuggerContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
        public void threadAction() {
          final SourcePosition position = getSourcePosition(node, debuggerContext);
          if (position != null) {
            DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
              public void run() {
                presentation.setEnabled(true);
              }
            });
          }
        }
      });
    }

    e.getPresentation().setText(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getTemplatePresentation().getText());
  }

}

@@ -1429,16 +1429,24 @@
 ull)
+ %7B%0A     
  return;
 %0A%0A  
@@ -1441,16 +1441,22 @@
  return;
+%0A    %7D
 %0A%0A    fi
@@ -1796,34 +1796,32 @@
 text) %7B%0A        
-  
 public void thre
@@ -1825,34 +1825,32 @@
 hreadAction() %7B%0A
-  
           final 
@@ -1937,26 +1937,24 @@
 ;%0A          
-  
 if (sourcePo
@@ -1983,18 +1983,16 @@
         
- 
- 
 sourcePo
@@ -2016,38 +2016,34 @@
 rue);%0A          
-  %7D%0A  
+%7D%0A
         %7D%0A      
@@ -2032,26 +2032,24 @@
 %7D%0A        %7D%0A
-  
       %7D);%0A  
@@ -2301,30 +2301,12 @@
 null
-) return null;%0A    if(
+ %7C%7C 
 cont
@@ -2309,32 +2309,40 @@
 context == null)
+ %7B%0A     
  return null;%0A%0A 
@@ -2334,24 +2334,30 @@
 return null;
+%0A    %7D
 %0A%0A    final 
@@ -2495,32 +2495,40 @@
 Session == null)
+ %7B%0A     
  return null;%0A%0A 
@@ -2520,24 +2520,30 @@
 return null;
+%0A    %7D
 %0A%0A    NodeDe
@@ -2725,25 +2725,24 @@
 Modifier();%0A
-%0A
       if(mod
@@ -2755,16 +2755,26 @@
 == null)
+ %7B%0A       
  return 
@@ -2779,16 +2779,23 @@
 n null;%0A
+      %7D
 %0A      n
@@ -3860,339 +3860,8 @@
 ();%0A
-%0A    presentation.setEnabled(true);%0A%0A    //if user used shortcut actionPerformed is called immediately after update%0A    //we not disable presentation here to allow actionPerform work%0A    DebuggerInvocationUtil.invokeLater(project, new Runnable() %7B%0A      public void run() %7B%0A        presentation.setEnabled(false);%0A      %7D%0A    %7D);%0A%0A
     
@@ -3927,32 +3927,69 @@
 ss() != null) %7B%0A
+      presentation.setEnabled(true);%0A
       debuggerCo
@@ -4226,33 +4226,33 @@
    if (position 
-!
+=
 = null) %7B%0A      
@@ -4389,35 +4389,36 @@
 tion.setEnabled(
-tru
+fals
 e);%0A            
@@ -4471,24 +4471,78 @@
   %7D);%0A    %7D%0A
+    else %7B%0A      presentation.setEnabled(false);%0A    %7D
 %0A    e.getPr

fix problem when action is disabled in popup menu, but working from keyboard shortcut