Merge remote-tracking branch 'origin/master'
authorIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Fri, 30 Jan 2015 18:29:04 +0000 (21:29 +0300)
committerIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Fri, 30 Jan 2015 18:29:04 +0000 (21:29 +0300)
25 files changed:
java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java
platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java [new file with mode: 0644]
platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java
platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java
platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java
platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java
platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java
platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java
platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java
platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
platform/platform-impl/src/com/intellij/ui/popup/MovablePopup.java
platform/platform-resources/src/META-INF/XmlActions.xml
platform/projectModel-impl/src/messages/ProjectBundle.properties
platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
platform/util/src/com/intellij/execution/rmi/RemoteUtil.java
plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java
xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java
xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java

index 68dce61619cb6a1f57a87ad05db4e82c7dbf2d1d..63cf2cabb1c497dddf820be6479c72bdce47348e 100644 (file)
@@ -18,10 +18,10 @@ package com.intellij.compiler.impl;
 import com.intellij.compiler.ProblemsView;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.errorTreeView.ErrorTreeElement;
+import com.intellij.ide.errorTreeView.ErrorTreeElementKind;
 import com.intellij.ide.errorTreeView.ErrorViewStructure;
 import com.intellij.ide.errorTreeView.GroupingElement;
 import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.compiler.CompileScope;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.ide.PooledThreadExecutor;
 
 import javax.swing.*;
+import java.util.EnumSet;
 import java.util.UUID;
 
 /**
@@ -48,7 +49,8 @@ import java.util.UUID;
  */
 public class ProblemsViewImpl extends ProblemsView{
   private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
-  
+  private static final EnumSet<ErrorTreeElementKind> ALL_MESSAGE_KINDS = EnumSet.allOf(ErrorTreeElementKind.class);
+
   private final ProblemsViewPanel myPanel;
   private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
   private final Icon myActiveIcon = AllIcons.Toolwindows.Problems;
@@ -70,7 +72,6 @@ public class ProblemsViewImpl extends ProblemsView{
           return;
         }
         final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project, true);
-        updateIcon(false);
         final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false);
         // todo: setup content?
         tw.getContentManager().addContent(content);
@@ -80,6 +81,7 @@ public class ProblemsViewImpl extends ProblemsView{
             tw.getContentManager().removeAllContents(true);
           }
         });
+        updateIcon();
       }
     });
   }
@@ -89,19 +91,16 @@ public class ProblemsViewImpl extends ProblemsView{
     myViewUpdater.execute(new Runnable() {
       @Override
       public void run() {
-        updateIcon(!cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId));
+        cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId);
+        updateIcon();
         myPanel.reload();
       }
     });
   }
 
-  private boolean cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
+  private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
     final ErrorViewStructure structure = myPanel.getErrorViewStructure();
-    ErrorTreeElement[] elements = structure.getChildElements(fromElement);
-    if (elements.length ==0) return true;
-
-    boolean result = false;
-    for (ErrorTreeElement element : elements) {
+    for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
       if (element instanceof GroupingElement) {
         if (scope != null) {
           final VirtualFile file = ((GroupingElement)element).getFile();
@@ -111,20 +110,17 @@ public class ProblemsViewImpl extends ProblemsView{
         }
         if (!currentSessionId.equals(element.getData())) {
           structure.removeElement(element);
-          result = true;
         }
         else {
-          result |= cleanupChildrenRecursively(element, scope, currentSessionId);
+          cleanupChildrenRecursively(element, scope, currentSessionId);
         }
       }
       else {
         if (!currentSessionId.equals(element.getData())) {
           structure.removeElement(element);
-          result = true;
         }
       }
     }
-    return result;
   }
 
   @Override
@@ -139,7 +135,7 @@ public class ProblemsViewImpl extends ProblemsView{
       public void run() {
         final ErrorViewStructure structure = myPanel.getErrorViewStructure();
         final GroupingElement group = structure.lookupGroupingElement(groupName);
-        if (group != null && !sessionId.equals(group.getData())) {
+        if (group != null && sessionId != null && !sessionId.equals(group.getData())) {
           structure.removeElement(group);
         }
         if (navigatable != null) {
@@ -148,21 +144,24 @@ public class ProblemsViewImpl extends ProblemsView{
         else {
           myPanel.addMessage(type, text, null, -1, -1, sessionId);
         }
-        updateIcon(true);
+        updateIcon();
       }
     });
   }
 
-  private void updateIcon(final boolean active) {
-    ApplicationManager.getApplication().invokeLater(new Runnable() {
+  private void updateIcon() {
+    UIUtil.invokeLaterIfNeeded(new Runnable() {
       @Override
       public void run() {
-        final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
-        if (tw != null) {
-          tw.setIcon(active ? myActiveIcon : myPassiveIcon);
+        if (!myProject.isDisposed()) {
+          final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
+          if (tw != null) {
+            final boolean active = myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS);
+            tw.setIcon(active ? myActiveIcon : myPassiveIcon);
+          }
         }
       }
-    }, myProject.getDisposed());
+    });
   }
 
   @Override
index 618774541686032c2c6ff8176da6e28e8144b292..393b85f1424b673e4fbbb31978522a52fa374258 100644 (file)
@@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project;
 
 public class ProblemsViewPanel extends NewErrorTreeViewPanel {
   public ProblemsViewPanel(Project project) {
-    super(project, null, false, true, null);
+    super(project, "reference.problems.tool.window", false, true, null);
     myTree.getEmptyText().setText("No compilation problems found");
   }
 
index 1ed84cda2c7fc779c617b202d9905228667aa9b3..a22242f4093ac6b3a7d55847c598999c70496e67 100644 (file)
@@ -46,7 +46,9 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable {
     });
     myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0);
 
-    myPanel.add(new JLabel(ProjectBundle.message("module.module.language.level")),
+    JLabel label = new JLabel(ProjectBundle.message("module.module.language.level"));
+    label.setLabelFor(myLanguageLevelCombo);
+    myPanel.add(label,
                 new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(12, 6, 12, 0), 0, 0));
     myPanel.add(myLanguageLevelCombo,
                 new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0));
