switcher - actions for simplw tool windows
authorKirill Kalishev <kirill.kalishev@jetbrains.com>
Tue, 27 Apr 2010 12:44:46 +0000 (16:44 +0400)
committerKirill Kalishev <kirill.kalishev@jetbrains.com>
Tue, 27 Apr 2010 12:44:46 +0000 (16:44 +0400)
platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java
platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java
platform/lang-impl/src/com/intellij/ide/todo/TodoPanel.java
platform/platform-api/src/com/intellij/openapi/actionSystem/ActionToolbar.java
platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java
platform/platform-api/src/com/intellij/ui/switcher/QuickActionManager.java
platform/platform-api/src/com/intellij/ui/switcher/SwitchingSession.java
platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java
plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java

index 704a3c3f9077d538b5c876d23674d11465a90b52..bc6f7554e463cbc1946ea6eff1f3be002fba0066 100644 (file)
@@ -196,7 +196,7 @@ public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel impleme
   public Object getData(@NonNls final String dataId) {
       if (LangDataKeys.PSI_ELEMENT.is(dataId)) {
       final PsiElement anElement = getSelectedElement();
-      return anElement != null && anElement.isValid() ? anElement : null;
+      return anElement != null && anElement.isValid() ? anElement : super.getData(dataId);
     }
     if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
       return getSelectedElements();
@@ -214,7 +214,7 @@ public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel impleme
     if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) {
       return getNavigatables();
     }
-    return null;
+    return super.getData(dataId);
   }
 
   private final class CloseAction extends CloseTabToolbarAction {
index 410ea91a87cdc7b32f3d0c40e69e96de867bb416..d7790f098fc9559055359f2671b5f52bd9b214ec 100644 (file)
@@ -77,6 +77,8 @@ import com.intellij.ui.AutoScrollToSourceHandler;
 import com.intellij.ui.GuiUtils;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentManager;
+import com.intellij.ui.switcher.QuickAccessProvider;
+import com.intellij.ui.switcher.QuickActionProvider;
 import com.intellij.util.Alarm;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IJSwingUtilities;
@@ -113,7 +115,7 @@ import java.util.List;
       file = "$WORKSPACE_FILE$"
     )}
 )
