diff options
Diffstat (limited to 'platform/platform-api/src/com/intellij/ui')
19 files changed, 526 insertions, 257 deletions
diff --git a/platform/platform-api/src/com/intellij/ui/AnActionButton.java b/platform/platform-api/src/com/intellij/ui/AnActionButton.java index 7c539b1bb2a4..d1c19df6e3ad 100644 --- a/platform/platform-api/src/com/intellij/ui/AnActionButton.java +++ b/platform/platform-api/src/com/intellij/ui/AnActionButton.java @@ -17,6 +17,7 @@ package com.intellij.ui; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.containers.SmartHashSet; import com.intellij.util.ui.UIUtil; @@ -187,7 +188,7 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide @Override public void actionPerformed(AnActionEvent e) { - myAction.actionPerformed(e); + myAction.actionPerformed(new AnActionEventWrapper(e, this)); } @Override @@ -205,4 +206,20 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide return myAction.isDumbAware(); } } + + public static class AnActionEventWrapper extends AnActionEvent { + private final AnActionButton myPeer; + + private AnActionEventWrapper(AnActionEvent e, AnActionButton peer) { + super(e.getInputEvent(), e.getDataContext(), e.getPlace(), e.getPresentation(), e.getActionManager(), e.getModifiers()); + myPeer = peer; + } + + public void showPopup(JBPopup popup) { + popup.show(myPeer.getPreferredPopupPoint()); + } + + + + } } diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java new file mode 100644 index 000000000000..186904a4a843 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2014 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.ui; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class CheckboxTreeAdapter implements CheckboxTreeListener { + @Override + public void mouseDoubleClicked(@NotNull CheckedTreeNode node) { + } + + @Override + public void nodeStateChanged(@NotNull CheckedTreeNode node) { + } + + @Override + public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) { + } +} diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java index d9755f342a3f..88f433f7c62a 100644 --- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java +++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java @@ -16,67 +16,49 @@ package com.intellij.ui; import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.EventDispatcher; import com.intellij.util.ui.UIUtil; -import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; 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; public class CheckboxTreeBase extends Tree { - private final CheckPolicy myCheckPolicy; - private static final CheckPolicy DEFAULT_POLICY = new CheckPolicy(true, true, false, true); + private final CheckboxTreeHelper myHelper; + private final EventDispatcher<CheckboxTreeListener> myEventDispatcher; public CheckboxTreeBase() { this(new CheckboxTreeCellRendererBase(), null); } public CheckboxTreeBase(final CheckboxTreeCellRendererBase cellRenderer, CheckedTreeNode root) { - this(cellRenderer, root, DEFAULT_POLICY); + this(cellRenderer, root, CheckboxTreeHelper.DEFAULT_POLICY); } public CheckboxTreeBase(CheckboxTreeCellRendererBase cellRenderer, @Nullable CheckedTreeNode root, CheckPolicy checkPolicy) { - myCheckPolicy = checkPolicy; - - setRootVisible(false); - setShowsRootHandles(true); - setLineStyleAngled(); - TreeUtil.installActions(this); - - installRenderer(cellRenderer); - - addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - if (isToggleEvent(e)) { - TreePath treePath = 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 = 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)getModel()).nodeChanged(node); - } - - e.consume(); - } + myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class); + myEventDispatcher.addListener(new CheckboxTreeListener() { + @Override + public void mouseDoubleClicked(@NotNull CheckedTreeNode node) { + onDoubleClick(node); + } + + @Override + public void nodeStateChanged(@NotNull CheckedTreeNode node) { + CheckboxTreeBase.this.onNodeStateChanged(node); + } + + @Override + public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) { + CheckboxTreeBase.this.nodeStateWillChange(node); } }); + myHelper = new CheckboxTreeHelper(checkPolicy, myEventDispatcher); + myHelper.initTree(this, this, cellRenderer); setSelectionRow(0); if (root != null) { @@ -84,55 +66,37 @@ public class CheckboxTreeBase extends Tree { } } + @Deprecated public void installRenderer(final CheckboxTreeCellRendererBase cellRenderer) { setCellRenderer(cellRenderer); - new ClickListener() { - @Override - public boolean onClick(@NotNull MouseEvent e, int clickCount) { - int row = getRowForLocation(e.getX(), e.getY()); - if (row < 0) return false; - final Object o = getPathForRow(row).getLastPathComponent(); - if (!(o instanceof CheckedTreeNode)) return false; - Rectangle rowBounds = getRowBounds(row); - cellRenderer.setBounds(rowBounds); - Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); - checkBounds.setLocation(rowBounds.getLocation()); - - if (checkBounds.height == 0) checkBounds.height = checkBounds.width = rowBounds.height; - - final CheckedTreeNode node = (CheckedTreeNode)o; - if (checkBounds.contains(e.getPoint())) { - if (node.isEnabled()) { - toggleNode(node); - setSelectionRow(row); - return true; - } - } - else if (clickCount > 1) { - onDoubleClick(node); - return true; - } - return false; - } - }.installOn(this); } - protected void onDoubleClick(final CheckedTreeNode node) { + /** + * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes + */ + @Deprecated + protected boolean toggleNode(CheckedTreeNode node) { + setNodeState(node, !node.isChecked()); + return node.isChecked(); } - protected boolean isToggleEvent(KeyEvent e) { - return e.getKeyCode() == KeyEvent.VK_SPACE; + /** + * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes + */ + @Deprecated + protected void checkNode(CheckedTreeNode node, boolean checked) { + setNodeState(node, checked); } - protected boolean toggleNode(CheckedTreeNode node) { - boolean checked = !node.isChecked(); - checkNode(node, checked); + public void setNodeState(@NotNull CheckedTreeNode node, boolean checked) { + myHelper.setNodeState(this, node, checked); + } - // notify model listeners about model change - final TreeModel model = getModel(); - model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject()); + public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) { + myEventDispatcher.addListener(listener); + } - return checked; + protected void onDoubleClick(final CheckedTreeNode node) { } /** @@ -144,38 +108,8 @@ public class CheckboxTreeBase extends Tree { * @param <T> the type of the node * @return an array of collected nodes */ - @SuppressWarnings("unchecked") public <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final NodeFilter<T> filter) { - final ArrayList<T> nodes = new ArrayList<T>(); - final Object root = 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; - if (filter != null && !filter.accept(value)) return; - 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; + return CheckboxTreeHelper.getCheckedNodes(nodeType, filter, getModel()); } @@ -184,118 +118,14 @@ public class CheckboxTreeBase extends Tree { return -1; } - protected void checkNode(CheckedTreeNode node, boolean checked) { - adjustParentsAndChildren(node, checked); - repaint(); - } - protected void onNodeStateChanged(CheckedTreeNode node) { - } protected void nodeStateWillChange(CheckedTreeNode node) { - - } - - protected void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) { - changeNodeState(node, checked); - if (!checked) { - if (myCheckPolicy.uncheckParentWithUncheckedChild) { - TreeNode parent = node.getParent(); - while (parent != null) { - if (parent instanceof CheckedTreeNode) { - changeNodeState((CheckedTreeNode)parent, false); - } - parent = parent.getParent(); - } - } - if (myCheckPolicy.uncheckChildrenWithUncheckedParent) { - uncheckChildren(node); - } - - } - else { - if (myCheckPolicy.checkChildrenWithCheckedParent) { - checkChildren(node); - } - - if (myCheckPolicy.checkParentWithCheckedChild) { - TreeNode parent = node.getParent(); - while (parent != null) { - if (parent instanceof CheckedTreeNode) { - changeNodeState((CheckedTreeNode)parent, true); - } - parent = parent.getParent(); - } - } - - } - repaint(); - } - - private void changeNodeState(final CheckedTreeNode node, final boolean checked) { - if (node.isChecked() != checked) { - nodeStateWillChange(node); - node.setChecked(checked); - onNodeStateChanged(node); - } - } - - private 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 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); - } } + @Deprecated protected void adjustParents(final CheckedTreeNode node, final boolean checked) { - TreeNode parentNode = node.getParent(); - if (!(parentNode instanceof CheckedTreeNode)) return; - CheckedTreeNode parent = (CheckedTreeNode)parentNode; - - if (!checked && isAllChildrenUnchecked(parent)) { - changeNodeState(parent, false); - adjustParents(parent, false); - } - else if (checked && isAllChildrenChecked(parent)) { - changeNodeState(parent, true); - adjustParents(parent, true); - } - } - - private static boolean isAllChildrenUnchecked(final CheckedTreeNode node) { - for (int i = 0; i < node.getChildCount(); i++) { - final TreeNode o = node.getChildAt(i); - if ((o instanceof CheckedTreeNode) && ((CheckedTreeNode)o).isChecked()) { - return false; - } - } - return true; - } - - private static boolean isAllChildrenChecked(final CheckedTreeNode node) { - for (int i = 0; i < node.getChildCount(); i++) { - final TreeNode o = node.getChildAt(i); - if ((o instanceof CheckedTreeNode) && !((CheckedTreeNode)o).isChecked()) { - return false; - } - } - return true; } public static class CheckboxTreeCellRendererBase extends JPanel implements TreeCellRenderer { @@ -395,8 +225,8 @@ public class CheckboxTreeBase extends Tree { } /** - * @deprecated * @see CheckboxTreeCellRendererBase#customizeRenderer(javax.swing.JTree, Object, boolean, boolean, boolean, int, boolean) + * @deprecated */ @Deprecated public void customizeCellRenderer(JTree tree, diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java new file mode 100644 index 000000000000..3048d131caa7 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java @@ -0,0 +1,234 @@ +/* + * Copyright 2000-2014 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.ui; + +import com.intellij.ui.speedSearch.SpeedSearchSupply; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.EventDispatcher; +import com.intellij.util.ui.tree.TreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +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 + */ +class CheckboxTreeHelper { + static final CheckboxTreeBase.CheckPolicy DEFAULT_POLICY = new CheckboxTreeBase.CheckPolicy(true, true, false, true); + private final CheckboxTreeBase.CheckPolicy myCheckPolicy; + private final EventDispatcher<CheckboxTreeListener> myEventDispatcher; + + CheckboxTreeHelper(CheckboxTreeBase.CheckPolicy checkPolicy, EventDispatcher<CheckboxTreeListener> dispatcher) { + myCheckPolicy = checkPolicy; + myEventDispatcher = dispatcher; + } + + public void initTree(@NotNull final Tree tree, JComponent mainComponent, CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) { + tree.setCellRenderer(cellRenderer); + tree.setRootVisible(false); + tree.setShowsRootHandles(true); + tree.setLineStyleAngled(); + TreeUtil.installActions(tree); + + setupKeyListener(tree, mainComponent); + setupMouseListener(tree, mainComponent, cellRenderer); + } + + public void setNodeState(Tree tree, CheckedTreeNode node, boolean checked) { + changeNodeState(node, checked); + adjustParentsAndChildren(node, checked); + tree.repaint(); + + // notify model listeners about model change + final TreeModel model = tree.getModel(); + model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject()); + } + + private void toggleNode(Tree tree, CheckedTreeNode node) { + setNodeState(tree, node, !node.isChecked()); + } + + private void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) { + if (!checked) { + if (myCheckPolicy.uncheckParentWithUncheckedChild) { + TreeNode parent = node.getParent(); + while (parent != null) { + if (parent instanceof CheckedTreeNode) { + changeNodeState((CheckedTreeNode)parent, false); + } + parent = parent.getParent(); + } + } + if (myCheckPolicy.uncheckChildrenWithUncheckedParent) { + uncheckChildren(node); + } + } + else { + if (myCheckPolicy.checkChildrenWithCheckedParent) { + checkChildren(node); + } + + if (myCheckPolicy.checkParentWithCheckedChild) { + TreeNode parent = node.getParent(); + while (parent != null) { + if (parent instanceof CheckedTreeNode) { + changeNodeState((CheckedTreeNode)parent, true); + } + parent = parent.getParent(); + } + } + } + } + + private void changeNodeState(final CheckedTreeNode node, final boolean checked) { + if (node.isChecked() != checked) { + myEventDispatcher.getMulticaster().beforeNodeStateChanged(node); + node.setChecked(checked); + myEventDispatcher.getMulticaster().nodeStateChanged(node); + } + } + + private 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 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); + } + } + + private void setupKeyListener(final Tree tree, final JComponent mainComponent) { + mainComponent.addKeyListener(new KeyAdapter() { + public void keyPressed(@NotNull KeyEvent e) { + if (isToggleEvent(e, mainComponent)) { + TreePath treePath = tree.getLeadSelectionPath(); + if (treePath == null) return; + final Object o = treePath.getLastPathComponent(); + if (!(o instanceof CheckedTreeNode)) return; + CheckedTreeNode firstNode = (CheckedTreeNode)o; + toggleNode(tree, firstNode); + boolean checked = firstNode.isChecked(); + + 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; + setNodeState(tree, node, checked); + } + + e.consume(); + } + } + }); + } + + private static boolean isToggleEvent(KeyEvent e, JComponent mainComponent) { + return e.getKeyCode() == KeyEvent.VK_SPACE && SpeedSearchSupply.getSupply(mainComponent) == null; + } + + private void setupMouseListener(final Tree tree, JComponent mainComponent, final CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) { + 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 = checkBounds.width = rowBounds.height; + + final CheckedTreeNode node = (CheckedTreeNode)o; + if (checkBounds.contains(e.getPoint())) { + if (node.isEnabled()) { + toggleNode(tree, node); + tree.setSelectionRow(row); + return true; + } + } + else if (clickCount > 1) { + myEventDispatcher.getMulticaster().mouseDoubleClicked(node); + return true; + } + + return false; + } + }.installOn(mainComponent); + } + + @SuppressWarnings("unchecked") + public static <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final Tree.NodeFilter<T> filter, final TreeModel model) { + final ArrayList<T> nodes = new ArrayList<T>(); + final Object root = model.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; + if (filter != null && !filter.accept(value)) return; + 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/platform-api/src/com/intellij/ui/CheckboxTreeListener.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java new file mode 100644 index 000000000000..792c4589c85d --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 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.ui; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface CheckboxTreeListener extends EventListener { + void mouseDoubleClicked(@NotNull CheckedTreeNode node); + + void nodeStateChanged(@NotNull CheckedTreeNode node); + + void beforeNodeStateChanged(@NotNull CheckedTreeNode node); +} diff --git a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java index 846378cc1633..2d4213da3954 100644 --- a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java +++ b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -165,6 +165,9 @@ public class CommonActionsPanel extends JPanel { @Override public void addNotify() { + if (getBackground() != null && !getBackground().equals(UIUtil.getPanelBackground())) { + SwingUtilities.updateComponentTreeUI(this.getParent()); + } final JRootPane pane = getRootPane(); for (AnActionButton button : myActions) { final ShortcutSet shortcut = button.getShortcut(); diff --git a/platform/platform-api/src/com/intellij/ui/JBSplitter.java b/platform/platform-api/src/com/intellij/ui/JBSplitter.java index b4000dbcfae2..5f01602d92c5 100644 --- a/platform/platform-api/src/com/intellij/ui/JBSplitter.java +++ b/platform/platform-api/src/com/intellij/ui/JBSplitter.java @@ -94,14 +94,6 @@ public class JBSplitter extends Splitter { saveProportion(); } - public void setOnePixelMode() { - setDividerWidth(1); - setShowDividerIcon(false); - getDivider().setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128))); - setShowDividerControls(false); - setOrientation(getOrientation()); - } - protected void loadProportion() { if (! StringUtil.isEmpty(mySplitterProportionKey)) { setProportion(PropertiesComponent.getInstance().getFloat(mySplitterProportionKey, myProportion)); diff --git a/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java new file mode 100644 index 000000000000..15dd5fdc2abb --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2014 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.ui; + +import com.intellij.openapi.ui.Divider; +import com.intellij.openapi.ui.OnePixelDivider; + +/** + * @author Konstantin Bulenkov + */ +public class OnePixelSplitter extends JBSplitter { + + public OnePixelSplitter() { + super(); + init(); + } + + public OnePixelSplitter(boolean vertical) { + super(vertical); + init(); + } + + public OnePixelSplitter(boolean vertical, float proportion) { + super(vertical, proportion); + init(); + } + + public OnePixelSplitter(float proportion) { + super(proportion); + init(); + } + + public OnePixelSplitter(boolean vertical, float proportion, float minProp, float maxProp) { + super(vertical, proportion, minProp, maxProp); + init(); + } + + protected void init() { + setDividerWidth(1); + } + + @Override + protected Divider createDivider() { + return new OnePixelDivider(isVertical(), this); + } +} diff --git a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java index ee68a3f94ae8..2f5bf0343ed6 100644 --- a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java +++ b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -17,6 +17,7 @@ package com.intellij.ui.border; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.border.Border; import java.awt.*; @@ -28,17 +29,17 @@ public class CustomLineBorder implements Border { private final Color myColor; private final Insets myInsets; - public CustomLineBorder(@NotNull Color color, @NotNull Insets insets) { + public CustomLineBorder(@Nullable Color color, @NotNull Insets insets) { myColor = color; myInsets = insets; } - public CustomLineBorder(@NotNull Color color, int top, int left, int bottom, int right) { + public CustomLineBorder(@Nullable Color color, int top, int left, int bottom, int right) { this(color, new Insets(top, left, bottom, right)); } public CustomLineBorder(@NotNull Insets insets) { - this(UIUtil.getBorderColor(), insets); + this(null, insets); } public CustomLineBorder(int top, int left, int bottom, int right) { @@ -59,7 +60,7 @@ public class CustomLineBorder implements Border { } protected Color getColor() { - return myColor; + return myColor == null ? UIUtil.getBorderColor() : myColor; } @Override diff --git a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java index a79349b5f6aa..46bce6b3834d 100644 --- a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java @@ -17,12 +17,12 @@ package com.intellij.ui.table; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.config.Storage; -import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NonNls; import javax.swing.*; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; import java.util.ArrayList; import java.util.Arrays; @@ -33,10 +33,14 @@ import java.util.Arrays; public class BaseTableView extends JBTable { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.table.BaseTableView"); - public BaseTableView(final ListTableModel model) { + public BaseTableView(final TableModel model) { super(model); } + public BaseTableView(TableModel model, TableColumnModel columnModel) { + super(model, columnModel); + } + @NonNls private static String orderPropertyName(final int index) { return "Order"+index; diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index e7ff935e57f9..435c4358959f 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -62,8 +62,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component this(new DefaultTableModel()); } - public JBTable(final TableModel model) { - super(model); + public JBTable(TableModel model) { + this(model, null); + } + + public JBTable(final TableModel model, final TableColumnModel columnModel) { + super(model, columnModel); myEmptyText = new StatusText(this) { @Override diff --git a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java index d1dfa976e479..c8c944c86e4a 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java @@ -92,6 +92,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> { * out of its container. (IDEA-61536) */ private WeakReference<TabInfo> myPreviousSelection = new WeakReference<TabInfo>(null); + private boolean myTitleShortened; public TabInfo(final JComponent component) { myComponent = component; @@ -392,6 +393,14 @@ public final class TabInfo implements Queryable, PlaceProvider<String> { return myPreviousSelection.get(); } + public boolean isTitleShortened() { + return myTitleShortened; + } + + public void setTitleIsShortened(boolean titleIsShortened) { + myTitleShortened = titleIsShortened; + } + public interface DragOutDelegate { void dragOutStarted(MouseEvent mouseEvent, TabInfo info); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java index 655854ac933c..b0df0917dfe0 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java @@ -240,7 +240,7 @@ class DragHelper extends MouseDragHelper { final JBTabsPosition position = myTabs.getTabsPosition(); - if (!willDragOutStart && JBEditorTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) { + if (!willDragOutStart && myTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) { Point p = new Point(event.getPoint()); p = SwingUtilities.convertPoint(event.getComponent(), p, myTabs); if (myTabs.getVisibleRect().contains(p) && myPressedOnScreenPoint.distance(new RelativePoint(event).getScreenPoint()) > 15) { diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java index 761d3ea0d341..a842f623ac45 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java @@ -43,7 +43,8 @@ import java.util.List; * @author pegov */ public class JBEditorTabs extends JBTabsImpl { - private static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical"; + public static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical"; + static final String TABS_SHORTEN_TITLE_IF_NEED = "tabs.shorten.title.if.need"; private JBEditorTabsPainter myDarkPainter = new DarculaEditorTabsPainter(); private JBEditorTabsPainter myDefaultPainter = new DefaultEditorTabsPainter(); @@ -61,6 +62,13 @@ public class JBEditorTabs extends JBTabsImpl { } @Override + protected TabLabel createTabLabel(TabInfo info) { + TabLabel label = super.createTabLabel(info); + label.putClientProperty(TABS_SHORTEN_TITLE_IF_NEED, Boolean.TRUE); + return label; + } + + @Override public boolean isEditorTabs() { return true; } @@ -130,7 +138,7 @@ public class JBEditorTabs extends JBTabsImpl { return UIUtil.isUnderDarcula() ? myDarkPainter : myDefaultPainter; } - public static boolean isAlphabeticalMode() { + public boolean isAlphabeticalMode() { return Registry.is(TABS_ALPHABETICAL_KEY); } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index a058badddd41..60898a6e9bd8 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -1262,6 +1262,10 @@ public class JBTabsImpl extends JComponent return null; } + public boolean isAlphabeticalMode() { + return false; + } + @Nullable private TabInfo findEnabledBackward(int from, boolean cycle) { if (from < 0) return null; @@ -1653,19 +1657,13 @@ public class JBTabsImpl extends JComponent config.setAntialiasing(false); - if (isSideComponentVertical()) { - Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo); - if (toolbarComp != null && !toolbarComp.isEmpty()) { - Rectangle toolBounds = toolbarComp.getBounds(); - g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR); + Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo); + if (toolbarComp != null && !toolbarComp.isEmpty()) { + Rectangle toolBounds = toolbarComp.getBounds(); + g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR); + if (isSideComponentVertical()) { g2d.drawLine((int)toolBounds.getMaxX(), toolBounds.y, (int)toolBounds.getMaxX(), (int)toolBounds.getMaxY() - 1); - } - } - else if (!isSideComponentOnTabs()) { - Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo); - if (toolbarComp != null && !toolbarComp.isEmpty()) { - Rectangle toolBounds = toolbarComp.getBounds(); - g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR); + } else if (!isSideComponentOnTabs()) { g2d.drawLine(toolBounds.x, (int)toolBounds.getMaxY(), (int)toolBounds.getMaxX() - 1, (int)toolBounds.getMaxY()); } } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java index 21c36d5dd66a..a360c4e9294f 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.ui.components.panels.Wrapper; import com.intellij.ui.tabs.JBTabsPosition; @@ -317,6 +318,16 @@ public class TabLabel extends JPanel { public void setText(final SimpleColoredText text) { + myInfo.setTitleIsShortened(false); + if (text != null && text.getTexts().size() == 1 && Boolean.TRUE == getClientProperty(JBEditorTabs.TABS_SHORTEN_TITLE_IF_NEED)) { + String title = text.getTexts().get(0); + if (title.length() > UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT) { + SimpleTextAttributes attributes = text.getAttributes().get(0); + text.clear(); + text.append(StringUtil.getShortened(title, UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT), attributes); + myInfo.setTitleIsShortened(true); + } + } myLabel.change(new Runnable() { public void run() { myLabel.clear(); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java index 653420ae261f..4e5925d2a2ee 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -147,7 +147,7 @@ public class SingleRowLayout extends TabLayout { } public LayoutPassInfo layoutSingleRow(List<TabInfo> visibleInfos) { - if (JBEditorTabs.isAlphabeticalMode()) { + if (myTabs.isAlphabeticalMode()) { Collections.sort(visibleInfos, new Comparator<TabInfo>() { @Override public int compare(TabInfo o1, TabInfo o2) { diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java index 169b5d57479b..0975876055b2 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -828,4 +828,35 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith public void setHorizontalAutoScrollingEnabled(boolean enabled) { myHorizontalAutoScrolling = enabled; } + + /** + * Returns the deepest visible component + * that will be rendered at the specified location. + * + * @param x horizontal location in the tree + * @param y vertical location in the tree + * @return the deepest visible component of the renderer + */ + @Nullable + protected Component getDeepestRendererComponentAt(int x, int y) { + int row = getRowForLocation(x, y); + if (row >= 0) { + TreeCellRenderer renderer = getCellRenderer(); + if (renderer != null) { + TreePath path = getPathForRow(row); + Object node = path.getLastPathComponent(); + Component component = renderer.getTreeCellRendererComponent(this, node, + isRowSelected(row), + isExpanded(row), + getModel().isLeaf(node), + row, true); + Rectangle bounds = getPathBounds(path); + if (bounds != null) { + component.setBounds(bounds); // initialize size to layout complex renderer + return SwingUtilities.getDeepestComponentAt(component, x - bounds.x, y - bounds.y); + } + } + } + return null; + } }
\ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java index dac3354a24fb..b574926a7eb8 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java @@ -98,7 +98,9 @@ public class TreeTableTree extends Tree { public void setVisibleRow(int row) { myVisibleRow = row; - setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width, getPreferredSize().height)); + final Rectangle rowBounds = getRowBounds(myVisibleRow); + final int indent = rowBounds.x - getVisibleRect().x; + setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width + indent, getPreferredSize().height)); } public void _processKeyEvent(KeyEvent e){ |