svn: Refactored "IntersectingLocalChangesPanel" - code simplified
authorKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Thu, 20 Oct 2016 11:43:17 +0000 (14:43 +0300)
committerKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Wed, 9 Nov 2016 20:53:59 +0000 (23:53 +0300)
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/IntersectingLocalChangesPanel.java

index e04f1b8edca7ba32773f10b2be3ed8076b8cd62f..81bfb5050550f46dffa5e440b6db689ce528ca4c 100644 (file)
  */
 package org.jetbrains.idea.svn.dialogs;
 
+import com.intellij.ide.DataManager;
 import com.intellij.ide.actions.EditSourceAction;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.CommonShortcuts;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.MultiLineLabelUI;
 import com.intellij.openapi.util.BooleanGetter;
@@ -25,122 +26,109 @@ import com.intellij.openapi.vcs.FilePath;
 import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode;
 import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNodeRenderer;
 import com.intellij.openapi.vcs.changes.ui.TreeModelBuilder;
-import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowId;
 import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.pom.Navigatable;
+import com.intellij.ui.TreeUIHelper;
+import com.intellij.ui.components.JBLabel;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentFactory;
-import com.intellij.ui.content.ContentManager;
-import com.intellij.util.ContentsUtil;
-import com.intellij.util.EditSourceOnDoubleClickHandler;
-import com.intellij.util.EditSourceOnEnterKeyHandler;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.components.BorderLayoutPanel;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreePath;
 import java.awt.*;
