diff --git a/build.xml b/build.xml index 0ee6355da613..fa2c7bd0ee23 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,7 @@ + @@ -9,6 +10,7 @@ + @@ -17,6 +19,8 @@ + + @@ -37,5 +41,9 @@ + + + + diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java index c8c4bae7334e..9d92c03e0781 100644 --- a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java +++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java @@ -28,7 +28,6 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.cls.BytePointer; import com.intellij.util.cls.ClsFormatException; import com.intellij.util.cls.ClsUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +53,8 @@ public class ClassFileReader { private final SymbolTable mySymbolTable; private AnnotationConstantValue[] myRuntimeVisibleAnnotations; private AnnotationConstantValue[] myRuntimeInvisibleAnnotations; - @NonNls private static final String CONSTRUCTOR_NAME = ""; + private static final String CONSTRUCTOR_NAME = ""; + private boolean myParsingDone; public ClassFileReader(@NotNull File file, SymbolTable symbolTable, @Nullable final byte[] fileContent) { mySymbolTable = symbolTable; @@ -72,20 +72,19 @@ public class ClassFileReader { } public MethodInfo[] getMethods() throws ClsFormatException{ - if (myMethods == null) { - parseMembers(); - } + parseMembers(); return myMethods.toArray(new MethodInfo[myMethods.size()]); } public FieldInfo[] getFields() throws ClsFormatException{ - if (myFields == null) { - parseMembers(); - } + parseMembers(); return myFields.toArray(new FieldInfo[myFields.size()]); } private void parseMembers() throws ClsFormatException { + if (myParsingDone) { + return; + } initConstantPool(); myMethods = new ArrayList(); myFields = new ArrayList(); @@ -121,6 +120,7 @@ public class ClassFileReader { myGenericSignature = attributeTable.genericSignature; myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations; myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations; + myParsingDone = true; } private String getSymbol(final int id) throws ClsFormatException { @@ -253,43 +253,27 @@ public class ClassFileReader { public String getSourceFileName() throws ClsFormatException { - if (mySourceFileName == null) { - parseMembers(); - if (mySourceFileName == null) { - mySourceFileName = ""; - } - } - return mySourceFileName; + parseMembers(); + final String fName = mySourceFileName; + return fName != null? fName : ""; } public String getGenericSignature() throws ClsFormatException { - if (myGenericSignature == null) { - parseMembers(); - if (myGenericSignature == null) { - myGenericSignature = ""; - } - } - return myGenericSignature.length() == 0 ? null : myGenericSignature; + parseMembers(); + final String genericSignature = myGenericSignature; + return genericSignature != null && !genericSignature.isEmpty() ? genericSignature : null; } public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException { - if (myRuntimeVisibleAnnotations == null) { - parseMembers(); - if (myRuntimeVisibleAnnotations == null) { - myRuntimeVisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; - } - } - return myRuntimeVisibleAnnotations; + parseMembers(); + final AnnotationConstantValue[] annotations = myRuntimeVisibleAnnotations; + return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY; } public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException { - if (myRuntimeInvisibleAnnotations == null) { - parseMembers(); - if (myRuntimeInvisibleAnnotations == null) { - myRuntimeInvisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; - } - } - return myRuntimeInvisibleAnnotations; + parseMembers(); + final AnnotationConstantValue[] annotations = myRuntimeInvisibleAnnotations; + return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY; } private boolean isInterface(){ diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index e884f85dbfd8..b4321a5b9322 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -190,7 +190,7 @@ public class CompileDriver { } scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING); - final CompilerTask task = new CompilerTask(myProject, true, "", true); + final CompilerTask task = new CompilerTask(myProject, true, "Classes up-to-date check", true); final CompileContextImpl compileContext = new CompileContextImpl(myProject, task, scope, createDependencyCache(), true, false); checkCachesVersion(compileContext, ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp()); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java index 6b5eadf8ff34..ca323d4ad528 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java @@ -37,7 +37,6 @@ public interface DebuggerActions extends XDebuggerActions { @NonNls String REMOVE_WATCH = "Debugger.RemoveWatch"; @NonNls String NEW_WATCH = "Debugger.NewWatch"; @NonNls String EDIT_WATCH = "Debugger.EditWatch"; - @NonNls String MARK_OBJECT = "Debugger.MarkObject"; @NonNls String COPY_VALUE = "Debugger.CopyValue"; @NonNls String SET_VALUE = "Debugger.SetValue"; @NonNls String EDIT_FRAME_SOURCE = "Debugger.EditFrameSource"; diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java similarity index 86% rename from java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java rename to java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java index 37b129cd385f..18e54211dc45 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java @@ -16,6 +16,7 @@ package com.intellij.debugger.actions; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; @@ -26,17 +27,18 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; -import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.util.containers.HashMap; +import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.sun.jdi.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -51,14 +53,13 @@ import java.util.Map; * Class SetValueAction * @author Jeka */ -public class MarkObjectAction extends DebuggerAction { - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.MarkObjectAction"); +public class JavaMarkObjectActionHandler extends MarkObjectActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.JavaMarkObjectActionHandler"); public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit - private final String MARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.text"); - private final String UNMARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.unmark.text"); - public void actionPerformed(final AnActionEvent event) { - final DebuggerTreeNodeImpl node = getSelectedNode(event.getDataContext()); + @Override + public void perform(@NotNull Project project, AnActionEvent event) { + final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext()); if (node == null) { return; } @@ -233,24 +234,27 @@ public class MarkObjectAction extends DebuggerAction { return builder.append("
").append(refType.name()).append(".").append(fieldName).append("").toString(); } + @Override + public boolean isEnabled(@NotNull Project project, AnActionEvent event) { + final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext()); + return node != null && node.getDescriptor() instanceof ValueDescriptor; + } - public void update(AnActionEvent e) { - boolean enable = false; - String text = MARK_TEXT; - final DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); - if (node != null) { - final NodeDescriptorImpl descriptor = node.getDescriptor(); - enable = (descriptor instanceof ValueDescriptor); - if (enable) { - final ValueMarkup markup = ((ValueDescriptor)descriptor).getMarkup(node.getTree().getDebuggerContext().getDebugProcess()); - if (markup != null) { // already exists - text = UNMARK_TEXT; - } - } - } - final Presentation presentation = e.getPresentation(); - presentation.setVisible(enable); - presentation.setText(text); + @Override + public boolean isHidden(@NotNull Project project, AnActionEvent event) { + return DebuggerAction.getSelectedNode(event.getDataContext()) == null; + } + + @Override + public boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event) { + final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext()); + if (node == null) return false; + + final NodeDescriptorImpl descriptor = node.getDescriptor(); + if (!(descriptor instanceof ValueDescriptor)) return false; + + DebugProcess debugProcess = node.getTree().getDebuggerContext().getDebugProcess(); + return ((ValueDescriptor)descriptor).getMarkup(debugProcess) != null; } public static Color getAutoMarkupColor() { diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java index 15ef421bdea1..fe2ac9ee5bf5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java @@ -17,7 +17,7 @@ package com.intellij.debugger.actions; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.ui.ex.MultiLineLabel; -import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialogBase; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -28,7 +28,7 @@ import java.awt.*; * @author Eugene Zhuravlev * Date: Feb 4, 2007 */ -public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialog { +public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialogBase { @NonNls private static final String MARK_ALL_REFERENCED_VALUES_KEY = "debugger.mark.all.referenced.values"; private JCheckBox myCbMarkAdditionalFields; private final boolean mySuggestAdditionalMarkup; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 76d5a6985672..71646e033b74 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -29,8 +29,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.xdebugger.AbstractDebuggerSession; import com.intellij.xdebugger.impl.DebuggerSupport; -import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; -import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler; +import com.intellij.xdebugger.impl.actions.*; +import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler; import com.intellij.xdebugger.impl.breakpoints.ui.AbstractBreakpointPanel; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; @@ -63,6 +63,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final MuteBreakpointsActionHandler myMuteBreakpointsHandler = new MuteBreakpointsActionHandler(); private final DebuggerActionHandler mySmartStepIntoHandler = new SmartStepIntoActionHandler(); private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler(); + private JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler(); @NotNull public BreakpointPanelProvider getBreakpointPanelProvider() { @@ -150,6 +151,12 @@ public class JavaDebuggerSupport extends DebuggerSupport { return myMuteBreakpointsHandler; } + @NotNull + @Override + public MarkObjectActionHandler getMarkObjectHandler() { + return myMarkObjectActionHandler; + } + @Override public AbstractDebuggerSession getCurrentSession(@NotNull Project project) { final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java index fbbcad3b909c..7dd324df7cfa 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java @@ -19,7 +19,6 @@ */ package com.intellij.debugger.ui.impl; -import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.DebuggerStateManager; import com.intellij.debugger.ui.impl.watch.DebuggerTree; @@ -30,6 +29,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; import com.intellij.ui.PopupHandler; +import com.intellij.xdebugger.impl.actions.XDebuggerActions; import javax.swing.*; import java.awt.*; @@ -68,7 +68,7 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("ToggleBookmark"); final CustomShortcutSet shortcutSet = shortcuts.length > 0? new CustomShortcutSet(shortcuts) : new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0)); - overrideShortcut(myTree, DebuggerActions.MARK_OBJECT, shortcutSet); + overrideShortcut(myTree, XDebuggerActions.MARK_OBJECT, shortcutSet); } protected abstract DebuggerTree createTreeView(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index c1f9de00e9e8..b4e46edf150b 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -48,6 +48,8 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.refactoring.util.occurences.OccurenceManager; import com.intellij.ui.StateRestoringCheckBox; import com.intellij.ui.TitlePanel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -261,14 +263,24 @@ public class InplaceIntroduceConstantPopup { } public void performInplaceIntroduce() { - startIntroduceTemplate(false); + startIntroduceTemplate(false, null); } - private void startIntroduceTemplate(final boolean replaceAllOccurrences) { + private void startIntroduceTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) { CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { myTypeSelectorManager.setAllOccurences(replaceAllOccurrences); - final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType(); + PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType(); + if (fieldDefaultType != null) { + if (replaceAllOccurrences) { + if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) { + defaultType = fieldDefaultType; + } + } + else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1) { + defaultType = fieldDefaultType; + } + } final String propName = myLocalVariable != null ? JavaCodeStyleManager .getInstance(myProject).variableNameToPropertyName(myLocalVariable.getName(), VariableKind.LOCAL_VARIABLE) : null; final String[] names = IntroduceConstantDialog.createNameSuggestionGenerator(propName, myExpr, JavaCodeStyleManager.getInstance(myProject)) @@ -337,7 +349,7 @@ public class InplaceIntroduceConstantPopup { private SmartTypePointer myFieldTypePointer; public FieldInplaceIntroducer(PsiField field) { - super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), + super(myProject, new TypeExpression(myProject, myReplaceAllCb.isSelected() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()), myEditor, field, false, myTypeSelectorManager.getTypesForAll().length > 1, myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers(), @@ -456,8 +468,8 @@ public class InplaceIntroduceConstantPopup { final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); if (templateState != null) { templateState.gotoEnd(true); - myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myFieldTypePointer.getType(), null, myExpr, myOccurrences); - startIntroduceTemplate(isReplaceAllOccurrences()); + myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myExpr, myOccurrences); + startIntroduceTemplate(isReplaceAllOccurrences(), myFieldTypePointer.getType()); } } }); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 50ae57f05937..39b4b3df62bc 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -35,6 +35,8 @@ import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.refactoring.util.occurences.OccurenceManager; import com.intellij.ui.TitlePanel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -151,15 +153,24 @@ public class InplaceIntroduceFieldPopup { } public void startTemplate() { - startTemplate(false); + startTemplate(false, null); } - public void startTemplate(final boolean replaceAllOccurrences) { + public void startTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) { CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { myTypeSelectorManager.setAllOccurences(replaceAllOccurrences); - final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType(); + PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType(); + if (fieldDefaultType != null) { + if (replaceAllOccurrences) { + if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) { + defaultType = fieldDefaultType; + } + } else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1){ + defaultType = fieldDefaultType; + } + } final SuggestedNameInfo suggestedNameInfo = IntroduceFieldDialog.createGenerator(myStatic, myLocalVariable, myInitializerExpression, myLocalVariable != null) @@ -227,7 +238,7 @@ public class InplaceIntroduceFieldPopup { private SmartTypePointer myFieldTypePointer; public FieldInplaceIntroducer(PsiVariable psiVariable) { - super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), + super(myProject, new TypeExpression(myProject, myIntroduceFieldPanel.isReplaceAllOccurrences() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()), myEditor, psiVariable, false, myTypeSelectorManager.getTypesForAll().length > 1, myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers(), @@ -296,8 +307,8 @@ public class InplaceIntroduceFieldPopup { final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); if (templateState != null) { templateState.gotoEnd(true); - myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myFieldTypePointer.getType(), null, myInitializerExpression, myOccurrences); - startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences()); + myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myInitializerExpression, myOccurrences); + startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences(), myFieldTypePointer.getType()); } } }); @@ -312,6 +323,10 @@ public class InplaceIntroduceFieldPopup { if (element instanceof PsiWhiteSpace) { element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class); } + if (element instanceof PsiField) return (PsiVariable)element; + final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class, false); + if (field != null) return field; + element = PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace.class); return PsiTreeUtil.getParentOfType(element, PsiField.class, false); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java index 63c3e400c22a..708f256124e3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java @@ -116,7 +116,9 @@ public abstract class IntroduceFieldCentralPanel { if (myCbReplaceAll != null && myAllowInitInMethod) { updateInitializerSelection(); } - updateTypeSelector(); + if (shouldUpdateTypeSelector()) { + updateTypeSelector(); + } } }; ItemListener finalUpdater = new ItemListener() { @@ -137,6 +139,10 @@ public abstract class IntroduceFieldCentralPanel { protected void updateInitializerSelection() { } + protected boolean shouldUpdateTypeSelector() { + return true; + } + private JPanel appendCheckboxes(ItemListener itemListener) { GridBagConstraints gbConstraints = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1,1,0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); JPanel panel = new JPanel(new GridBagLayout()); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java index 7459de29e621..18d512e77e47 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java @@ -232,6 +232,11 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel { return allowFinal; } + @Override + protected boolean shouldUpdateTypeSelector() { + return false; + } + protected JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel) { final JPanel panel = new JPanel(new GridBagLayout()); final GridBagConstraints constraints = diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index def824918107..578852739796 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -20,9 +20,7 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; @@ -184,6 +182,11 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { } private void startIntroduceTemplate(final boolean replaceAllOccurrences) { + startIntroduceTemplate(replaceAllOccurrences, hasFinalModifier()); + } + + private void startIntroduceTemplate(final boolean replaceAllOccurrences, + final boolean hasFinalModifier) { CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { myTypeSelectorManager.setAllOccurences(replaceAllOccurrences); @@ -192,7 +195,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject) .getSuggestedNameInfo(defaultType).names; - final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType); + final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType, hasFinalModifier); if (parameter != null) { myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter); myEditor.getCaretModel().moveToOffset(parameter.getTextOffset()); @@ -399,14 +402,17 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { if (myParameterIndex < 0) return; final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); if (templateState != null) { + PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument()); + final PsiParameter parameter = getParameter(); + final boolean hasFinalModifier = parameter.hasModifierProperty(PsiModifier.FINAL); templateState.gotoEnd(true); - startIntroduceTemplate(isReplaceAllOccurences()); + startIntroduceTemplate(isReplaceAllOccurences(), hasFinalModifier); } } private PsiParameter createParameterToStartTemplateOn(final String[] names, - final PsiType defaultType) { + final PsiType defaultType, final boolean hasFinalModifier) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject()); return ApplicationManager.getApplication().runWriteAction(new Computable() { @Override @@ -415,7 +421,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod); final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList() .addAfter(elementFactory.createParameter(name, defaultType), anchor); - PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier()); + PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier); return psiParameter; } }); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 01c6be53da7d..26e83f1db733 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -456,8 +456,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final IntroduceVariableSettings settings = getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, choice); if (!settings.isOK()) return; - typeSelectorManager.setAllOccurences(choice != OccurrencesChooser.ReplaceChoice.NO); - final TypeExpression expression = new TypeExpression(project, typeSelectorManager.getTypesForAll()); + final boolean allOccurences = choice != OccurrencesChooser.ReplaceChoice.NO; + typeSelectorManager.setAllOccurences(allOccurences); + final TypeExpression expression = new TypeExpression(project, allOccurences ? typeSelectorManager.getTypesForAll() : typeSelectorManager.getTypesForOne()); final RangeMarker exprMarker = editor.getDocument().createRangeMarker(expr.getTextRange()); final SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr); final List occurrenceMarkers = new ArrayList(); diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java index 79f624db5293..e1d2f4a31f95 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java @@ -179,10 +179,12 @@ public class PullUpConflictsUtil { } }); if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { - String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + - " abstract as it won't be accessible from the subclass."; - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(abstractMethod, message); + if (!isInterfaceTarget) { + String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + + " abstract as it won't be accessible from the subclass."; + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(abstractMethod, message); + } } } return conflicts; diff --git a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java index a4ae0cdf045b..cb7e3f16398b 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -133,6 +133,10 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { return myTypesForAll; } + public PsiType[] getTypesForOne() { + return myTypesForMain; + } + public PsiType getDefaultType() { if (myDefaultType.isValid()) { return myDefaultType; diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java index 8dc6a06991c9..3802d1bd7cc6 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull; public abstract class CompletionResultSet { private final PrefixMatcher myPrefixMatcher; private final Consumer myConsumer; - private final CompletionService myCompletionService = CompletionService.getCompletionService(); + protected final CompletionService myCompletionService = CompletionService.getCompletionService(); protected final CompletionContributor myContributor; private boolean myStopped; @@ -41,11 +41,7 @@ public abstract class CompletionResultSet { * If a given element matches the prefix, give it for further processing (which may eventually result in its appearing in the completion list) * @param element */ - public void addElement(@NotNull final LookupElement element) { - if (myCompletionService.prefixMatches(element, getPrefixMatcher())) { - myConsumer.consume(element); - } - } + public abstract void addElement(@NotNull final LookupElement element); public void addAllElements(@NotNull final Iterable elements) { for (LookupElement element : elements) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index be5f27255a0a..f140027481f2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -23,7 +23,6 @@ import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupArranger; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.WeighingService; import com.intellij.psi.statistics.StatisticsInfo; @@ -38,13 +37,14 @@ import org.jetbrains.annotations.NotNull; import java.util.*; public class CompletionLookupArranger extends LookupArranger { - public static final Key SORTER_KEY = Key.create("SORTER_KEY"); private static final String SELECTED = "selected"; static final String IGNORED = "ignored"; private final CompletionLocation myLocation; private final Map mySortingWeights = new THashMap(TObjectHashingStrategy.IDENTITY); + private final CompletionProgressIndicator myProcess; - public CompletionLookupArranger(final CompletionParameters parameters) { + public CompletionLookupArranger(final CompletionParameters parameters, CompletionProgressIndicator process) { + myProcess = process; myLocation = new CompletionLocation(parameters); } @@ -150,7 +150,7 @@ public class CompletionLookupArranger extends LookupArranger { @NotNull private CompletionSorterImpl obtainSorter(LookupElement element) { - return element.getUserData(SORTER_KEY); + return myProcess.getSorter(element); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 056d4a99ae1b..4b058324d323 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; +import com.intellij.codeInsight.completion.impl.CompletionSorterImpl; import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.EditorHintListener; import com.intellij.codeInsight.hint.HintManager; @@ -62,6 +63,7 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Collections; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -103,6 +105,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } }; private volatile int myCount; + private final ConcurrentHashMap myItemSorters = new ConcurrentHashMap(); public CompletionProgressIndicator(final Editor editor, CompletionParameters parameters, CodeCompletionHandlerBase handler, Semaphore freezeSemaphore, final OffsetMap offsetMap, LookupImpl lookup, boolean hasModifiers) { @@ -113,7 +116,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myOffsetMap = offsetMap; myLookup = lookup; - myLookup.setArranger(new CompletionLookupArranger(parameters)); + myLookup.setArranger(new CompletionLookupArranger(parameters, this)); myLookup.addLookupListener(myLookupListener); myLookup.setCalculating(true); @@ -187,6 +190,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } + public void setItemSorter(LookupElement element, CompletionSorterImpl sorter) { + myItemSorters.putIfAbsent(element, sorter); + } + + @NotNull + public CompletionSorterImpl getSorter(LookupElement element) { + return myItemSorters.get(element); + } + private static int findReplacementOffset(int selectionEndOffset, PsiReference reference) { final List ranges = ReferenceRange.getAbsoluteRanges(reference); for (TextRange range : ranges) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 7cba8937de37..b9f853acff0f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -46,7 +46,7 @@ import java.util.ArrayList; public class CompletionServiceImpl extends CompletionService{ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl"); private Throwable myTrace = null; - private CompletionProgressIndicator myCurrentCompletion; + private volatile CompletionProgressIndicator myCurrentCompletion; private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion; private static String ourPhaseTrace; @@ -82,7 +82,11 @@ public class CompletionServiceImpl extends CompletionService{ final PsiElement position = parameters.getPosition(); final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); - return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix, true, parameters.relaxMatching()), contributor, parameters, defaultSorter(parameters), null); + CompletionProgressIndicator process = myCurrentCompletion; + LOG.assertTrue(process != null, "createResultSet may be invoked only during completion"); + CamelHumpMatcher matcher = new CamelHumpMatcher(prefix, true, parameters.relaxMatching()); + CompletionSorterImpl sorter = defaultSorter(parameters); + return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null); } @Override @@ -110,6 +114,7 @@ public class CompletionServiceImpl extends CompletionService{ private final String myTextBeforePosition; private final CompletionParameters myParameters; private final CompletionSorterImpl mySorter; + private final CompletionProgressIndicator myProcess; @Nullable private final CompletionResultSetImpl myOriginal; public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition, @@ -117,18 +122,21 @@ public class CompletionServiceImpl extends CompletionService{ CompletionContributor contributor, CompletionParameters parameters, @NotNull CompletionSorterImpl sorter, + @NotNull CompletionProgressIndicator process, CompletionResultSetImpl original) { super(prefixMatcher, consumer, contributor); myTextBeforePosition = textBeforePosition; myParameters = parameters; mySorter = sorter; + myProcess = process; myOriginal = original; } - @Override - public void addElement(@NotNull LookupElement element) { - element.putUserDataIfAbsent(CompletionLookupArranger.SORTER_KEY, mySorter); - super.addElement(element); + public void addElement(@NotNull final LookupElement element) { + if (myCompletionService.prefixMatches(element, getPrefixMatcher())) { + myProcess.setItemSorter(element, mySorter); + getConsumer().consume(element); + } } @NotNull @@ -142,7 +150,7 @@ public class CompletionServiceImpl extends CompletionService{ "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) + "\nlang=" + positionFile.getLanguage()); } - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, this); + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this); } @Override @@ -162,7 +170,7 @@ public class CompletionServiceImpl extends CompletionService{ @NotNull @Override public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) { - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, this); + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java index 0caed03d9f5c..e1100feb35fe 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java @@ -40,6 +40,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -281,17 +282,22 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme return myCurrentInfo; } + private final @NonNls String PASTE_COMMAND_NAME = EditorBundle.message("paste.command.name"); + private final @NonNls String TYPING_COMMAND_NAME = EditorBundle.message("typing.in.editor.command.name"); + @Override public void beforeDocumentChange(DocumentEvent e) { if (myDeaf) return; if (myInitialText == null) { final Document document = e.getDocument(); final PsiDocumentManager documentManager = myPsiDocumentManager; + if (!documentManager.isUncommited(document)) { final CommandProcessor processor = CommandProcessor.getInstance(); final String currentCommandName = processor.getCurrentCommandName(); - if (!Comparing.strEqual(EditorBundle.message("typing.in.editor.command.name"), currentCommandName) && - !Comparing.strEqual(EditorBundle.message("paste.command.name"), currentCommandName) && + + if (!Comparing.strEqual(TYPING_COMMAND_NAME, currentCommandName) && + !Comparing.strEqual(PASTE_COMMAND_NAME, currentCommandName) && !Comparing.strEqual("Cut", currentCommandName) && !Comparing.strEqual(LanguageChangeSignatureDetector.MOVE_PARAMETER, currentCommandName) && !Comparing.equal(EditorActionUtil.DELETE_COMMAND_GROUP, processor.getCurrentCommandGroupId())) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 509b6dee0a40..a1a4ea9afca6 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -413,9 +413,11 @@ public class VariableInplaceRenamer { ourRenamersStack.pop(); } if (myHighlighters != null) { - final HighlightManager highlightManager = HighlightManager.getInstance(myProject); - for (RangeHighlighter highlighter : myHighlighters) { - highlightManager.removeSegmentHighlighter(myEditor, highlighter); + if (!myProject.isDisposed()) { + final HighlightManager highlightManager = HighlightManager.getInstance(myProject); + for (RangeHighlighter highlighter : myHighlighters) { + highlightManager.removeSegmentHighlighter(myEditor, highlighter); + } } myHighlighters = null; diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java index 9fc55f36650f..d40b8486d465 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java @@ -78,34 +78,50 @@ public class AbstractTreeBuilder implements Disposable { } public final void select(final Object element) { + if (isDisposed()) return; + getUi().userSelect(new Object[] {element}, null, false, true); } public final void select(final Object element, @Nullable final Runnable onDone) { + if (isDisposed()) return; + getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), false, true); } public final void select(final Object element, @Nullable final Runnable onDone, boolean addToSelection) { + if (isDisposed()) return; + getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), addToSelection, true); } public final void select(final Object[] elements, @Nullable final Runnable onDone) { + if (isDisposed()) return; + getUi().userSelect(elements, new UserRunnable(onDone), false, true); } public final void select(final Object[] elements, @Nullable final Runnable onDone, boolean addToSelection) { + if (isDisposed()) return; + getUi().userSelect(elements, new UserRunnable(onDone), addToSelection, true); } public final void expand(Object element, @Nullable Runnable onDone) { + if (isDisposed()) return; + getUi().expand(element, new UserRunnable(onDone)); } public final void expand(Object[] element, @Nullable Runnable onDone) { + if (isDisposed()) return; + getUi().expand(element, new UserRunnable(onDone)); } public final void collapseChildren(Object element, @Nullable Runnable onDone) { + if (isDisposed()) return; + getUi().collapseChildren(element, new UserRunnable(onDone)); } @@ -115,37 +131,54 @@ public class AbstractTreeBuilder implements Disposable { } public final AbstractTreeBuilder setClearOnHideDelay(final long clearOnHideDelay) { + if (isDisposed()) return this; + getUi().setClearOnHideDelay(clearOnHideDelay); + return this; } protected AbstractTreeUpdater createUpdater() { + if (isDisposed()) return null; + AbstractTreeUpdater updater = new AbstractTreeUpdater(this); updater.setModalityStateComponent(MergingUpdateQueue.ANY_COMPONENT); return updater; } protected final AbstractTreeUpdater getUpdater() { + if (isDisposed()) return null; + return getUi().getUpdater(); } public final boolean addSubtreeToUpdateByElement(Object element) { + if (isDisposed()) return false; + return getUpdater().addSubtreeToUpdateByElement(element); } public final void addSubtreeToUpdate(DefaultMutableTreeNode node) { + if (isDisposed()) return; + getUi().addSubtreeToUpdate(node); } public final void addSubtreeToUpdate(DefaultMutableTreeNode node, Runnable afterUpdate) { + if (isDisposed()) return; + getUi().addSubtreeToUpdate(node, afterUpdate); } public final DefaultMutableTreeNode getRootNode() { + if (isDisposed()) return null; + return getUi().getRootNode(); } public final void setNodeDescriptorComparator(Comparator nodeDescriptorComparator) { + if (isDisposed()) return; + getUi().setNodeDescriptorComparator(nodeDescriptorComparator); } @@ -161,6 +194,8 @@ public class AbstractTreeBuilder implements Disposable { protected void updateNode(final DefaultMutableTreeNode node) { + if (isDisposed()) return; + getUi().doUpdateNode(node); } @@ -173,14 +208,20 @@ public class AbstractTreeBuilder implements Disposable { } public final JTree getTree() { + if (isDisposed()) return null; + return getUi().getTree(); } public final AbstractTreeStructure getTreeStructure() { + if (isDisposed()) return null; + return getUi().getTreeStructure(); } public final void setTreeStructure(final AbstractTreeStructure structure) { + if (isDisposed()) return; + getUi().setTreeStructure(structure); } @@ -201,6 +242,8 @@ public class AbstractTreeBuilder implements Disposable { } public void initRootNode() { + if (isDisposed()) return; + getUi().initRootNode(); } @@ -216,16 +259,29 @@ public class AbstractTreeBuilder implements Disposable { return queueUpdateFrom(element, forceResort, true); } - public ActionCallback queueUpdateFrom(final Object element, final boolean forceResort, boolean updateStructure) { - if (!updateStructure) { - return getUi().queueUpdate(element, false); - } else { - if (forceResort) { - getUi().incComparatorStamp(); - } + public ActionCallback queueUpdateFrom(final Object element, final boolean forceResort, final boolean updateStructure) { + if (getUi() == null) return new ActionCallback.Rejected(); - return getUi().queueUpdate(element, true); - } + final ActionCallback result = new ActionCallback(); + + getUi().invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!updateStructure) { + getUi().queueUpdate(element, false).notify(result); + } + else { + if (forceResort) { + getUi().incComparatorStamp(); + } + + getUi().queueUpdate(element, true).notify(result); + } + } + }); + + + return result; } /** @@ -233,6 +289,8 @@ public class AbstractTreeBuilder implements Disposable { * @param element */ public void buildNodeForElement(Object element) { + if (isDisposed()) return; + getUi().buildNodeForElement(element); } @@ -243,10 +301,14 @@ public class AbstractTreeBuilder implements Disposable { */ @Nullable public DefaultMutableTreeNode getNodeForElement(Object element) { + if (isDisposed()) return null; + return getUi().getNodeForElement(element, false); } public void cleanUp() { + if (isDisposed()) return; + getUi().doCleanUp(); } @@ -256,10 +318,14 @@ public class AbstractTreeBuilder implements Disposable { } protected void expandNodeChildren(final DefaultMutableTreeNode node) { + if (isDisposed()) return; + getUi().doExpandNodeChildren(node); } protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) { + if (isDisposed()) return false; + return getTreeStructure().getRootElement() == getTreeStructureElement(nodeDescriptor); } @@ -282,14 +348,20 @@ public class AbstractTreeBuilder implements Disposable { * @param node */ public final void updateSubtree(final DefaultMutableTreeNode node) { + if (isDisposed()) return; + getUi().updateSubtree(node, true); } public final boolean wasRootNodeInitialized() { + if (isDisposed()) return false; + return getUi().wasRootNodeInitialized(); } public final boolean isNodeBeingBuilt(final TreePath path) { + if (isDisposed()) return false; + return getUi().isNodeBeingBuilt(path); } @@ -298,6 +370,8 @@ public class AbstractTreeBuilder implements Disposable { * @param path */ public final void buildNodeForPath(final Object[] path) { + if (isDisposed()) return; + getUi().buildNodeForPath(path); } @@ -305,10 +379,14 @@ public class AbstractTreeBuilder implements Disposable { * @deprecated */ public final DefaultMutableTreeNode getNodeForPath(final Object[] path) { + if (isDisposed()) return null; + return getUi().getNodeForPath(path); } protected Object findNodeByElement(final Object element) { + if (isDisposed()) return null; + return getUi().findNodeByElement(element); } @@ -321,6 +399,8 @@ public class AbstractTreeBuilder implements Disposable { } protected void runOnYeildingDone(Runnable onDone) { + if (isDisposed()) return; + if (myUi.isPassthroughMode()) { onDone.run(); } else { @@ -329,6 +409,8 @@ public class AbstractTreeBuilder implements Disposable { } protected void yield(Runnable runnable) { + if (isDisposed()) return; + if (myUi.isPassthroughMode()) { runnable.run(); } else { @@ -346,6 +428,7 @@ public class AbstractTreeBuilder implements Disposable { protected void runBackgroundLoading(final Runnable runnable) { if (isDisposed()) return; + final Application app = ApplicationManager.getApplication(); if (app != null) { app.runReadAction(new Runnable() { @@ -359,6 +442,8 @@ public class AbstractTreeBuilder implements Disposable { } protected void updateAfterLoadedInBackground(Runnable runnable) { + if (isDisposed()) return; + if (myUi.isPassthroughMode()) { runnable.run(); } else { @@ -367,10 +452,14 @@ public class AbstractTreeBuilder implements Disposable { } public final ActionCallback getIntialized() { + if (isDisposed()) return new ActionCallback.Rejected(); + return myUi.getInitialized(); } public final ActionCallback getReady(Object requestor) { + if (isDisposed()) return new ActionCallback.Rejected(); + return myUi.getReady(requestor); } @@ -379,22 +468,32 @@ public class AbstractTreeBuilder implements Disposable { } public void setPassthroughMode(boolean passthrough) { + if (isDisposed()) return; + myUi.setPassthroughMode(passthrough); } public void expandAll(@Nullable Runnable onDone) { + if (isDisposed()) return; + getUi().expandAll(onDone); } public ActionCallback cancelUpdate() { + if (isDisposed()) return new ActionCallback.Rejected(); + return getUi().cancelUpdate(); } public ActionCallback batch(Progressive progressive) { + if (isDisposed()) return new ActionCallback.Rejected(); + return getUi().batch(progressive); } public AsyncResult revalidateElement(Object element) { + if (isDisposed()) return new AsyncResult.Rejected(); + return getTreeStructure().revalidateElement(element); } @@ -427,16 +526,21 @@ public class AbstractTreeBuilder implements Disposable { } protected boolean updateNodeDescriptor(final NodeDescriptor descriptor) { + if (isDisposed()) return false; + return getUi().doUpdateNodeDescriptor(descriptor); } public final DefaultTreeModel getTreeModel() { + if (isDisposed()) return null; + return (DefaultTreeModel)getTree().getModel(); } @NotNull public final Set getSelectedElements() { if (isDisposed()) return Collections.emptySet(); + return getUi().getSelectedElements(); } @@ -458,6 +562,8 @@ public class AbstractTreeBuilder implements Disposable { } public final void setCanYieldUpdate(boolean yield) { + if (isDisposed()) return; + getUi().setCanYield(yield); } @@ -500,6 +606,8 @@ public class AbstractTreeBuilder implements Disposable { } public void scrollSelectionToVisible(@Nullable Runnable onDone, boolean shouldBeCentered) { + if (isDisposed()) return; + myUi.scrollSelectionToVisible(onDone, shouldBeCentered); } @@ -534,4 +642,8 @@ public class AbstractTreeBuilder implements Disposable { } } + private void assertDisposed() { + assert !isDisposed(); + } + } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index 7af773067a1d..27f270952272 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -340,13 +340,17 @@ public class AbstractTreeUi { } } - private ActionCallback invokeLaterIfNeeded(@NotNull final Runnable runnable) { + public ActionCallback invokeLaterIfNeeded(@NotNull final Runnable runnable) { final ActionCallback result = new ActionCallback(); Runnable actual = new Runnable() { public void run() { - runnable.run(); - result.setDone(); + if (isReleased()) { + result.setRejected(); + } else { + runnable.run(); + result.setDone(); + } } }; @@ -880,7 +884,7 @@ public class AbstractTreeUi { } } - private void assertIsDispatchThread() { + public void assertIsDispatchThread() { if (isPassthroughMode()) return; if ((isTreeShowing() || myWasEverShown) && !isEdt()) { @@ -923,6 +927,8 @@ public class AbstractTreeUi { } public ActionCallback queueUpdate(Object element, boolean updateStructure) { + assertIsDispatchThread(); + try { AbstractTreeUpdater updater = getUpdater(); if (updater == null) { @@ -3387,17 +3393,26 @@ public class AbstractTreeUi { TreeBuilderUtil.restorePaths(getBuilder(), pathsToExpand, selectionPaths, false); } else { - myTreeModel.nodeChanged(node); + nodeChanged(node); } } else { - myTreeModel.nodeChanged(node); + nodeChanged(node); } } else if (nodeChanged) { - myTreeModel.nodeChanged(node); + nodeChanged(node); } } + private void nodeChanged(final DefaultMutableTreeNode node) { + invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + myTreeModel.nodeChanged(node); + } + }); + } + public DefaultTreeModel getTreeModel() { return myTreeModel; } @@ -3599,6 +3614,8 @@ public class AbstractTreeUi { final boolean canSmartExpand, final boolean mayQueue) { + assertIsDispatchThread(); + AbstractTreeUpdater updater = getUpdater(); if (mayQueue && updater != null) { updater.queueSelection( diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java index 077bf8052a30..63e268e90d7c 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java @@ -57,6 +57,11 @@ public class TreeState implements JDOMExternalizable { myUserObject = null; } + @Override + public String toString() { + return myItemId + ":" + myItemType; + } + public boolean matchedWith(NodeDescriptor nodeDescriptor) { return Comparing.equal(myItemId, getDescriptorKey(nodeDescriptor)) && Comparing.equal(myItemType, getDescriptorType(nodeDescriptor)); @@ -318,7 +323,9 @@ public class TreeState implements JDOMExternalizable { } - private static boolean applyTo(final int positionInPath, final List path, final Object root, final TreeFacade tree, final ProgressIndicator indicator) { + private TreeNode requestedExpand; + + private boolean applyTo(final int positionInPath, final List path, final Object root, final TreeFacade tree, final ProgressIndicator indicator) { if (!(root instanceof DefaultMutableTreeNode)) return false; final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)root; @@ -439,7 +446,7 @@ public class TreeState implements JDOMExternalizable { myBuilder.expand(element, new Runnable() { public void run() { - myBuilder.getUi().getReady(this).notify(result); + result.setDone(); } }); diff --git a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java index 5ba558f748fc..63eb44056db5 100644 --- a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java +++ b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java @@ -16,9 +16,11 @@ package com.intellij.ui.components.editors; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBList; +import com.intellij.util.Function; import com.intellij.util.Icons; import com.intellij.util.ui.EmptyIcon; @@ -40,13 +42,14 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel { private final JBList myList = new JBList(); private Object[] myOptions = {}; private Object myValue; + private Function myToString = StringUtil.createToStringFunction(Object.class); private ListCellRenderer myRenderer = new DefaultListCellRenderer() { public Icon myEmptyIcon; @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + final JLabel label = (JLabel)super.getListCellRendererComponent(list, myToString.fun(value), index, isSelected, cellHasFocus); if (value == myValue) { label.setIcon(getIcon(isSelected)); } else { @@ -135,4 +138,8 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel { public void setDefaultValue(Object value) { myValue = value; } + + public void setToString(Function toString) { + myToString = toString; + } } diff --git a/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/TreeUiTest.java b/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/TreeUiTest.java index 7ded4a44c823..331925510f3d 100644 --- a/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/TreeUiTest.java +++ b/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/TreeUiTest.java @@ -2120,13 +2120,18 @@ public class TreeUiTest extends AbstractTreeBuilderTest { buildStructure(myRoot); final boolean[] done = new boolean[] {false}; - getBuilder().select(new NodeElement("jetbrains"), new Runnable() { + invokeLaterIfNeeded(new Runnable() { @Override public void run() { - getBuilder().expand(new NodeElement("fabrique"), new Runnable() { + getBuilder().select(new NodeElement("jetbrains"), new Runnable() { @Override public void run() { - done[0] = true; + getBuilder().expand(new NodeElement("fabrique"), new Runnable() { + @Override + public void run() { + done[0] = true; + } + }); } }); } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 0cb49983565e..40a936ed0728 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -128,7 +128,7 @@ minuscule.humps.matching.description=Camel Case without holding Shift in Ctrl+N/ jvmbugfix.mac.caccessibleLeak=true -projectView.showHierarchyErrors=false +projectView.showHierarchyErrors=true dir.diff.default.src.folder= dir.diff.default.trg.folder= show.live.templates.in.completion=false diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index f2e736bea908..78e3728bee67 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -672,6 +672,7 @@ icon="/debugger/muteBreakpoints.png"/> + @@ -699,12 +700,14 @@ + + @@ -717,6 +720,7 @@ + @@ -727,6 +731,7 @@ + diff --git a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java index 1b82d50fdd18..9c9390371f87 100644 --- a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java +++ b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java @@ -23,17 +23,15 @@ import org.jetbrains.annotations.NotNull; * @author peter */ public abstract class NotNullLazyValue { - private boolean myComputed; - @NotNull private T myValue; + private T myValue; @NotNull protected abstract T compute(); @NotNull public T getValue() { - if (!myComputed) { + if (myValue == null) { myValue = compute(); - myComputed = true; } return myValue; } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index 9a2079acb9b4..f40c0b90db7f 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -24,6 +24,7 @@ import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.frame.XValueMarkerProvider; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -161,6 +162,15 @@ public abstract class XDebugProcess { return consoleBuilder.getConsole(); } + /** + * Override this method to enable 'Mark Object' action + * @return new instance of {@link XValueMarkerProvider}'s implementation or {@code null} if 'Mark Object' feature isn't supported + */ + @Nullable + public XValueMarkerProvider createValueMarkerProvider() { + return null; + } + /** * Override this method to provide additional tabs for 'Debug' tool window */ diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java index b7723c2874d6..2278aa06af48 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java @@ -116,7 +116,6 @@ public abstract class XDebuggerEvaluator { * Override this method to format selected text before it is shown in 'Evaluate' dialog */ @NotNull - @SuppressWarnings({"MethodMayBeStatic"}) public String formatTextForEvaluation(@NotNull String text) { return text; } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueMarkerProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueMarkerProvider.java new file mode 100644 index 000000000000..07aa065b02e5 --- /dev/null +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueMarkerProvider.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2011 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.frame; + +import org.jetbrains.annotations.NotNull; + +/** + * Provides implementation of 'Mark Object' feature.

+ * + * If debugger values have unique ids just return these ids from {@link #getMarker(XValue)} method. + * Alternatively implement {@link #markValue(XValue)} to store a value in some registry and implement {@link #unmarkValue(XValue, Object)} + * to remote it from the registry. In such a case the {@link #getMarker(XValue)} method can return {@code null} if the {@code value} isn't marked. + * + * @author nik + */ +public abstract class XValueMarkerProvider { + private final Class myValueClass; + + protected XValueMarkerProvider(Class valueClass) { + myValueClass = valueClass; + } + + /** + * @return {@code true} if 'Mark Object' action should be enabled for {@code value} + */ + public abstract boolean canMark(@NotNull V value); + + /** + * This method is used to determine whether the {@code value} was marked or not. The returned object is compared using {@link Object#equals(Object)} + * method with markers returned by {@link #markValue(XValue)} methods.

+ * This method may return {@code null} if the {@code value} wasn't marked by {@link #markValue(XValue)} method. + * @return a marker for {@code value} + */ + public abstract M getMarker(@NotNull V value); + + /** + * This method is called when 'Mark Object' action is invoked. Return an unique marker for {@code value} and store it in some registry + * if necessary. + * @return a marker for {@code value} + */ + @NotNull + public M markValue(@NotNull V value) { + return getMarker(value); + } + + /** + * This method is called when 'Unmark Object' action is invoked. + */ + public void unmarkValue(@NotNull V value, @NotNull M marker) { + } + + public final Class getValueClass() { + return myValueClass; + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java index 5b3394d8fa4a..9dc881326df8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.xdebugger.AbstractDebuggerSession; import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler; +import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider; @@ -33,7 +34,7 @@ import org.jetbrains.annotations.Nullable; public abstract class DebuggerSupport { private static final ExtensionPointName EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.debuggerSupport"); - @NotNull + @NotNull public static DebuggerSupport[] getDebuggerSupports() { return Extensions.getExtensions(EXTENSION_POINT); } @@ -96,6 +97,10 @@ public abstract class DebuggerSupport { @NotNull public abstract DebuggerToggleActionHandler getMuteBreakpointsHandler(); + @NotNull + public abstract MarkObjectActionHandler getMarkObjectHandler(); + + @Nullable public abstract AbstractDebuggerSession getCurrentSession(@NotNull Project project); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index ea8d0cfa129f..22affa7ee12c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -29,6 +29,7 @@ import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.diagnostic.Logger; @@ -46,8 +47,10 @@ import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XSuspendContext; +import com.intellij.xdebugger.frame.XValueMarkerProvider; import com.intellij.xdebugger.impl.breakpoints.*; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager; +import com.intellij.xdebugger.impl.frame.XValueMarkers; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebugSessionData; import com.intellij.xdebugger.impl.ui.XDebugSessionTab; @@ -78,6 +81,7 @@ public class XDebugSessionImpl implements XDebugSession { private XSourcePosition myCurrentPosition; private boolean myPaused; private MyDependentBreakpointListener myDependentBreakpointListener; + private XValueMarkers myValueMarkers; private String mySessionName; private XDebugSessionTab mySessionTab; private XDebugSessionData mySessionData; @@ -255,6 +259,17 @@ public class XDebugSessionImpl implements XDebugSession { ExecutionManager.getInstance(getProject()).getContentManager().showRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), descriptor); } + public XValueMarkers getValueMarkers() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myValueMarkers == null) { + XValueMarkerProvider provider = myDebugProcess.createValueMarkerProvider(); + if (provider != null) { + myValueMarkers = XValueMarkers.createValueMarkers(provider); + } + } + return myValueMarkers; + } + private static > XBreakpointType getBreakpointTypeClass(final XBreakpointHandler handler) { return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java index f1a33999d901..4a5858d3c598 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java @@ -22,6 +22,7 @@ import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler; +import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler; import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler; import com.intellij.xdebugger.impl.actions.handlers.*; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; @@ -54,6 +55,7 @@ public class XDebuggerSupport extends DebuggerSupport { private final XAddToWatchesFromEditorActionHandler myAddToWatchesActionHandler; private final DebuggerToggleActionHandler myMuteBreakpointsHandler; private final DebuggerActionHandler mySmartStepIntoHandler; + private final XMarkObjectActionHandler myMarkObjectActionHandler; public XDebuggerSupport() { myBreakpointPanelProvider = new XBreakpointPanelProvider(); @@ -106,6 +108,7 @@ public class XDebuggerSupport extends DebuggerSupport { myEvaluateHandler = new XDebuggerEvaluateActionHandler(); myQuickEvaluateHandler = new XQuickEvaluateHandler(); mySettingsPanelProvider = new XDebuggerSettingsPanelProviderImpl(); + myMarkObjectActionHandler = new XMarkObjectActionHandler(); } @NotNull @@ -194,6 +197,12 @@ public class XDebuggerSupport extends DebuggerSupport { return myMuteBreakpointsHandler; } + @NotNull + @Override + public MarkObjectActionHandler getMarkObjectHandler() { + return myMarkObjectActionHandler; + } + @Override public AbstractDebuggerSession getCurrentSession(@NotNull Project project) { return XDebuggerManager.getInstance(project).getCurrentSession(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectAction.java new file mode 100644 index 000000000000..a4d08501bb3e --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectAction.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2011 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.actions; + +import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.impl.DebuggerSupport; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class MarkObjectAction extends XDebuggerActionBase { + @Override + public void update(AnActionEvent event) { + Project project = event.getData(PlatformDataKeys.PROJECT); + boolean enabled = false; + Presentation presentation = event.getPresentation(); + boolean hidden = true; + if (project != null) { + for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { + MarkObjectActionHandler handler = support.getMarkObjectHandler(); + hidden &= handler.isHidden(project, event); + if (handler.isEnabled(project, event)) { + enabled = true; + String text; + if (handler.isMarked(project, event)) { + text = ActionsBundle.message("action.Debugger.MarkObject.unmark.text"); + } + else { + text = ActionsBundle.message("action.Debugger.MarkObject.text"); + } + presentation.setText(text); + break; + } + } + } + presentation.setVisible(!hidden && (!ActionPlaces.isPopupPlace(event.getPlace()) || enabled)); + presentation.setEnabled(enabled); + } + + @NotNull + @Override + protected DebuggerActionHandler getHandler(@NotNull DebuggerSupport debuggerSupport) { + return debuggerSupport.getMarkObjectHandler(); + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectActionHandler.java new file mode 100644 index 000000000000..e5a965ab37dc --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/MarkObjectActionHandler.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2011 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.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class MarkObjectActionHandler extends DebuggerActionHandler { + public abstract boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event); +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java index 4819bbe1574d..5e3de16c1ebd 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java @@ -62,4 +62,5 @@ public interface XDebuggerActions { @NonNls String TOGGLE_SORT_VALUES = "XDebugger.ToggleSortValues"; @NonNls String AUTO_TOOLTIP = "XDebugger.AutoTooltip"; + @NonNls String MARK_OBJECT = "Debugger.MarkObject"; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XMarkObjectActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XMarkObjectActionHandler.java new file mode 100644 index 000000000000..c3a9b9842661 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XMarkObjectActionHandler.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2011 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.actions.handlers; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.XDebugSessionImpl; +import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler; +import com.intellij.xdebugger.impl.frame.XValueMarkers; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class XMarkObjectActionHandler extends MarkObjectActionHandler { + @Override + public void perform(@NotNull Project project, AnActionEvent event) { + XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); + if (session == null) return; + + XValueMarkers markers = ((XDebugSessionImpl)session).getValueMarkers(); + XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(event.getDataContext()); + if (markers == null || node == null) return; + XValue value = node.getValueContainer(); + + ValueMarkup existing = markers.getMarkup(value); + if (existing != null) { + markers.unmarkValue(value); + } + else { + ValueMarkerPresentationDialog dialog = new ValueMarkerPresentationDialog(node.getName()); + dialog.show(); + ValueMarkup markup = dialog.getConfiguredMarkup(); + if (dialog.isOK() && markup != null) { + markers.markValue(value, markup); + } + } + session.rebuildViews(); + } + + @Override + public boolean isEnabled(@NotNull Project project, AnActionEvent event) { + XValueMarkers markers = getValueMarkers(project); + if (markers == null) return false; + + XValue value = XDebuggerTreeActionBase.getSelectedValue(event.getDataContext()); + return value != null && markers.canMarkValue(value); + } + + @Override + public boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event) { + XValueMarkers markers = getValueMarkers(project); + if (markers == null) return false; + + XValue value = XDebuggerTreeActionBase.getSelectedValue(event.getDataContext()); + return value != null && markers.getMarkup(value) != null; + } + + @Override + public boolean isHidden(@NotNull Project project, AnActionEvent event) { + return getValueMarkers(project) == null; + } + + @Nullable + private static XValueMarkers getValueMarkers(@NotNull Project project) { + XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); + return session != null ? ((XDebugSessionImpl)session).getValueMarkers() : null; + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XValueMarkers.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XValueMarkers.java new file mode 100644 index 000000000000..56d34dafd6fa --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XValueMarkers.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2011 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.frame; + +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.frame.XValueMarkerProvider; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public class XValueMarkers { + private final XValueMarkerProvider myProvider; + private final Map myMarkers; + + private XValueMarkers(@NotNull XValueMarkerProvider provider) { + myProvider = provider; + myMarkers = new HashMap(); + } + + public static XValueMarkers createValueMarkers(@NotNull XValueMarkerProvider provider) { + return new XValueMarkers(provider); + } + + @Nullable + public ValueMarkup getMarkup(@NotNull XValue value) { + Class valueClass = myProvider.getValueClass(); + if (!valueClass.isInstance(value)) return null; + + V v = valueClass.cast(value); + if (!myProvider.canMark(v)) return null; + + M m = myProvider.getMarker(v); + if (m == null) return null; + + return myMarkers.get(m); + } + + public boolean canMarkValue(@NotNull XValue value) { + Class valueClass = myProvider.getValueClass(); + if (!valueClass.isInstance(value)) return false; + + return myProvider.canMark(valueClass.cast(value)); + } + + public void markValue(@NotNull XValue value, @NotNull ValueMarkup markup) { + //noinspection unchecked + M m = myProvider.markValue((V)value); + myMarkers.put(m, markup); + } + + public void unmarkValue(@NotNull XValue value) { + //noinspection unchecked + M m = myProvider.getMarker((V)value); + if (m != null) { + myMarkers.remove(m); + } + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java index 57164045b3d8..4e164cc7fd15 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java @@ -15,83 +15,14 @@ */ package com.intellij.xdebugger.impl.ui.tree; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.FixedSizeButton; -import com.intellij.ui.ColorChooser; -import com.intellij.ui.DocumentAdapter; -import com.intellij.ui.SimpleColoredComponent; -import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - /** * @author nik */ -public abstract class ValueMarkerPresentationDialog extends DialogWrapper { - private static final Color DEFAULT_COLOR = Color.RED; - private SimpleColoredComponent myColorSample; - private Color myColor; - private JPanel myMainPanel; - private JTextField myLabelField; - private FixedSizeButton myChooseColorButton; - private JPanel mySamplePanel; - - public ValueMarkerPresentationDialog(final @Nullable String defaultText) { - super(true); - setTitle("Select Object Label"); - setModal(true); - myLabelField.getDocument().addDocumentListener(new DocumentAdapter() { - protected void textChanged(final DocumentEvent e) { - updateLabelSample(); - } - }); - myChooseColorButton.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - final Color color = ColorChooser.chooseColor(myColorSample, "Choose Label Color", myColor); - if (color != null) { - myColor = color; - updateLabelSample(); - } - } - }); - myColor = DEFAULT_COLOR; - if (defaultText != null) { - myLabelField.setText(defaultText.trim()); - updateLabelSample(); - } - } - - public JComponent getPreferredFocusedComponent() { - return myLabelField; - } - - @Override - protected JComponent createCenterPanel() { - return myMainPanel; - } - - private void updateLabelSample() { - myColorSample.clear(); - SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, myColor); - myColorSample.append(myLabelField.getText().trim(), attributes); - } - - @Nullable - public ValueMarkup getConfiguredMarkup() { - final String text = myLabelField.getText().trim(); - return text.isEmpty() ? null : new ValueMarkup(text, myColor, null); - } - - private void createUIComponents() { - myColorSample = new SimpleColoredComponent(); - mySamplePanel = new JPanel(new BorderLayout()); - mySamplePanel.setBorder(BorderFactory.createEtchedBorder()); - mySamplePanel.add(BorderLayout.CENTER, myColorSample); - myChooseColorButton = new FixedSizeButton(mySamplePanel); +public class ValueMarkerPresentationDialog extends ValueMarkerPresentationDialogBase { + public ValueMarkerPresentationDialog(@Nullable String defaultText) { + super(defaultText); + init(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.form similarity index 99% rename from platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form rename to platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.form index 1a09d3670a7a..ed01c69a295b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.form @@ -1,5 +1,5 @@ -

+ diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.java new file mode 100644 index 000000000000..3633c553e57e --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialogBase.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2011 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; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.ui.ColorChooser; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author nik + */ +public abstract class ValueMarkerPresentationDialogBase extends DialogWrapper { + private static final Color DEFAULT_COLOR = Color.RED; + private SimpleColoredComponent myColorSample; + private Color myColor; + private JPanel myMainPanel; + private JTextField myLabelField; + private FixedSizeButton myChooseColorButton; + private JPanel mySamplePanel; + + public ValueMarkerPresentationDialogBase(final @Nullable String defaultText) { + super(true); + setTitle("Select Object Label"); + setModal(true); + myLabelField.getDocument().addDocumentListener(new DocumentAdapter() { + protected void textChanged(final DocumentEvent e) { + updateLabelSample(); + } + }); + myChooseColorButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final Color color = ColorChooser.chooseColor(myColorSample, "Choose Label Color", myColor); + if (color != null) { + myColor = color; + updateLabelSample(); + } + } + }); + myColor = DEFAULT_COLOR; + if (defaultText != null) { + myLabelField.setText(defaultText.trim()); + updateLabelSample(); + } + } + + public JComponent getPreferredFocusedComponent() { + return myLabelField; + } + + @Override + protected JComponent createCenterPanel() { + return myMainPanel; + } + + private void updateLabelSample() { + myColorSample.clear(); + SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, myColor); + myColorSample.append(myLabelField.getText().trim(), attributes); + } + + @Nullable + public ValueMarkup getConfiguredMarkup() { + final String text = myLabelField.getText().trim(); + return text.isEmpty() ? null : new ValueMarkup(text, myColor, null); + } + + private void createUIComponents() { + myColorSample = new SimpleColoredComponent(); + mySamplePanel = new JPanel(new BorderLayout()); + mySamplePanel.setBorder(BorderFactory.createEtchedBorder()); + mySamplePanel.add(BorderLayout.CENTER, myColorSample); + myChooseColorButton = new FixedSizeButton(mySamplePanel); + } +} 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 14db80c9e617..64483c7ab66e 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 @@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener; import com.intellij.ui.PopupHandler; @@ -210,6 +211,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa actionManager.getAction(XDebuggerActions.SET_VALUE).unregisterCustomShortcutSet(this); actionManager.getAction(XDebuggerActions.COPY_VALUE).unregisterCustomShortcutSet(this); actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).unregisterCustomShortcutSet(this); + actionManager.getAction(XDebuggerActions.MARK_OBJECT).unregisterCustomShortcutSet(this); } private void registerShortcuts() { @@ -217,6 +219,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa actionManager.getAction(XDebuggerActions.SET_VALUE).registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), this); actionManager.getAction(XDebuggerActions.COPY_VALUE).registerCustomShortcutSet(CommonShortcuts.getCopy(), this); actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).registerCustomShortcutSet(CommonShortcuts.getEditSource(), this); + actionManager.getAction(XDebuggerActions.MARK_OBJECT).registerCustomShortcutSet(new CustomShortcutSet( KeymapManager.getInstance().getActiveKeymap().getShortcuts("ToggleBookmark")), this); } private static void markNodesObsolete(final XValueContainerNode node) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java index d67dbe636b9a..25205fa1da98 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java @@ -24,6 +24,7 @@ import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -34,7 +35,7 @@ import javax.swing.*; public class XInspectDialog extends DialogWrapper { private final XDebuggerTreePanel myTreePanel; - public XInspectDialog(final XDebugSession session, XDebuggerEditorsProvider editorsProvider, XSourcePosition sourcePosition, String nodeName, XValue value) { + public XInspectDialog(final XDebugSession session, XDebuggerEditorsProvider editorsProvider, XSourcePosition sourcePosition, @NotNull String nodeName, @NotNull XValue value) { super(session.getProject(), false); setTitle(XDebuggerBundle.message("inspect.value.dialog.title", nodeName)); setModal(false); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XDebuggerTreeActionBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XDebuggerTreeActionBase.java index 120916b82546..367061ff369e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XDebuggerTreeActionBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XDebuggerTreeActionBase.java @@ -53,7 +53,7 @@ public abstract class XDebuggerTreeActionBase extends AnAction { } @Nullable - protected static XValueNodeImpl getSelectedNode(final DataContext dataContext) { + public static XValueNodeImpl getSelectedNode(final DataContext dataContext) { XDebuggerTree tree = XDebuggerTree.getTree(dataContext); if (tree == null) return null; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java index 590bce5318d8..fa32ebcc4d75 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java @@ -17,12 +17,13 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import org.jetbrains.annotations.NotNull; /** * @author nik */ public class XStackFrameNode extends XValueContainerNode { - public XStackFrameNode(final XDebuggerTree tree, final XStackFrame xStackFrame) { + public XStackFrameNode(final @NotNull XDebuggerTree tree, final @NotNull XStackFrame xStackFrame) { super(tree, null, xStackFrame); setLeaf(false); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index 237ef6b99e71..4053b2b877b1 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -39,7 +39,7 @@ public abstract class XValueContainerNode implements XValu private String mySeparator; private boolean myChanged; - public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, String name, final XValue value) { + public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, String name, final @NotNull XValue value) { super(tree, parent, value); myName = name; if (myName != null) { @@ -106,6 +109,13 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu private void updateText() { myText.clear(); + XValueMarkers markers = ((XDebugSessionImpl)myTree.getSession()).getValueMarkers(); + if (markers != null) { + ValueMarkup markup = markers.getMarkup(myValueContainer); + if (markup != null) { + myText.append("[" + markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor())); + } + } myText.append(myName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES); myText.append(mySeparator, SimpleTextAttributes.REGULAR_ATTRIBUTES); if (myType != null) { diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index c7146a82f873..5d07dcd316b7 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -299,7 +299,6 @@ -