unified exclude/include actions for inspection & find usages tool windows IDEA-154536 appcode/146.1620 clion/146.1619 phpstorm/146.1621
authorDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Sat, 30 Apr 2016 08:07:56 +0000 (11:07 +0300)
committerDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Sat, 30 Apr 2016 08:09:24 +0000 (11:09 +0300)
platform/platform-api/src/com/intellij/ide/actions/exclusion/TreeNodeExclusionAction.java
platform/platform-resources/src/idea/LangActions.xml
platform/usageView/src/com/intellij/usages/actions/ExcludeUsageAction.java [deleted file]
platform/usageView/src/com/intellij/usages/actions/IncludeExcludeActionBase.java [deleted file]
platform/usageView/src/com/intellij/usages/actions/IncludeUsageAction.java [deleted file]
platform/usageView/src/com/intellij/usages/actions/RemoveUsageAction.java
platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java

index dab2817af74ffdd25ecdb38cb2233cc36af9cc71..ef6e68b71850fcc0dbd00451191a576441589b0b 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ui.tree.TreeUtil;
 
 import javax.swing.*;
 import javax.swing.tree.MutableTreeNode;
@@ -53,8 +54,8 @@ abstract class TreeNodeExclusionAction<T extends MutableTreeNode> extends AnActi
       return;
     }
     JTree tree = (JTree) component;
