IDEA-127739 Navigation Tab
authorVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Wed, 3 Sep 2014 19:31:50 +0000 (23:31 +0400)
committerVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Wed, 3 Sep 2014 19:33:03 +0000 (23:33 +0400)
Stage 4 mock gear actions

platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java
platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java

index 2dd2ee50d12012d401e91655ba94985e974516ed..191c8c01ce32b45b9d9918c45148c39c12a648cb 100644 (file)
@@ -41,6 +41,11 @@ public final class Separator extends AnAction implements DumbAware {
     return ourInstance;
   }
 
+  @Override
+  public String toString() {
+    return "Separator (" + myText + ")";
+  }
+
   @Override
   public void actionPerformed(AnActionEvent e){
     throw new UnsupportedOperationException();
index 85c0555f9bc6756c328eed4263eed7a516ab6815..9af1d30c28bf4e7e7a555dfa7fd4a1f8fd4a35c5 100644 (file)
@@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.ActionCallback;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
@@ -164,7 +165,7 @@ public class Utils{
         }
       }
       else if (child instanceof Separator) {
-        if (!list.isEmpty() && !(list.get(list.size() - 1) instanceof Separator)) {
+        if (!StringUtil.isEmpty(((Separator)child).getText()) || (!list.isEmpty() && !(list.get(list.size() - 1) instanceof Separator))) {
           list.add(child);
         }
       }
@@ -284,8 +285,10 @@ public class Utils{
     for (int i = 0, size = list.size(); i < size; i++) {
       final AnAction action = list.get(i);
       if (action instanceof Separator) {
-        if (i > 0 && i < size - 1) {
+        final String text = ((Separator)action).getText();
+        if (!StringUtil.isEmpty(text) || (i > 0 && i < size - 1)) {
           component.add(new JPopupMenu.Separator() {
+            private final JMenuItem myMenu = !StringUtil.isEmpty(text) ? new JMenuItem(text) : null;
             @Override
             public Insets getInsets() {
               final Insets insets = super.getInsets();
@@ -295,13 +298,30 @@ public class Utils{
               return fix ? new Insets(2, insets.left, 3, insets.right) : insets;  // workaround for Sun bug #6636964
             }
 
+            @Override
+            public void doLayout() {
+              super.doLayout();
+              if (myMenu != null) {
+                myMenu.setBounds(getBounds());
+              }
+            }
+
             @Override
             protected void paintComponent(Graphics g) {
               if (UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderDarcula() || UIUtil.isUnderWindowsLookAndFeel()) {
                 g.setColor(component.getBackground());
                 g.fillRect(0, 0, getWidth(), getHeight());
               }
-              super.paintComponent(g);
+              if (myMenu != null) {
+                myMenu.paint(g);
+              } else {
+                super.paintComponent(g);
+              }
+            }
+
+            @Override
+            public Dimension getPreferredSize() {
+              return myMenu != null ? myMenu.getPreferredSize() : super.getPreferredSize();
             }
           });
         }
index 06a3966ade1d04ce15b1dcbe3161fe507425427c..c1515a817b2681237bf9b74577e3c99fe58948e4 100644 (file)
@@ -701,6 +701,7 @@ public class EditorWindow {
 
   public void setEditor(@Nullable final EditorWithProviderComposite editor, final boolean selectEditor, final boolean focusEditor) {
     if (editor != null) {
+      onBeforeSetEditor(editor.getFile());
       if (myTabbedPane == null) {
         myPanel.removeAll ();
         myPanel.add (new TCompForTablessMode(this, editor), BorderLayout.CENTER);
@@ -741,6 +742,9 @@ public class EditorWindow {
     myOwner.validate();
   }
 
+  protected void onBeforeSetEditor(VirtualFile file) {
+  }
+
   private boolean splitAvailable() {
     return getTabCount() >= 1;
   }
index fa0a4dbd6fe4b9a346d1613468c488d8db77b9b4..b0f274e9e5a428cc7e7ec89518bb214fdd610a42 100644 (file)
@@ -614,10 +614,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
 
   public void createCurrentWindow() {
     LOG.assertTrue(myCurrentWindow == null);
-    setCurrentWindow(new EditorWindow(this));
+    setCurrentWindow(createEditorWindow());
     add(myCurrentWindow.myPanel, BorderLayout.CENTER);
   }
 
+  protected EditorWindow createEditorWindow() {
+    return new EditorWindow(this);
+  }
+
   /**
    * sets the window passed as a current ('focused') window among all splitters. All file openings will be done inside this
    * current window
@@ -832,7 +836,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
       UIUtil.invokeAndWaitIfNeeded(new Runnable() {
         @Override
         public void run() {
-          windowRef.set(context == null ? new EditorWindow(EditorsSplitters.this) : findWindowWith(context));
+          windowRef.set(context == null ? createEditorWindow() : findWindowWith(context));
         }
       });
       final EditorWindow window = windowRef.get();
index 1cedbd8c3c006d50ccb55fa9d588a1da6dd1cca0..c0135f98dfea5fb7bac3981bbbbc301ebb66527e 100644 (file)
@@ -58,7 +58,6 @@ import com.intellij.openapi.vcs.FileStatusListener;
 import com.intellij.openapi.vcs.FileStatusManager;
 import com.intellij.openapi.vfs.*;
 import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.ToolWindowId;
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.openapi.wm.WindowManager;
 import com.intellij.openapi.wm.ex.StatusBarEx;
@@ -91,7 +90,6 @@ import java.beans.PropertyChangeListener;
 import java.lang.ref.WeakReference;
 import java.util.*;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * @author Anton Katilin
@@ -113,7 +111,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
   private final Project myProject;
   private final List<Pair<VirtualFile, EditorWindow>> mySelectionHistory = new ArrayList<Pair<VirtualFile, EditorWindow>>();
   private WeakReference<EditorComposite> myLastSelectedComposite = new WeakReference<EditorComposite>(null);
-  private final AtomicBoolean myPreviewBlocker = new AtomicBoolean(false);
 
 
   private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null);
@@ -181,8 +178,9 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
     HashSet<EditorsSplitters> all = new LinkedHashSet<EditorsSplitters>();
     if (PreviewPanel.isAvailable()) {
       initUI();
-      if (!myProject.isDisposed()) {
-        all.add(myPreviewPanel.getWindow().getOwner());
+      EditorWindow window = myPreviewPanel.getWindow();
+      if (window != null) {
+        all.add(window.getOwner());
       }
     }
     all.add(getMainSplitters());
@@ -644,7 +642,8 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
     }
 
     if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) {
-      EditorWindow previewWindow = getPreviewWindow(file, focusEditor, searchForSplitter);
+      initUI();
+      EditorWindow previewWindow = myPreviewPanel.getWindow();
       if (previewWindow != null) {
         wndToOpenIn = previewWindow;
       }
@@ -660,31 +659,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
     return openFileImpl2(wndToOpenIn, file, focusEditor);
   }
 
-  @Nullable
-  private EditorWindow getPreviewWindow(@NotNull VirtualFile virtualFile, final boolean focusEditor, final boolean searchForSplitter) {
-    EditorWindow wndToOpenIn = null;
-    if (PreviewPanel.isAvailable() && !myPreviewBlocker.get()) {
-      wndToOpenIn = myPreviewPanel.getWindow();
-      if (myPreviewPanel.hasCurrentFile(virtualFile)) return wndToOpenIn;
-      final VirtualFile modifiedFile = myPreviewPanel.getCurrentModifiedFile();
-      ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).activate(null, false);
-      if (modifiedFile != null) {
-        CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
-          @Override
-          public void run() {
-            myPreviewBlocker.set(true);
-            try {
-              openFileWithProviders(modifiedFile, focusEditor, searchForSplitter);
-            } finally {
-              myPreviewBlocker.set(false);
-            }
-          }
-        }, "", null);
-      }
-    }
-    return wndToOpenIn;
-  }
-
   public Pair<FileEditor[], FileEditorProvider[]> openFileInNewWindow(@NotNull VirtualFile file) {
     return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this);
   }
index ade7001fc27949a3a723ea4b3429f81fb1d92589..1c9af86cd12a1f5762368037b0761d7a69345b74 100644 (file)
@@ -17,8 +17,11 @@ package com.intellij.openapi.fileEditor.impl;
 
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.ui.UISettings;
+import com.intellij.ide.ui.UISettingsListener;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.ToggleAction;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.FileEditorManagerListener;
@@ -41,8 +44,11 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 import java.awt.*;
 import java.util.ArrayList;
+import java.util.EnumSet;
 
 class PreviewPanel extends JPanel {
+  enum ContentType {Files, Usages, Diagrams, Documentation}
+
   private static final Key<VirtualFile> FILE_KEY = Key.create("v_file");
   private static final int HISTORY_LIMIT = 10;
 
@@ -57,6 +63,9 @@ class PreviewPanel extends JPanel {
   private VirtualFile myAwaitingForOpen = null;
   private ContentManager myContentManager;
   private Content myStubContent;
+  private boolean myBlocked = false;
+
+  private EnumSet<ContentType> myTypes = EnumSet.noneOf(ContentType.class);
 
   static boolean isAvailable() {
     return UISettings.getInstance().NAVIGATE_TO_PREVIEW;
@@ -68,28 +77,37 @@ class PreviewPanel extends JPanel {
     myDockManager = dockManager;
   }
 
-  // package-private API
-
+  /*
+  * @return null if preview is not avalable
+   */
+  @Nullable
   EditorWindow getWindow() {
+    if (!isAvailable() || isBlocked() || myProject.isDisposed()) return null;
     initToolWindowIfNeed();
     return myWindow;
   }
 
-  boolean hasCurrentFile(@NotNull VirtualFile file) {
-    return file.equals(getCurrentFile());
-  }
-
-  @Nullable
-  VirtualFile getCurrentModifiedFile() {
-    VirtualFile file = getCurrentFile();
-    return file != null && file.equals(myModifiedFile) ? file : null;
+  boolean isBlocked() {
+    return myBlocked;
   }
 
   private void initToolWindowIfNeed() {
-    if (ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW) != null) return;
+    if (!isAvailable() || ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW) != null) return;
 
     myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject)
       .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false);
+    UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
+      @Override
+      public void uiSettingsChanged(UISettings source) {
+        if (!isAvailable()) {
+          VirtualFile[] files = myWindow.getFiles();
+          for (VirtualFile file : files) {
+            close(file);
+          }
+          ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.PREVIEW);
+        }
+      }
+    }, myProject);
     myToolWindow.setIcon(AllIcons.Actions.PreviewDetails);
     myToolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null);
     myContentManager = myToolWindow.getContentManager();
@@ -147,6 +165,11 @@ class PreviewPanel extends JPanel {
     setLayout(new GridLayout(1, 1));
     add(myEditorsSplitters);
     myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction());
+    ArrayList<AnAction> myGearActions = new ArrayList<AnAction>();
+    for (ContentType contentType : ContentType.values()) {
+      myGearActions.add(new ContentTypeToggleAction(contentType));
+    }
+    myToolWindow.setAdditionalGearActions(new DefaultActionGroup("Preview", myGearActions));
     myToolWindow.hide(null);
   }
 
@@ -204,7 +227,7 @@ class PreviewPanel extends JPanel {
         @Override
         public void run() {
           if (myContentManager.getIndexOfContent(myStubContent) != -1) {
-            ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null);
+            toggleToolWindow(false);
           }
         }
       });
@@ -224,6 +247,13 @@ class PreviewPanel extends JPanel {
       myAwaitingForOpen = null;
     }
     if (file.equals(myModifiedFile)) {
+      myBlocked = true;
+      try {
+        myManager.openFileWithProviders(myModifiedFile, false, true);
+      }
+      finally {
+        myBlocked = false;
+      }
       myModifiedFile = null;
     }
     Content content = getContent(file);
@@ -233,9 +263,22 @@ class PreviewPanel extends JPanel {
     }
   }
 
