diff --git a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.form b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.form
index b6012a096c95..db191dde6fa3 100644
--- a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.form
+++ b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.form
@@ -1,6 +1,6 @@
diff --git a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
index 071f348a79a4..debdb7b9fdc6 100644
--- a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
+++ b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.jar;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.ui.AlternativeJREPanel;
import com.intellij.execution.ui.CommonJavaParametersPanel;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
@@ -34,6 +35,7 @@ import javax.swing.*;
public class JarApplicationConfigurable extends SettingsEditor implements PanelWithAnchor {
private CommonJavaParametersPanel myCommonProgramParameters;
private LabeledComponent myJarPathComponent;
+ private LabeledComponent myModuleComponent;
private JPanel myWholePanel;
private AlternativeJREPanel myAlternativeJREPanel;
@@ -43,6 +45,9 @@ public class JarApplicationConfigurable extends SettingsEditor");
+ modulesComboBox.fillModules(project);
}
public void applyEditorTo(final JarApplicationConfiguration configuration) throws ConfigurationException {
@@ -50,12 +55,14 @@ public class JarApplicationConfigurable extends SettingsEditor myEnvs = new LinkedHashMap();
+ private JavaRunConfigurationModule myConfigurationModule;
public JarApplicationConfiguration(Project project, ConfigurationFactory factory, String name) {
super(project, factory, name);
+ myConfigurationModule = new JavaRunConfigurationModule(project, true);
}
@NotNull
@@ -67,6 +70,15 @@ public class JarApplicationConfiguration extends RunConfigurationBase implements
JavaRunConfigurationExtensionManager.getInstance().readExternal(this, element);
XmlSerializer.deserializeInto(myBean, element);
EnvironmentVariablesComponent.readExternal(element, getEnvs());
+ myConfigurationModule.readExternal(element);
+ }
+
+ public void setModule(Module module) {
+ myConfigurationModule.setModule(module);
+ }
+
+ public Module getModule() {
+ return myConfigurationModule.getModule();
}
@Override
@@ -76,6 +88,9 @@ public class JarApplicationConfiguration extends RunConfigurationBase implements
XmlSerializer.serializeInto(myBean, element, SERIALIZATION_FILTERS);
EnvironmentVariablesComponent.writeExternal(element, getEnvs());
PathMacroManager.getInstance(getProject()).collapsePathsRecursively(element);
+ if (myConfigurationModule.getModule() != null) {
+ myConfigurationModule.writeExternal(element);
+ }
}
@Override
@@ -89,6 +104,13 @@ public class JarApplicationConfiguration extends RunConfigurationBase implements
JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
}
+ @NotNull
+ @Override
+ public Module[] getModules() {
+ Module module = myConfigurationModule.getModule();
+ return module != null ? new Module[] {module}: Module.EMPTY_ARRAY;
+ }
+
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java b/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
index 9a1dfad2955a..45519c91baeb 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
@@ -19,5 +19,5 @@ package com.intellij.execution.configurations;
/**
* @author spleaner
*/
-public interface ModuleRunProfile extends RunProfileWithCompileBeforeLaunchOption {
+public interface ModuleRunProfile extends RunProfileWithCompileBeforeLaunchOption, SearchScopeProvidingRunProfile {
}
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
index ea6b158e0bc2..e3f0c22a2132 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
@@ -28,8 +28,8 @@ public class SearchScopeProvider {
@NotNull
public static GlobalSearchScope createSearchScope(@NotNull Project project, @Nullable RunProfile runProfile) {
Module[] modules = null;
- if (runProfile instanceof ModuleRunProfile) {
- modules = ((ModuleRunProfile)runProfile).getModules();
+ if (runProfile instanceof SearchScopeProvidingRunProfile) {
+ modules = ((SearchScopeProvidingRunProfile)runProfile).getModules();
}
if (modules == null || modules.length == 0) {
return GlobalSearchScope.allScope(project);
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java
new file mode 100644
index 000000000000..afdd273384e8
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 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.execution.configurations;
+
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Base interface for run configurations that can specify which part of the project should be used to search sources. This information
+ * will be used to provide more accurate navigation to sources from stack traces, debugger, etc
+ *
+ * @author nik
+ */
+public interface SearchScopeProvidingRunProfile extends RunProfile {
+ /**
+ * @return modules where to search sources for this configuration
+ */
+ @NotNull
+ Module[] getModules();
+}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java b/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java
index f544517bb5d4..6bc5f6505c92 100644
--- a/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java
@@ -3,6 +3,7 @@ package com.intellij.application.options;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.ui.ListCellRendererWrapper;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -10,10 +11,20 @@ import javax.swing.*;
* @author yole
*/
public class ModuleListCellRenderer extends ListCellRendererWrapper {
+ private final String myEmptySelectionText;
+
+ public ModuleListCellRenderer() {
+ this("[none]");
+ }
+
+ public ModuleListCellRenderer(@NotNull String emptySelectionText) {
+ myEmptySelectionText = emptySelectionText;
+ }
+
@Override
public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) {
if (module == null) {
- setText("[none]");
+ setText(myEmptySelectionText);
}
else {
setIcon(ModuleType.get(module).getIcon());
diff --git a/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java b/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java
index 17434cb0c7ba..4c2ef3a3d16c 100644
--- a/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java
+++ b/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java
@@ -36,6 +36,7 @@ import java.util.List;
*/
public class ModulesComboBox extends ComboBox {
private final SortedComboBoxModel myModel;
+ private boolean myAllowEmptySelection;
public ModulesComboBox() {
this(new SortedComboBoxModel(ModulesAlphaComparator.INSTANCE));
@@ -58,8 +59,17 @@ public class ModulesComboBox extends ComboBox {
setRenderer(new ModuleListCellRenderer());
}
+ public void allowEmptySelection(@NotNull String emptySelectionText) {
+ myAllowEmptySelection = true;
+ myModel.add(null);
+ setRenderer(new ModuleListCellRenderer(emptySelectionText));
+ }
+
public void setModules(@NotNull Collection modules) {
myModel.setAll(modules);
+ if (myAllowEmptySelection) {
+ myModel.add(null);
+ }
}
public void fillModules(@NotNull Project project) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java
index 8a561e4003b4..61a5c71861c3 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java
@@ -29,8 +29,9 @@ public class ModulesAlphaComparator implements Comparator{
@Override
public int compare(Module module1, Module module2) {
- final String name1 = module1.getName();
- final String name2 = module2.getName();
- return name1.compareToIgnoreCase(name2);
+ if (module1 == null && module2 == null) return 0;
+ if (module1 == null && module2 != null) return -1;
+ if (module1 != null && module2 == null) return 1;
+ return module1.getName().compareToIgnoreCase(module2.getName());
}
}
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index c26cb10030c4..c2b7de8ba7ed 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -153,17 +153,26 @@ public class StringUtil extends StringUtilRt {
int i = 0;
while (i < text.length()) {
- final int i1 = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
- if (i1 < 0) {
- if (i == 0) return text;
+ final int index = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
+ if (index < 0) {
+ if (i == 0) {
+ return text;
+ }
+
newText.append(text, i, text.length());
break;
}
else {
- if (newText == null) newText = new StringBuilder(text.length() - i);
- newText.append(text, i, i1);
+ if (newText == null) {
+ if (text.length() == oldS.length()) {
+ return newS;
+ }
+ newText = new StringBuilder(text.length() - i);
+ }
+
+ newText.append(text, i, index);
newText.append(newS);
- i = i1 + oldS.length();
+ i = index + oldS.length();
}
}
return newText != null ? newText.toString() : "";
@@ -1786,7 +1795,7 @@ public class StringUtil extends StringUtilRt {
public static boolean contains(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
return indexOf(sequence, infix) >= 0;
}
-
+
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
for (int i = 0; i < sequence.length() - infix.length(); i++) {
@@ -2448,7 +2457,7 @@ public class StringUtil extends StringUtilRt {
* \r
*
* will return the following array: foo\r\n, \n, bar\n, \r\n, baz\r, \r
- *
+ *
*/
@NotNull
@Contract(pure = true)
diff --git a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
index d2f593d13ff1..93ebb038cae1 100644
--- a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
+++ b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
@@ -111,7 +111,7 @@ public class StringUtilTest extends TestCase {
public void testFormatLinks() {
assertEquals("http://a-b+c", StringUtil.formatLinks("http://a-b+c"));
}
-
+
public void testCopyHeapCharBuffer() {
String s = "abcde";
CharBuffer buffer = CharBuffer.allocate(s.length());
@@ -124,7 +124,7 @@ public class StringUtilTest extends TestCase {
assertNull(CharArrayUtil.fromSequenceWithoutCopying(buffer.subSequence(1, 5)));
assertNull(CharArrayUtil.fromSequenceWithoutCopying(buffer.subSequence(1, 2)));
}
-
+
public void testTitleCase() {
assertEquals("Couldn't Connect to Debugger", StringUtil.wordsToBeginFromUpperCase("Couldn't connect to debugger"));
}
@@ -198,7 +198,7 @@ public class StringUtilTest extends TestCase {
assertEquals(Arrays.asList("aa"), Arrays.asList(StringUtil.splitByLinesKeepSeparators("aa")));
assertEquals(Arrays.asList("\n", "\n", "aa\n", "\n", "bb\n", "cc\n", "\n"),
Arrays.asList(StringUtil.splitByLinesKeepSeparators("\n\naa\n\nbb\ncc\n\n")));
-
+
assertEquals(Arrays.asList("\r", "\r\n", "\r"), Arrays.asList(StringUtil.splitByLinesKeepSeparators("\r\r\n\r")));
assertEquals(Arrays.asList("\r\n", "\r", "\r\n"), Arrays.asList(StringUtil.splitByLinesKeepSeparators("\r\n\r\r\n")));
@@ -224,4 +224,13 @@ public class StringUtilTest extends TestCase {
}
}
}
+
+ public void testReplaceReturnReplacementIfTextEqualsToReplacedText() {
+ String newS = "/tmp";
+ assertSame(StringUtil.replace("$PROJECT_FILE$", "$PROJECT_FILE$".toLowerCase().toUpperCase() /* ensure new String instance */, newS), newS);
+ }
+
+ public void testReplace() {
+ assertEquals(StringUtil.replace("$PROJECT_FILE$/filename", "$PROJECT_FILE$", "/tmp"), "/tmp/filename");
+ }
}