diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointDefaults.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointDefaults.java index 96a1d0eb2aa4..89b5f9c17dc3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointDefaults.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointDefaults.java @@ -40,7 +40,7 @@ public final class BreakpointDefaults { } public void setSuspendPolicy(String suspendPolicy) { - if (DebuggerSettings.SUSPEND_NONE.equals(suspendPolicy) || DebuggerSettings.SUSPEND_THREAD.equals(suspendPolicy) || DebuggerSettings.SUSPEND_ALL.equals( suspendPolicy)) { + if (DebuggerSettings.SUSPEND_THREAD.equals(suspendPolicy) || DebuggerSettings.SUSPEND_ALL.equals( suspendPolicy)) { mySuspendPolicy = suspendPolicy; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index 09a73fd894c9..cc7aaaa8c9aa 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -34,7 +34,6 @@ import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerContextListener; import com.intellij.debugger.impl.DebuggerManagerImpl; import com.intellij.debugger.impl.DebuggerSession; -import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.debugger.ui.DebuggerExpressionTextField; import com.intellij.openapi.application.ApplicationManager; @@ -318,7 +317,7 @@ public class BreakpointManager implements JDOMExternalizable { String text = selection != null ? selection : DebuggerBundle.message("breakpoint.log.message", breakpoint.getDisplayName()); breakpoint.setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, text)); - breakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_NONE; + breakpoint.SUSPEND = false; DialogWrapper dialog = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager() .createConfigurationDialog(breakpoint, BreakpointPropertiesPanel.CONTROL_LOG_MESSAGE); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form index 3f24242ac3fa..7d71e2166522 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form @@ -48,7 +48,7 @@ - + @@ -56,7 +56,7 @@ - + @@ -77,7 +77,7 @@ - + diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java index 893cdd9d06ad..705b30011c0a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -51,7 +51,6 @@ import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointChooser; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointNoneItem; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -101,9 +100,9 @@ public abstract class BreakpointPropertiesPanel { private JPanel mySpecialBoxPanel; private PsiClass myBreakpointPsiClass; - private JRadioButton mySuspendThreadRadio; - private JRadioButton mySuspendAllRadio; - private JBCheckBox mySuspendJBCheckBox; + private JRadioButton myRbSuspendThread; + private JRadioButton myRbSuspendAll; + private JBCheckBox myCbSuspend; private JButton myMakeDefaultButton; private JRadioButton myDisableAgainRadio; @@ -119,8 +118,7 @@ public abstract class BreakpointPropertiesPanel { private JBCheckBox myConditionCheckbox; ButtonGroup mySuspendPolicyGroup; - @NonNls public static final String CONTROL_LOG_MESSAGE = "logMessage"; - private static final int MAX_COMBO_WIDTH = 300; + public static final String CONTROL_LOG_MESSAGE = "logMessage"; private final FixedSizeButton myConditionMagnifierButton; private boolean myMoreOptionsVisible = true; private Breakpoint myBreakpoint; @@ -154,10 +152,6 @@ public abstract class BreakpointPropertiesPanel { }; } - public DetailView getDetailView() { - return myDetailView; - } - public interface Delegate { void showActionsPanel(); @@ -233,8 +227,8 @@ public abstract class BreakpointPropertiesPanel { myCompact = compact; mySuspendPolicyGroup = new ButtonGroup(); - mySuspendPolicyGroup.add(mySuspendAllRadio); - mySuspendPolicyGroup.add(mySuspendThreadRadio); + mySuspendPolicyGroup.add(myRbSuspendAll); + mySuspendPolicyGroup.add(myRbSuspendThread); updateSuspendPolicyRbFont(); final ItemListener suspendPolicyChangeListener = new ItemListener() { @@ -244,17 +238,18 @@ public abstract class BreakpointPropertiesPanel { } }; - mySuspendJBCheckBox.addActionListener(new ActionListener() { + myCbSuspend.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { - mySuspendAllRadio.setEnabled(mySuspendJBCheckBox.isSelected()); - mySuspendThreadRadio.setEnabled(mySuspendJBCheckBox.isSelected()); + final boolean enabled = myCbSuspend.isSelected(); + myRbSuspendAll.setEnabled(enabled); + myRbSuspendThread.setEnabled(enabled); } }); - mySuspendAllRadio.addItemListener(suspendPolicyChangeListener); - mySuspendThreadRadio.addItemListener(suspendPolicyChangeListener); + myRbSuspendAll.addItemListener(suspendPolicyChangeListener); + myRbSuspendThread.addItemListener(suspendPolicyChangeListener); myConditionCheckbox.addItemListener(suspendPolicyChangeListener); myMakeDefaultButton.addActionListener(new ActionListener() { @@ -264,10 +259,10 @@ public abstract class BreakpointPropertiesPanel { breakpointManager.setBreakpointDefaults(breakpointCategory, new BreakpointDefaults(suspendPolicy, myConditionCheckbox.isSelected())); updateSuspendPolicyRbFont(); if (DebuggerSettings.SUSPEND_THREAD.equals(suspendPolicy)) { - mySuspendThreadRadio.requestFocus(); + myRbSuspendThread.requestFocus(); } else { - mySuspendAllRadio.requestFocus(); + myRbSuspendAll.requestFocus(); } myMakeDefaultButton.setEnabled(false); } @@ -380,7 +375,7 @@ public abstract class BreakpointPropertiesPanel { DebuggerUIUtil.focusEditorOnCheck(myClassFiltersCheckBox, myClassFiltersField.getTextField()); DebuggerUIUtil.focusEditorOnCheck(myConditionCheckbox, myConditionCombo); - IJSwingUtilities.adjustComponentsOnMac(mySuspendJBCheckBox); + IJSwingUtilities.adjustComponentsOnMac(myCbSuspend); IJSwingUtilities.adjustComponentsOnMac(myLogExpressionCheckBox); IJSwingUtilities.adjustComponentsOnMac(myLogMessageCheckBox); } @@ -415,19 +410,12 @@ public abstract class BreakpointPropertiesPanel { return; } } - getBreakpointManager(myProject).addBreakpointRule(new EnableBreakpointRule(getBreakpointManager(myProject), - masterBreakpoint, - myBreakpoint, - selected)); + getBreakpointManager(myProject).addBreakpointRule(new EnableBreakpointRule(getBreakpointManager(myProject), masterBreakpoint, myBreakpoint, selected)); } - } private String getSelectedSuspendPolicy() { - if (!mySuspendJBCheckBox.isSelected()) { - return DebuggerSettings.SUSPEND_NONE; - } - if (mySuspendThreadRadio.isSelected()) { + if (myRbSuspendThread.isSelected()) { return DebuggerSettings.SUSPEND_THREAD; } return DebuggerSettings.SUSPEND_ALL; @@ -436,11 +424,11 @@ public abstract class BreakpointPropertiesPanel { private void updateSuspendPolicyRbFont() { final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy(); - final Font font = mySuspendAllRadio.getFont().deriveFont(Font.PLAIN); + final Font font = myRbSuspendAll.getFont().deriveFont(Font.PLAIN); final Font boldFont = font.deriveFont(Font.BOLD); - mySuspendAllRadio.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font); - mySuspendThreadRadio.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font); + myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font); + myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font); } protected ClassFilter createClassConditionFilter() { @@ -491,32 +479,32 @@ public abstract class BreakpointPropertiesPanel { myConditionCombo.setContext(context); - mySuspendJBCheckBox.setSelected(!breakpoint.SUSPEND_POLICY.equals(DebuggerSettings.SUSPEND_NONE)); - mySuspendThreadRadio.setEnabled(mySuspendJBCheckBox.isSelected()); - mySuspendAllRadio.setEnabled(mySuspendJBCheckBox.isSelected()); + myCbSuspend.setSelected(breakpoint.SUSPEND); + myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); + myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); - if(DebuggerSettings.SUSPEND_NONE.equals(breakpoint.SUSPEND_POLICY)) { + if(!breakpoint.SUSPEND) { actionsPanelVisible = true; } - else if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){ - mySuspendPolicyGroup.setSelected(mySuspendThreadRadio.getModel(), true); + if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){ + myRbSuspendThread.setSelected(true); } else { - mySuspendPolicyGroup.setSelected(mySuspendAllRadio.getModel(), true); + myRbSuspendAll.setSelected(true); } - mySuspendJBCheckBox.addActionListener(new ActionListener() { + myCbSuspend.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { if (!myActionsPanel.isVisible()) { - if (!mySuspendJBCheckBox.isSelected()) { + if (!myCbSuspend.isSelected()) { if (myDelegate != null) { myDelegate.showActionsPanel(); } } } - mySuspendThreadRadio.setEnabled(mySuspendJBCheckBox.isSelected()); - mySuspendAllRadio.setEnabled(mySuspendJBCheckBox.isSelected()); + myRbSuspendThread.setEnabled(myCbSuspend.isSelected()); + myRbSuspendAll.setEnabled(myCbSuspend.isSelected()); } }); myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED); @@ -635,6 +623,7 @@ public abstract class BreakpointPropertiesPanel { breakpoint.setLogMessage(myLogExpressionCombo.getText()); breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected(); breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected(); + breakpoint.SUSPEND = myCbSuspend.isSelected(); breakpoint.SUSPEND_POLICY = getSelectedSuspendPolicy(); reloadInstanceFilters(); reloadClassFilters(); @@ -652,10 +641,6 @@ public abstract class BreakpointPropertiesPanel { breakpoint.updateUI(afterUpdate); } - private static String concatWith(List s, String concator) { - return StringUtil.join(s, concator); - } - private static String concatWithEx(List s, String concator, int N, String NthConcator) { String result = ""; int i = 1; @@ -665,7 +650,8 @@ public abstract class BreakpointPropertiesPanel { if(iterator.hasNext()){ if(i % N == 0){ result += NthConcator; - } else { + } + else { result += concator; } } @@ -681,8 +667,7 @@ public abstract class BreakpointPropertiesPanel { } } if (updateText) { - String editorText = concatWith(filters, " "); - myInstanceFiltersField.setText(editorText); + myInstanceFiltersField.setText(StringUtil.join(filters, " ")); } String tipText = concatWithEx(filters, " ", (int)Math.sqrt(myInstanceFilters.length) + 1, "\n"); @@ -695,9 +680,12 @@ public abstract class BreakpointPropertiesPanel { ArrayList idxs = new ArrayList(); int startNumber = -1; for(int i = 0; i <= filtersText.length(); i++) { - if(i < filtersText.length() && Character.isDigit(filtersText.charAt(i))){ - if(startNumber == -1) startNumber = i; - } else { + if(i < filtersText.length() && Character.isDigit(filtersText.charAt(i))) { + if(startNumber == -1) { + startNumber = i; + } + } + else { if(startNumber >=0) { idxs.add(InstanceFilter.create(filtersText.substring(startNumber, i))); startNumber = -1; @@ -705,7 +693,9 @@ public abstract class BreakpointPropertiesPanel { } } for (InstanceFilter instanceFilter : myInstanceFilters) { - if (!instanceFilter.isEnabled()) idxs.add(instanceFilter); + if (!instanceFilter.isEnabled()) { + idxs.add(instanceFilter); + } } myInstanceFilters = idxs.toArray(new InstanceFilter[idxs.size()]); } @@ -724,18 +714,21 @@ public abstract class BreakpointPropertiesPanel { } } if (updateText) { - String editorText = concatWith(filters, " "); - if(!filters.isEmpty()) editorText += " "; - editorText += concatWith(excludeFilters, " "); + String editorText = StringUtil.join(filters, " "); + if(!filters.isEmpty()) { + editorText += " "; + } + editorText += StringUtil.join(excludeFilters, " "); myClassFiltersField.setText(editorText); } int width = (int)Math.sqrt(myClassExclusionFilters.length + myClassFilters.length) + 1; String tipText = concatWithEx(filters, " ", width, "\n"); - if(!filters.isEmpty()) tipText += "\n"; + if(!filters.isEmpty()) { + tipText += "\n"; + } tipText += concatWithEx(excludeFilters, " ", width, "\n"); myClassFiltersField.getTextField().setToolTipText(tipText); - } private void reloadClassFilters() { @@ -746,12 +739,16 @@ public abstract class BreakpointPropertiesPanel { int startFilter = -1; for(int i = 0; i <= filtersText.length(); i++) { if(i < filtersText.length() && !Character.isWhitespace(filtersText.charAt(i))){ - if(startFilter == -1) startFilter = i; - } else { + if(startFilter == -1) { + startFilter = i; + } + } + else { if(startFilter >=0) { - if(filtersText.charAt(startFilter) == '-'){ + if(filtersText.charAt(startFilter) == '-') { exclusionFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter + 1, i))); - } else { + } + else { classFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter, i))); } startFilter = -1; @@ -759,10 +756,14 @@ public abstract class BreakpointPropertiesPanel { } } for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassFilters) { - if (!classFilter.isEnabled()) classFilters.add(classFilter); + if (!classFilter.isEnabled()) { + classFilters.add(classFilter); + } } for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassExclusionFilters) { - if (!classFilter.isEnabled()) exclusionFilters.add(classFilter); + if (!classFilter.isEnabled()) { + exclusionFilters.add(classFilter); + } } myClassFilters = classFilters .toArray(new com.intellij.ui.classFilter.ClassFilter[classFilters .size()]); myClassExclusionFilters = exclusionFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[exclusionFilters.size()]); @@ -809,7 +810,7 @@ public abstract class BreakpointPropertiesPanel { return myPanel; } - private BreakpointManager getBreakpointManager(Project project) { + private static BreakpointManager getBreakpointManager(Project project) { return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); } @@ -841,8 +842,7 @@ public abstract class BreakpointPropertiesPanel { @Nullable protected JComponent createCenterPanel() { final JPanel panel = new JPanel(new BorderLayout()); - myEditor = new DebuggerStatementEditor(myProject, myTargetEditor.getContext(), myTargetEditor.getRecentsId(), - DefaultCodeFragmentFactory.getInstance()); + myEditor = new DebuggerStatementEditor(myProject, myTargetEditor.getContext(), myTargetEditor.getRecentsId(), DefaultCodeFragmentFactory.getInstance()); myEditor.setPreferredSize(new Dimension(400, 150)); myEditor.setText(myTargetEditor.getText()); panel.add(myEditor, BorderLayout.CENTER); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java index e84f445ad0a0..e8fd23ead332 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java @@ -48,6 +48,7 @@ import java.util.List; public abstract class FilteredRequestor implements LocatableEventRequestor, JDOMExternalizable { public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + public boolean SUSPEND = true; public boolean COUNT_FILTER_ENABLED = false; public int COUNT_FILTER = 0; @@ -82,7 +83,7 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM } public String getSuspendPolicy() { - return SUSPEND_POLICY; + return SUSPEND? SUSPEND_POLICY : DebuggerSettings.SUSPEND_NONE; } /** @@ -122,6 +123,10 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM public void readExternal(Element parentNode) throws InvalidDataException { DefaultJDOMExternalizer.readExternal(this, parentNode); + if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { // compatibility with older format + SUSPEND = false; + SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + } String condition = JDOMExternalizerUtil.readField(parentNode, CONDITION_OPTION_NAME); if (condition != null) { setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition)); diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java index 271d39872974..c002951d4551 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java @@ -356,17 +356,23 @@ public class ProjectNameWithTypeStep extends ProjectNameStep { public void updateStep() { super.updateStep(); - if (myCreateModuleCb.isSelected()) { - mySequence.setType(getSelectedBuilderId()); - } else { - mySequence.setType(null); + if (myHeader.isVisible()) { + if (myCreateModuleCb.isSelected()) { + mySequence.setType(getSelectedBuilderId()); + } else { + mySequence.setType(null); + } } } public void updateDataModel() { - if (myCreateModuleCb.isSelected()) { - mySequence.setType(getSelectedBuilderId()); - super.updateDataModel(); + + if (myHeader.isVisible()) { + mySequence.setType(myCreateModuleCb.isSelected() ? getSelectedBuilderId() : null); + } + super.updateDataModel(); + + if (myHeader.isVisible() && myCreateModuleCb.isSelected()) { final ModuleBuilder builder = (ModuleBuilder)myMode.getModuleBuilder(); assert builder != null; final String moduleName = getModuleName(); @@ -374,9 +380,6 @@ public class ProjectNameWithTypeStep extends ProjectNameStep { builder.setModuleFilePath( FileUtil.toSystemIndependentName(myModuleFileLocation.getText()) + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION); builder.setContentEntryPath(FileUtil.toSystemIndependentName(myModuleContentRoot.getText())); - } else { - mySequence.setType(null); - super.updateDataModel(); } } diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java index 59d67f4a8ca0..7af6ca11b872 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java @@ -76,13 +76,16 @@ public class SelectTemplateStep extends ModuleWizardStep { private JPanel myDescriptionPanel; private final WizardContext myContext; + private final StepSequence mySequence; + private final ElementFilter.Active.Impl myFilter; private final FilteringTreeBuilder myBuilder; private MinusculeMatcher[] myMatchers; - public SelectTemplateStep(WizardContext context) { + public SelectTemplateStep(WizardContext context, StepSequence sequence) { myContext = context; + mySequence = sequence; Messages.installHyperlinkSupport(myDescriptionPane); ProjectTemplatesFactory[] factories = ProjectTemplatesFactory.EP_NAME.getExtensions(); @@ -242,6 +245,12 @@ public class SelectTemplateStep extends ModuleWizardStep { @Override public void updateStep() { myBuilder.queueUpdate(); + setModuleType(); + } + + private void setModuleType() { + ProjectTemplate template = getSelectedTemplate(); + mySequence.setType(template == null ? null : template.createModuleBuilder().getBuilderId()); } @Override @@ -342,6 +351,7 @@ public class SelectTemplateStep extends ModuleWizardStep { @Override public void updateDataModel() { + setModuleType(); } @Override diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java index ff24e526f97e..1874404a7fbb 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java @@ -53,18 +53,29 @@ public class CreateFromScratchMode extends WizardMode { @Nullable protected StepSequence createSteps(final WizardContext context, @NotNull final ModulesProvider modulesProvider) { - final StepSequence sequence = new StepSequence(); - sequence.addCommonStep(new ProjectNameWithTypeStep(context, sequence, this)); + for (ModuleBuilder builder : ModuleBuilder.getAllBuilders()) { + myBuildersMap.put(builder.getBuilderId(), builder); + } + myBuildersMap.put(ModuleType.EMPTY.getId(), new EmptyModuleBuilder()); + return addSteps(context, modulesProvider, this, new StepSequence()); + } + + static StepSequence addSteps(WizardContext context, + ModulesProvider modulesProvider, + WizardMode mode, + StepSequence sequence) { + sequence.addCommonStep(new ProjectNameWithTypeStep(context, sequence, mode)); for (ModuleBuilder builder : ModuleBuilder.getAllBuilders()) { addModuleBuilder(builder, context, modulesProvider, sequence); } - myBuildersMap.put(ModuleType.EMPTY.getId(), new EmptyModuleBuilder()); return sequence; } - private void addModuleBuilder(ModuleBuilder builder, WizardContext context, ModulesProvider modulesProvider, StepSequence myStepSequence) { + private static void addModuleBuilder(ModuleBuilder builder, + WizardContext context, + ModulesProvider modulesProvider, + StepSequence myStepSequence) { final String id = builder.getBuilderId(); - myBuildersMap.put(id, builder); for (ModuleWizardStep step : builder.createWizardSteps(context, modulesProvider)) { myStepSequence.addSpecificStep(id, step); } diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java index 06731b5ef68e..ec5e18e76afc 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java @@ -15,10 +15,9 @@ */ package com.intellij.ide.util.newProjectWizard.modes; -import com.intellij.ide.util.newProjectWizard.ProjectNameWithTypeStep; import com.intellij.ide.util.newProjectWizard.SelectTemplateStep; import com.intellij.ide.util.newProjectWizard.StepSequence; -import com.intellij.ide.util.projectWizard.ProjectBuilder; +import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; @@ -54,15 +53,15 @@ public class CreateFromTemplateMode extends WizardMode { @Nullable @Override protected StepSequence createSteps(WizardContext context, @NotNull ModulesProvider modulesProvider) { - mySelectTemplateStep = new SelectTemplateStep(context); - StepSequence sequence = new StepSequence(mySelectTemplateStep); - sequence.addCommonStep(new ProjectNameWithTypeStep(context, sequence, this)); - return sequence; + StepSequence sequence = new StepSequence(); + mySelectTemplateStep = new SelectTemplateStep(context, sequence); + sequence.addCommonStep(mySelectTemplateStep); + return CreateFromScratchMode.addSteps(context, modulesProvider, this, sequence); } @Nullable @Override - public ProjectBuilder getModuleBuilder() { + public ModuleBuilder getModuleBuilder() { final ProjectTemplate template = mySelectTemplateStep.getSelectedTemplate(); if (template == null) { return null; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java index a113ec229635..8ca01064da91 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java @@ -42,7 +42,9 @@ public class Java18CompletionData extends Java15CompletionData { } if (AFTER_DOUBLE_COLON.accepts(position)) { - result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), TailType.SEMICOLON)); + final PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiMethodReferenceExpression.class); + final TailType tailType = parent != null && !LambdaUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE; + result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), tailType)); return; } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java index 8f14fbd2d9ed..b91e1dee7e53 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.util.messages.Topic; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public abstract class DaemonCodeAnalyzer { public static DaemonCodeAnalyzer getInstance(Project project) { @@ -35,15 +36,15 @@ public abstract class DaemonCodeAnalyzer { public abstract void updateVisibleHighlighters(@NotNull Editor editor); public abstract void setUpdateByTimerEnabled(boolean value); - public abstract void disableUpdateByTimer(Disposable parentDisposable); + public abstract void disableUpdateByTimer(@NotNull Disposable parentDisposable); - public abstract boolean isHighlightingAvailable(PsiFile file); + public abstract boolean isHighlightingAvailable(@Nullable PsiFile file); public abstract void setImportHintsEnabled(@NotNull PsiFile file, boolean value); public abstract void resetImportHintsEnabledForProject(); public abstract void setHighlightingEnabled(@NotNull PsiFile file, boolean value); public abstract boolean isImportHintsEnabled(@NotNull PsiFile file); - public abstract boolean isAutohintsAvailable(PsiFile file); + public abstract boolean isAutohintsAvailable(@Nullable PsiFile file); /** * Force rehighlighting for all files diff --git a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java index 2cff2aaf6291..f052cdfa82de 100644 --- a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java +++ b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.execution.filters; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; @@ -26,6 +27,7 @@ import java.util.List; public class CompositeFilter implements Filter, FilterMixin { private final List myFilters = new ArrayList(); + private static final Logger LOG = Logger.getInstance(CompositeFilter.class); private boolean myIsAnyHeavy; private final DumbService myDumbService; @@ -42,7 +44,10 @@ public class CompositeFilter implements Filter, FilterMixin { for (int i = 0; i < count; i++) { Filter filter = filters.get(i); if (!dumb || DumbService.isDumbAware(filter)) { + long t0 = System.currentTimeMillis(); final Result info = filter.applyFilter(line, entireLength); + t0 = (System.currentTimeMillis() - t0); + if (t0 > 1000) LOG.error("applyFilter " + filter.getClass().getSimpleName() + " took" + t0 + "ms on '''" + line + "'''"); if (info != null) { return info; } diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java index fe8844a58ea2..09b5b4980538 100644 --- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java +++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java @@ -79,12 +79,15 @@ public abstract class ModuleBuilder extends ProjectBuilder{ return myName; } + @Nullable public String getBuilderId() { - return getModuleType().getId(); + ModuleType moduleType = getModuleType(); + return moduleType == null ? null : moduleType.getId(); } public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider) { - return getModuleType().createWizardSteps(wizardContext, this, modulesProvider); + ModuleType moduleType = getModuleType(); + return moduleType == null ? ModuleWizardStep.EMPTY_ARRAY : moduleType.createWizardSteps(wizardContext, this, modulesProvider); } public void setName(String name) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 478a33fcc001..d4c48bd7f24d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -381,9 +381,11 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx private int myDisableCount = 0; @Override - public void disableUpdateByTimer(Disposable parentDisposable) { + public void disableUpdateByTimer(@NotNull Disposable parentDisposable) { setUpdateByTimerEnabled(false); myDisableCount++; + ApplicationManager.getApplication().assertIsDispatchThread(); + Disposer.register(parentDisposable, new Disposable() { @Override public void dispose() { diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index 94f359b9b696..2daa054cab0d 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -24,6 +24,7 @@ import com.intellij.find.findUsages.*; import com.intellij.find.impl.FindManagerImpl; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; +import com.intellij.ide.util.gotoByName.ModelDiff; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -44,7 +45,10 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.psi.*; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.SmartPsiElementPointer; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.PsiElementProcessor; @@ -57,17 +61,18 @@ import com.intellij.usages.*; import com.intellij.usages.impl.*; import com.intellij.usages.rules.UsageFilteringRuleProvider; import com.intellij.util.Alarm; -import com.intellij.util.ArrayUtil; import com.intellij.util.PlatformIcons; import com.intellij.util.Processor; +import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.AsyncProcessIcon; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.ActionEvent; @@ -82,13 +87,13 @@ public class ShowUsagesAction extends AnAction implements PopupAction { static final NullUsage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE; private static final UsageNode MORE_USAGES_SEPARATOR_NODE = UsageViewImpl.NULL_NODE; - private static final Comparator USAGE_NODE_COMPARATOR = new Comparator() { + private static final Comparator USAGE_NODE_COMPARATOR = new Comparator() { @Override - public int compare(Object c1, Object c2) { - if (!(c1 instanceof UsageNode)) return 1; - if (!(c2 instanceof UsageNode)) return -1; - Usage o1 = ((UsageNode)c1).getUsage(); - Usage o2 = ((UsageNode)c2).getUsage(); + public int compare(UsageNode c1, UsageNode c2) { + if (c1 instanceof StringNode) return 1; + if (c2 instanceof StringNode) return -1; + Usage o1 = c1.getUsage(); + Usage o2 = c2.getUsage(); if (o1 == MORE_USAGES_SEPARATOR) return 1; if (o2 == MORE_USAGES_SEPARATOR) return -1; @@ -193,7 +198,10 @@ public class ShowUsagesAction extends AnAction implements PopupAction { @NotNull private static FindUsagesOptions getDefaultOptions(@NotNull FindUsagesHandler handler) { - return handler.getFindUsagesOptions(DataManager.getInstance().getDataContext()); + FindUsagesOptions options = handler.getFindUsagesOptions(DataManager.getInstance().getDataContext()); + // by default, scope in FindUsagesOptions is copied from the FindSettings, but we need a default one + options.searchScope = getMaximalScope(handler); + return options; } private void showElementUsages(@NotNull final FindUsagesHandler handler, @@ -201,6 +209,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { @NotNull final RelativePoint popupPosition, final int maxUsages, @NotNull final FindUsagesOptions options) { + ApplicationManager.getApplication().assertIsDispatchThread(); final UsageViewSettings usageViewSettings = UsageViewSettings.getInstance(); final UsageViewSettings savedGlobalSettings = new UsageViewSettings(); @@ -229,8 +238,24 @@ public class ShowUsagesAction extends AnAction implements PopupAction { final MyTable table = new MyTable(); final AsyncProcessIcon processIcon = new AsyncProcessIcon("xxx"); + boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE); + if (hadMoreSeparator) { + usages.add(MORE_USAGES_SEPARATOR); + visibleNodes.add(MORE_USAGES_SEPARATOR_NODE); + } + + addUsageNodes(usageView.getRoot(), usageView, new ArrayList()); + + TableScrollingUtil.installActions(table); + + final List data = collectData(usages, visibleNodes, usageView, presentation); + setTableModel(table, usageView, data); + + SpeedSearchBase speedSearch = new MySpeedSearch(table); + speedSearch.setComparator(new SpeedSearchComparator(false)); + final JBPopup popup = createUsagePopup(usages, descriptor, visibleNodes, handler, editor, popupPosition, - maxUsages, usageView, options, table, presentation, processIcon); + maxUsages, usageView, options, table, presentation, processIcon, hadMoreSeparator); Disposer.register(popup, usageView); @@ -248,10 +273,14 @@ public class ShowUsagesAction extends AnAction implements PopupAction { public boolean value(Object o) { return popup.isDisposed(); } - }, 1000, new Runnable() { + }, 100, new Runnable() { @Override public void run() { - rebuildPopup(usageView, usages, table, popup, presentation, popupPosition, !processIcon.isDisposed()); + List copy; + synchronized (usages) { + copy = new ArrayList(usages); + } + rebuildPopup(usageView, copy, table, popup, presentation, popupPosition, !processIcon.isDisposed()); } }); @@ -281,7 +310,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction { usages.add(MORE_USAGES_SEPARATOR); continueSearch = false; } - pingEDT.ping(); + boolean invoked = pingEDT.ping(); + return continueSearch; } } @@ -349,6 +379,49 @@ public class ShowUsagesAction extends AnAction implements PopupAction { }); } + @NotNull + private static UsageNode createStringNode(@NotNull final Object string) { + return new StringNode(string); + } + + private static class MyModel extends ListTableModel implements ModelDiff.Model { + private MyModel(@NotNull List data, int cols) { + super(cols(cols), data, 0); + } + + @NotNull + private static ColumnInfo[] cols(int cols) { + ColumnInfo o = new ColumnInfo("") { + @Nullable + @Override + public UsageNode valueOf(UsageNode node) { + return node; + } + }; + List> list = Collections.nCopies(cols, o); + return list.toArray(new ColumnInfo[list.size()]); + } + + @Override + public void addToModel(int idx, Object element) { + UsageNode node = element instanceof UsageNode ? (UsageNode)element : createStringNode(element); + + if (idx < getRowCount()) { + insertRow(idx, node); + } + else { + addRow(node); + } + } + + @Override + public void removeRangeFromModel(int start, int end) { + for (int i=end-1; i>=start; i--) { + removeRow(i); + } + } + } + private static boolean showPopupIfNeedTo(@NotNull JBPopup popup, @NotNull RelativePoint popupPosition) { if (!popup.isDisposed() && !popup.isVisible()) { popup.show(popupPosition); @@ -383,7 +456,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { @NotNull final Runnable cancelAction, final int maxUsages, @NotNull final FindUsagesOptions options) { - JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text+" ")); + JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text + " ")); InplaceButton button = createSettingsButton(handler, popupPosition, editor, maxUsages, cancelAction); JPanel panel = new JPanel(new BorderLayout()) { @@ -474,24 +547,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction { @NotNull final FindUsagesOptions options, @NotNull final JTable table, @NotNull final UsageViewPresentation presentation, - @NotNull final AsyncProcessIcon processIcon) { - final String title = presentation.getTabText(); - boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE); - - final Project project = handler.getProject(); - - if (hadMoreSeparator) { - usages.add(MORE_USAGES_SEPARATOR); - visibleNodes.add(MORE_USAGES_SEPARATOR_NODE); - } - List outNodes = new ArrayList(); - addUsageNodes(usageView.getRoot(), usageView, outNodes); - int filtered = filtered(usages, usageView); - - TableScrollingUtil.installActions(table); - final Vector data = new Vector(); - setTableModel(table, visibleNodes, usageView, data, filtered, presentation); - + @NotNull final AsyncProcessIcon processIcon, + boolean hadMoreSeparator) { table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2); table.setShowGrid(false); table.setShowVerticalLines(false); @@ -500,7 +557,16 @@ public class ShowUsagesAction extends AnAction implements PopupAction { table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); table.setIntercellSpacing(new Dimension(0, 0)); - final Runnable navigateRunnable = new Runnable() { + PopupChooserBuilder builder = new PopupChooserBuilder(table); + final String title = presentation.getTabText(); + if (title != null) { + String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true); + builder.setTitle(result); + builder.setAdText(getSecondInvocationTitle(options, handler)); + } + + builder.setMovable(true).setResizable(true); + builder.setItemChoosenCallback(new Runnable() { @Override public void run() { int[] selected = table.getSelectedRows(); @@ -516,54 +582,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { } } } - }; - - SpeedSearchBase speedSearch = new SpeedSearchBase(table) { - @Override - protected int getSelectedIndex() { - return table.getSelectedRow(); - } - - @Override - protected int convertIndexToModel(int viewIndex) { - return table.convertRowIndexToModel(viewIndex); - } - - @NotNull - @Override - protected Object[] getAllElements() { - return ArrayUtil.toObjectArray(data); - } - - @Override - protected String getElementText(@NotNull Object element) { - if (!(element instanceof UsageNode)) return element.toString(); - UsageNode node = (UsageNode)element; - GroupNode group = (GroupNode)node.getParent(); - Usage usage = node.getUsage(); - if (usage == MORE_USAGES_SEPARATOR) return ""; - return usage.getPresentation().getPlainText() + group.toString(); - } - - @Override - protected void selectElement(Object element, String selectedText) { - int i = data.indexOf(element); - if (i == -1) return; - final int viewRow = table.convertRowIndexToView(i); - table.getSelectionModel().setSelectionInterval(viewRow, viewRow); - } - }; - speedSearch.setComparator(new SpeedSearchComparator(false)); - - PopupChooserBuilder builder = new PopupChooserBuilder(table); - if (title != null) { - String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true); - builder.setTitle(result); - builder.setAdText(getSecondInvocationTitle(options, handler)); - } - - builder.setMovable(true).setResizable(true); - builder.setItemChoosenCallback(navigateRunnable); + }); final JBPopup[] popup = new JBPopup[1]; KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(); @@ -619,7 +638,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { public void actionPerformed(AnActionEvent e) { hideHints(); popup[0].cancel(); - FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager(); + FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(usageView.getProject())).getFindUsagesManager(); FindUsagesManager.SearchData data = new FindUsagesManager.SearchData(); data.myOptions = options; List> plist = descriptor.getAllElementPointers(); @@ -745,53 +764,57 @@ public class ShowUsagesAction extends AnAction implements PopupAction { return true; } - private static int setTableModel(@NotNull JTable table, - @NotNull Collection visibleNodes, - @NotNull UsageViewImpl usageView, - @NotNull final Vector data, - int filtered, - @NotNull UsageViewPresentation presentation) { + @NotNull + private static MyModel setTableModel(@NotNull JTable table, + @NotNull UsageViewImpl usageView, + @NotNull final List data) { ApplicationManager.getApplication().assertIsDispatchThread(); + final int columnCount = calcColumnCount(data); + MyModel model = table.getModel() instanceof MyModel ? (MyModel)table.getModel() : null; + if (model == null || model.getColumnCount() != columnCount) { + model = new MyModel(data, columnCount); + table.setModel(model); + + ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView); + for (int i=0;i data) { + return data.isEmpty() || data.get(0) instanceof StringNode ? 1 : 3; + } + + @NotNull + private static List collectData(@NotNull List usages, + @NotNull Collection visibleNodes, + @NotNull UsageViewImpl usageView, + @NotNull UsageViewPresentation presentation) { + @NotNull List data = new ArrayList(); + int filtered = filtered(usages, usageView); if (filtered != 0) { - data.add(UsageViewBundle.message("usages.were.filtered.out", filtered)); + data.add(createStringNode(UsageViewBundle.message("usages.were.filtered.out", filtered))); } data.addAll(visibleNodes); if (data.isEmpty()) { String progressText = UsageViewManagerImpl.getProgressTitle(presentation); - data.add(progressText); + data.add(createStringNode(progressText)); } Collections.sort(data, USAGE_NODE_COMPARATOR); - AbstractTableModel model = new AbstractTableModel() { - @Override - public int getRowCount() { - return data.size(); - } - - @Override - public int getColumnCount() { - return !data.isEmpty() && data.get(0) instanceof UsageNode ? 3 : 1; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - return data.get(rowIndex); - } - }; - table.setModel(model); - - ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView); - for (int i=0;i nodes = new ArrayList(); - int filtered; String fullTitle; synchronized (usages) { // open up popup as soon as several usages 've been found @@ -841,7 +863,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction { if (shouldShowMoreSeparator) { nodes.add(MORE_USAGES_SEPARATOR_NODE); } - filtered = filtered(usages, usageView); String title = presentation.getTabText(); fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator, nodes.size() - (shouldShowMoreSeparator ? 1 : 0), findUsagesInProgress); @@ -849,12 +870,58 @@ public class ShowUsagesAction extends AnAction implements PopupAction { ((AbstractPopup)popup).setCaption(fullTitle); + + List data = collectData(usages, nodes, usageView, presentation); + MyModel tableModel = setTableModel(table, usageView, data); + List existingData = tableModel.getItems(); + + int row = table.getSelectedRow(); + + int newSelection = updateModel(tableModel, existingData, data, row == -1 ? 0 : row); + if (newSelection < 0 || newSelection >= tableModel.getRowCount()) { + TableScrollingUtil.ensureSelectionExists(table); + newSelection = table.getSelectedRow(); + } + else { + table.getSelectionModel().setSelectionInterval(newSelection, newSelection); + } + TableScrollingUtil.ensureIndexIsVisible(table, newSelection, 0); + + setSizeAndDimensions(table, popup, popupPosition, data); + } + + // returns new selection + private static int updateModel(@NotNull MyModel tableModel, @NotNull List listOld, @NotNull List listNew, int oldSelection) { + UsageNode[] oa = listOld.toArray(new UsageNode[listOld.size()]); + UsageNode[] na = listNew.toArray(new UsageNode[listNew.size()]); + List cmds = ModelDiff.createDiffCmds(tableModel, oa, na); + int selection = oldSelection; + if (cmds != null) { + for (ModelDiff.Cmd cmd : cmds) { + selection = cmd.translateSelection(selection); + cmd.apply(); + } + } + return selection; + } + + private final TransferToEDTQueue myEDTQueue = new TransferToEDTQueue("update table", new Processor() { + @Override + public boolean process(ModelDiff.Cmd cmd) { + cmd.apply(); + return true; + } + }, Condition.FALSE, 100); + + private void setSizeAndDimensions(@NotNull JTable table, + @NotNull JBPopup popup, + @NotNull RelativePoint popupPosition, + @NotNull List data) { JComponent content = popup.getContent(); Window window = SwingUtilities.windowForComponent(content); Dimension d = window.getSize(); - Vector data = new Vector(); - int width = setTableModel(table, nodes, usageView, data, filtered, presentation); + int width = calcMaxWidth(table); width = (int)Math.max(d.getWidth(), width); Dimension headerSize = ((AbstractPopup)popup).getHeaderPreferredSize(); width = Math.max((int)headerSize.getWidth(), width); @@ -910,7 +977,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { } private void appendMoreUsages(Editor editor, @NotNull RelativePoint popupPosition, @NotNull FindUsagesHandler handler, int maxUsages) { - showElementUsages(handler, editor, popupPosition, maxUsages+USAGES_PAGE_SIZE, getDefaultOptions(handler)); + showElementUsages(handler, editor, popupPosition, maxUsages+USAGES_PAGE_SIZE, getDefaultOptions(handler)); } private static void addUsageNodes(@NotNull GroupNode root, @NotNull final UsageViewImpl usageView, @NotNull List outNodes) { @@ -1005,4 +1072,65 @@ public class ShowUsagesAction extends AnAction implements PopupAction { return null; } } + + static class StringNode extends UsageNode { + private final Object myString; + + public StringNode(Object string) { + super(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY)); + myString = string; + } + + @Override + public String toString() { + return myString.toString(); + } + } + + private static class MySpeedSearch extends SpeedSearchBase { + public MySpeedSearch(@NotNull MyTable table) { + super(table); + } + + @Override + protected int getSelectedIndex() { + return getTable().getSelectedRow(); + } + + @Override + protected int convertIndexToModel(int viewIndex) { + return getTable().convertRowIndexToModel(viewIndex); + } + + @NotNull + @Override + protected Object[] getAllElements() { + return ((MyModel)getTable().getModel()).getItems().toArray(); + } + + @Override + protected String getElementText(@NotNull Object element) { + if (!(element instanceof UsageNode)) return element.toString(); + UsageNode node = (UsageNode)element; + if (node instanceof StringNode) return ""; + Usage usage = node.getUsage(); + if (usage == MORE_USAGES_SEPARATOR) return ""; + GroupNode group = (GroupNode)node.getParent(); + return usage.getPresentation().getPlainText() + group; + } + + @Override + protected void selectElement(Object element, String selectedText) { + List data = ((MyModel)getTable().getModel()).getItems(); + int i = data.indexOf(element); + if (i == -1) return; + final int viewRow = getTable().convertRowIndexToView(i); + getTable().getSelectionModel().setSelectionInterval(viewRow, viewRow); + TableUtil.scrollSelectionToVisible(getTable()); + } + + private MyTable getTable() { + return (MyTable)myComponent; + } + } } diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java index 7bf0d165fea5..e4ac2e0ea15e 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java @@ -62,7 +62,7 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer { panel.setBackground(isSelected ? bg : fileBgColor == null ? list.getBackground() : fileBgColor); panel.setForeground(isSelected ? fg : list.getForeground()); - if (usage == null) { + if (usage == null || usageNode instanceof ShowUsagesAction.StringNode) { panel.setLayout(new BorderLayout()); if (column == 0) { panel.add(new JLabel("" + value + "", SwingConstants.CENTER)); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index a2df9687d058..554f04c6b22c 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -23,6 +23,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.IdeBundle; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.actions.CopyReferenceAction; +import com.intellij.openapi.Disposable; import com.intellij.openapi.MnemonicHelper; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -39,10 +40,7 @@ import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.*; -import com.intellij.openapi.util.ActionCallback; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; @@ -64,8 +62,6 @@ import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.*; import com.intellij.util.Alarm; import com.intellij.util.Processor; -import com.intellij.util.diff.Diff; -import com.intellij.util.diff.FilesTooBigForDiffException; import com.intellij.util.text.Matcher; import com.intellij.util.text.MatcherHolder; import com.intellij.util.ui.AsyncProcessIcon; @@ -110,7 +106,7 @@ public abstract class ChooseByNameBase { protected JScrollPane myListScrollPane; // Located in the layered pane protected JList myList; - private DefaultListModel myListModel; + private MyListModel myListModel; private List> myHistory; private List> myFuture; @@ -610,7 +606,7 @@ public abstract class ChooseByNameBase { } }); - myListModel = new DefaultListModel(); + myListModel = new MyListModel(); myList = new JBList(myListModel); myList.setFocusable(false); myList.setSelectionMode(allowMultipleSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : @@ -804,6 +800,7 @@ public abstract class ChooseByNameBase { } } myNames[index] = myModel.getNames(checkboxState); + assert myNames[index] != null : "Model "+myModel+ "("+myModel.getClass()+") returned null names"; if (window != null) { window.setCursor(Cursor.getDefaultCursor()); @@ -862,6 +859,12 @@ public abstract class ChooseByNameBase { DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(myTextPopup); } + Disposer.register(myTextPopup, new Disposable() { + @Override + public void dispose() { + cancelCalcElementsThread(); + } + }); myTextPopup.show(layeredPane); } @@ -949,8 +952,10 @@ public abstract class ChooseByNameBase { ((MatcherHolder)cellRenderer).setPatternMatcher(matcher); } - myCalcElementsThread = new CalcElementsThread(text, myCheckBox.isSelected(), callback, modalityState, postRunnable == null); - ApplicationManager.getApplication().executeOnPooledThread(myCalcElementsThread); + CalcElementsThread calcElementsThread = + new CalcElementsThread(text, myCheckBox.isSelected(), callback, modalityState, postRunnable == null); + myCalcElementsThread = calcElementsThread; + ApplicationManager.getApplication().executeOnPooledThread(calcElementsThread); } }; @@ -969,8 +974,9 @@ public abstract class ChooseByNameBase { } private void cancelCalcElementsThread() { - if (myCalcElementsThread != null) { - myCalcElementsThread.cancel(); + CalcElementsThread calcElementsThread = myCalcElementsThread; + if (calcElementsThread != null) { + calcElementsThread.cancel(); myCalcElementsThread = null; } } @@ -989,45 +995,14 @@ public abstract class ChooseByNameBase { Object[] oldElements = myListModel.toArray(); Object[] newElements = elements.toArray(); - Diff.Change change = null; - try { - change = Diff.buildChanges(oldElements, newElements); - } - catch (FilesTooBigForDiffException e) { - // should not occur - } - - if (change == null) { + List commands = ModelDiff.createDiffCmds(myListModel, oldElements, newElements); + if (commands == null) { myListUpdater.doPostponedOkIfNeeded(); - return; // Nothing changed - } - - List commands = new ArrayList(); - int inserted = 0; - int deleted = 0; - while (change != null) { - if (change.deleted > 0) { - final int start = change.line0 + inserted - deleted; - commands.add(new RemoveCmd(start, start + change.deleted - 1)); - } - - if (change.inserted > 0) { - for (int i = 0; i < change.inserted; i++) { - commands.add(new InsertCmd(change.line0 + i + inserted - deleted, newElements[change.line1 + i])); - } - } - - deleted += change.deleted; - inserted += change.inserted; - change = change.link; + return; } myTextField.setForeground(UIUtil.getTextFieldForeground()); - if (!commands.isEmpty()) { - showList(); - myListUpdater.appendToModel(commands, pos); - } - else { + if (commands.isEmpty()) { if (pos <= 0) { pos = detectBestStatisticalPosition(); } @@ -1037,6 +1012,10 @@ public abstract class ChooseByNameBase { showList(); updateDocPosition(); } + else { + showList(); + myListUpdater.appendToModel(commands, pos); + } } private int detectBestStatisticalPosition() { @@ -1077,41 +1056,21 @@ public abstract class ChooseByNameBase { return "choose_by_name#" + myModel.getPromptText() + "#" + myCheckBox.isSelected() + "#" + myTextField.getText(); } - private interface Cmd { - void apply(); - } - - private class RemoveCmd implements Cmd { - private final int start; - private final int end; - - private RemoveCmd(final int start, final int end) { - this.start = start; - this.end = end; - } - + private static class MyListModel extends DefaultListModel implements ModelDiff.Model { @Override - public void apply() { - myListModel.removeRange(start, end); - } - } - - private class InsertCmd implements Cmd { - private final int idx; - private final Object element; - - private InsertCmd(final int idx, final Object element) { - this.idx = idx; - this.element = element; - } - - @Override - public void apply() { - if (idx < myListModel.size()) { - myListModel.add(idx, element); + public void addToModel(int idx, T element) { + if (idx < size()) { + add(idx, element); } else { - myListModel.addElement(element); + addElement(element); + } + } + + @Override + public void removeRangeFromModel(int start, int end) { + if (start < size()) { + removeRange(start, Math.min(end, size())); } } } @@ -1120,14 +1079,14 @@ public abstract class ChooseByNameBase { private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private static final int DELAY = 10; private static final int MAX_BLOCKING_TIME = 30; - private final List myCommands = Collections.synchronizedList(new ArrayList()); + private final List myCommands = Collections.synchronizedList(new ArrayList()); public void cancelAll() { myCommands.clear(); myAlarm.cancelAllRequests(); } - public void appendToModel(final List commands, final int selectionPos) { + public void appendToModel(@NotNull List commands, final int selectionPos) { myAlarm.cancelAllRequests(); myCommands.addAll(commands); @@ -1142,7 +1101,7 @@ public abstract class ChooseByNameBase { } final long startTime = System.currentTimeMillis(); while (!myCommands.isEmpty() && System.currentTimeMillis() - startTime < MAX_BLOCKING_TIME) { - final Cmd cmd = myCommands.remove(0); + final ModelDiff.Cmd cmd = myCommands.remove(0); cmd.apply(); } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java new file mode 100644 index 000000000000..96f4601c1e30 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.util.diff.Diff; +import com.intellij.util.diff.FilesTooBigForDiffException; + +import java.util.ArrayList; +import java.util.List; + +public class ModelDiff { + public static List createDiffCmds(Model listModel, Object[] oldElements, Object[] newElements) { + Diff.Change change = null; + try { + change = Diff.buildChanges(oldElements, newElements); + } + catch (FilesTooBigForDiffException e) { + // should not occur + } + + if (change == null) { + return null; + } + + List commands = new ArrayList(); + int inserted = 0; + int deleted = 0; + while (change != null) { + if (change.deleted > 0) { + final int start = change.line0 + inserted - deleted; + commands.add(new RemoveCmd(listModel, start, start + change.deleted - 1)); + } + + if (change.inserted > 0) { + for (int i = 0; i < change.inserted; i++) { + commands.add(new InsertCmd(listModel, change.line0 + i + inserted - deleted, newElements[change.line1 + i])); + } + } + + deleted += change.deleted; + inserted += change.inserted; + change = change.link; + } + return commands; + } + + public interface Cmd { + void apply(); + int translateSelection(int row); + } + + public interface Model { + void addToModel(int index, T element); + void removeRangeFromModel(int start, int end); + } + + private static class RemoveCmd implements Cmd { + private final Model myListModel; + private final int start; + private final int end; + + private RemoveCmd(Model model, final int start, final int end) { + myListModel = model; + this.start = start; + this.end = end; + } + + @Override + public void apply() { + myListModel.removeRangeFromModel(start, end+1); + } + + @Override + public int translateSelection(int row) { + if (row < start) return row; + if (row >= end) return row - (end-start); + return start-1; + } + + @Override + public String toString() { + return "-["+start+", "+end+")"; + } + } + + private static class InsertCmd implements Cmd { + private final Model myListModel; + private final int idx; + private final T element; + + private InsertCmd(Model model, final int idx, T element) { + myListModel = model; + this.idx = idx; + this.element = element; + } + + @Override + public void apply() { + myListModel.addToModel(idx, element); + } + + @Override + public int translateSelection(int row) { + return idx > row ? row : row + 1; + } + @Override + public String toString() { + return "+["+idx+"]"; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubTagListProvider.java b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubTagListProvider.java index 9625b651519a..5deb52c5dae2 100644 --- a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubTagListProvider.java +++ b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubTagListProvider.java @@ -15,6 +15,7 @@ import com.intellij.openapi.progress.Task; import com.intellij.platform.templates.github.DownloadUtil; import com.intellij.platform.templates.github.GeneratorException; import com.intellij.platform.templates.github.GithubTagInfo; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,9 +63,13 @@ public class GithubTagListProvider { File cacheFile = getCacheFile(); try { DownloadUtil.downloadAtomically(indicator, url, cacheFile, myUserName, myRepositoryName); - ImmutableSet infos = readTagsFromFile(cacheFile); + final ImmutableSet infos = readTagsFromFile(cacheFile); peer.setErrorMessage(null); - peer.updateTagList(infos); + UIUtil.invokeLaterIfNeeded(new Runnable() { + public void run() { + peer.updateTagList(infos); + } + }); } catch (IOException e) { peer.setErrorMessage("Can not fetch tag list from '" + url + "'!"); diff --git a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java index 3628dd3fd44c..91c9ad0a3b14 100644 --- a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java +++ b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java @@ -18,7 +18,6 @@ package com.intellij.ui; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.psi.PsiElement; -import com.intellij.ui.components.JBList; import com.intellij.ui.popup.PopupUpdateProcessor; import com.intellij.ui.table.JBTable; @@ -26,7 +25,6 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableModel; -import java.util.Collection; public abstract class JBTableWithHintProvider extends JBTable { private JBPopup myHint; @@ -46,9 +44,10 @@ public abstract class JBTableWithHintProvider extends JBTable { if (getClientProperty(PopupChooserBuilder.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) { final int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex(); - if (selected == -1) return; + int rowCount = getRowCount(); + if (selected == -1 || rowCount == 0) return; - final PsiElement element = getPsiElementForHint(getValueAt(selected, 0)); + PsiElement element = getPsiElementForHint(getValueAt(Math.min(selected, rowCount -1), 0)); if (element != null && element.isValid()) { updateHint(element); } 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 79c8b7052bc0..61fda59ac4f6 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 @@ -257,24 +257,10 @@ public class TreeState implements JDOMExternalizable { } public void applyTo(JTree tree) { - applyExpanded(getFacade(tree), tree.getModel().getRoot()); + applyTo(tree, (DefaultMutableTreeNode)tree.getModel().getRoot()); } - private void applyExpanded(final TreeFacade tree, final Object root) { - tree.getInitialized().doWhenDone(new Runnable() { - @Override - public void run() { - tree.batch(new Progressive() { - @Override - public void run(@NotNull ProgressIndicator indicator) { - _applyExpanded(tree, root, indicator); - } - }); - } - }); - } - - private void _applyExpanded(TreeFacade tree, Object root, ProgressIndicator indicator) { + private void applyExpanded(TreeFacade tree, Object root, ProgressIndicator indicator) { indicator.checkCanceled(); if (!(root instanceof DefaultMutableTreeNode)) { @@ -290,9 +276,20 @@ public class TreeState implements JDOMExternalizable { } public void applyTo(final JTree tree, final DefaultMutableTreeNode node) { - applyExpanded(getFacade(tree), node); + final TreeFacade facade = getFacade(tree); + ActionCallback callback = facade.getInitialized().doWhenDone(new Runnable() { + @Override + public void run() { + facade.batch(new Progressive() { + @Override + public void run(@NotNull ProgressIndicator indicator) { + applyExpanded(facade, node, indicator); + } + }); + } + }); if (tree.getSelectionCount() == 0) { - getFacade(tree).getInitialized().doWhenDone(new Runnable() { + callback.doWhenDone(new Runnable() { @Override public void run() { applySelected(tree, node); @@ -301,7 +298,6 @@ public class TreeState implements JDOMExternalizable { } } - // todo private void applySelected(final JTree tree, final DefaultMutableTreeNode node) { TreeUtil.unselect(tree, node); List selectionPaths = new ArrayList(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/GraphicsConfig.java b/platform/util/src/com/intellij/openapi/ui/GraphicsConfig.java similarity index 100% rename from platform/platform-api/src/com/intellij/openapi/ui/GraphicsConfig.java rename to platform/util/src/com/intellij/openapi/ui/GraphicsConfig.java diff --git a/platform/util/src/com/intellij/util/ui/GraphicsUtil.java b/platform/util/src/com/intellij/util/ui/GraphicsUtil.java index 560b5decae5a..d5031a2e9ae2 100644 --- a/platform/util/src/com/intellij/util/ui/GraphicsUtil.java +++ b/platform/util/src/com/intellij/util/ui/GraphicsUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.util.ui; +import com.intellij.openapi.ui.GraphicsConfig; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -43,4 +44,12 @@ public class GraphicsUtil { } } } + + public static GraphicsConfig setupAAPainting(Graphics g) { + final GraphicsConfig config = new GraphicsConfig(g); + final Graphics2D g2 = (Graphics2D)g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + return config; + } } diff --git a/platform/util/src/com/intellij/util/ui/ListTableModel.java b/platform/util/src/com/intellij/util/ui/ListTableModel.java index 09028186666e..3acc7996e342 100644 --- a/platform/util/src/com/intellij/util/ui/ListTableModel.java +++ b/platform/util/src/com/intellij/util/ui/ListTableModel.java @@ -17,6 +17,7 @@ package com.intellij.util.ui; import com.intellij.openapi.util.Condition; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.*; @@ -29,15 +30,15 @@ public class ListTableModel extends TableViewModel implements ItemRe private boolean myIsSortable = false; private SortOrder mySortOrder = SortOrder.ASCENDING; - public ListTableModel(ColumnInfo... columnInfos) { + public ListTableModel(@NotNull ColumnInfo... columnInfos) { this(columnInfos, new ArrayList(), 0, SortOrder.ASCENDING); } - public ListTableModel(ColumnInfo[] columnNames, List items, int selectedColumn) { + public ListTableModel(@NotNull ColumnInfo[] columnNames, @NotNull List items, int selectedColumn) { this(columnNames, items, selectedColumn, SortOrder.ASCENDING); } - public ListTableModel(ColumnInfo[] columnNames, List items, int selectedColumn, final SortOrder order) { + public ListTableModel(@NotNull ColumnInfo[] columnNames, @NotNull List items, int selectedColumn, @NotNull SortOrder order) { myColumnInfos = columnNames; myItems = items; mySortByColumn = selectedColumn; @@ -51,22 +52,27 @@ public class ListTableModel extends TableViewModel implements ItemRe }) != null); } + @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return myColumnInfos[columnIndex].isCellEditable(myItems.get(rowIndex)); } + @Override public Class getColumnClass(int columnIndex) { return myColumnInfos[columnIndex].getColumnClass(); } + @Override public ColumnInfo[] getColumnInfos() { return myColumnInfos; } + @Override public String getColumnName(int column) { return myColumnInfos[column].getName(); } + @Override public int getRowCount() { return myItems.size(); } @@ -85,19 +91,23 @@ public class ListTableModel extends TableViewModel implements ItemRe return myItems.get(row); } + @Override public int getColumnCount() { return myColumnInfos.length; } - public void setItems(List items) { + @Override + public void setItems(@NotNull List items) { myItems = items; fireTableDataChanged(); } + @Override public Object getValueAt(int rowIndex, int columnIndex) { return myColumnInfos[columnIndex].valueOf(myItems.get(rowIndex)); } + @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (rowIndex < myItems.size()) { myColumnInfos[columnIndex].setValue(myItems.get(rowIndex), aValue); @@ -110,7 +120,7 @@ public class ListTableModel extends TableViewModel implements ItemRe * @param columnInfos * @return */ - public boolean setColumnInfos(final ColumnInfo[] columnInfos) { + public boolean setColumnInfos(ColumnInfo[] columnInfos) { if (myColumnInfos != null && Arrays.equals(columnInfos, myColumnInfos)) { return false; } @@ -121,6 +131,8 @@ public class ListTableModel extends TableViewModel implements ItemRe return true; } + @NotNull + @Override public List getItems() { return Collections.unmodifiableList(myItems); } @@ -129,10 +141,12 @@ public class ListTableModel extends TableViewModel implements ItemRe return myColumnInfos[aspectIndex].valueOf(item); } + @Override public void setSortable(boolean aBoolean) { myIsSortable = aBoolean; } + @Override public boolean isSortable() { return myIsSortable; } @@ -145,11 +159,13 @@ public class ListTableModel extends TableViewModel implements ItemRe public void addRow() { } + @Override public void removeRow(int idx) { myItems.remove(idx); fireTableRowsDeleted(idx, idx); } + @Override public void exchangeRows(int idx1, int idx2) { Collections.swap(myItems, idx1, idx2); if (idx1 < idx2) { @@ -170,7 +186,12 @@ public class ListTableModel extends TableViewModel implements ItemRe fireTableRowsInserted(myItems.size() - 1, myItems.size() - 1); } - public void addRows(final Collection items) { + public void insertRow(int index, Item item) { + myItems.add(index, item); + fireTableRowsInserted(index, index); + } + + public void addRows(@NotNull Collection items) { myItems.addAll(items); fireTableRowsInserted(myItems.size() - items.size(), myItems.size() - 1); } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java index 67dbca89f8a2..e3b8c7a02edd 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java @@ -26,20 +26,13 @@ class ReplaceConditionalWithIfPredicate implements PsiElementPredicate { return false; } final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)element; - if (JspPsiUtil.isInJspFile(element)) { - final PsiExpression thenExpression = conditionalExpression.getThenExpression(); - if (thenExpression == null) { - return false; - } - final PsiExpression elseExpression = conditionalExpression.getElseExpression(); - if (elseExpression == null) { - return false; - } - } final PsiElement parent = conditionalExpression.getParent(); if (parent instanceof PsiExpressionStatement) { return false; } + if (JspPsiUtil.isInJspFile(element)) { + return false; + } final PsiMember member = PsiTreeUtil.getParentOfType(element, PsiMember.class); if (member instanceof PsiMethod) { final PsiMethod method = (PsiMethod)member; diff --git a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy index 7675888c4620..2c2619153037 100644 --- a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy +++ b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy @@ -306,7 +306,7 @@ class GitBranchWorkerTest { } @Test - public void "merge with local changes overwritten by checkout should show smart checkout dialog"() { + public void "merge with local changes overwritten by merge should show smart merge dialog"() { test_operation_with_local_changes_overwritten_by_should_show_smart_checkout_dialog("merge"); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java index 6194efa48996..f389393ac909 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.execution.HgDeleteModifyPromptHandler; import java.util.LinkedList; import java.util.List; @@ -66,7 +67,7 @@ public class HgUpdateCommand { final HgCommandExecutor executor = new HgCommandExecutor(project); executor.setShowOutput(true); - final HgCommandResult result = executor.executeInCurrentThread(repo, "update", arguments); + final HgCommandResult result = executor.executeInCurrentThread(repo, "update", arguments,new HgDeleteModifyPromptHandler()); project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project); return result; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java index 5204f2ded5cb..575cb123fcb8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java @@ -13,9 +13,9 @@ package org.zmlx.hg4idea.execution; import com.intellij.execution.ui.ConsoleViewContentType; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsImplUtil; @@ -28,7 +28,6 @@ import org.zmlx.hg4idea.util.HgEncodingUtil; import org.zmlx.hg4idea.util.HgErrorUtil; import org.zmlx.hg4idea.util.HgUtil; -import javax.swing.*; import java.awt.*; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -52,7 +51,7 @@ import java.util.List; *

*/ public final class HgCommandExecutor { - + private static final Logger LOG = Logger.getInstance(HgCommandExecutor.class.getName()); private static final List DEFAULT_OPTIONS = Arrays.asList("--config", "ui.merge=internal:merge"); @@ -100,6 +99,12 @@ public final class HgCommandExecutor { @Nullable public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo, @NotNull final String operation, @Nullable final List arguments) { + return executeInCurrentThread(repo, operation, arguments, null); + } + + @Nullable + public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo, @NotNull final String operation, + @Nullable final List arguments, @Nullable HgPromptHandler handler) { //LOG.assertTrue(!ApplicationManager.getApplication().isDispatchThread()); disabled for release if (myProject == null || myProject.isDisposed() || myVcs == null) { return null; @@ -114,11 +119,11 @@ public final class HgCommandExecutor { WarningReceiver warningReceiver = new WarningReceiver(); PassReceiver passReceiver = new PassReceiver(myProject); - - SocketServer promptServer = new SocketServer(new PromptReceiver()); + + SocketServer promptServer = new SocketServer(new PromptReceiver(handler)); SocketServer warningServer = new SocketServer(warningReceiver); SocketServer passServer = new SocketServer(passReceiver); - + try { int promptPort = promptServer.start(); int warningPort = warningServer.start(); @@ -258,37 +263,46 @@ public final class HgCommandExecutor { } private static class PromptReceiver extends SocketServer.Protocol { + @Nullable HgPromptHandler myHandler; + + public PromptReceiver(@Nullable HgPromptHandler handler) { + myHandler = handler; + } public boolean handleConnection(Socket socket) throws IOException { DataInputStream dataInput = new DataInputStream(socket.getInputStream()); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); final String message = new String(readDataBlock(dataInput)); int numOfChoices = dataInput.readInt(); - final Choice[] choices = new Choice[numOfChoices]; + final HgPromptChoice[] choices = new HgPromptChoice[numOfChoices]; for (int i = 0; i < numOfChoices; i++) { String choice = new String(readDataBlock(dataInput)); - choices[i] = new Choice(choice); + choices[i] = new HgPromptChoice(i, choice); } int defaultChoiceInt = dataInput.readInt(); - final Choice defaultChoice = choices[defaultChoiceInt]; - + final HgPromptChoice defaultChoice = choices[defaultChoiceInt]; + if (myHandler != null && myHandler.shouldHandle(message)) { + int chosen = myHandler.promptUser(message, choices, defaultChoice).getChosenIndex(); + sendChoiceToHg(out, chosen); + return true; + } final int[] index = new int[]{-1}; try { EventQueue.invokeAndWait(new Runnable() { public void run() { - Window parent = ApplicationManager.getApplication().getComponent(Window.class); - index[0] = JOptionPane - .showOptionDialog(parent, message, "hg4idea", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, choices, - defaultChoice); + String[] choicePresentationArray = new String[choices.length]; + for (int i = 0; i < choices.length; ++i) { + choicePresentationArray[i] = choices[i].toString(); + } + index[0] = Messages + .showChooseDialog(message, "hg4idea", + choicePresentationArray, + defaultChoice.toString(), Messages.getQuestionIcon()); } }); - + int chosen = index[0]; - if (chosen == JOptionPane.CLOSED_OPTION) { - out.writeInt(-1); - } else { - out.writeInt(chosen); - } + sendChoiceToHg(out, chosen); return true; } catch (InterruptedException e) { @@ -301,43 +315,16 @@ public final class HgCommandExecutor { } } - private static class Choice{ - private final String fullString; - private final String representation; - private final String choiceChar; - - private Choice(String fullString) { - this.fullString = fullString; - this.representation = fullString.replaceAll("&", ""); - int index = fullString.indexOf("&"); - this.choiceChar = "" + fullString.charAt(index + 1); - + private static void sendChoiceToHg(@NotNull DataOutputStream outStream, int choice) throws IOException { + if (choice == HgPromptChoice.CLOSED_OPTION) { + outStream.writeInt(-1); } - - @Override - public String toString() { - return representation; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Choice choice = (Choice) o; - - if (!fullString.equals(choice.fullString)) return false; - - return true; - } - - @Override - public int hashCode() { - return fullString.hashCode(); + else { + outStream.writeInt(choice); } } } - + private static class PassReceiver extends SocketServer.Protocol{ private final Project myProject; private HgCommandAuthenticator myAuthenticator; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgDeleteModifyPromptHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgDeleteModifyPromptHandler.java new file mode 100644 index 000000000000..1402d6b735f3 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgDeleteModifyPromptHandler.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.zmlx.hg4idea.execution; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.lang.reflect.InvocationTargetException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Nadya Zabrodina + */ +public class HgDeleteModifyPromptHandler implements HgPromptHandler { + + private static final Logger LOG = Logger.getInstance("#org.zmlx.hg4idea.execution.HgDeleteModifyPromptHandler"); + + private static final Pattern LOCAL_DELETE_REMOTE_MODIFIED_CONFLICT_MESSAGE_PATTERN = Pattern.compile( + "remote\\schanged(.+)which\\slocal\\sdeleted\\s.+"); + private static final Pattern REMOTE_DELETE_LOCAL_MODIFIED_CONFLICT_MESSAGE_PATTERN = Pattern.compile( + "\\slocal\\schanged(.+)which\\sremote\\sdeleted\\s.+"); + + + public HgPromptChoice promptUser(@NotNull final String message, + @NotNull final HgPromptChoice[] choices, + @NotNull final HgPromptChoice defaultChoice) { + + Matcher localDelMatcher = LOCAL_DELETE_REMOTE_MODIFIED_CONFLICT_MESSAGE_PATTERN.matcher(message); + Matcher localModifyMatcher = REMOTE_DELETE_LOCAL_MODIFIED_CONFLICT_MESSAGE_PATTERN.matcher(message); + String filename; + final String modifiedMessage; + if (localDelMatcher.matches()) { + filename = localDelMatcher.group(1); + modifiedMessage = + "File " + filename + " is deleted locally, but modified remotely. Do you want to keep the modified version or remove the file?"; + } + else if (localModifyMatcher.matches()) { + filename = localModifyMatcher.group(1); + modifiedMessage = + "File " + filename + " is deleted remotely, but modified locally. Do you want to keep the modified version or remove the file?"; + } + else { + modifiedMessage = ""; + } + final int[] chosen = new int[]{-1}; + try { + EventQueue.invokeAndWait + (new Runnable() { + public void run() { + String[] choicePresentationArray = new String[choices.length]; + for (int i = 0; i < choices.length; ++i) { + choicePresentationArray[i] = choices[i].toString(); + } + chosen[0] = Messages + .showChooseDialog(modifiedMessage, "Delete-Modify Conflict", + choicePresentationArray, + defaultChoice.toString(), Messages.getQuestionIcon()); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + return defaultChoice; + } + catch (InvocationTargetException e) { + LOG.error(e); + return defaultChoice; + } + return chosen[0] >= 0 ? choices[chosen[0]] : HgPromptChoice.ABORT; + } + + public boolean shouldHandle(@Nullable String message) { + if (message == null) { + return false; + } + Matcher localDelMatcher = LOCAL_DELETE_REMOTE_MODIFIED_CONFLICT_MESSAGE_PATTERN.matcher(message); + Matcher localModifyMatcher = REMOTE_DELETE_LOCAL_MODIFIED_CONFLICT_MESSAGE_PATTERN.matcher(message); + if (localDelMatcher.matches() || localModifyMatcher.matches()) { + return true; + } + return false; + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptChoice.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptChoice.java new file mode 100644 index 000000000000..2291528e6274 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptChoice.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.zmlx.hg4idea.execution; + + +public class HgPromptChoice { + private final String fullString; + private final String representation; + private final int chosenIndex; + public static final int CLOSED_OPTION = -1; + public static final HgPromptChoice ABORT = new HgPromptChoice(-1, "AbortChoice"); + + public int getChosenIndex() { + return chosenIndex; + } + + + HgPromptChoice(int chosenIndex, String fullString) { + this.fullString = fullString; + this.representation = fullString.replaceAll("&", ""); + this.chosenIndex = chosenIndex; + } + + @Override + public String toString() { + return representation; + } + + @Override + public boolean equals(Object o) { + if (null == o) return true; + if (getClass() != o.getClass()) return false; + + HgPromptChoice choice = (HgPromptChoice)o; + + if (!fullString.equals(choice.fullString)) return false; + + return true; + } + + @Override + public int hashCode() { + return fullString.hashCode(); + } +} \ No newline at end of file diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptHandler.java new file mode 100644 index 000000000000..0acdbde5178b --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.zmlx.hg4idea.execution; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * HgPromptHandler is used by {@link HgCommandExecutor}, when you want to change the behavior of + * standard commands execution in the Mercurial. + * + * @author Nadya Zabrodina + */ +public interface HgPromptHandler { + + /** + * Checks you need to change the default behavior. + * + * @param message standard output message from Mercurial + * @return + */ + boolean shouldHandle(@Nullable String message); + + /** + * Change default behavior in commands execution. Execute only if shouldHandle method return true. + * + * @param message standard output message from Mercurial + * @param choices possible choices + * @param defaultChoice + * @return + */ + HgPromptChoice promptUser(@NotNull final String message, + @NotNull final HgPromptChoice[] choices, + @NotNull final HgPromptChoice defaultChoice); +} diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java index 9d32c7109ef1..9c657396a854 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java @@ -40,6 +40,7 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.PathUtil; +import com.intellij.util.concurrency.Semaphore; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.idea.maven.execution.*; @@ -49,6 +50,7 @@ import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; import org.jetbrains.idea.maven.project.MavenProjectsTree; +import javax.swing.*; import java.io.File; import java.io.IOException; import java.util.*; @@ -522,6 +524,8 @@ public abstract class MavenImportingTestCase extends MavenTestCase { final CompileScope scope = new ModuleCompileScope(myProject, modules.toArray(new Module[modules.size()]), false); + final Semaphore semaphore = new Semaphore(); + semaphore.down(); UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { @@ -531,10 +535,16 @@ public abstract class MavenImportingTestCase extends MavenTestCase { //assertFalse(aborted); //assertEquals(collectMessages(compileContext, CompilerMessageCategory.ERROR), 0, errors); //assertEquals(collectMessages(compileContext, CompilerMessageCategory.WARNING), 0, warnings); + semaphore.up(); } }); } }); + while (!semaphore.waitFor(100)) { + if (SwingUtilities.isEventDispatchThread()) { + UIUtil.dispatchAllInvocationEvents(); + } + } } private static String collectMessages(CompileContext compileContext, CompilerMessageCategory messageType) {