+  private void toggleToolWindow(boolean activate) {
+    ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW);
+    if (toolWindow != null) {
+      if (activate) {
+        toolWindow.activate(null, false);
+      }
+      else {
+        toolWindow.hide(null);
+      }
+    }
+  }
+
   private class MoveToEditorTabsAction extends AnAction {
+
     public MoveToEditorTabsAction() {
-      super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed);
+      super("Move to main tabs", "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed);
     }
 
     @Override
@@ -252,14 +295,14 @@ class PreviewPanel extends JPanel {
       }
       myManager.openFileWithProviders(virtualFile, true, window);
       close(virtualFile);
-      ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null);
+      toggleToolWindow(false);
     }
   }
 
 
   private class CloseFileAction extends AnAction {
     public CloseFileAction() {
-      super(null, "Close", AllIcons.Actions.Close);
+      super("Close", "Close", AllIcons.Actions.Close);
     }
 
     @Override
@@ -267,6 +310,30 @@ class PreviewPanel extends JPanel {
       for (VirtualFile file : myHistory.toArray(new VirtualFile[myHistory.size()])) {
         close(file);
       }
+      toggleToolWindow(false);
+    }
+  }
+
+  private class ContentTypeToggleAction extends ToggleAction {
+    private final ContentType myContentType;
+
+    ContentTypeToggleAction(ContentType contentType) {
+      super(contentType.toString());
+      myContentType = contentType;
+    }
+
+    @Override
+    public boolean isSelected(AnActionEvent e) {
+      return myTypes.contains(myContentType);
+    }
+
+    @Override
+    public void setSelected(AnActionEvent e, boolean state) {
+      if (state) {
+        myTypes.add(myContentType);
+      } else {
+        myTypes.remove(myContentType);
+      }
     }
   }
 
