| /* |
| * 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.ide.errorTreeView; |
| |
| import com.intellij.ui.CustomizeColoredTreeCellRenderer; |
| import com.intellij.ui.JBColor; |
| import com.intellij.ui.LoadingNode; |
| import com.intellij.ui.treeStructure.Tree; |
| import com.intellij.util.ui.UIUtil; |
| import com.intellij.util.ui.tree.WideSelectionTreeUI; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.tree.DefaultMutableTreeNode; |
| import javax.swing.tree.TreeCellEditor; |
| import javax.swing.tree.TreeCellRenderer; |
| import javax.swing.tree.TreePath; |
| import java.awt.*; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.MouseMotionListener; |
| import java.util.EventObject; |
| |
| /** |
| * @author Vladislav.Soroka |
| * @since 3/25/14 |
| */ |
| public class NewErrorTreeEditor extends AbstractCellEditor implements TreeCellEditor, MouseMotionListener { |
| |
| public static void install(Tree tree) { |
| NewErrorTreeEditor treeEditor = new NewErrorTreeEditor(tree); |
| tree.setCellEditor(treeEditor); |
| tree.addMouseMotionListener(treeEditor); |
| tree.setEditable(true); |
| } |
| |
| private final MyWrapperEditor myWrapperEditor; |
| private final CallingBackColoredTreeCellRenderer myColoredTreeCellRenderer; |
| private final CellEditorDelegate myRightCellRenderer; |
| private final JTree myTree; |
| |
| private NewErrorTreeEditor(JTree tree) { |
| myTree = tree; |
| myRightCellRenderer = new CellEditorDelegate(); |
| myColoredTreeCellRenderer = new CallingBackColoredTreeCellRenderer(); |
| myWrapperEditor = new MyWrapperEditor(myColoredTreeCellRenderer, myRightCellRenderer); |
| } |
| |
| @Override |
| public boolean isCellEditable(EventObject e) { |
| Object node; |
| if(e instanceof MouseEvent) { |
| final Point point = ((MouseEvent)e).getPoint(); |
| final TreePath location = myTree.getClosestPathForLocation(point.x, point.y); |
| node = location.getLastPathComponent(); |
| } else { |
| node = myTree.getLastSelectedPathComponent(); |
| } |
| final ErrorTreeElement element = getElement(node); |
| return element instanceof EditableMessageElement; |
| } |
| |
| @Override |
| public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { |
| final ErrorTreeElement element = getElement(value); |
| if (element instanceof EditableMessageElement) { |
| EditableMessageElement editableMessageElement = (EditableMessageElement)element; |
| final CustomizeColoredTreeCellRenderer leftSelfRenderer = editableMessageElement.getLeftSelfRenderer(); |
| final TreeCellEditor rightSelfEditor = editableMessageElement.getRightSelfEditor(); |
| myColoredTreeCellRenderer.setCurrentCallback(leftSelfRenderer); |
| myRightCellRenderer.setCurrentCallback(rightSelfEditor); |
| return myWrapperEditor.getTreeCellEditorComponent(tree, value, selected, expanded, leaf, row); |
| } |
| return myTree.getCellRenderer().getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, true); |
| } |
| |
| @Override |
| public Object getCellEditorValue() { |
| return null; |
| } |
| |
| @Override |
| public void mouseDragged(MouseEvent e) { |
| } |
| |
| @Override |
| public void mouseMoved(MouseEvent e) { |
| JTree tree = (JTree)e.getSource(); |
| int selRow = tree.getRowForLocation(e.getX(), e.getY()); |
| if (selRow != -1) { |
| TreePath treePath = tree.getPathForRow(selRow); |
| if (treePath != null && treePath != tree.getEditingPath()) { |
| final ErrorTreeElement element = getElement(treePath.getLastPathComponent()); |
| if (element instanceof EditableMessageElement && ((EditableMessageElement)element).startEditingOnMouseMove()) { |
| if (!tree.isRowSelected(selRow)) { |
| tree.setSelectionRow(selRow); |
| } |
| tree.startEditingAtPath(treePath); |
| } |
| } |
| } |
| } |
| |
| @Nullable |
| private static ErrorTreeElement getElement(@Nullable Object value) { |
| if (!(value instanceof DefaultMutableTreeNode)) return null; |
| final Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); |
| if (!(userObject instanceof ErrorTreeNodeDescriptor)) return null; |
| return ((ErrorTreeNodeDescriptor)userObject).getElement(); |
| } |
| |
| private static class MyWrapperEditor extends AbstractCellEditor implements TreeCellEditor { |
| private final TreeCellRenderer myLeft; |
| private final TreeCellEditor myRight; |
| private final JPanel myPanel; |
| |
| public TreeCellRenderer getLeft() { |
| return myLeft; |
| } |
| |
| public TreeCellEditor getRight() { |
| return myRight; |
| } |
| |
| public MyWrapperEditor(final TreeCellRenderer left, final TreeCellEditor right) { |
| myLeft = left; |
| myRight = right; |
| myPanel = new JPanel(new BorderLayout()); |
| } |
| |
| public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { |
| myPanel.removeAll(); |
| myPanel.add(myLeft.getTreeCellRendererComponent(tree, value, false, expanded, leaf, row, true), BorderLayout.WEST); |
| myPanel.add(myRight.getTreeCellEditorComponent(tree, value, selected, expanded, leaf, row), BorderLayout.EAST); |
| |
| if (UIUtil.isFullRowSelectionLAF()) { |
| myPanel.setBackground(selected ? UIUtil.getTreeSelectionBackground() : null); |
| } |
| else if (tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection()) { |
| if (selected) { |
| myPanel.setBackground(UIUtil.getTreeSelectionBackground()); |
| } |
| } |
| else if (selected) { |
| myPanel.setBackground(UIUtil.getTreeSelectionBackground()); |
| } |
| else { |
| myPanel.setBackground(null); |
| } |
| |
| if (value instanceof LoadingNode) { |
| myPanel.setForeground(JBColor.GRAY); |
| } |
| else { |
| myPanel.setForeground(tree.getForeground()); |
| } |
| |
| if (UIUtil.isUnderGTKLookAndFeel() || |
| UIUtil.isUnderNimbusLookAndFeel() && selected || |
| tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection()) { |
| myPanel.setOpaque(false); |
| } |
| return myPanel; |
| } |
| |
| @Override |
| public Object getCellEditorValue() { |
| return null; |
| } |
| } |
| |
| |
| private static class CellEditorDelegate extends AbstractCellEditor implements TreeCellEditor { |
| private TreeCellEditor myCurrentCallback; |
| |
| public Component getTreeCellEditorComponent(JTree tree, |
| Object value, |
| boolean selected, |
| boolean expanded, |
| boolean leaf, |
| int row) { |
| return myCurrentCallback.getTreeCellEditorComponent(tree, value, selected, expanded, leaf, row); |
| } |
| |
| public void setCurrentCallback(final TreeCellEditor currentCallback) { |
| myCurrentCallback = currentCallback; |
| } |
| |
| @Override |
| public Object getCellEditorValue() { |
| return null; |
| } |
| } |
| } |