diff options
Diffstat (limited to 'platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui')
3 files changed, 38 insertions, 221 deletions
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java deleted file mode 100644 index dd72da957fa2..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2000-2012 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.openapi.roots.libraries.ui.impl; - -import com.intellij.ui.CheckboxTree; -import com.intellij.ui.CheckedTreeNode; -import com.intellij.ui.ClickListener; -import com.intellij.ui.dualView.TreeTableView; -import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; -import com.intellij.ui.treeStructure.treetable.TreeTableTree; -import com.intellij.util.ui.ColumnInfo; -import com.intellij.util.ui.tree.TreeUtil; -import org.jetbrains.annotations.NotNull; - -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; -import java.awt.*; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Enumeration; - -/** - * @author nik - */ -public class CheckboxTreeTable extends TreeTableView { - public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) { - super(new ListTreeTableModelOnColumns(root, columns)); - initTree(getTree(), renderer); - } - - //todo[nik] I hate to copy-paste but have to copy the code below from CheckboxTreeBase to support CheckboxTree inside TreeTable in IDEA 11.1.x branch - //todo[nik] I solemnly swear to get rid of this code in IDEA 12 branch - private void initTree(final TreeTableTree tree, final CheckboxTree.CheckboxTreeCellRenderer cellRenderer) { - tree.setCellRenderer(cellRenderer); - tree.setRootVisible(false); - tree.setShowsRootHandles(true); - tree.setLineStyleAngled(); - TreeUtil.installActions(tree); - - new ClickListener() { - @Override - public boolean onClick(@NotNull MouseEvent e, int clickCount) { - int row = tree.getRowForLocation(e.getX(), e.getY()); - if (row < 0) return false; - final Object o = tree.getPathForRow(row).getLastPathComponent(); - if (!(o instanceof CheckedTreeNode)) return false; - Rectangle rowBounds = tree.getRowBounds(row); - cellRenderer.setBounds(rowBounds); - Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); - checkBounds.setLocation(rowBounds.getLocation()); - - if (checkBounds.height == 0) checkBounds.height = rowBounds.height; - - final CheckedTreeNode node = (CheckedTreeNode)o; - if (checkBounds.contains(e.getPoint())) { - if (node.isEnabled()) { - toggleNode(node); - tree.setSelectionRow(row); - return true; - } - } - - return false; - } - }.installOn(this); - - addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (isToggleEvent(e)) { - TreePath treePath = tree.getLeadSelectionPath(); - if (treePath == null) return; - final Object o = treePath.getLastPathComponent(); - if (!(o instanceof CheckedTreeNode)) return; - CheckedTreeNode firstNode = (CheckedTreeNode)o; - boolean checked = toggleNode(firstNode); - - TreePath[] selectionPaths = tree.getSelectionPaths(); - for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) { - final TreePath selectionPath = selectionPaths[i]; - final Object o1 = selectionPath.getLastPathComponent(); - if (!(o1 instanceof CheckedTreeNode)) continue; - CheckedTreeNode node = (CheckedTreeNode)o1; - checkNode(node, checked); - ((DefaultTreeModel)tree.getModel()).nodeChanged(node); - } - - e.consume(); - } - } - }); - - tree.setSelectionRow(0); - } - - private static boolean isToggleEvent(KeyEvent e) { - return e.getKeyCode() == KeyEvent.VK_SPACE; - } - - protected boolean toggleNode(CheckedTreeNode node) { - boolean checked = !node.isChecked(); - checkNode(node, checked); - - // notify model listeners about model change - final TreeModel model = getTree().getModel(); - model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject()); - - return checked; - } - - private void checkNode(CheckedTreeNode node, boolean checked) { - adjustParentsAndChildren(node, checked); - repaint(); - } - - private void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) { - changeNodeState(node, checked); - if (!checked) { - TreeNode parent = node.getParent(); - while (parent != null) { - if (parent instanceof CheckedTreeNode) { - changeNodeState((CheckedTreeNode)parent, false); - } - parent = parent.getParent(); - } - uncheckChildren(node); - } - else { - checkChildren(node); - } - repaint(); - } - - private static void changeNodeState(final CheckedTreeNode node, final boolean checked) { - if (node.isChecked() != checked) { - node.setChecked(checked); - } - } - - private static void uncheckChildren(final CheckedTreeNode node) { - final Enumeration children = node.children(); - while (children.hasMoreElements()) { - final Object o = children.nextElement(); - if (!(o instanceof CheckedTreeNode)) continue; - CheckedTreeNode child = (CheckedTreeNode)o; - changeNodeState(child, false); - uncheckChildren(child); - } - } - - private static void checkChildren(final CheckedTreeNode node) { - final Enumeration children = node.children(); - while (children.hasMoreElements()) { - final Object o = children.nextElement(); - if (!(o instanceof CheckedTreeNode)) continue; - CheckedTreeNode child = (CheckedTreeNode)o; - changeNodeState(child, true); - checkChildren(child); - } - } - - @SuppressWarnings("unchecked") - public <T> T[] getCheckedNodes(final Class<T> nodeType) { - final ArrayList<T> nodes = new ArrayList<T>(); - final Object root = getTree().getModel().getRoot(); - if (!(root instanceof CheckedTreeNode)) { - throw new IllegalStateException("The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName()); - } - new Object() { - @SuppressWarnings("unchecked") - public void collect(CheckedTreeNode node) { - if (node.isLeaf()) { - Object userObject = node.getUserObject(); - if (node.isChecked() && userObject != null && nodeType.isAssignableFrom(userObject.getClass())) { - final T value = (T)userObject; - nodes.add(value); - } - } - else { - for (int i = 0; i < node.getChildCount(); i++) { - final TreeNode child = node.getChildAt(i); - if (child instanceof CheckedTreeNode) { - collect((CheckedTreeNode)child); - } - } - } - } - }.collect((CheckedTreeNode)root); - T[] result = (T[])Array.newInstance(nodeType, nodes.size()); - nodes.toArray(result); - return result; - } -} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java index ee44bdf2f08b..bf3d383aeebb 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java @@ -26,11 +26,13 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.*; import com.intellij.ui.treeStructure.treetable.TreeColumnInfo; import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.Convertor; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ComboBoxCellEditor; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -38,12 +40,11 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; +import javax.swing.tree.TreePath; import java.awt.*; import java.io.File; -import java.util.Arrays; -import java.util.HashMap; +import java.util.*; import java.util.List; -import java.util.Map; /** * This dialog allows selecting paths inside selected archives or directories. @@ -108,17 +109,17 @@ public class DetectedRootsChooserDialog extends DialogWrapper { private JScrollPane myPane; private String myDescription; - public DetectedRootsChooserDialog(Component component, List<SuggestedChildRootInfo> suggestedRoots) { + public DetectedRootsChooserDialog(Component component, Collection<SuggestedChildRootInfo> suggestedRoots) { super(component, true); init(suggestedRoots); } - public DetectedRootsChooserDialog(Project project, List<SuggestedChildRootInfo> suggestedRoots) { + public DetectedRootsChooserDialog(Project project, Collection<SuggestedChildRootInfo> suggestedRoots) { super(project, true); init(suggestedRoots); } - private void init(List<SuggestedChildRootInfo> suggestedRoots) { + private void init(Collection<SuggestedChildRootInfo> suggestedRoots) { myDescription = XmlStringUtil.wrapInHtml(ApplicationNamesInfo.getInstance().getFullProductName() + " just scanned files and detected the following " + StringUtil.pluralize("root", suggestedRoots.size()) + ".<br>" + "Select items in the tree below or press Cancel to cancel operation."); @@ -128,7 +129,7 @@ public class DetectedRootsChooserDialog extends DialogWrapper { init(); } - private static CheckboxTreeTable createTreeTable(List<SuggestedChildRootInfo> suggestedRoots) { + private static CheckboxTreeTable createTreeTable(Collection<SuggestedChildRootInfo> suggestedRoots) { final CheckedTreeNode root = createRoot(suggestedRoots); CheckboxTreeTable treeTable = new CheckboxTreeTable(root, new CheckboxTree.CheckboxTreeCellRenderer(true) { @Override @@ -189,14 +190,30 @@ public class DetectedRootsChooserDialog extends DialogWrapper { column.setPreferredWidth(width); column.setMaxWidth(width); treeTable.setRootVisible(false); + new TreeTableSpeedSearch(treeTable, new Convertor<TreePath, String>() { + @Override + public String convert(TreePath o) { + Object node = o.getLastPathComponent(); + if (!(node instanceof VirtualFileCheckedTreeNode)) return ""; + return ((VirtualFileCheckedTreeNode)node).getFile().getPresentableUrl(); + } + }); TreeUtil.expandAll(treeTable.getTree()); return treeTable; } - private static CheckedTreeNode createRoot(List<SuggestedChildRootInfo> suggestedRoots) { + private static CheckedTreeNode createRoot(Collection<SuggestedChildRootInfo> suggestedRoots) { + SuggestedChildRootInfo[] sortedRoots = suggestedRoots.toArray(new SuggestedChildRootInfo[suggestedRoots.size()]); + Arrays.sort(sortedRoots, new Comparator<SuggestedChildRootInfo>() { + @Override + public int compare(@NotNull SuggestedChildRootInfo o1, @NotNull SuggestedChildRootInfo o2) { + return o1.getDetectedRoot().getFile().getPresentableUrl().compareTo(o2.getDetectedRoot().getFile().getPresentableUrl()); + } + }); + CheckedTreeNode root = new CheckedTreeNode(null); Map<VirtualFile, CheckedTreeNode> rootCandidateNodes = new HashMap<VirtualFile, CheckedTreeNode>(); - for (SuggestedChildRootInfo rootInfo : suggestedRoots) { + for (SuggestedChildRootInfo rootInfo : sortedRoots) { final VirtualFile rootCandidate = rootInfo.getRootCandidate(); CheckedTreeNode parent = rootCandidateNodes.get(rootCandidate); if (parent == null) { @@ -230,6 +247,12 @@ public class DetectedRootsChooserDialog extends DialogWrapper { return "DetectedRootsChooserDialog"; } + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myTreeTable; + } + private static class VirtualFileCheckedTreeNode extends CheckedTreeNode { private final VirtualFile myFile; diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java index 743e408b8c97..725216600ffa 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java @@ -19,6 +19,7 @@ import com.intellij.openapi.roots.libraries.LibraryRootType; import com.intellij.openapi.roots.libraries.ui.DetectedLibraryRoot; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.Map; @@ -32,17 +33,19 @@ class SuggestedChildRootInfo { private final Map<LibraryRootType, String> myRootTypeNames; private LibraryRootType mySelectedRootType; - SuggestedChildRootInfo(VirtualFile rootCandidate, DetectedLibraryRoot detectedRoot, Map<LibraryRootType, String> rootTypeNames) { + SuggestedChildRootInfo(@NotNull VirtualFile rootCandidate, @NotNull DetectedLibraryRoot detectedRoot, @NotNull Map<LibraryRootType, String> rootTypeNames) { myRootCandidate = rootCandidate; myDetectedRoot = detectedRoot; myRootTypeNames = rootTypeNames; mySelectedRootType = detectedRoot.getTypes().get(0); } + @NotNull public VirtualFile getRootCandidate() { return myRootCandidate; } + @NotNull public DetectedLibraryRoot getDetectedRoot() { return myDetectedRoot; } @@ -51,6 +54,7 @@ class SuggestedChildRootInfo { return myRootTypeNames.get(type); } + @NotNull public LibraryRootType getSelectedRootType() { return mySelectedRootType; } @@ -64,6 +68,7 @@ class SuggestedChildRootInfo { } } + @NotNull public String[] getRootTypeNames() { final String[] types = ArrayUtil.toStringArray(myRootTypeNames.values()); Arrays.sort(types, String.CASE_INSENSITIVE_ORDER); |