index e7c1e5b955a9b4d137261f1045ac16a479969916..87867565f63adf2c17951d0af39fa99d325cf338 100644 (file)
@@ -27,6 +27,8 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.projectRoots.JdkVersionUtil;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.PsiFile;
@@ -96,6 +98,7 @@ public class IncreaseLanguageLevelFix implements IntentionAction {
     }
     else {
       LanguageLevelProjectExtension.getInstance(project).setLanguageLevel(myLevel);
+      ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.INSTANCE, false, true);
     }
   }
 
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java b/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java
new file mode 100644 (file)
index 0000000..27baddc
--- /dev/null
@@ -0,0 +1,18 @@
+package com.intellij.codeInspection;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.util.ThreeState;
+
+/**
+ * This kind of suppression fix allows to clients to specify whether the fix should
+ * be invoked on injected elements or on elements of host files.
+ * <p/>
+ * By default suppression fixes on injected elements are able to make suppression inside injection only.
+ * Whereas implementation of this interface will be provided for suppressing inside injection and in injection host. 
+ * See {@link InspectionProfileEntry#getBatchSuppressActions(PsiElement)} for details.
+ */
+public interface InjectionAwareSuppressQuickFix extends SuppressQuickFix {
+  ThreeState isShouldBeAppliedToInjectionHost();
+
+  void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost);
+}
index af1e65c67598461c1bef2987c6a4821c34564f9f..886d02aa55a21f61665f86ab702bca2c0ac898a5 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.codeInspection;
 
 import com.intellij.codeHighlighting.HighlightDisplayLevel;
 import com.intellij.lang.Language;
+import com.intellij.lang.injection.InjectedLanguageManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.InvalidDataException;
@@ -24,8 +25,10 @@ import com.intellij.openapi.util.WriteExternalException;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.FileViewProvider;
 import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiLanguageInjectionHost;
 import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
 import com.intellij.util.ResourceUtil;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.xmlb.SerializationFilter;
 import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
@@ -44,14 +47,16 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URL;
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 /**
  * @author anna
  * @since 28-Nov-2005
  */
-@SuppressWarnings("JavadocReference")
-public abstract class InspectionProfileEntry implements BatchSuppressableTool{
+public abstract class InspectionProfileEntry implements BatchSuppressableTool {
   public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name");
 
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry");
@@ -93,22 +98,52 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
     Set<SuppressQuickFix> fixes = new THashSet<SuppressQuickFix>(new TObjectHashingStrategy<SuppressQuickFix>() {
       @Override
       public int computeHashCode(SuppressQuickFix object) {
-        return object.getName().hashCode();
+        int result = object instanceof InjectionAwareSuppressQuickFix
+          ? ((InjectionAwareSuppressQuickFix)object).isShouldBeAppliedToInjectionHost().hashCode()
+          : 0;
+        return 31 * result + object.getName().hashCode();
       }
 
       @Override
       public boolean equals(SuppressQuickFix o1, SuppressQuickFix o2) {
+        if (o1 instanceof InjectionAwareSuppressQuickFix && o2 instanceof InjectionAwareSuppressQuickFix) {
+          if (((InjectionAwareSuppressQuickFix)o1).isShouldBeAppliedToInjectionHost() != ((InjectionAwareSuppressQuickFix)o2).isShouldBeAppliedToInjectionHost()) {
+            return false;
+          }
+        }
         return o1.getName().equals(o2.getName());
       }
     });
+    
     Set<InspectionSuppressor> suppressors = getSuppressors(element);
+    final PsiLanguageInjectionHost injectionHost = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element);
+    if (injectionHost != null) {
+      Set<InspectionSuppressor> injectionHostSuppressors = getSuppressors(injectionHost);
+      for (InspectionSuppressor suppressor : injectionHostSuppressors) {
+        addAllSuppressActions(fixes, injectionHost, suppressor, ThreeState.YES, getShortName());
+      }
+    }
+
     for (InspectionSuppressor suppressor : suppressors) {
-      SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
-      fixes.addAll(Arrays.asList(actions));
+      addAllSuppressActions(fixes, element, suppressor, injectionHost != null ? ThreeState.NO : ThreeState.UNSURE, getShortName());
     }
     return fixes.toArray(new SuppressQuickFix[fixes.size()]);
   }
 
+  private static void addAllSuppressActions(Set<SuppressQuickFix> fixes,
+                                            PsiElement element,
+                                            InspectionSuppressor suppressor,
+                                            ThreeState appliedToInjectionHost,
+                                            String toolShortName) {
+    final SuppressQuickFix[] actions = suppressor.getSuppressActions(element, toolShortName);
+    for (SuppressQuickFix action : actions) {
+      if (action instanceof InjectionAwareSuppressQuickFix) {
+        ((InjectionAwareSuppressQuickFix)action).setShouldBeAppliedToInjectionHost(appliedToInjectionHost);
+      }
+      fixes.add(action);
+    }
+  }
+
   private boolean isSuppressed(@NotNull String toolId,
                                @NotNull InspectionSuppressor suppressor,
                                @NotNull PsiElement element) {
@@ -132,7 +167,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
       ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor);
       return suppressors;
     }
-    return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.<InspectionSuppressor>emptySet();
+    return elementLanguageSuppressor != null
+           ? Collections.singleton(elementLanguageSuppressor)
+           : Collections.<InspectionSuppressor>emptySet();
   }
 
   public void cleanup(Project project) {
@@ -148,9 +185,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
   protected volatile DefaultNameProvider myNameProvider = null;
 
   /**
-   * @see com.intellij.codeInspection.InspectionEP#groupDisplayName
-   * @see com.intellij.codeInspection.InspectionEP#groupKey
-   * @see com.intellij.codeInspection.InspectionEP#groupBundle
+   * @see InspectionEP#groupDisplayName
+   * @see InspectionEP#groupKey
+   * @see InspectionEP#groupBundle
    */
   @Nls
   @NotNull
@@ -166,7 +203,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
   }
 
   /**
-   * @see com.intellij.codeInspection.InspectionEP#groupPath
+   * @see InspectionEP#groupPath
    */
   @NotNull
   public String[] getGroupPath() {
@@ -178,9 +215,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
   }
 
   /**
-   * @see com.intellij.codeInspection.InspectionEP#displayName
-   * @see com.intellij.codeInspection.InspectionEP#key
-   * @see com.intellij.codeInspection.InspectionEP#bundle
+   * @see InspectionEP#displayName
+   * @see InspectionEP#key
+   * @see InspectionEP#bundle
    */
   @Nls
   @NotNull