@@ -296,6 +363,28 @@ class PreviewPanel extends JPanel {
       }
     }
 
+    @Override
+    protected EditorWindow createEditorWindow() {
+      return new EditorWindow(this) {
+        @Override
+        protected void onBeforeSetEditor(VirtualFile file) {
+          VirtualFile currentFile = getCurrentFile();
+          if (currentFile != null && currentFile.equals(myModifiedFile)) {
+            myBlocked = true;
+            try {
+              myManager.openFileWithProviders(myModifiedFile, false, true);
+            }
+            finally {
+              myBlocked = false;
+            }
+          }
+          else {
+            toggleToolWindow(true);
+          }
+        }
+      };
+    }
+
     @Override
     public void setTabsPlacement(int tabPlacement) {
       super.setTabsPlacement(UISettings.TABS_NONE);
index e6c84f5e77683cbce459bbcd9d6f30c8dbc5b364..17acd7d1ee6646b4cffec4b328abd49558a92a3f 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.openapi.ui.Splitter;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.wm.*;
 import com.intellij.ui.Gray;
 import com.intellij.ui.JBColor;
@@ -447,6 +448,10 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa
         }
       }
     }
+    String separatorText = group.getTemplatePresentation().getText();
+    if (children.length > 0 && !StringUtil.isEmpty(separatorText)) {
+      main.addAction(new Separator(separatorText), Constraints.FIRST);
+    }
   }
 
   /**