-    final TreePath[] selection = tree.getSelectionPaths();
-    if (selection == null) {
+    final TreePath[] selection = TreeUtil.selectMaximals(tree.getSelectionPaths());
+    if (selection.length == 0) {
       presentation.setEnabledAndVisible(false);
       return;
     }
index e8f461c30a4baaac2987eee9fb33026a6efda26b..f2856c733114dc8dba88df078ea4c5bb33ed84de 100644 (file)
       <add-to-group group-id="EditorTabPopupMenu" anchor="last"/>
     </group>
 
+    <group id="TreeNodeExclusion">
+      <action id="UsageView.Include" class="com.intellij.ide.actions.exclusion.IncludeTreeNodeAction"/>
+      <action id="UsageView.Exclude" class="com.intellij.ide.actions.exclusion.ExcludeTreeNodeAction" use-shortcut-of="$Delete"/>
+    </group>>
+
     <group id="UsageView.Popup">
       <action id="UsageView.Rerun" class="com.intellij.usages.actions.RerunSearchAction" icon="AllIcons.Actions.Rerun" use-shortcut-of="Rerun"/>
       <separator/>
       <reference ref="EditSource"/>
-      <action id="UsageView.Include" class="com.intellij.usages.actions.IncludeUsageAction"/>
-      <action id="UsageView.Exclude" class="com.intellij.usages.actions.ExcludeUsageAction" use-shortcut-of="$Delete"/>
+      <reference ref="TreeNodeExclusion"/>
       <action id="UsageView.Remove" class="com.intellij.usages.actions.RemoveUsageAction" use-shortcut-of="SafeDelete"/>
       <separator/>
       <action id="UsageView.ShowRecentFindUsages" class="com.intellij.find.impl.ShowRecentFindUsagesAction" icon="AllIcons.Actions.Back"
 
     <action id="SeverityEditorDialog" class="com.intellij.codeInspection.ex.SeverityEditorDialogAction"/>
 
-    <group id="TreeNodeExclusion">
-      <action id="TreeNodeExclusionInclude" class="com.intellij.ide.actions.exclusion.IncludeTreeNodeAction"/>
-      <action id="TreeNodeExclusionExclude" class="com.intellij.ide.actions.exclusion.ExcludeTreeNodeAction" use-shortcut-of="$Delete"/>
-    </group>>
-
     <group id="InspectionToolWindow.TreePopup" compact="true">
       <reference ref="EditSource"/>
       <reference ref="FindUsages"/>
diff --git a/platform/usageView/src/com/intellij/usages/actions/ExcludeUsageAction.java b/platform/usageView/src/com/intellij/usages/actions/ExcludeUsageAction.java
deleted file mode 100644 (file)
index cea1bdb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.usages.actions;
-
-import com.intellij.usages.Usage;
-import com.intellij.usages.UsageView;
-
-/**
- * @author max
- */
-public class ExcludeUsageAction extends IncludeExcludeActionBase {
-  @Override
-  protected void process(Usage[] usages, UsageView usageView) {
-    usageView.excludeUsages(usages);
-  }
-}
diff --git a/platform/usageView/src/com/intellij/usages/actions/IncludeExcludeActionBase.java b/platform/usageView/src/com/intellij/usages/actions/IncludeExcludeActionBase.java
deleted file mode 100644 (file)
index 7da5d90..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.usages.actions;
-
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.usages.Usage;
-import com.intellij.usages.UsageView;
-
-/**
- * @author max
- */
-public abstract class IncludeExcludeActionBase extends AnAction {
-  protected abstract void process(Usage[] usages, UsageView usageView);
-
-  private static Usage[] getUsages(AnActionEvent context) {
-    UsageView usageView = context.getData(UsageView.USAGE_VIEW_KEY);
-    if (usageView == null) return Usage.EMPTY_ARRAY;
-    Usage[] usages = context.getData(UsageView.USAGES_KEY);
-    return usages == null ? Usage.EMPTY_ARRAY : usages;
-  }
-
-  @Override
-  public void update(AnActionEvent e) {
-    e.getPresentation().setEnabled(getUsages(e).length > 0);
-  }
-
-  @Override
-  public void actionPerformed(AnActionEvent e) {
-    process(getUsages(e), e.getData(UsageView.USAGE_VIEW_KEY));
-  }
-}
diff --git a/platform/usageView/src/com/intellij/usages/actions/IncludeUsageAction.java b/platform/usageView/src/com/intellij/usages/actions/IncludeUsageAction.java
deleted file mode 100644 (file)
index d38782c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.usages.actions;
-
-import com.intellij.usages.Usage;
-import com.intellij.usages.UsageView;
-
-/**
- * @author max
- */
-public class IncludeUsageAction extends IncludeExcludeActionBase {
-  @Override
-  protected void process(Usage[] usages, UsageView usageView) {
-    usageView.includeUsages(usages);
-  }
-}
index 0fcd9501cc994af632ccb652eafa8e444610fa5b..57d960ae8351a869a1c528e8b3a26227200b4bcb 100644 (file)
@@ -15,6 +15,8 @@
  */
 package com.intellij.usages.actions;
 
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.usages.Usage;
 import com.intellij.usages.UsageView;
 import com.intellij.usages.impl.UsageViewImpl;
@@ -25,10 +27,18 @@ import java.util.List;
 /**
  * @author Manuel Stadelmann
  */
-public class RemoveUsageAction extends IncludeExcludeActionBase {
+public class RemoveUsageAction extends AnAction {
+  @Override
+  public void update(AnActionEvent e) {
+    e.getPresentation().setEnabled(getUsages(e).length > 0);
+  }
 
   @Override
-  protected void process(Usage[] usages, UsageView usageView) {
+  public void actionPerformed(AnActionEvent e) {
+    process(getUsages(e), e.getData(UsageView.USAGE_VIEW_KEY));
+  }
+
+  private static void process(Usage[] usages, UsageView usageView) {
     if (usages.length == 0) return;
     Arrays.sort(usages, UsageViewImpl.USAGE_COMPARATOR);
     final Usage nextToSelect = getNextToSelect(usageView, usages[usages.length - 1]);
@@ -42,7 +52,14 @@ public class RemoveUsageAction extends IncludeExcludeActionBase {
     }
   }
 
-  private Usage getNextToSelect(UsageView usageView, Usage toDelete) {
+  private static Usage[] getUsages(AnActionEvent context) {
+    UsageView usageView = context.getData(UsageView.USAGE_VIEW_KEY);
+    if (usageView == null) return Usage.EMPTY_ARRAY;
+    Usage[] usages = context.getData(UsageView.USAGES_KEY);
+    return usages == null ? Usage.EMPTY_ARRAY : usages;
+  }
+
+  private static Usage getNextToSelect(UsageView usageView, Usage toDelete) {
     List<Usage> sortedUsages = usageView.getSortedUsages();
     int curIndex = sortedUsages.indexOf(toDelete);
 
index 18b18d270ef7486d197daca5bbeca09303e516a9..0bc898a367e0cdfc8ce2819bd0ff9dce617c9471 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.find.FindManager;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.*;
 import com.intellij.ide.actions.CloseTabToolbarAction;
+import com.intellij.ide.actions.exclusion.ExclusionHandler;
 import com.intellij.navigation.NavigationItem;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
@@ -102,6 +103,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
   private final ExporterToTextFile myTextFileExporter = new ExporterToTextFile(this);
   private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
 
+  private final ExclusionHandler<Node> myExclusionHandler;
   private final UsageModelTracker myModelTracker;
   private final Map<Usage, UsageNode> myUsageNodes = new ConcurrentHashMap<Usage, UsageNode>();
   public static final UsageNode NULL_NODE = new UsageNode(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
@@ -274,6 +276,36 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
         return isDisposed || project.isDisposed();
       }
     },200);
+    myExclusionHandler = new ExclusionHandler<Node>() {
+      @Override
+      public boolean isNodeExcluded(@NotNull Node node) {
+        return node.isDataExcluded();
+      }
+
+      @Override
+      public void excludeNode(@NotNull Node node) {
+        final HashSet<Usage> usages = new HashSet<>();
+        collectUsages(node, usages);
+        excludeUsages(usages.toArray(new Usage[usages.size()]));
+      }
+
+      @Override
+      public void includeNode(@NotNull Node node) {
+        final HashSet<Usage> usages = new HashSet<>();
+        collectUsages(node, usages);
+        includeUsages(usages.toArray(new Usage[usages.size()]));
+      }
+
+      @Override
+      public boolean isActionEnabled(boolean isExcludeAction) {
+        return true;
+      }
+
+      @Override
+      public void onDone(boolean isExcludeAction) {
+
+      }
+    };
   }
 
   protected boolean searchHasBeenCancelled() {
@@ -1572,6 +1604,9 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
       else if (key == USAGE_VIEW_KEY) {
         sink.put(USAGE_VIEW_KEY, UsageViewImpl.this);
       }
+      else if (key == ExclusionHandler.EXCLUSION_HANDLER) {
+        sink.put(ExclusionHandler.EXCLUSION_HANDLER, myExclusionHandler);
+      }
 
       else if (key == CommonDataKeys.NAVIGATABLE_ARRAY) {
         sink.put(CommonDataKeys.NAVIGATABLE_ARRAY, getNavigatablesForNodes(getSelectedNodes()));