@@ -198,7 +235,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
   /**
    * DO NOT OVERRIDE this method.
    *
-   * @see com.intellij.codeInspection.InspectionEP#shortName
+   * @see InspectionEP#shortName
    */
   @NonNls
   @NotNull
@@ -214,13 +251,13 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
 
   @NotNull
   public static String getShortName(@NotNull String className) {
-    return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"),"InspectionBase");
+    return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"), "InspectionBase");
   }
 
   /**
    * DO NOT OVERRIDE this method.
    *
-   * @see com.intellij.codeInspection.InspectionEP#level
+   * @see InspectionEP#level
    */
   @NotNull
   public HighlightDisplayLevel getDefaultLevel() {
@@ -230,7 +267,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
   /**
    * DO NOT OVERRIDE this method.
    *
-   * @see com.intellij.codeInspection.InspectionEP#enabledByDefault
+   * @see InspectionEP#enabledByDefault
    */
   public boolean isEnabledByDefault() {
     return false;
@@ -238,6 +275,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
 
   /**
    * This method is called each time UI is shown.
+   *
    * @return null if no UI options required.
    */
   @Nullable
@@ -348,7 +386,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
    * Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation.
    *
    * @param project to be associated with this entry
-   * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
+   * @deprecated this won't work for inspections configured via {@link InspectionEP}
    */
   public void projectOpened(@NotNull Project project) {
   }
@@ -357,7 +395,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
    * Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion.
    *
    * @param project to be disassociated from this entry
-   * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
+   * @deprecated this won't work for inspections configured via {@link InspectionEP}
    */
   public void projectClosed(@NotNull Project project) {
   }
@@ -411,7 +449,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
       if (descriptionUrl == null) return null;
       return ResourceUtil.loadText(descriptionUrl);
     }
-    catch (IOException ignored) { }
+    catch (IOException ignored) {
+    }
 
     return null;
   }
index 7a8c3e3c6cde63707020d3a95d185da09a5b8d4b..6bc8511bd5b5a8b702bc15874a13cf44cd878b68 100644 (file)
@@ -17,9 +17,9 @@
 package com.intellij.codeInsight.daemon.impl.actions;
 
 import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInspection.InjectionAwareSuppressQuickFix;
 import com.intellij.codeInspection.InspectionsBundle;
 import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.codeInspection.SuppressQuickFix;
 import com.intellij.codeInspection.SuppressionUtil;
 import com.intellij.icons.AllIcons;
 import com.intellij.lang.Language;
@@ -32,6 +32,7 @@ import com.intellij.psi.PsiManager;
 import com.intellij.psi.PsiWhiteSpace;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ThreeState;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -43,9 +44,10 @@ import java.util.List;
  * @author Roman.Chernyatchik
  * @date Aug 13, 2009
  */
-public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements SuppressQuickFix, Iconable {
+public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements InjectionAwareSuppressQuickFix, Iconable {
   @NotNull protected final String myID;
   private final boolean myReplaceOtherSuppressionIds;
+  private ThreeState myShouldBeAppliedToInjectionHost = ThreeState.UNSURE;
 
   @Nullable
   public abstract PsiElement getContainer(final PsiElement context);
@@ -60,6 +62,15 @@ public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements S
     myReplaceOtherSuppressionIds = replaceOtherSuppressionIds;
   }
 
+  public void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost) {
+    myShouldBeAppliedToInjectionHost = shouldBeAppliedToInjectionHost;
+  }
+
+  @Override
+  public ThreeState isShouldBeAppliedToInjectionHost() {
+    return myShouldBeAppliedToInjectionHost;
+  }
+
   @NotNull
   @Override
   public String getName() {
index 3fc800e8787987dc268f0ca654fa588114a85546..d92101c386fb00636f61a906a68468e1428ca3e3 100644 (file)
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiElement;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
@@ -59,9 +60,15 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction {
     }
   }
 
+  public ThreeState isShouldBeAppliedToInjectionHost() {
+    return myFix instanceof InjectionAwareSuppressQuickFix
+           ? ((InjectionAwareSuppressQuickFix)myFix).isShouldBeAppliedToInjectionHost()
+           : ThreeState.UNSURE;
+  }
+
   public PsiElement getContainer(PsiElement element) {
     return myFix instanceof AbstractBatchSuppressByNoInspectionCommentFix
-                           ? ((AbstractBatchSuppressByNoInspectionCommentFix )myFix).getContainer(element) : null;
+           ? ((AbstractBatchSuppressByNoInspectionCommentFix)myFix).getContainer(element) : null;
   }
 
   @Override
