diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
index e36efc870d41..b57def2b36be 100644
--- a/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
+++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
@@ -27,7 +27,6 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -93,8 +92,6 @@ public class TextPainter implements Printable {
myFileName = fileName;
mySegmentEnd = myDocument.getTextLength();
- PsiDocumentManager.getInstance(project).commitAllDocuments();
-
myFileType = psiFile.getFileType();
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
index 08d9c320118f..9b63a06d17bc 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
@@ -253,8 +253,6 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
myViewContentPanel = new JPanel();
myPanel = new SimpleToolWindowPanel(true).setProvideQuickActions(false);
myPanel.setContent(myViewContentPanel);
-
- myPanel.setBorder(new ToolWindow.Border(true, false, false, false));
}
public String getName() {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
index 62c78bbb0f6c..c7d0dcbacf19 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
@@ -462,7 +462,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
boolean hasFocus) {
if (value instanceof MyNode) {
final MyNode node = ((MyNode)value);
- setIcon(node.getConfigurable().getIcon(expanded));
+ setIcon(node.getIcon(expanded));
final Font font = UIUtil.getTreeFont();
if (node.isDisplayInBold()) {
setFont(font.deriveFont(Font.BOLD));
@@ -699,8 +699,8 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
throw new ConfigurationException("Name should contain non-space characters");
}
if (names.contains(name)) {
- final NamedConfigurable selectedConfugurable = getSelectedConfugurable();
- if (selectedConfugurable == null || !Comparing.strEqual(selectedConfugurable.getDisplayName(), name)) {
+ final NamedConfigurable selectedConfigurable = getSelectedConfugurable();
+ if (selectedConfigurable == null || !Comparing.strEqual(selectedConfigurable.getDisplayName(), name)) {
selectNodeInTree(node);
}
throw new ConfigurationException(CommonBundle.message("smth.already.exist.error.message", prefix, name), title);
@@ -836,6 +836,16 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
public void setDisplayInBold(boolean displayInBold) {
myDisplayInBold = displayInBold;
}
+
+ @Nullable
+ public Icon getIcon(boolean expanded) {
+ // thanks to invokeLater() in TreeUtil.showAndSelect(), we can get calls to getIcon() after the tree has been disposed
+ final NamedConfigurable configurable = getConfigurable();
+ if (configurable != null) {
+ return configurable.getIcon(expanded);
+ }
+ return null;
+ }
}
@SuppressWarnings({"ConstantConditions"})
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
index e53742e1e2f4..4c32efd347a6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.editor.highlighter;
import com.intellij.lang.Language;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
@@ -32,6 +33,8 @@ import org.jetbrains.annotations.Nullable;
* @author yole
*/
public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.highlighter.EditorHighlighterFactoryImpl");
+
@Override
public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, final EditorColorsScheme colors) {
if (highlighter == null) highlighter = new PlainSyntaxHighlighter();
@@ -74,8 +77,16 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
final ContentBasedFileSubstitutor[] processors = Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME);
SyntaxHighlighter highlighter = null;
for (ContentBasedFileSubstitutor processor : processors) {
- if (processor.isApplicable(project, vFile) && processor instanceof ContentBasedClassFileProcessor) {
- highlighter = ((ContentBasedClassFileProcessor) processor).createHighlighter(project, vFile);
+ boolean applicable;
+ try {
+ applicable = processor.isApplicable(project, vFile);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ continue;
+ }
+ if (applicable && processor instanceof ContentBasedClassFileProcessor) {
+ highlighter = ((ContentBasedClassFileProcessor)processor).createHighlighter(project, vFile);
}
}
if (highlighter == null) {
diff --git a/platform/util/src/com/intellij/openapi/util/Comparing.java b/platform/util/src/com/intellij/openapi/util/Comparing.java
index 95f5f8ab166a..4860c7ab53f7 100644
--- a/platform/util/src/com/intellij/openapi/util/Comparing.java
+++ b/platform/util/src/com/intellij/openapi/util/Comparing.java
@@ -140,6 +140,10 @@ public class Comparing {
return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;
}
+ public static int compare(boolean o1, boolean o2) {
+ return o1 == o2 ? 0 : o1 ? 1 : -1;
+ }
+
public static int compare(int o1, int o2) {
return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;
}
diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties
index ba66305c6f68..a5203a77da24 100644
--- a/plugins/android/resources/messages/AndroidBundle.properties
+++ b/plugins/android/resources/messages/AndroidBundle.properties
@@ -36,7 +36,8 @@ activity.class.not.specified.error=Activity class not specified
not.activity.subclass.error={0} is not an Activity subclass
no.facet.error=No Android facet found for {0}
android.logcat.tab.title=Logcat
-android.logcat.title=Android Logcat
+android.adb.logs.tab.title=ADB logs
+android.logcat.title=Android
android.logcat.error.dialog.title=Android Logcat Error
android.logcat.color.page.name=Android Logcat
warning.level.title=Warning
diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml
index 1cfc42b1a4fd..008774bdaad1 100644
--- a/plugins/android/src/META-INF/plugin.xml
+++ b/plugins/android/src/META-INF/plugin.xml
@@ -181,7 +181,7 @@
- {
return ApplicationManager.getApplication().runReadAction(new Computable() {
@Nullable
public PsiClass compute() {
- return c.getSuperClass();
+ return c.isValid() ? c.getSuperClass() : null;
}
});
}
diff --git a/plugins/android/src/org/jetbrains/android/dom/manifest/ManifestDomFileDescription.java b/plugins/android/src/org/jetbrains/android/dom/manifest/ManifestDomFileDescription.java
index acea0d6bb5f5..641838ee575c 100644
--- a/plugins/android/src/org/jetbrains/android/dom/manifest/ManifestDomFileDescription.java
+++ b/plugins/android/src/org/jetbrains/android/dom/manifest/ManifestDomFileDescription.java
@@ -42,7 +42,7 @@ public class ManifestDomFileDescription extends DomFileDescription {
return false;
}
final Module module = ModuleUtil.findModuleForPsiElement(file);
- return module == null || AndroidFacet.getInstance(module) != null;
+ return module == null || !module.isDisposed() && AndroidFacet.getInstance(module) != null;
}
protected void initializeFileDescription() {
diff --git a/plugins/android/src/org/jetbrains/android/logcat/AdbErrors.java b/plugins/android/src/org/jetbrains/android/logcat/AdbErrors.java
new file mode 100644
index 000000000000..4fd6125e134d
--- /dev/null
+++ b/plugins/android/src/org/jetbrains/android/logcat/AdbErrors.java
@@ -0,0 +1,37 @@
+package org.jetbrains.android.logcat;
+
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AdbErrors {
+ private AdbErrors() {
+ }
+
+ private static volatile List ourAdbErrorList;
+
+ @NotNull
+ public static synchronized String[] getErrors() {
+ return ourAdbErrorList != null ? ArrayUtil.toStringArray(ourAdbErrorList) : ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
+ public static synchronized void clear() {
+ if (ourAdbErrorList != null) {
+ ourAdbErrorList.clear();
+ }
+ }
+
+ public static synchronized void reportError(@NotNull String message, @Nullable String tag) {
+ final String fullMessage = tag != null ? tag + ": " + message : message;
+ if (ourAdbErrorList == null) {
+ ourAdbErrorList = new ArrayList();
+ }
+ ourAdbErrorList.add(fullMessage);
+ }
+}
diff --git a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatToolWindowFactory.java b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatToolWindowFactory.java
index 82f5a22cdd84..389f0f05b1a6 100644
--- a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatToolWindowFactory.java
+++ b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatToolWindowFactory.java
@@ -16,8 +16,10 @@
package org.jetbrains.android.logcat;
+import com.android.ddmlib.Log;
import com.intellij.ProjectTopics;
import com.intellij.execution.filters.HyperlinkInfo;
+import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.facet.ProjectFacetManager;
@@ -34,6 +36,7 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
+import com.intellij.ui.content.impl.ContentImpl;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.maven.AndroidMavenUtil;
@@ -90,12 +93,34 @@ public class AndroidLogcatToolWindowFactory implements ToolWindowFactory {
JPanel contentPanel = view.getContentPanel();
final ContentManager contentManager = toolWindow.getContentManager();
- final Content content = contentManager.getFactory().createContent(contentPanel, null, false);
- content.setDisposer(view);
- content.setCloseable(false);
- content.setPreferredFocusableComponent(contentPanel);
- contentManager.addContent(content);
- contentManager.setSelectedContent(content, true);
+
+ final Content logcatContent =
+ contentManager.getFactory().createContent(contentPanel, AndroidBundle.message("android.logcat.tab.title"), false);
+ logcatContent.setDisposer(view);
+ logcatContent.setCloseable(false);
+ logcatContent.setPreferredFocusableComponent(contentPanel);
+ contentManager.addContent(logcatContent);
+ contentManager.setSelectedContent(logcatContent, true);
+
+ final ConsoleView console = new ConsoleViewImpl(project, false);
+ final Content adbLogsContent = new ContentImpl(console.getComponent(), AndroidBundle.message("android.adb.logs.tab.title"), false);
+ adbLogsContent.setCloseable(false);
+ contentManager.addContent(adbLogsContent);
+
+ //noinspection UnnecessaryFullyQualifiedName
+ com.android.ddmlib.Log.setLogOutput(new Log.ILogOutput() {
+ @Override
+ public void printLog(Log.LogLevel logLevel, String tag, String message) {
+ reportAdbLogMessage(logLevel, tag, message, console);
+ }
+
+ @Override
+ public void printAndPromptLog(Log.LogLevel logLevel, String tag, String message) {
+ // todo: should we show dialog?
+ reportAdbLogMessage(logLevel, tag, message, console);
+ }
+ });
+
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
view.activate();
@@ -107,6 +132,48 @@ public class AndroidLogcatToolWindowFactory implements ToolWindowFactory {
});
}
+ private static void reportAdbLogMessage(Log.LogLevel logLevel, String tag, String message, @NotNull ConsoleView consoleView) {
+ if (message == null) {
+ return;
+ }
+ if (logLevel == null) {
+ logLevel = Log.LogLevel.INFO;
+ }
+
+ if (logLevel == Log.LogLevel.ERROR || logLevel == Log.LogLevel.ASSERT) {
+ AdbErrors.reportError(message, tag);
+ }
+
+ final ConsoleViewContentType contentType = toConsoleViewContentType(logLevel);
+ if (contentType == null) {
+ return;
+ }
+
+ final String fullMessage = tag != null ? tag + ": " + message : message;
+ consoleView.print(fullMessage + '\n', contentType);
+ }
+
+ @Nullable
+ private static ConsoleViewContentType toConsoleViewContentType(@NotNull Log.LogLevel logLevel) {
+ switch (logLevel) {
+ case VERBOSE:
+ return null;
+ case DEBUG:
+ return null;
+ case INFO:
+ return ConsoleViewContentType.getConsoleViewType(AndroidLogcatConstants.INFO);
+ case WARN:
+ return ConsoleViewContentType.getConsoleViewType(AndroidLogcatConstants.WARNING);
+ case ERROR:
+ return ConsoleViewContentType.getConsoleViewType(AndroidLogcatConstants.ERROR);
+ case ASSERT:
+ return ConsoleViewContentType.getConsoleViewType(AndroidLogcatConstants.ASSERT);
+ default:
+ assert false : "Unknown log level " + logLevel;
+ }
+ return null;
+ }
+
private static void checkFacetAndSdk(Project project, AndroidLogcatToolWindowView view) {
final List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID);
final ConsoleView console = view.getLogConsole().getConsole();
diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkData.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkData.java
index c63650b914fb..616a78281a17 100644
--- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkData.java
+++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkData.java
@@ -18,6 +18,7 @@ package org.jetbrains.android.sdk;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.DdmPreferences;
+import com.android.ddmlib.Log;
import com.android.sdklib.*;
import com.android.sdklib.internal.project.ProjectProperties;
import com.intellij.CommonBundle;
@@ -33,6 +34,7 @@ import com.intellij.reference.SoftReference;
import com.intellij.util.containers.HashMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.android.actions.AndroidEnableAdbServiceAction;
+import org.jetbrains.android.logcat.AdbErrors;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.BufferingFileWrapper;
@@ -182,12 +184,15 @@ public class AndroidSdkData {
return getLocation().hashCode();
}
+ @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
private boolean initializeDdmlib(@NotNull Project project) {
ApplicationManager.getApplication().assertIsDispatchThread();
while (true) {
final MyInitializeDdmlibTask task = new MyInitializeDdmlibTask(project);
+ AdbErrors.clear();
+
Thread t = new Thread(new Runnable() {
@Override
public void run() {
@@ -205,25 +210,33 @@ public class AndroidSdkData {
boolean finished = task.isFinished();
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- myAdbCrashed = !finished;
-
if (task.isCanceled()) {
+ myAdbCrashed = !finished;
forceInterrupt(t);
return false;
}
- if (!finished) {
- int result = Messages
- .showOkCancelDialog(project,
- "ADB not responding. Please, kill \"" + SdkConstants.FN_ADB + "\" process manually and click 'Retry'",
- CommonBundle.getErrorTitle(), "&Retry", "&Cancel", Messages.getErrorIcon());
+ myAdbCrashed = false;
- if (result == 1) {
+ if (!finished) {
+ final String adbErrorString = combine(AdbErrors.getErrors());
+ final int result = Messages.showDialog(project, "ADB not responding. You can wait more, or kill \"" +
+ SdkConstants.FN_ADB +
+ "\" process manually and click 'Restart'" +
+ (adbErrorString.length() > 0 ? "\nErrors from ADB:\n" + adbErrorString : ""),
+ CommonBundle.getErrorTitle(), new String[]{"&Wait more", "&Restart", "&Cancel"}, 0,
+ Messages.getErrorIcon());
+ if (result == 2) {
+ // cancel
+ myAdbCrashed = true;
forceInterrupt(t);
return false;
}
- retryWas = true;
+ else if (result == 1) {
+ // restart
+ myAdbCrashed = true;
+ retryWas = true;
+ }
}
}
@@ -236,6 +249,19 @@ public class AndroidSdkData {
return true;
}
+ @NotNull
+ private static String combine(@NotNull String[] strs) {
+ final StringBuilder builder = new StringBuilder();
+
+ for (String str : strs) {
+ if (builder.length() > 0) {
+ builder.append('\n');
+ }
+ builder.append(str);
+ }
+ return builder.toString();
+ }
+
@SuppressWarnings({"BusyWait"})
private static void forceInterrupt(Thread thread) {
/*
@@ -262,6 +288,7 @@ public class AndroidSdkData {
synchronized (myDdmsLock) {
if (!myDdmLibInitialized) {
myDdmLibInitialized = true;
+ DdmPreferences.setLogLevel(Log.LogLevel.INFO.getStringValue());
DdmPreferences.setTimeOut(AndroidUtils.TIMEOUT);
AndroidDebugBridge.init(AndroidEnableAdbServiceAction.isAdbServiceEnabled());
LOG.info("DDMLib initialized");
diff --git a/plugins/groovy/resources/inspectionDescriptions/GroovyUnusedAssignment.html b/plugins/groovy/resources/inspectionDescriptions/GroovyUnusedAssignment.html
index f10ac59f3c47..d093014e3eab 100644
--- a/plugins/groovy/resources/inspectionDescriptions/GroovyUnusedAssignment.html
+++ b/plugins/groovy/resources/inspectionDescriptions/GroovyUnusedAssignment.html
@@ -2,6 +2,6 @@
This inspection reports on unnecessary Groovy assignment statement
-
Powered by InspectorGroovy
+