Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vassiliy Kudryashov
2012-10-15 16:07:40 +04:00
32 changed files with 885 additions and 407 deletions
@@ -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;
}
}
@@ -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);
@@ -48,7 +48,7 @@
<font/>
</border>
<children>
<component id="f6192" class="javax.swing.JRadioButton" binding="mySuspendThreadRadio">
<component id="f6192" class="javax.swing.JRadioButton" binding="myRbSuspendThread">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -56,7 +56,7 @@
<text resource-bundle="messages/DebuggerBundle" key="breakpoint.properties.panel.option.suspend.thread"/>
</properties>
</component>
<component id="106f5" class="javax.swing.JRadioButton" binding="mySuspendAllRadio">
<component id="106f5" class="javax.swing.JRadioButton" binding="myRbSuspendAll">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -77,7 +77,7 @@
<text resource-bundle="messages/DebuggerBundle" key="breakpoint.properties.panel.option.suspend.default"/>
</properties>
</component>
<component id="cd928" class="com.intellij.ui.components.JBCheckBox" binding="mySuspendJBCheckBox">
<component id="cd928" class="com.intellij.ui.components.JBCheckBox" binding="myCbSuspend">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<String> s, String concator) {
return StringUtil.join(s, concator);
}
private static String concatWithEx(List<String> 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<InstanceFilter> idxs = new ArrayList<InstanceFilter>();
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);
@@ -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));
@@ -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();
}
}
@@ -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<SimpleNode> 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
@@ -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);
}
@@ -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;
@@ -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;
}
}
@@ -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
@@ -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<Filter> myFilters = new ArrayList<Filter>();
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;
}
@@ -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) {
@@ -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() {
@@ -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<Object> USAGE_NODE_COMPARATOR = new Comparator<Object>() {
private static final Comparator<UsageNode> USAGE_NODE_COMPARATOR = new Comparator<UsageNode>() {
@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<UsageNode>());
TableScrollingUtil.installActions(table);
final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
setTableModel(table, usageView, data);
SpeedSearchBase<JTable> 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<Usage> copy;
synchronized (usages) {
copy = new ArrayList<Usage>(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<UsageNode> implements ModelDiff.Model<Object> {
private MyModel(@NotNull List<UsageNode> data, int cols) {
super(cols(cols), data, 0);
}
@NotNull
private static ColumnInfo[] cols(int cols) {
ColumnInfo<UsageNode, UsageNode> o = new ColumnInfo<UsageNode, UsageNode>("") {
@Nullable
@Override
public UsageNode valueOf(UsageNode node) {
return node;
}
};
List<ColumnInfo<UsageNode, UsageNode>> 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+"&nbsp;"));
JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text + "&nbsp;"));
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<UsageNode> outNodes = new ArrayList<UsageNode>();
addUsageNodes(usageView.getRoot(), usageView, outNodes);
int filtered = filtered(usages, usageView);
TableScrollingUtil.installActions(table);
final Vector<Object> data = new Vector<Object>();
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<JTable> speedSearch = new SpeedSearchBase<JTable>(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<SmartPsiElementPointer<PsiElement>> 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<UsageNode> visibleNodes,
@NotNull UsageViewImpl usageView,
@NotNull final Vector<Object> data,
int filtered,
@NotNull UsageViewPresentation presentation) {
@NotNull
private static MyModel setTableModel(@NotNull JTable table,
@NotNull UsageViewImpl usageView,
@NotNull final List<UsageNode> 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<table.getColumnModel().getColumnCount();i++) {
TableColumn column = table.getColumnModel().getColumn(i);
column.setCellRenderer(renderer);
}
}
return model;
}
private static int calcColumnCount(@NotNull List<UsageNode> data) {
return data.isEmpty() || data.get(0) instanceof StringNode ? 1 : 3;
}
@NotNull
private static List<UsageNode> collectData(@NotNull List<Usage> usages,
@NotNull Collection<UsageNode> visibleNodes,
@NotNull UsageViewImpl usageView,
@NotNull UsageViewPresentation presentation) {
@NotNull List<UsageNode> data = new ArrayList<UsageNode>();
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<table.getColumnModel().getColumnCount();i++) {
TableColumn column = table.getColumnModel().getColumn(i);
column.setCellRenderer(renderer);
}
return data;
}
private static int calcMaxWidth(JTable table) {
int colsNum = table.getColumnModel().getColumnCount();
int totalWidth = 0;
for (int col = 0; col < colsNum -1; col++) {
TableColumn column = table.getColumnModel().getColumn(col);
int preferred = column.getPreferredWidth();
int width = Math.max(preferred, calcMaxWidth(table, col));
int width = Math.max(preferred, columnMaxWidth(table, col));
totalWidth += width;
column.setMinWidth(width);
column.setMaxWidth(width);
@@ -799,12 +822,12 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
column.setPreferredWidth(width);
}
totalWidth += calcMaxWidth(table, colsNum - 1);
totalWidth += columnMaxWidth(table, colsNum - 1);
return totalWidth;
}
private static int calcMaxWidth(@NotNull JTable table, int col) {
private static int columnMaxWidth(@NotNull JTable table, int col) {
TableColumn column = table.getColumnModel().getColumn(col);
int width = 0;
for (int row = 0; row < table.getRowCount(); row++) {
@@ -829,7 +852,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (popup.isDisposed()) return;
final List<UsageNode> nodes = new ArrayList<UsageNode>();
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<UsageNode> data = collectData(usages, nodes, usageView, presentation);
MyModel tableModel = setTableModel(table, usageView, data);
List<UsageNode> 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<UsageNode> listOld, @NotNull List<UsageNode> listNew, int oldSelection) {
UsageNode[] oa = listOld.toArray(new UsageNode[listOld.size()]);
UsageNode[] na = listNew.toArray(new UsageNode[listNew.size()]);
List<ModelDiff.Cmd> 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<ModelDiff.Cmd> myEDTQueue = new TransferToEDTQueue<ModelDiff.Cmd>("update table", new Processor<ModelDiff.Cmd>() {
@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<UsageNode> data) {
JComponent content = popup.getContent();
Window window = SwingUtilities.windowForComponent(content);
Dimension d = window.getSize();
Vector<Object> data = new Vector<Object>();
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<UsageNode> 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<JTable> {
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<UsageNode> 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;
}
}
}
@@ -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("<html><body><b>" + value + "</b></body></html>", SwingConstants.CENTER));
@@ -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<Object> myListModel;
private List<Pair<String, Integer>> myHistory;
private List<Pair<String, Integer>> myFuture;
@@ -610,7 +606,7 @@ public abstract class ChooseByNameBase {
}
});
myListModel = new DefaultListModel();
myListModel = new MyListModel<Object>();
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<ModelDiff.Cmd> commands = ModelDiff.createDiffCmds(myListModel, oldElements, newElements);
if (commands == null) {
myListUpdater.doPostponedOkIfNeeded();
return; // Nothing changed
}
List<Cmd> commands = new ArrayList<Cmd>();
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<T> extends DefaultListModel implements ModelDiff.Model<T> {
@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<Cmd> myCommands = Collections.synchronizedList(new ArrayList<Cmd>());
private final List<ModelDiff.Cmd> myCommands = Collections.synchronizedList(new ArrayList<ModelDiff.Cmd>());
public void cancelAll() {
myCommands.clear();
myAlarm.cancelAllRequests();
}
public void appendToModel(final List<Cmd> commands, final int selectionPos) {
public void appendToModel(@NotNull List<ModelDiff.Cmd> 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();
}
@@ -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<Cmd> createDiffCmds(Model<Object> 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<Cmd> commands = new ArrayList<Cmd>();
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<T> {
void addToModel(int index, T element);
void removeRangeFromModel(int start, int end);
}
private static class RemoveCmd<T> implements Cmd {
private final Model<T> myListModel;
private final int start;
private final int end;
private RemoveCmd(Model<T> 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<T> implements Cmd {
private final Model<T> myListModel;
private final int idx;
private final T element;
private InsertCmd(Model<T> 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+"]";
}
}
}
@@ -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<GithubTagInfo> infos = readTagsFromFile(cacheFile);
final ImmutableSet<GithubTagInfo> 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 + "'!");
@@ -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);
}
@@ -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<TreePath> selectionPaths = new ArrayList<TreePath>();
@@ -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;
}
}
@@ -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<Item> extends TableViewModel<Item> implements ItemRe
private boolean myIsSortable = false;
private SortOrder mySortOrder = SortOrder.ASCENDING;
public ListTableModel(ColumnInfo... columnInfos) {
public ListTableModel(@NotNull ColumnInfo... columnInfos) {
this(columnInfos, new ArrayList<Item>(), 0, SortOrder.ASCENDING);
}
public ListTableModel(ColumnInfo[] columnNames, List<Item> items, int selectedColumn) {
public ListTableModel(@NotNull ColumnInfo[] columnNames, @NotNull List<Item> items, int selectedColumn) {
this(columnNames, items, selectedColumn, SortOrder.ASCENDING);
}
public ListTableModel(ColumnInfo[] columnNames, List<Item> items, int selectedColumn, final SortOrder order) {
public ListTableModel(@NotNull ColumnInfo[] columnNames, @NotNull List<Item> items, int selectedColumn, @NotNull SortOrder order) {
myColumnInfos = columnNames;
myItems = items;
mySortByColumn = selectedColumn;
@@ -51,22 +52,27 @@ public class ListTableModel<Item> extends TableViewModel<Item> 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<Item> extends TableViewModel<Item> implements ItemRe
return myItems.get(row);
}
@Override
public int getColumnCount() {
return myColumnInfos.length;
}
public void setItems(List<Item> items) {
@Override
public void setItems(@NotNull List<Item> 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<Item> extends TableViewModel<Item> 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<Item> extends TableViewModel<Item> implements ItemRe
return true;
}
@NotNull
@Override
public List<Item> getItems() {
return Collections.unmodifiableList(myItems);
}
@@ -129,10 +141,12 @@ public class ListTableModel<Item> extends TableViewModel<Item> 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<Item> extends TableViewModel<Item> 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<Item> extends TableViewModel<Item> implements ItemRe
fireTableRowsInserted(myItems.size() - 1, myItems.size() - 1);
}
public void addRows(final Collection<Item> items) {
public void insertRow(int index, Item item) {
myItems.add(index, item);
fireTableRowsInserted(index, index);
}
public void addRows(@NotNull Collection<Item> items) {
myItems.addAll(items);
fireTableRowsInserted(myItems.size() - items.size(), myItems.size() - 1);
}
@@ -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;
@@ -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");
}
@@ -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;
}
@@ -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;
* </p>
*/
public final class HgCommandExecutor {
private static final Logger LOG = Logger.getInstance(HgCommandExecutor.class.getName());
private static final List<String> 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<String> arguments) {
return executeInCurrentThread(repo, operation, arguments, null);
}
@Nullable
public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo, @NotNull final String operation,
@Nullable final List<String> 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;
@@ -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;
}
}
@@ -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();
}
}
@@ -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);
}
@@ -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) {