mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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);
|
||||
|
||||
+3
-3
@@ -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>
|
||||
|
||||
+68
-68
@@ -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));
|
||||
|
||||
+13
-10
@@ -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
|
||||
|
||||
+16
-5
@@ -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);
|
||||
}
|
||||
|
||||
+6
-7
@@ -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) {
|
||||
|
||||
+3
-1
@@ -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+" "));
|
||||
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<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+"]";
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -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);
|
||||
}
|
||||
|
||||
+3
-10
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user