-import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
+
+import static com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray;
+import static com.intellij.util.ContentsUtil.addContent;
+import static com.intellij.util.containers.UtilKt.stream;
 
 public class IntersectingLocalChangesPanel {
-  private final JPanel myPanel;
-  private final String myText;
-  private final List<FilePath> myFilesToShow;
-  private final Project myProject;
-  private JTree myJTree;
 
-  public IntersectingLocalChangesPanel(final Project project, final List<FilePath> filesToShow, String text) {
+  @NotNull private final BorderLayoutPanel myPanel;
+  @NotNull private final List<FilePath> myFiles;
+  @NotNull private final Project myProject;
+
+  public IntersectingLocalChangesPanel(@NotNull Project project, @NotNull List<FilePath> files, @NotNull String text) {
     myProject = project;
-    myText = text;
-    myPanel = new MyPanel(new BorderLayout());
-    myFilesToShow = filesToShow;
-    initUI();
+    myFiles = files;
+    myPanel = createPanel(createLabel(text), createTree());
   }
 
-  private class MyPanel extends JPanel implements TypeSafeDataProvider {
-    private MyPanel(LayoutManager layout) {
-      super(layout);
-    }
-
-    public void calcData(DataKey key, DataSink sink) {
-      if (CommonDataKeys.NAVIGATABLE_ARRAY.equals(key)) {
-        final TreePath[] treePaths = myJTree.getSelectionModel().getSelectionPaths();
-        final List<Navigatable> navigatables = new ArrayList<>(treePaths.length);
-        for (TreePath treePath : treePaths) {
-          final List<FilePath> filePaths = ((ChangesBrowserNode)treePath.getLastPathComponent()).getAllFilePathsUnder();
-          for (FilePath filePath : filePaths) {
-            if (filePath.getVirtualFile() != null) {
-              navigatables.add(new OpenFileDescriptor(myProject, filePath.getVirtualFile()));
-            }
-          }
-        }
-        sink.put(key, navigatables.toArray(new Navigatable[navigatables.size()]));
+  @NotNull
+  private BorderLayoutPanel createPanel(@NotNull JLabel label, @NotNull JTree tree) {
+    BorderLayoutPanel panel = JBUI.Panels.simplePanel();
+
+    panel.setBackground(UIUtil.getTextFieldBackground());
+    panel.addToTop(label).addToCenter(tree);
+    new EditSourceAction().registerCustomShortcutSet(CommonShortcuts.getEditSource(), panel);
+
+    DataManager.registerDataProvider(panel, dataId -> {
+      if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) {
+        return getNavigatableArray(myProject, stream(tree.getSelectionPaths())
+          .map(TreePath::getLastPathComponent)
+          .map(node -> (ChangesBrowserNode<?>)node)
+          .flatMap(ChangesBrowserNode::getFilePathsUnderStream)
+          .map(FilePath::getVirtualFile)
+          .filter(Objects::nonNull)
+          .distinct());
       }
-    }
-  }
-
-  public JPanel getPanel() {
-    return myPanel;
-  }
 
-  private void initUI() {
-    final DefaultMutableTreeNode root = new DefaultMutableTreeNode();
+      return null;
+    });
 
-    myJTree = new JTree(root);
-    myJTree.setRootVisible(false);
-    myJTree.setShowsRootHandles(false);
-    myJTree.setCellRenderer(new ChangesBrowserNodeRenderer(myProject, BooleanGetter.TRUE, false));
+    return panel;
+  }
 
-    TreeModelBuilder builder = new TreeModelBuilder(myProject, true);
-    final DefaultTreeModel treeModel = builder.buildModelFromFilePaths(myFilesToShow);
-    myJTree.setModel(treeModel);
+  @NotNull
+  private SimpleTree createTree() {
+    SimpleTree tree = new SimpleTree(new TreeModelBuilder(myProject, true).buildModelFromFilePaths(myFiles)) {
+      @Override
+      protected void configureUiHelper(@NotNull TreeUIHelper helper) {
+        super.configureUiHelper(helper);
+        helper.installEditSourceOnDoubleClick(this);
+        helper.installEditSourceOnEnterKeyHandler(this);
+      }
+    };
+    tree.setRootVisible(false);
+    tree.setShowsRootHandles(false);
+    tree.setCellRenderer(new ChangesBrowserNodeRenderer(myProject, BooleanGetter.TRUE, false));
 
-    myJTree.expandPath(new TreePath(root.getPath()));
+    return tree;
+  }
 
-    final JLabel label = new JLabel(myText) {
+  @NotNull
+  private static JBLabel createLabel(@NotNull String text) {
+    JBLabel label = new JBLabel(text) {
       @Override
       public Dimension getPreferredSize() {
-        final Dimension superValue = super.getPreferredSize();
-        return new Dimension((int) superValue.getWidth(), (int) (superValue.getHeight() * 1.7));
+        Dimension size = super.getPreferredSize();
+        return new Dimension(size.width, (int)(size.height * 1.7));
       }
     };
     label.setUI(new MultiLineLabelUI());
     label.setBackground(UIUtil.getTextFieldBackground());
-    label.setVerticalTextPosition(JLabel.TOP);
-    myPanel.setBackground(UIUtil.getTextFieldBackground());
-    myPanel.add(label, BorderLayout.NORTH);
-    myPanel.add(myJTree, BorderLayout.CENTER);
-
-    EditSourceOnDoubleClickHandler.install(myJTree);
-    EditSourceOnEnterKeyHandler.install(myJTree);
-    
-    final EditSourceAction editSourceAction = new EditSourceAction();
-    editSourceAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), myPanel);
-  }
+    label.setVerticalTextPosition(SwingConstants.TOP);
 
-  private Component getPrefferedFocusComponent() {
-    return myJTree;
+    return label;
   }
 
-  public static void showInVersionControlToolWindow(final Project project, final String title, final List<FilePath> filesToShow,
-                                                    final String prompt) {
-    final IntersectingLocalChangesPanel component = new IntersectingLocalChangesPanel(project, filesToShow, prompt);
-
+  @SuppressWarnings("SameParameterValue")
+  public static void showInVersionControlToolWindow(@NotNull Project project,
+                                                    @NotNull String title,
+                                                    @NotNull List<FilePath> files,
+                                                    @NotNull String prompt) {
+    IntersectingLocalChangesPanel intersectingPanel = new IntersectingLocalChangesPanel(project, files, prompt);
+    Content content = ContentFactory.SERVICE.getInstance().createContent(intersectingPanel.myPanel, title, true);
     ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS);
-    final ContentManager contentManager = toolWindow.getContentManager();
-
-    Content content = ContentFactory
-      .SERVICE.getInstance().createContent(component.getPanel(), title, true);
-    ContentsUtil.addContent(contentManager, content, true);
-    toolWindow.activate(new Runnable() {
-      public void run() {
-        IdeFocusManager.getInstance(project).requestFocus(component.getPrefferedFocusComponent(), true);
-      }
-    });
 
+    addContent(toolWindow.getContentManager(), content, true);
+    toolWindow.activate(null);
   }
 }