@@ -72,7 +79,7 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction {
   @NotNull
   @Override
   public String getText() {
-    return myFix.getName();
+    return myFix.getName() + (isShouldBeAppliedToInjectionHost() == ThreeState.NO ? " in injection" : "");
   }
 
   @NotNull
index 8a355d263a07a58c487e670823b50d151cd95df7..552d7563a2f232dbe2e78f38f4ede18236f27199 100644 (file)
@@ -143,7 +143,7 @@ public class EnvVariablesTable extends ListTableWithButtons<EnvironmentVariable>
       public void actionPerformed(@NotNull AnActionEvent e) {
         stopEditing();
         StringBuilder sb = new StringBuilder();
-        List<EnvironmentVariable> variables = getEnvironmentVariables();
+        List<EnvironmentVariable> variables = getSelection();
         for (EnvironmentVariable environmentVariable : variables) {
           if (environmentVariable.getIsPredefined() || isEmpty(environmentVariable)) continue;
           if (sb.length() > 0) sb.append('\n');
@@ -152,10 +152,16 @@ public class EnvVariablesTable extends ListTableWithButtons<EnvironmentVariable>
         }
         CopyPasteManager.getInstance().setContents(new StringSelection(sb.toString()));
       }
+
+      @Override
+      public boolean isEnabled() {
+        return super.isEnabled() && !getSelection().isEmpty();
+      }
     };
     AnActionButton pasteButton = new AnActionButton(ActionsBundle.message("action.EditorPaste.text"), AllIcons.Actions.Menu_paste) {
       @Override
       public void actionPerformed(@NotNull AnActionEvent e) {
+        removeSelected();
         stopEditing();
         String content = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
         if (content == null || !content.contains("=")) return;
@@ -172,13 +178,7 @@ public class EnvVariablesTable extends ListTableWithButtons<EnvironmentVariable>
             StringUtil.unescapeStringCharacters(line.substring(pos + 1)),
             false));
         }
-        List<EnvironmentVariable> variables =
-          new ArrayList<EnvironmentVariable>(ContainerUtil.filter(getEnvironmentVariables(), new Condition<EnvironmentVariable>() {
-            @Override
-            public boolean value(EnvironmentVariable variable) {
-              return variable.getIsPredefined();
-            }
-          }));
+        List<EnvironmentVariable> variables = new ArrayList<EnvironmentVariable>(getEnvironmentVariables());
         variables.addAll(parsed);
         setValues(variables);
       }
index 71ed67719cb99ce1ba924fc3a6d8ea7d676162f7..5ea5a2ae5ac78df4c68f34d2b67e4ffdae17ac47 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.execution.util;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.util.Condition;
 import com.intellij.ui.*;
 import com.intellij.ui.table.TableView;
 import com.intellij.util.containers.ContainerUtil;
@@ -30,6 +31,7 @@ import javax.swing.table.DefaultTableCellRenderer;
 import javax.swing.table.TableCellRenderer;
 import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Observable;
@@ -110,31 +112,19 @@ public abstract class ListTableWithButtons<T> extends Observable {
       }).setRemoveAction(new AnActionButtonRunnable() {
         @Override
         public void run(AnActionButton button) {
-          myTableView.stopEditing();
-          setModified();
-          T selected = getSelection();
-          if (selected != null) {
-            int selectedIndex = myElements.indexOf(selected);
-            myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true));
-            myElements.remove(selected);
-            myTableView.getTableViewModel().setItems(myElements);
-
-            int prev = selectedIndex - 1;
-            if (prev >= 0) {
-              myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev);
-            }
-            else if (selectedIndex < myElements.size()) {
-              myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);
-            }
-          }
+          removeSelected();
         }
       }).disableUpDownActions().addExtraActions(createExtraActions()).createPanel();
 
     ToolbarDecorator.findRemoveButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() {
       @Override
       public boolean isEnabled(AnActionEvent e) {
-        T selection = getSelection();
-        return selection != null && myIsEnabled && canDeleteElement(selection);
+        List<T> selection = getSelection();
+        if (selection.isEmpty() || !myIsEnabled) return false;
+        for (T t : selection) {
+          if (!canDeleteElement(t)) return false;
+        }
+        return true;
       }
     });
     ToolbarDecorator.findAddButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() {
@@ -146,7 +136,33 @@ public abstract class ListTableWithButtons<T> extends Observable {
 
     myActionsPanel = decorator.getActionsPanel();
 
-    myTableView.getComponent().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    myTableView.getComponent().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+  }
+
+  protected void removeSelected() {
+    List<T> selected = getSelection();
+    if (!selected.isEmpty()) {
+      myTableView.stopEditing();
+      setModified();
+      int selectedIndex = myTableView.getSelectionModel().getLeadSelectionIndex();
+      myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true));
+      selected = ContainerUtil.filter(selected, new Condition<T>() {
+        @Override
+        public boolean value(T t) {
+          return canDeleteElement(t);
+        }
+      });
+      myElements.removeAll(selected);
+      myTableView.getTableViewModel().setItems(myElements);
+
+      int prev = selectedIndex - 1;
+      if (prev >= 0) {
+        myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev);
+      }
+      else if (selectedIndex < myElements.size()) {
+        myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);
+      }
+    }
   }
 
   @NotNull