-public final class ProjectViewImpl extends ProjectView implements PersistentStateComponent<Element>, Disposable {
+public final class ProjectViewImpl extends ProjectView implements PersistentStateComponent<Element>, Disposable, QuickActionProvider {
   private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.ProjectViewImpl");
   private final CopyPasteDelegator myCopyPasteDelegator;
   private boolean isInitialized;
@@ -285,13 +287,96 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat
     myTopPanel.add(myActionGroupPanel, new GridBagConstraints(1, 0, 1, 1, 0.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
 
     myViewContentPanel = new JPanel();
-    myPanel = new SimpleToolWindowPanel(true);
+    myPanel = new SimpleToolWindowPanel(true).setProvideQuickActions(false);
     myPanel.setToolbar(myTopPanel);
     myPanel.setContent(myViewContentPanel);
 
     myPanel.setBorder(new ToolWindow.Border(true, false, false, false));
   }
 
+  public String getName() {
+    return "Project";
+  }
+
+  public List<AnAction> getActions(boolean originalProvider) {
+    ArrayList<AnAction> result = new ArrayList<AnAction>();
+
+    DefaultActionGroup views = new DefaultActionGroup("Change View", true);
+    boolean lastWasHeader = false;
+    boolean lastHeaderHadKids = false;
+    for (int i = 0; i < myCombo.getModel().getSize(); i++) {
+      Object each = myCombo.getModel().getElementAt(i);
+      if (each instanceof Pair) {
+        Pair<String, String> eachPair = (Pair<String, String>)each;
+
+        if (eachPair.getSecond() == null) {
+          if (lastHeaderHadKids) {
+            views.add(new Separator());
+          } else {
+            if (i + 1 < myCombo.getModel().getSize()) {
+              Object next = myCombo.getModel().getElementAt(i + 1);
+              if (next instanceof Pair) {
+                if (((Pair)next).getSecond() != null) {
+                  views.add(new Separator());
+                }
+              }
+            }
+          }
+        } else {
+          lastHeaderHadKids = true;
+        }
+
+        lastWasHeader = eachPair.getSecond() == null;
+
+        views.add(new ChangeViewAction(eachPair.getFirst(), eachPair.getSecond()));
+      }
+    }
+    result.add(views);
+    result.add(new Separator());
+
+
+    ArrayList<AnAction> secondary = new ArrayList<AnAction>();
+    if (myActionGroup != null) {
+      AnAction[] kids = myActionGroup.getChildren(null);
+      for (AnAction each : kids) {
+        if (myActionGroup.isPrimary(each)) {
+          result.add(each);
+        } else {
+          secondary.add(each);
+        }
+      }
+    }
+    result.add(new Separator());
+    result.addAll(secondary);
+
+    return result;
+  }
+
+  private class ChangeViewAction extends AnAction {
+    private String myId;
+    private String mySubId;
+
+    private ChangeViewAction(String id, String subId) {
+      myId = id;
+      mySubId = subId;
+    }
+
+    @Override
+    public void update(AnActionEvent e) {
+      AbstractProjectViewPane pane = getProjectViewPaneById(myId);
+      e.getPresentation().setText(pane.getTitle() + (mySubId != null ? (" - " + pane.getPresentableSubIdName(mySubId)) : ""));
+    }
+
+    @Override
+    public void actionPerformed(AnActionEvent e) {
+      changeView(myId, mySubId);
+    }
+  }
+
+  public boolean isCycleRoot() {
+    return false;
+  }
+
   public synchronized void addProjectPane(final AbstractProjectViewPane pane) {
     myUninitializedPanes.add(pane);
     SelectInTarget selectInTarget = pane.createSelectInTarget();
@@ -740,7 +825,7 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat
     myConnection.disconnect();
   }
 
-  private JComponent getComponent() {
+  public JComponent getComponent() {
     return myDataProvider;
   }
 
@@ -1084,6 +1169,11 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat
         final List<NamedLibraryElement> selectedElements = getSelectedElements(NamedLibraryElement.class);
         return selectedElements.isEmpty() ? null : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]);
       }
+
+      if (QuickActionProvider.KEY.is(dataId)) {
+        return ProjectViewImpl.this;
+      }
+
       return null;
     }
 
index 9a73e95bba400fc98cbb9226590be22d1ab6de89..3e04fe510da3ae01b303dbad8de07813a6c631ae 100644 (file)
@@ -672,7 +672,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
     if (PlatformDataKeys.HELP_ID.is(dataId)) {
       return getHelpID();
     }
-    return null;
+    return super.getData(dataId);
   }
 
   private static PsiElement[] convertToPsiElementsArray(final Object[] selectedElements) {
index b971bf6f6f7c431914c94968cb837e0fbc06b61a..67cd629755094ec76ac66cfe280fefb67986d8ae 100644 (file)
@@ -326,7 +326,7 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig
       //noinspection HardCodedStringLiteral
       return "find.todoList";
     }
-    return null;
+    return super.getData(dataId);
   }
 
   @Nullable
index 42ad8821c69fb4118c1beb91320f882ce4719760..8eaf5ed38430bc923f3cb78b62026754a102d9bb 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.openapi.actionSystem;
 
+import com.intellij.ui.switcher.QuickActionProvider;
 import com.intellij.ui.switcher.SwitchProvider;
 import org.jetbrains.annotations.NotNull;
 
@@ -26,7 +27,7 @@ import java.awt.*;
  *
  * @see ActionManager#createActionToolbar(String, ActionGroup, boolean)
  */
