diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java index 71a89c534f37..c22da9f943d1 100644 --- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java @@ -197,7 +197,7 @@ public class FieldCanBeLocalInspection extends BaseLocalInspectionTool { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { final PsiExpression qualifier = expression.getQualifierExpression(); - if (qualifier == null || qualifier instanceof PsiThisExpression && ((PsiThisExpression)qualifier).getQualifier() == null) { + if (qualifier == null || qualifier instanceof PsiThisExpression) { final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiField) { final PsiField field = (PsiField)resolved; diff --git a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java index 9e306a10e0ab..09e6dd5f12aa 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java +++ b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.net.ServerSocket; import java.net.Socket; @@ -105,6 +106,10 @@ public class AppMain { parms[j - 1] = args[j]; } Method m = Class.forName(mainClass).getMethod("main", new Class[]{parms.getClass()}); + if (!Modifier.isStatic(m.getModifiers())) { + System.err.println("main method should be static"); + return; + } try { ensureAccess(m); m.invoke(null, new Object[]{parms}); diff --git a/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/expected.xml b/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/expected.xml new file mode 100644 index 000000000000..4704d91e891d --- /dev/null +++ b/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/expected.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/src/Test.java b/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/src/Test.java new file mode 100644 index 000000000000..018f6498b391 --- /dev/null +++ b/java/java-tests/testData/inspection/fieldCanBeLocal/innerClassFieldInitializer/src/Test.java @@ -0,0 +1,7 @@ +public class Outer { + private int value = 0; + + public class Inner { + private final int myValue = Outer.this.value; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/FieldCanBeLocalTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/FieldCanBeLocalTest.java index 0cec8f0eb285..5ebd2c2cf9f6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/FieldCanBeLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/FieldCanBeLocalTest.java @@ -29,4 +29,5 @@ public class FieldCanBeLocalTest extends InspectionTestCase { public void testStateField() throws Exception { doTest(); } public void testLocalStateVar2InnerClass() throws Exception { doTest(); } public void testNotConstantInitializer() throws Exception {doTest();} + public void testInnerClassFieldInitializer() throws Exception {doTest();} } diff --git a/platform/lang-api/src/com/intellij/openapi/roots/libraries/LibraryUtil.java b/platform/lang-api/src/com/intellij/openapi/roots/libraries/LibraryUtil.java index a384d7d6e6b2..e614dadde889 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/libraries/LibraryUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/libraries/LibraryUtil.java @@ -141,11 +141,11 @@ public class LibraryUtil { } @Nullable - public static LibraryOrderEntry findLibraryEntry(VirtualFile file, final Project project) { + public static OrderEntry findLibraryEntry(VirtualFile file, final Project project) { List entries = ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(file); for (OrderEntry entry : entries) { - if (entry instanceof LibraryOrderEntry) { - return (LibraryOrderEntry)entry; + if (entry instanceof LibraryOrderEntry || entry instanceof JdkOrderEntry) { + return entry; } } return null; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index e25651a9547f..8e73be8d15a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -39,10 +39,11 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.ui.popup.JBPopup; @@ -81,6 +82,7 @@ import java.util.List; import java.util.Set; public class DocumentationManager { + private static final Logger LOG = Logger.getInstance("#" + DocumentationManager.class.getName()); private static final String SHOW_DOCUMENTATION_IN_TOOL_WINDOW = "ShowDocumentationInToolWindow"; private static final String DOCUMENTATION_AUTO_UPDATE_ENABLED = "DocumentationAutoUpdateEnabled"; @NonNls public static final String JAVADOC_LOCATION_AND_SIZE = "javadoc.popup"; @@ -661,6 +663,7 @@ public class DocumentationManager { text = provider.getDocumentation(); } catch (Throwable e) { + LOG.info(e); ex[0] = e; } @@ -800,7 +803,7 @@ public class DocumentationManager { final PsiFile containingFile = psiElement.getContainingFile(); if (containingFile != null) { final VirtualFile virtualFile = containingFile.getVirtualFile(); - final LibraryOrderEntry libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, myProject); + final OrderEntry libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, myProject); if (libraryEntry != null) { ProjectSettingsService.getInstance(myProject).openProjectLibrarySettings(new NamedLibraryElement(libraryEntry.getOwnerModule(), libraryEntry)); } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java index f7b2a7c26b3c..d1e06aaceb53 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java @@ -92,7 +92,9 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope { if (myModules != null) { final Module module = myProjectFileIndex.getModuleForFile(file); - if (module != null) return myModules.contains(module) && myFileIndex.getOrderEntryForFile(file) != null; + if (module != null) return myModules.contains(module) && + myFileIndex.getOrderEntryForFile(file) != null && + (myIncludeTests || !myProjectFileIndex.isInTestSourceContent(file)); } final List entries = myFileIndex.getOrderEntriesForFile(file); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/RevisionsList.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/RevisionsList.java index 740f7bc25a62..3d1235c3b530 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/RevisionsList.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/RevisionsList.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SeparatorWithText; import com.intellij.util.ui.Table; +import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.apache.commons.lang.time.DateUtils; @@ -139,7 +140,7 @@ public class RevisionsList { TODAY(LocalHistoryBundle.message("revisions.table.period.today")), YESTERDAY(LocalHistoryBundle.message("revisions.table.period.yesterday")), OLDER(LocalHistoryBundle.message("revisions.table.period.older")); - + private final String myDisplayString; private Period(String displayString) { @@ -241,21 +242,25 @@ public class RevisionsList { myPeriodLabel.setCaption(p.getDisplayString()); } - myBorder.set(table.getGridColor(), p != null, row == table.getModel().getRowCount() - 1); + myBorder.set(row == table.getModel().getRowCount() - 1); myDateLabel.setText(ensureString(FormatUtil.formatTimestamp(r.getTimestamp()))); - myTitleLabel.setText(ensureString(labelsAndColor.titleText)); + String text = ensureString(labelsAndColor.titleText); + if (r.getChangeSetName() != null) { + text = "" + text + ""; + } + myTitleLabel.setText(text); myFilesNumberLabel.setText(ensureString(labelsAndColor.filesNumberText)); - JComponent templ = (JComponent)myTemplate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + JComponent orig = (JComponent)myTemplate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - Color bg = isSelected ? templ.getBackground() : labelsAndColor.color; - Color fg = isSelected ? templ.getForeground() : Color.GRAY; + Color bg = isSelected ? orig.getBackground() : labelsAndColor.color; + Color fg = isSelected ? orig.getForeground() : Color.GRAY; myItemPanel.setBackground(bg); myDateLabel.setForeground(fg); myFilesNumberLabel.setForeground(fg); - myTitleLabel.setForeground(templ.getForeground()); + myTitleLabel.setForeground(orig.getForeground()); myWrapperPanel.setBackground(table.getBackground()); return myWrapperPanel; @@ -304,26 +309,22 @@ public class RevisionsList { } private static class MyBorder extends EmptyBorder { - private Color myColor; - private boolean isFirstInGroup; private boolean isLast; private MyBorder() { super(2, 2, 2, 2); } - public void set(Color c, boolean isFirstInGroup, boolean isLast) { - myColor = c; - this.isFirstInGroup = isFirstInGroup; + public void set(boolean isLast) { this.isLast = isLast; } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - g.setColor(myColor); - if (!isFirstInGroup) { - g.drawLine(x, y, x + width, y); - } + g.setColor(UIUtil.getBorderSeparatorColor()); + Graphics2D g2d = (Graphics2D)g; + g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[]{1}, 1)); + g.drawLine(x, y, x + width, y); if (isLast) { g.drawLine(x, y + height - 1, x + width, y + height - 1); } diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VirtualFile.java b/platform/platform-api/src/com/intellij/openapi/vfs/VirtualFile.java index a26cfd9612c2..f60217bfd97a 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VirtualFile.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VirtualFile.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent; +import com.intellij.util.Icons; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -254,6 +255,9 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica } public Icon getIcon() { + if (isDirectory()) { + return Icons.FOLDER_ICON; + } return getFileType().getIcon(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffStatusBar.java b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffStatusBar.java index ff92d0d0ac7f..ad481d58d4db 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffStatusBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffStatusBar.java @@ -42,8 +42,8 @@ public class DiffStatusBar extends JPanel { private final Collection myLabels = new ArrayList(); - private final JLabel myTextLabel = new JLabel("", JLabel.CENTER); - private static final int COMP_HEIGHT = 40; + private final JLabel myTextLabel = new JLabel(""); + private static final int COMP_HEIGHT = 30; private EditorColorsScheme myColorScheme = null; public DiffStatusBar(List types) { @@ -51,7 +51,6 @@ public class DiffStatusBar extends JPanel { addDiffType(differenceType); } initGui(); - setBorder(IdeBorderFactory.createSimpleBorder()); } private void addDiffType(final LegendTypeDescriptor diffType){ @@ -112,29 +111,29 @@ public class DiffStatusBar extends JPanel { } private void initGui() { - setLayout(new GridBagLayout()); - Border emptyBorder = BorderFactory.createEmptyBorder(3, 20, 5, 20); - setBorder(emptyBorder); + JComponent filler = new JComponent() { + @Override + public Dimension getPreferredSize() { + return myTextLabel.getPreferredSize(); + } + }; + setLayout(new BorderLayout()); + setBorder(BorderFactory.createCompoundBorder(IdeBorderFactory.createSimpleBorder(), + BorderFactory.createEmptyBorder(3, 20, 3, 20))); - GridBagConstraints c = new GridBagConstraints(); - c.gridy = 0; - c.gridx = 0; - c.gridwidth = 0; - - add(myTextLabel, c); + add(myTextLabel, BorderLayout.WEST); + Box box = Box.createHorizontalBox(); + box.add(Box.createHorizontalGlue()); JPanel panel = new JPanel(new GridLayout(1, myLabels.size(), 0, 0)); for (final JComponent myLabel : myLabels) { panel.add(myLabel); } panel.setMaximumSize(panel.getPreferredSize()); + box.add(panel); + box.add(Box.createHorizontalGlue()); + add(box, BorderLayout.CENTER); - c.gridx = 1; - c.gridwidth = 1; - add(panel, c); - - c.gridx = 2; - c.gridwidth = 0; - add(Box.createHorizontalGlue(), c); + add(filler, BorderLayout.EAST); } public void setColorScheme(EditorColorsScheme colorScheme) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java index ccd9a8f27039..23c09509fe06 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java @@ -30,11 +30,11 @@ public abstract class LinkMouseListenerBase extends MouseAdapter implements Mous public void mouseClicked(final MouseEvent e) { if (!e.isPopupTrigger() && e.getButton() == 1) { Object tag = getTagAt(e); - handleTagClick(tag); + handleTagClick(tag, e); } } - protected void handleTagClick(final Object tag) { + protected void handleTagClick(final Object tag, MouseEvent event) { if (tag instanceof Runnable) { ((Runnable) tag).run(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/TreeLinkMouseListener.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/TreeLinkMouseListener.java index fc1dba6b1f5d..affa31a42f24 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/TreeLinkMouseListener.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/TreeLinkMouseListener.java @@ -21,7 +21,7 @@ import com.intellij.ui.ColoredTreeCellRenderer; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.MouseEvent; @@ -31,7 +31,7 @@ import java.awt.event.MouseEvent; */ public class TreeLinkMouseListener extends LinkMouseListenerBase { private final ColoredTreeCellRenderer myRenderer; - protected DefaultMutableTreeNode myLastHitNode; + protected TreeNode myLastHitNode; public TreeLinkMouseListener(final ColoredTreeCellRenderer renderer) { myRenderer = renderer; @@ -54,7 +54,7 @@ public class TreeLinkMouseListener extends LinkMouseListenerBase { if (path != null) { final Rectangle rectangle = tree.getPathBounds(path); int dx = e.getX() - rectangle.x; - final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent(); + final TreeNode treeNode = (TreeNode) path.getLastPathComponent(); if (myLastHitNode != treeNode) { myLastHitNode = treeNode; myRenderer.getTreeCellRendererComponent(tree, treeNode, false, false, treeNode.isLeaf(), -1, false); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java index 66394a03892a..de922b904dc5 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java @@ -35,4 +35,12 @@ public interface XValueNode extends Obsolescent { void setPresentation(@NonNls @NotNull String name, @Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @NotNull String value, boolean hasChildren); + /** + * If string representation of the value is too long to show in the tree pass truncated value to {@link #setPresentation(String, javax.swing.Icon, String, String, boolean)} + * method and call this method to provide full value. + * This will add a link to the node and show fullValue text if a user click on that link. + * @param fullValue full text of the value. Will be shown in popup window + * @param linkText text of the link. Will be appended to the node text + */ + void setFullValue(@NotNull String fullValue, @NotNull String linkText); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java index f77c5374b647..4a6ceb994bf5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java @@ -90,6 +90,10 @@ public class XValueHint extends AbstractValueHint { }); } + public void setFullValue(@NotNull String fullValue, @NotNull String linkText) { + //todo[nik] implement? + } + public boolean isObsolete() { //todo[nik] return false; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java index 6cb0b905ff2b..0e161a49bb30 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java @@ -15,15 +15,23 @@ */ package com.intellij.xdebugger.impl.ui; +import com.intellij.codeInsight.hint.HintUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.awt.RelativePoint; +import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.*; +import java.awt.event.MouseEvent; /** * User: lex @@ -81,4 +89,27 @@ public class DebuggerUIUtil { } return new RelativePoint(editor.getContentComponent(), p); } + + public static void showValuePopup(@NotNull String text, @NotNull MouseEvent event, @NotNull Project project) { + JTextArea textArea = new JTextArea(text); + textArea.setEditable(false); + textArea.setBackground(HintUtil.INFORMATION_COLOR); + textArea.setLineWrap(false); + final JScrollPane component = ScrollPaneFactory.createScrollPane(textArea); + component.setBorder(null); + final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null) + .setResizable(true) + .setMovable(true) + .setRequestFocus(false) + .createPopup(); + + final Dimension size = textArea.getPreferredSize(); + final Component parentComponent = event.getComponent(); + final Dimension frameSize = WindowManager.getInstance().getFrame(project).getSize(); + size.width = Math.min(size.width, frameSize.width / 2); + size.height = Math.min(size.height, frameSize.height / 2); + component.setPreferredSize(size); + RelativePoint point = new RelativePoint(parentComponent, new Point(event.getX()-size.width, event.getY()-size.height)); + popup.show(point); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java index c2c17fe92c14..6955e5f55ef3 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java @@ -21,16 +21,14 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener; import com.intellij.ui.TreeSpeedSearch; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; -import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import com.intellij.xdebugger.impl.ui.tree.nodes.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -75,6 +73,14 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider { myTreeModel = new DefaultTreeModel(null); setModel(myTreeModel); setCellRenderer(new XDebuggerTreeRenderer()); + new TreeLinkMouseListener(new XDebuggerTreeRenderer()) { + @Override + protected void handleTagClick(Object tag, MouseEvent event) { + if (tag instanceof XDebuggerNodeLink) { + ((XDebuggerNodeLink)tag).onClick(event); + } + } + }.install(this); setRootVisible(false); setShowsRootHandles(true); addMouseListener(new MouseAdapter() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java index ca23b3238f34..06f901c7f4c7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java @@ -16,6 +16,8 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerNodeLink; import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; import javax.swing.*; @@ -33,6 +35,10 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer { final boolean hasFocus) { XDebuggerTreeNode node = (XDebuggerTreeNode)value; node.getText().appendToComponent(this); + final XDebuggerNodeLink link = node.getLink(); + if (link != null) { + append(link.getLinkText(), SimpleTextAttributes.LINK_ATTRIBUTES, link); + } setIcon(node.getIcon()); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java new file mode 100644 index 000000000000..ea93a8ad7b99 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2010 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.xdebugger.impl.ui.tree.nodes; + +import java.awt.event.MouseEvent; + +/** + * @author nik + */ +public abstract class XDebuggerNodeLink { + private String myLinkText; + + protected XDebuggerNodeLink(String linkText) { + myLinkText = linkText; + } + + public String getLinkText() { + return myLinkText; + } + + public abstract void onClick(MouseEvent event); +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java index 3e3118e193c3..78019ab2d30d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java @@ -86,6 +86,11 @@ public abstract class XDebuggerTreeNode implements TreeNode { myLeaf = leaf; } + @Nullable + public XDebuggerNodeLink getLink() { + return null; + } + @NotNull public SimpleColoredText getText() { return myText; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index e34588039e74..43599c86f48b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -15,19 +15,20 @@ */ package com.intellij.xdebugger.impl.ui.tree.nodes; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.ui.SimpleTextAttributes; import com.intellij.xdebugger.frame.XCompositeNode; import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.frame.XValueNode; -import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; +import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; -import com.intellij.openapi.application.ApplicationManager; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NonNls; import javax.swing.*; +import java.awt.event.MouseEvent; /** * @author nik @@ -36,8 +37,10 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu private String myName; private String myType; private String myValue; + private String myFullValue; private String mySeparator; private boolean myChanged; + private String myLinkText; public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, final XValue value) { super(tree, parent, value); @@ -69,6 +72,16 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu }); } + public void setFullValue(@NotNull final String fullValue, @NotNull final String linkText) { + DebuggerUIUtil.invokeOnEventDispatch(new Runnable() { + public void run() { + myLinkText = linkText; + myFullValue = fullValue; + fireNodeChanged(); + } + }); + } + private void updateText() { myText.clear(); myText.append(myName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES); @@ -95,8 +108,24 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu return myName; } + @Override + public XDebuggerNodeLink getLink() { + if (myFullValue != null) { + return new XDebuggerNodeLink(myLinkText) { + @Override + public void onClick(MouseEvent event) { + DebuggerUIUtil.showValuePopup(myFullValue, event, myTree.getProject()); + } + }; + } + return null; + } + @Nullable public String getValue() { + if (myFullValue != null) { + return myFullValue; + } return myValue; }