@@ -197,7 +213,9 @@ public abstract class ListTableWithButtons<T> extends Observable {
   }
 
   protected void editSelection(int column) {
-    int row = myElements.indexOf(getSelection());
+    List<T> selection = getSelection();
+    if (selection.size() != 1) return;
+    int row = myElements.indexOf(selection.get(0));
     if (row != -1) {
       TableUtil.editCellAt(myTableView, row, column);
     }
@@ -213,13 +231,18 @@ public abstract class ListTableWithButtons<T> extends Observable {
   }
 
 
-  protected T getSelection() {
-    int selIndex = myTableView.getComponent().getSelectionModel().getMinSelectionIndex();
-    if (selIndex < 0) {
-      return null;
+  @NotNull
+  protected List<T> getSelection() {
+    int[] selection = myTableView.getComponent().getSelectedRows();
+    if (selection.length == 0) {
+      return Collections.emptyList();
     }
     else {
-      return myElements.get(selIndex);
+      List<T> result = new ArrayList<T>(selection.length);
+      for (int row : selection) {
+        result.add(myElements.get(row));
+      }
+      return result;
     }
   }
 
index d71f60589150185882119f5bf7eabf64fbaaac60..436356065f2ca0bcb507f109c31c7a902ef1eca9 100644 (file)
@@ -28,10 +28,14 @@ import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper;
 import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings;
 import com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable;
+import com.intellij.codeInsight.unwrap.ScopeHighlighter;
+import com.intellij.codeInspection.SuppressIntentionActionFromFix;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.DataProvider;
 import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
@@ -52,7 +56,9 @@ import com.intellij.openapi.ui.popup.ListPopup;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.refactoring.BaseRefactoringIntentionAction;
 import com.intellij.ui.HintHint;
 import com.intellij.ui.LightweightHint;
@@ -61,6 +67,7 @@ import com.intellij.ui.RowIcon;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.util.Alarm;
 import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.EmptyIcon;
 import org.jetbrains.annotations.NotNull;
@@ -69,11 +76,14 @@ import org.jetbrains.annotations.TestOnly;
 
 import javax.swing.*;
 import javax.swing.border.Border;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
 import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -441,12 +451,52 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll
       Disposer.dispose(myPopup);
     }
     myPopup = JBPopupFactory.getInstance().createListPopup(step);
+    
+    final PsiFile injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(myFile, myEditor.getCaretModel().getOffset());
+    final Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile);
+    
+    final ScopeHighlighter highlighter = new ScopeHighlighter(myEditor);
+    final ScopeHighlighter injectionHighlighter = new ScopeHighlighter(injectedEditor);
+    
     myPopup.addListener(new JBPopupListener.Adapter() {
       @Override
       public void onClosed(LightweightWindowEvent event) {
+        highlighter.dropHighlight();
+        injectionHighlighter.dropHighlight();
         myPopupShown = false;
       }
     });
+    myPopup.addListSelectionListener(new ListSelectionListener() {
+      @Override
+      public void valueChanged(ListSelectionEvent e) {
+        final Object source = e.getSource();
+        highlighter.dropHighlight();
+        injectionHighlighter.dropHighlight();
+        
+        if (source instanceof DataProvider) {
+          final Object selectedItem = PlatformDataKeys.SELECTED_ITEM.getData((DataProvider)source);
+          if (selectedItem instanceof IntentionActionWithTextCaching) {
+            final IntentionAction action = ((IntentionActionWithTextCaching)selectedItem).getAction();
+            if (action instanceof SuppressIntentionActionFromFix) {
+              if (injectedFile != null && ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost() == ThreeState.NO) {
+                final PsiElement at = injectedFile.findElementAt(injectedEditor.getCaretModel().getOffset());
+                final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at);
+                if (container != null) {
+                  injectionHighlighter.highlight(container, Collections.singletonList(container));
+                }
+              }
+              else {
+                final PsiElement at = myFile.findElementAt(myEditor.getCaretModel().getOffset());
+                final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at);
+                if (container != null) {
+                  highlighter.highlight(container, Collections.singletonList(container));
+                }
+              }
+            }
+          }
+        }
+      }
+    });
 
     if (myEditor.isOneLineMode()) {
       // hide popup on combobox popup show
index 0700b6e1e1b27b73f12ac1ce242be1480156a7e7..491508e2c7a8831df6436c77519dee172fcbc8dc 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper;
 import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings;
 import com.intellij.codeInspection.IntentionWrapper;
 import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.SuppressIntentionActionFromFix;
 import com.intellij.codeInspection.ex.QuickFixWrapper;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.application.ApplicationManager;
@@ -39,6 +40,7 @@ import com.intellij.openapi.util.Iconable;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
@@ -321,6 +323,11 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
     if (a instanceof LowPriorityAction) {
       return group - 3;
     }
+    if (a instanceof SuppressIntentionActionFromFix) {
+      if (((SuppressIntentionActionFromFix)a).isShouldBeAppliedToInjectionHost() == ThreeState.NO) {
+        return group - 1;
+      }
+    }
     if (a instanceof QuickFixWrapper) {
       final LocalQuickFix quickFix = ((QuickFixWrapper)a).getFix();
       if (quickFix instanceof HighPriorityAction) {
index 8ddebd7c383fa5597a966bc801c12a0f3f327996..31c1ecd533d1042c3d3cf6e9a9e2650031b06a85 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.lookup.LookupEx;
 import com.intellij.codeInsight.lookup.LookupManager;
 import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
 import com.intellij.codeInsight.template.impl.TemplateState;
+import com.intellij.codeInspection.SuppressIntentionActionFromFix;
 import com.intellij.featureStatistics.FeatureUsageTracker;
 import com.intellij.featureStatistics.FeatureUsageTrackerImpl;
 import com.intellij.injected.editor.EditorWindow;
@@ -45,6 +46,7 @@ import com.intellij.psi.PsiFile;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.PairProcessor;
+import com.intellij.util.ThreeState;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -107,6 +109,16 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
   private static boolean isAvailableHere(Editor editor, PsiFile psiFile, PsiElement psiElement, boolean inProject, IntentionAction action) {
     try {
       Project project = psiFile.getProject();
+      if (action instanceof SuppressIntentionActionFromFix) {
+        final ThreeState shouldBeAppliedToInjectionHost = ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost();
+        if (editor instanceof EditorWindow && shouldBeAppliedToInjectionHost == ThreeState.YES) {
+          return false;
+        }
+        if (!(editor instanceof EditorWindow) && shouldBeAppliedToInjectionHost == ThreeState.NO) {
+          return false;
+        }
+      }
+      
       if (action instanceof PsiElementBaseIntentionAction) {
         if (!inProject || psiElement == null || !((PsiElementBaseIntentionAction)action).isAvailable(project, editor, psiElement)) return false;
       }
index 7a65062fe33c9da6e9e2293b647c7a1687f041f9..78451fe4580ee4140f4ae211629db7c7bcb34fef 100644 (file)
@@ -30,9 +30,9 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.TextRange;
@@ -58,7 +58,7 @@ import java.util.Map;
 /**
  * @author gregsh
  */
-public class RunIdeConsoleAction extends ActionGroup implements DumbAware {
+public class RunIdeConsoleAction extends DumbAwareAction {
 
   private static final String DEFAULT_FILE_NAME = "ide-scripting";
   private static final Key<WeakReference<ConsoleView>> CONSOLE_VIEW_KEY = Key.create("CONSOLE_VIEW_KEY");
@@ -84,26 +84,23 @@ public class RunIdeConsoleAction extends ActionGroup implements DumbAware {
       runConsole(e, ourEngines.values().iterator().next());
     }
     else {
-      super.actionPerformed(e);
-    }
-  }
-
-  @NotNull
-  @Override
-  public AnAction[] getChildren(@Nullable AnActionEvent e) {
-    if (e == null) return EMPTY_ARRAY;
-    return ContainerUtil.map2Array(ourEngines.values(), AnAction.class, new NotNullFunction<ScriptEngineFactory, AnAction>() {
-      @NotNull
-      @Override
-      public AnAction fun(final ScriptEngineFactory engine) {
-        return new AnAction(engine.getLanguageName()) {
+      DefaultActionGroup actions = new DefaultActionGroup(
+        ContainerUtil.map(ourEngines.values(), new NotNullFunction<ScriptEngineFactory, AnAction>() {
+          @NotNull
           @Override
-          public void actionPerformed(@NotNull AnActionEvent e) {
-            runConsole(e, engine);
+          public AnAction fun(final ScriptEngineFactory engine) {
+            return new AnAction(engine.getLanguageName()) {
+              @Override
+              public void actionPerformed(@NotNull AnActionEvent e) {
+                runConsole(e, engine);
+              }
+            };
           }
-        };
-      }
-    });
+        })
+      );
+      JBPopupFactory.getInstance().createActionGroupPopup("Script Engine", actions, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false).
+        showInBestPositionFor(e.getDataContext());
+    }
   }
 
   protected void runConsole(@NotNull AnActionEvent e, @NotNull ScriptEngineFactory engine) {
index 937fee52279b4b0a022279448ccc5bda2cb5662c..2f813722b91d4550795964664a3e35ee21ea7474 100644 (file)
@@ -69,7 +69,7 @@ public final class ScratchRootType extends RootType {
     }
   }
 
-  private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile, InternalFileType {
+  private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile {
 
     MyFileType() {
       super(PlainTextLanguage.INSTANCE);
index b964f200fc41eff3e8461f96a748b39c496c3ed1..e96b5baa092d81d74fe5be4280a34d6df0f64ad3 100644 (file)
@@ -69,6 +69,30 @@ public class ErrorViewStructure extends AbstractTreeStructure {
     return myRoot;
   }
 
+  public boolean hasMessages(@NotNull Set<ErrorTreeElementKind> kinds) {
+    synchronized (myLock) {
+      for (Map.Entry<ErrorTreeElementKind, List<ErrorTreeElement>> entry : mySimpleMessages.entrySet()) {
+        if (kinds.contains(entry.getKey())) {
+          final List<ErrorTreeElement> messages = entry.getValue();
+          if (messages != null && !messages.isEmpty()) {
+            return true;
+          }
+        }
+      }
+      for (Map.Entry<String, List<NavigatableMessageElement>> entry : myGroupNameToMessagesMap.entrySet()) {
+        final List<NavigatableMessageElement> messages = entry.getValue();
+        if (messages != null && !messages.isEmpty()) {
+          for (NavigatableMessageElement message : messages) {
+            if (kinds.contains(message.getKind())) {
+              return true;
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+  
   @Override
   public ErrorTreeElement[] getChildElements(Object element) {
     if (element == myRoot) {
index 89e1b18c6bb23e37a3f1806964eebd231024f328..7cc7305fe3b0e47f4c9191f37658e3011274fd23 100644 (file)
@@ -267,6 +267,13 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
       return;
     }
     myUpdateAlarm.cancelAllRequests();
+    if (selected == null) {
+      hideHint();
+      return;
+    }
+    if (!selected.equals(myKey)) {
+      hideHint();
+    }
     myUpdateAlarm.addRequest(new Runnable() {
       @Override
       public void run() {
@@ -275,12 +282,8 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
     }, 10);
   }
 
-  private void doHandleSelectionChange(KeyType selected, boolean processIfUnfocused) {
-    Window window = SwingUtilities.getWindowAncestor(myComponent);
-    if (selected == null
-        || window == null
-        || !window.isActive()
-        || !myEnabled
+  private void doHandleSelectionChange(@NotNull KeyType selected, boolean processIfUnfocused) {
+    if (!myEnabled
         || !myComponent.isEnabled()
         || !myComponent.isShowing()
         || !myComponent.getVisibleRect().intersects(getVisibleRect(selected))
@@ -300,6 +303,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
     else {
       Dimension size = myTipComponent.getPreferredSize();
       myPopup.setBounds(location.x, location.y, size.width, size.height);
+      myPopup.setHeavyWeight(hasOwnedWindows());
       if (!myPopup.isVisible()) {
         myPopup.setVisible(true);
       }
@@ -324,6 +328,17 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
     return false;
   }
 
+  private boolean hasOwnedWindows() {
+    Window owner = SwingUtilities.getWindowAncestor(myComponent);
+    Window popup = SwingUtilities.getWindowAncestor(myTipComponent);
+    for (Window other : owner.getOwnedWindows()) {
+      if (popup != other && other.isVisible()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   private void hideHint() {
     myUpdateAlarm.cancelAllRequests();
     if (myPopup.isVisible()) {
index 7e53f5d5d11e84d7d0cf1a7b961ede85374d3806..31c79a1a7ac5458364357e73eafd284e228e9651 100644 (file)
@@ -210,6 +210,7 @@ public class MovablePopup implements Disposable {
       myView.setBounds(location.x, location.y, size.width, size.height);
       if (myView.isVisible()) {
         myView.invalidate();
+        myView.validate();
         myView.repaint();
       }
     }
index af42373b52a3a28037c8450b4fd37877a9726920..a7862132188f5cffb0a9a6e0fa70afc9f1d389b6 100644 (file)
 
         <action id="EmmetNextEditPoint" class="com.intellij.codeInsight.template.emmet.actions.GoToEditPointAction$Forward"
                 text="Next Emmet Edit Point" description="Go to next Emmet edit point">
-          <keyboard-shortcut first-keystroke="alt shift OPEN_BRACKET" keymap="$default"/>
+          <keyboard-shortcut first-keystroke="alt shift CLOSE_BRACKET" keymap="$default"/>
           <keyboard-shortcut first-keystroke="control alt RIGHT" keymap="Mac OS X 10.5+" replace-all="true"/>
         </action>
 
         <action id="EmmetPreviousEditPoint" class="com.intellij.codeInsight.template.emmet.actions.GoToEditPointAction$Backward"
                 text="Previous Emmet Edit Point" description="Go to previous Emmet edit point">
-          <keyboard-shortcut first-keystroke="alt shift CLOSE_BRACKET" keymap="$default"/>
+          <keyboard-shortcut first-keystroke="alt shift OPEN_BRACKET" keymap="$default"/>
           <keyboard-shortcut first-keystroke="control alt LEFT" keymap="Mac OS X 10.5+" replace-all="true"/>
         </action>
       </group>
index b971ee325fec890ca7e83ec2043291c51880af96..4b31b4aaca4530302060a18f87d92d74151bb573 100644 (file)
@@ -114,7 +114,7 @@ jdk.combo.box.project.item=<No Project SDK>
 jdk.combo.box.none.item=<None>
 jdk.combo.box.invalid.item={0} [Invalid]
 module.libraries.target.jdk.project.radio=<html><b>&Project SDK:</b><br>This SDK is default for all project modules.<br>\
-  A module specific SDK can be configured for each of the modules as required</html>
+  A module specific SDK can be configured for each of the modules as required.</html>
 module.libraries.target.jdk.module.radio=&Module SDK:
 module.libraries.target.jdk.select.title=Select Project SDK
 module.libraries.javadoc.url.button=Specify Documentation &URL...
@@ -263,11 +263,11 @@ project.inherit.compile.output.path=Inherit project compile output path
 project.module.compile.output.path=Use module compile output path
 project.compiler.output=<html><b>Project compiler output:</b><br>This path is used to store all project compilation results. <br>\
   A directory corresponding to each module is created under this path. <br>This directory contains two subdirectories: Production and Test for production code and test sources, respectively.<br>\
-  A module specific compiler output path can be configured for each of the modules as required</html>
+  A module specific compiler output path can be configured for each of the modules as required.</html>
 find.usages.action.text=Find Usages
 dependencies.used.in.popup.title=Used in
 project.language.level=<html><b>Project language level:</b><br>This language level is default for all project modules.<br>\
-  A module specific language level can be configured for each of the modules as required</html>
+  A module specific language level can be configured for each of the modules as required.</html>
 classpath.panel.analyze=Analyze
 classpath.panel.navigate.action.text=Navigate
 output.tab.title=Output
index 9f3fbc17f8e813243c25e5c7a7109ca80ca244fe..42f40fbfd265833962e67bed232c188fb350e88f 100644 (file)
@@ -1701,14 +1701,23 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
     descriptors.addAll(intentions.inspectionFixesToShow);
     descriptors.addAll(intentions.guttersToShow);
 
-    PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
+    final int fileOffset = editor.getCaretModel().getOffset();
+    PsiElement hostElement = file.getViewProvider().findElementAt(fileOffset, file.getLanguage());
+    PsiElement injectedElement = InjectedLanguageUtil.findElementAtNoCommit(file, fileOffset);
+    
+    PsiFile injectedFile = injectedElement != null ? injectedElement.getContainingFile() : null;
+    Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
+    
     List<IntentionAction> result = new ArrayList<IntentionAction>();
 
     List<HighlightInfo> infos = DaemonCodeAnalyzerEx.getInstanceEx(file.getProject()).getFileLevelHighlights(file.getProject(), file);
     for (HighlightInfo info : infos) {
       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
         HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
-        if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
+        final IntentionAction action = actionInGroup.getAction();
+        
+        if (ShowIntentionActionsHandler.availableFor(file, editor, action)
+          || (injectedElement != null && hostElement != injectedElement && ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) {
           descriptors.add(actionInGroup);
         }
       }
@@ -1717,11 +1726,25 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
     // add all intention options for simplicity
     for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
       result.add(descriptor.getAction());
-      List<IntentionAction> options = descriptor.getOptions(element,editor);
-      if (options != null) {
-        for (IntentionAction option : options) {
-          if (option.isAvailable(file.getProject(), editor, file)) {
-            result.add(option);
+      
+      if (injectedElement != null && injectedElement != hostElement) {
+        List<IntentionAction> options = descriptor.getOptions(injectedElement, injectedEditor);
+        if (options != null) {
+          for (IntentionAction option : options) {
+            if (ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, option)) {
+              result.add(option);
+            }
+          }
+        }
+      }
+      
+      if (hostElement != null) {
+        List<IntentionAction> options = descriptor.getOptions(hostElement, editor);
+        if (options != null) {
+          for (IntentionAction option : options) {
+            if (ShowIntentionActionsHandler.availableFor(file, editor, option)) {
+              result.add(option);
+            }
           }
         }
       }
index 9480a02ab81eaea3065cdadc5a5029000da4039c..6ec4a1ef09a0fae038240741d672e0335a300b36 100644 (file)
@@ -219,6 +219,8 @@ public class RemoteUtil {
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       if (method.getDeclaringClass() == Object.class) {
+        if ("equals".equals(method.getName())) return proxy == args[0];
+        if ("hashCode".equals(method.getName())) return hashCode();
         return method.invoke(myRemote, args);
       }
       else {
index a3d99c33228cd71b7dfb19e84a1038cbff11a8d0..a91983706af70d04df8c8cd3d77ddda9f6bf0773 100644 (file)
@@ -47,7 +47,7 @@ public class JiraIntegrationTest extends TaskManagerTestCase {
   /**
    * JIRA 4.4.5, REST API 2.0.alpha1
    */
-  @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://trackers-tests.labs.intellij.net:8014";
+  @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://idea-qa-task-2.labs.intellij.net:8014";
   /**
    * JIRA 5.0.6, REST API 2.0
    */
index 24fd7faaeee137b6ad828e1c77f20b41ac67c1f3..d23114a1d243e306622c0b8b5303b85dd2d51ed7 100644 (file)
@@ -17,59 +17,74 @@ package com.intellij.codeInsight.template.emmet.actions;
 
 import com.intellij.lang.Language;
 import com.intellij.lang.xml.XMLLanguage;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.*;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.*;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.xml.XmlText;
 import com.intellij.psi.xml.XmlTokenType;
+import com.intellij.util.ObjectUtils;
 
 /**
  * @author Dennis.Ushakov
  */
 public class EmmetEditPointUtil {
-  public static void moveForward(Editor editor, PsiFile file) {
+  public static void moveForward(final Editor editor, final PsiFile file) {
     if (!isApplicableFile(file)) return;
     moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), 1);
   }
 
-  public static void moveBackward(Editor editor, PsiFile file) {
+  public static void moveBackward(final Editor editor, final PsiFile file) {
     if (!isApplicableFile(file)) return;
     moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), -1);
   }
 
   private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) {
     final Document doc = editor.getDocument();
+    final TemplateLanguageFileViewProvider provider = ObjectUtils.tryCast(file.getViewProvider(), TemplateLanguageFileViewProvider.class);
+    final Language additionalLanguage = provider != null ? provider.getTemplateDataLanguage() : null;
     PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc);
     for (int i = offset + inc; i < doc.getTextLength() && i >= 0; i += inc) {
       PsiElement current = InjectedLanguageUtil.findElementAtNoCommit(file, i);
-      if (current == null) continue;
+      if (checkAndMove(editor, doc, i, current)) return;
+      if (additionalLanguage != null) {
+        current = provider.findElementAt(i, additionalLanguage);
+        if (checkAndMove(editor, doc, i, current)) return;
+      }
+    }
+  }
 
-      if (current.getParent() instanceof XmlText) {
-        final int line = doc.getLineNumber(i);
-        final int lineStart = doc.getLineStartOffset(line);
-        final int lineEnd = doc.getLineEndOffset(line);
-        if (lineEnd == offset) continue;
+  private static boolean checkAndMove(Editor editor, Document doc, int offset, PsiElement current) {
+    if (current == null) return false;
+    if (current.getParent() instanceof XmlText) {
+      final int line = doc.getLineNumber(offset);
+      final int lineStart = doc.getLineStartOffset(line);
+      final int lineEnd = doc.getLineEndOffset(line);
 
-        final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd);
-        if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) {
-          return;
-        }
-      } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) {
-        return;
+      final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd);
+      if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) {
+        return true;
       }
+    } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) {
+      return true;
     }
+    return false;
   }
 
   private static boolean moveCaret(Editor editor, PsiElement current, int offset) {
     editor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, current.getContainingFile());
-    if (editor.getCaretModel().getOffset() == offset) return false;
-    editor.getCaretModel().moveToOffset(offset);
+    final CaretModel caretModel = editor.getCaretModel();
+    if (caretModel.getOffset() == offset) return false;
+
+    caretModel.moveToOffset(offset);
+    final Caret caret = caretModel.getCurrentCaret();
+    ScrollingModel scrollingModel = editor.getScrollingModel();
+    if (caret == caretModel.getPrimaryCaret()) {
+      scrollingModel.scrollToCaret(ScrollType.RELATIVE);
+    }
     return true;
   }
 
@@ -89,7 +104,7 @@ public class EmmetEditPointUtil {
   static boolean isApplicableFile(PsiFile file) {
     if (file == null) return false;
     for (Language language : file.getViewProvider().getLanguages()) {
-      if (language.isKindOf(XMLLanguage.INSTANCE)) return true;
+      if (language.isKindOf(XMLLanguage.INSTANCE) || "JavaScript".equals(language.getID())) return true;
     }
     return false;
   }
index f6c66a88931f3841f610b7d1fe9f03f7b7b7d92d..840126aafa190831fa057c9870ea18a9338b1e9b 100644 (file)
  */
 package com.intellij.codeInsight.template.emmet.actions;
 
-import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.editor.Caret;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.editor.actionSystem.EditorAction;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.project.DumbAware;
 import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author Dennis.Ushakov
  */
-public abstract class GoToEditPointAction extends DumbAwareAction {
-  @Override
-  public void update(AnActionEvent e) {
-    final Editor editor = getEditor(e);
-    final PsiFile file = getFile(e);
-    final boolean isApplicable = editor != null && EmmetEditPointUtil.isApplicableFile(file);
-    e.getPresentation().setEnabledAndVisible(isApplicable);
+public abstract class GoToEditPointAction extends EditorAction implements DumbAware {
+  protected GoToEditPointAction(EditorActionHandler defaultHandler) {
+    super(defaultHandler);
   }
 
-  private static PsiFile getFile(AnActionEvent e) {
-    return CommonDataKeys.PSI_FILE.getData(e.getDataContext());
+  @Override
+  public void update(Editor editor, Presentation presentation, DataContext dataContext) {
+    super.update(editor, presentation, dataContext);
+    final PsiFile file = getFile(dataContext);
+    if (!EmmetEditPointUtil.isApplicableFile(file)) {
+      presentation.setEnabledAndVisible(false);
+    }
   }
 
-  private static Editor getEditor(AnActionEvent e) {
-    final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
-    return editor != null ? InjectedLanguageUtil.getTopLevelEditor(editor) : null;
+  private static PsiFile getFile(DataContext context) {
+    return CommonDataKeys.PSI_FILE.getData(context);
   }
 
   public static class Forward extends GoToEditPointAction {
-    @Override
-    public void actionPerformed(AnActionEvent e) {
-      EmmetEditPointUtil.moveForward(getEditor(e), getFile(e));
+    public Forward() {
+      super(new EditorActionHandler(true) {
+        @Override
+        protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) {
+          EmmetEditPointUtil.moveForward(editor, getFile(dataContext));
+        }
+      });
     }
   }
 
   public static class Backward extends GoToEditPointAction {
-    @Override
-    public void actionPerformed(AnActionEvent e) {
-      EmmetEditPointUtil.moveBackward(getEditor(e), getFile(e));
+    public Backward() {
+      super(new EditorActionHandler(true) {
+        @Override
+        protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) {
+          EmmetEditPointUtil.moveBackward(editor, getFile(dataContext));
+        }
+      });
     }
   }
 }