-public interface ActionToolbar extends SwitchProvider {
+public interface ActionToolbar extends SwitchProvider, QuickActionProvider {
   /**
    * This is default layout policy for the toolbar. It defines that
    * all toolbar component are in one row / column and they are not wrapped
index 2b6417d7f9ca48b589dcea66d3d431697dc0a043..bf45c5f64da1bcdb9747c89973984be877598a19 100644 (file)
  */
 package com.intellij.openapi.ui;
 
+import com.intellij.openapi.actionSystem.ActionToolbar;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DataProvider;
+import com.intellij.openapi.actionSystem.Separator;
+import com.intellij.openapi.util.Ref;
+import com.intellij.ui.switcher.QuickActionProvider;
+import com.intellij.util.ui.AwtVisitor;
 import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NonNls;
 
 import javax.swing.*;
 import java.awt.*;
+import java.util.*;
+import java.util.List;
 
-public class SimpleToolWindowPanel extends JPanel {
+public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider, DataProvider {
 
   private JComponent myToolbar;
   private JComponent myContent;
 
   private boolean myBorderless;
   private boolean myVertical;
+  private boolean myProvideQuickActions;
 
   public SimpleToolWindowPanel(boolean vertical) {
     this(vertical, false);
@@ -36,6 +47,7 @@ public class SimpleToolWindowPanel extends JPanel {
     setLayout(new BorderLayout(vertical ? 0 : 1, vertical ? 1 : 0));
     myBorderless = borderless;
     myVertical = vertical;
+    setProvideQuickActions(true);
   }
 
   public void setToolbar(JComponent c) {
@@ -55,6 +67,45 @@ public class SimpleToolWindowPanel extends JPanel {
     repaint();
   }
 
+  public Object getData(@NonNls String dataId) {
+    return QuickActionProvider.KEY.is(dataId) && myProvideQuickActions ? this : null;
+  }
+
+  public SimpleToolWindowPanel setProvideQuickActions(boolean provide) {
+    myProvideQuickActions = provide;
+    return this;
+  }
+
+  public List<AnAction> getActions(boolean originalProvider) {
+    final Ref<ActionToolbar> toolbar = new Ref<ActionToolbar>();
+    if (myToolbar != null) {
+      new AwtVisitor(myToolbar) {
+        @Override
+        public boolean visit(Component component) {
+          if (component instanceof ActionToolbar) {
+            toolbar.set((ActionToolbar)component);
+            return true;
+          }
+          return false;
+        }
+      };
+    }
+
+    if (toolbar.get() != null) {
+      return toolbar.get().getActions(originalProvider);
+    }
+
+    return null;
+  }
+
+  public JComponent getComponent() {
+    return this;
+  }
+
+  public boolean isCycleRoot() {
+    return false;
+  }
+
   public void setContent(JComponent c) {
     myContent = c;
     add(c, BorderLayout.CENTER);
index a792fa72c6fcf7fc4f27a87cdf1c6814a24cd814..458041b6e189e7ba4291a7cac8eae4432db87cec 100644 (file)
@@ -68,37 +68,38 @@ public class QuickActionManager implements ProjectComponent {
         if (provider == null) return;
 
         List<AnAction> actions = provider.getActions(true);
-        DefaultActionGroup group = new DefaultActionGroup();
-        for (AnAction each : actions) {
-          group.add(each);
-        }
-
-        boolean firstParent = true;
-        Component eachParent = provider.getComponent().getParent();
-        while (eachParent != null) {
-          if (eachParent instanceof QuickActionProvider) {
-            QuickActionProvider eachProvider = (QuickActionProvider)eachParent;
-            if (firstParent) {
-              group.addSeparator();
-              firstParent = false;
-            }
-            List<AnAction> eachActionList = eachProvider.getActions(false);
-            if (eachActionList.size() > 0) {
-              group.add(new Group(eachActionList, eachProvider.getName()));
-            }
-            if (eachProvider.isCycleRoot()) break;
-
+        if (actions != null) {
+          DefaultActionGroup group = new DefaultActionGroup();
+          for (AnAction each : actions) {
+            group.add(each);
           }
-          eachParent = eachParent.getParent();
-        }
 
-        JBPopupFactory.getInstance()
-          .createActionGroupPopup(null, group, context, JBPopupFactory.ActionSelectionAid.ALPHA_NUMBERING, true, new Runnable() {
-            public void run() {
-              myActiveProvider = null;
+          boolean firstParent = true;
+          Component eachParent = provider.getComponent().getParent();
+          while (eachParent != null) {
+            if (eachParent instanceof QuickActionProvider) {
+              QuickActionProvider eachProvider = (QuickActionProvider)eachParent;
+              if (firstParent) {
+                group.addSeparator();
+                firstParent = false;
+              }
+              List<AnAction> eachActionList = eachProvider.getActions(false);
+              if (eachActionList.size() > 0) {
+                group.add(new Group(eachActionList, eachProvider.getName()));
+              }
+              if (eachProvider.isCycleRoot()) break;
+
             }
-          }, -1).showInFocusCenter();
+            eachParent = eachParent.getParent();
+          }
 
+          JBPopupFactory.getInstance()
+            .createActionGroupPopup(null, group, context, JBPopupFactory.ActionSelectionAid.ALPHA_NUMBERING, true, new Runnable() {
+              public void run() {
+                myActiveProvider = null;
+              }
+            }, -1).showInFocusCenter();
+        }
       }
     });
 
index dc9186a5c4db4d606998d1205b21a0bfda831838..37456b5f902bcf41998eface639d8e5b0214c8d6 100644 (file)
@@ -40,7 +40,7 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
   private SwitchProvider myProvider;
   private KeyEvent myInitialEvent;
   private boolean myFinished;
-  private java.util.List<SwitchTarget> myTargets;
+  private LinkedHashSet<SwitchTarget> myTargets = new LinkedHashSet<SwitchTarget>();
   private IdeGlassPane myGlassPane;
 
   private Map<SwitchTarget, TargetPainer> myPainters = new Hashtable<SwitchTarget, TargetPainer>();
@@ -58,7 +58,7 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
     KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
 
 
-    myTargets = myProvider.getTargets(true, true);
+    myTargets.addAll(myProvider.getTargets(true, true));
 
     Component eachParent = myProvider.getComponent();
     eachParent = eachParent.getParent();
@@ -193,6 +193,8 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
   }
 
   private void setSelection(SwitchTarget target) {
+    if (target == null) return;
+
     mySelection = target;
 
     mySelectionWasMoved = !mySelection.equals(myStartSelection);
@@ -321,19 +323,15 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
       }
     }
 
-    return distance.values().iterator().next();
-  }
 
-  private void selectNext() {
-    int index = myTargets.indexOf(getSelection());
+    if (myTargets.size() == 0) return null;
+
+    List<SwitchTarget> all = Arrays.asList(myTargets.toArray(new SwitchTarget[myTargets.size()]));
+    int index = all.indexOf(getSelection());
     if (index + 1 < myTargets.size()) {
-      mySelection = myTargets.get(index + 1);
+      return all.get(index + 1);
     } else {
-      mySelection = myTargets.get(0);
-    }
-
-    for (TargetPainer each : myPainters.values()) {
-      each.setNeedsRepaint(true);
+      return all.get(0);
     }
   }
 
index 4da503448e81c79239a0399a0d36990028cd2ed9..e28a2cc22f862d6140d8a8a0ab8b670f5923ee72 100644 (file)
@@ -1036,4 +1036,24 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
   public boolean isCycleRoot() {
     return false;
   }
+
+  public List<AnAction> getActions(boolean originalProvider) {
+    ArrayList<AnAction> result = new ArrayList<AnAction>();
+
+    ArrayList<AnAction> secondary = new ArrayList<AnAction>();
+    if (myActionGroup != null) {
+      AnAction[] kids = myActionGroup.getChildren(null);
+      for (AnAction each : kids) {
+        if (myActionGroup.isPrimary(each)) {
+          result.add(each);
+        } else {
+          secondary.add(each);
+        }
+      }
+    }
+    result.add(new Separator());
+    result.addAll(secondary);
+
+    return result;
+  }
 }
index 8d850cc6525419b76f0c96fa64e6cc7f9fa0920d..38ebad57599a89e686f15cdb2d93b6c04a0a4e55 100644 (file)
@@ -471,7 +471,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider {
       }
       return VfsUtil.toVirtualFileArray(result);
     }
-    return null;
+    return super.getData(dataId);
   }
 
   public static FileChooserDescriptor createXmlDescriptor() {
index 21742f9e75455511aa8aec22d0f25fc3058e98d6..4b7e3ac1d98e273e61d6cc9844d74e91fd5d9f73 100644 (file)
@@ -115,7 +115,7 @@ public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implement
 
     if (MavenDataKeys.MAVEN_DEPENDENCIES.is(dataId)) return extractDependencies();
 
-    return null;
+    return super.getData(dataId);
   }
 
   private VirtualFile extractVirtualFile() {