mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-85676 add logcat to debugger session tab
This commit is contained in:
@@ -79,6 +79,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
private LogFilterModel myModel;
|
||||
|
||||
private final List<LogConsoleListener> myListeners = new ArrayList<LogConsoleListener>();
|
||||
private final List<? extends LogFilter> myFilters;
|
||||
|
||||
private FilterComponent myFilter = new FilterComponent("LOG_FILTER_HISTORY", 5) {
|
||||
public void filter() {
|
||||
@@ -100,6 +101,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
myProject = project;
|
||||
myTitle = title;
|
||||
myModel = model;
|
||||
myFilters = myModel.getLogFilters();
|
||||
myReaderThread = new ReaderThread(reader);
|
||||
myBuildInActions = buildInActions;
|
||||
TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
|
||||
@@ -215,6 +217,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
return;
|
||||
}
|
||||
if (isActive() && !readerThread.myRunning) {
|
||||
resetLogFilter();
|
||||
myFilter.setSelectedItem(myModel.getCustomFilter());
|
||||
readerThread.startRunning();
|
||||
ApplicationManager.getApplication().executeOnPooledThread(readerThread);
|
||||
@@ -476,14 +479,8 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
}
|
||||
|
||||
public JComponent getSearchComponent() {
|
||||
List<? extends LogFilter> filters = myModel.getLogFilters();
|
||||
myLogFilterCombo.setModel(new DefaultComboBoxModel(filters.toArray(new LogFilter[filters.size()])));
|
||||
for (LogFilter filter : filters) {
|
||||
if (myModel.isFilterSelected(filter)) {
|
||||
myLogFilterCombo.setSelectedItem(filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
myLogFilterCombo.setModel(new DefaultComboBoxModel(myFilters.toArray(new LogFilter[myFilters.size()])));
|
||||
resetLogFilter();
|
||||
myLogFilterCombo.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final LogFilter filter = (LogFilter)myLogFilterCombo.getSelectedItem();
|
||||
@@ -501,6 +498,15 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
return mySearchComponent;
|
||||
}
|
||||
|
||||
private void resetLogFilter() {
|
||||
for (LogFilter filter : myFilters) {
|
||||
if (myModel.isFilterSelected(filter)) {
|
||||
myLogFilterCombo.setSelectedItem(filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Component getTextFilterComponent() {
|
||||
return myFilter;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.diagnostic.logging.LogFilter;
|
||||
import com.intellij.diagnostic.logging.LogFilterListener;
|
||||
import com.intellij.diagnostic.logging.LogFilterModel;
|
||||
import com.intellij.execution.process.ProcessOutputTypes;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,19 +48,15 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
|
||||
private boolean myFullMessageApplicableByCustomFilter = false;
|
||||
private StringBuilder myMessageBuilder = new StringBuilder();
|
||||
|
||||
private LogFilter mySelectedLogFilter;
|
||||
private List<AndroidLogFilter> myLogFilters = new ArrayList<AndroidLogFilter>();
|
||||
protected List<AndroidLogFilter> myLogFilters = new ArrayList<AndroidLogFilter>();
|
||||
|
||||
public AndroidLogFilterModel(String initialLogLevelName) {
|
||||
public AndroidLogFilterModel() {
|
||||
for (Log.LogLevel logLevel : Log.LogLevel.values()) {
|
||||
AndroidLogFilter filter = new AndroidLogFilter(logLevel);
|
||||
if (logLevel.name().equals(initialLogLevelName)) {
|
||||
mySelectedLogFilter = filter;
|
||||
}
|
||||
myLogFilters.add(filter);
|
||||
myLogFilters.add(new AndroidLogFilter(logLevel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateCustomFilter(String filter) {
|
||||
super.updateCustomFilter(filter);
|
||||
setCustomFilter(filter);
|
||||
@@ -81,7 +78,7 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void saveLogLevel(Log.LogLevel logLevel);
|
||||
protected abstract void saveLogLevel(String logLevelName);
|
||||
|
||||
public void addFilterListener(LogFilterListener listener) {
|
||||
myListeners.add(listener);
|
||||
@@ -124,11 +121,8 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
|
||||
@Override
|
||||
public boolean isApplicable(String text) {
|
||||
if (!super.isApplicable(text)) return false;
|
||||
|
||||
if (!(mySelectedLogFilter == null || mySelectedLogFilter.isAcceptable(text))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
final LogFilter selectedLogLevelFilter = getSelectedLogLevelFilter();
|
||||
return selectedLogLevelFilter == null || selectedLogLevelFilter.isAcceptable(text);
|
||||
}
|
||||
|
||||
public boolean isApplicableByCustomFilter(String text) {
|
||||
@@ -207,7 +201,7 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Log.LogLevel getLogLevel(@NotNull String name) {
|
||||
protected static Log.LogLevel getLogLevel(@NotNull String name) {
|
||||
for (Log.LogLevel level : Log.LogLevel.values()) {
|
||||
if (name.equals(level.name())) {
|
||||
return level;
|
||||
@@ -216,14 +210,32 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract String getSelectedLogLevelName();
|
||||
|
||||
@Nullable
|
||||
private LogFilter getSelectedLogLevelFilter() {
|
||||
final String filterName = getSelectedLogLevelName();
|
||||
if (filterName != null) {
|
||||
for (AndroidLogFilter logFilter : myLogFilters) {
|
||||
if (filterName.equals(logFilter.myLogLevel.name())) {
|
||||
return logFilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isFilterSelected(LogFilter filter) {
|
||||
return mySelectedLogFilter == filter;
|
||||
return filter == getSelectedLogLevelFilter();
|
||||
}
|
||||
|
||||
public void selectFilter(LogFilter filter) {
|
||||
if (filter != mySelectedLogFilter && filter instanceof AndroidLogFilter) {
|
||||
mySelectedLogFilter = filter;
|
||||
saveLogLevel(((AndroidLogFilter)filter).myLogLevel);
|
||||
if (!(filter instanceof AndroidLogFilter)) {
|
||||
return;
|
||||
}
|
||||
String newFilterName = ((AndroidLogFilter)filter).myLogLevel.name();
|
||||
if (!Comparing.equal(newFilterName, getSelectedLogLevelName())) {
|
||||
saveLogLevel(newFilterName);
|
||||
fireFilterChange(filter);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ public class AndroidLogcatToolWindowFactory implements ToolWindowFactory {
|
||||
toolWindow.setToHideOnEmptyContent(true);
|
||||
toolWindow.setTitle(TOOL_WINDOW_ID);
|
||||
|
||||
final AndroidLogcatToolWindowView view = new AndroidLogcatToolWindowView(project) {
|
||||
final AndroidLogcatToolWindowView view = new AndroidLogcatToolWindowView(project, null, false) {
|
||||
@Override
|
||||
protected boolean isActive() {
|
||||
ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="5ef02" class="com.intellij.ui.components.JBScrollPane">
|
||||
<scrollpane id="5ef02" class="com.intellij.ui.components.JBScrollPane" binding="myFiltersListScrollPane">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
@@ -73,7 +73,7 @@
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="22eb0" binding="myRightPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="1">
|
||||
<margin top="3" left="0" bottom="3" right="3"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<splitpane position="right"/>
|
||||
</constraints>
|
||||
@@ -93,8 +93,8 @@
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="df093" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="5" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<grid id="df093" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="5" vgap="-1">
|
||||
<margin top="3" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
@@ -122,14 +122,6 @@
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="61fcc" class="javax.swing.JButton" binding="myClearLogButton">
|
||||
<constraints>
|
||||
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/AndroidBundle" key="android.logcat.clear.log.button.title"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f8aa6" class="com.intellij.ui.components.JBLabel">
|
||||
<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"/>
|
||||
|
||||
@@ -36,8 +36,10 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.IconUtil;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
@@ -71,13 +73,14 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
private JComboBox myDeviceCombo;
|
||||
private JPanel myConsoleWrapper;
|
||||
private final Splitter mySplitter;
|
||||
private JButton myClearLogButton;
|
||||
private JPanel mySearchComponentWrapper;
|
||||
private JPanel myFiltersToolbarPanel;
|
||||
|
||||
private JBList myFiltersList;
|
||||
private JPanel myLeftPanel;
|
||||
private JPanel myRightPanel;
|
||||
private JPanel myTopPanel;
|
||||
private JBScrollPane myFiltersListScrollPane;
|
||||
|
||||
private volatile IDevice myDevice;
|
||||
private final Object myLock = new Object();
|
||||
@@ -86,6 +89,8 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
private volatile Reader myCurrentReader;
|
||||
private volatile Writer myCurrentWriter;
|
||||
|
||||
private final IDevice myPreselectedDevice;
|
||||
|
||||
private final AndroidDebugBridge.IDeviceChangeListener myDeviceChangeListener = new AndroidDebugBridge.IDeviceChangeListener() {
|
||||
public void deviceConnected(IDevice device) {
|
||||
updateInUIThread();
|
||||
@@ -139,8 +144,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
|
||||
public AndroidLogcatToolWindowView(final Project project) {
|
||||
public AndroidLogcatToolWindowView(final Project project, @Nullable IDevice preselectedDevice, boolean addBorderToScrollPane) {
|
||||
myProject = project;
|
||||
myPreselectedDevice = preselectedDevice;
|
||||
Disposer.register(myProject, this);
|
||||
|
||||
mySplitter = new Splitter();
|
||||
@@ -148,26 +154,36 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
mySplitter.setSecondComponent(myRightPanel);
|
||||
mySplitter.setProportion(0.2f);
|
||||
|
||||
myFiltersList.setBorder(BorderFactory.createEmptyBorder());
|
||||
if (addBorderToScrollPane) {
|
||||
myFiltersListScrollPane.setViewportBorder(IdeBorderFactory.createBorder());
|
||||
}
|
||||
else {
|
||||
myFiltersList.setBorder(BorderFactory.createEmptyBorder());
|
||||
}
|
||||
|
||||
myDeviceCombo.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateLogConsole();
|
||||
}
|
||||
});
|
||||
myDeviceCombo.setRenderer(new ListCellRendererWrapper() {
|
||||
@Override
|
||||
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value == null) {
|
||||
setText("<html><font color='red'>[none]</font></html>");
|
||||
if (preselectedDevice == null) {
|
||||
myDeviceCombo.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateLogConsole();
|
||||
}
|
||||
else if (value instanceof IDevice) {
|
||||
setText(((IDevice)value).getSerialNumber());
|
||||
});
|
||||
myDeviceCombo.setRenderer(new ListCellRendererWrapper() {
|
||||
@Override
|
||||
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value == null) {
|
||||
setText("<html><font color='red'>[none]</font></html>");
|
||||
}
|
||||
else if (value instanceof IDevice) {
|
||||
setText(((IDevice)value).getSerialNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
myTopPanel.setVisible(false);
|
||||
}
|
||||
final AndroidLogFilterModel logFilterModel =
|
||||
new AndroidLogFilterModel(AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL) {
|
||||
new AndroidLogFilterModel() {
|
||||
private ConfiguredFilter myConfiguredFilter;
|
||||
|
||||
@Override
|
||||
@@ -176,8 +192,13 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveLogLevel(Log.LogLevel logLevel) {
|
||||
AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL = logLevel.name();
|
||||
protected void saveLogLevel(String logLevelName) {
|
||||
AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL = logLevelName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedLogLevelName() {
|
||||
return AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -215,7 +236,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
}
|
||||
});
|
||||
mySearchComponentWrapper.add(myLogConsole.getSearchComponent());
|
||||
if (preselectedDevice == null) {
|
||||
mySearchComponentWrapper.add(createSearchComponent(project));
|
||||
}
|
||||
JComponent consoleComponent = myLogConsole.getComponent();
|
||||
|
||||
final DefaultActionGroup group1 = new DefaultActionGroup();
|
||||
@@ -233,7 +256,6 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group2, true).getComponent();
|
||||
myFiltersToolbarPanel.add(tbComp2, BorderLayout.CENTER);
|
||||
|
||||
final String savedConfiguredFilterName = AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_CONFIGURED_FILTER;
|
||||
myFiltersList.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
@@ -242,7 +264,10 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
|
||||
final String filterName = (String)myFiltersList.getSelectedValue();
|
||||
final ConfiguredFilter filter = filterName != null ? compileConfiguredFilter(filterName) : null;
|
||||
if (filterName == null) {
|
||||
return;
|
||||
}
|
||||
final ConfiguredFilter filter = compileConfiguredFilter(filterName);
|
||||
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, LogConsoleBase.APPLYING_FILTER_TITLE) {
|
||||
@Override
|
||||
@@ -255,7 +280,22 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
|
||||
myConsoleWrapper.add(consoleComponent, BorderLayout.CENTER);
|
||||
Disposer.register(this, myLogConsole);
|
||||
myClearLogButton.addActionListener(new ActionListener() {
|
||||
|
||||
AndroidDebugBridge.addDeviceChangeListener(myDeviceChangeListener);
|
||||
|
||||
updateDevices();
|
||||
updateLogConsole();
|
||||
updateConfiguredFilters(AndroidLogcatFiltersPreferences.getInstance(myProject).TOOL_WINDOW_CONFIGURED_FILTER);
|
||||
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
|
||||
myFiltersList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JPanel createSearchComponent(final Project project) {
|
||||
final JPanel searchComponent = new JPanel(new BorderLayout());
|
||||
final JButton clearLogButton = new JButton(AndroidBundle.message("android.logcat.clear.log.button.title"));
|
||||
clearLogButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
IDevice device = getSelectedDevice();
|
||||
if (device != null) {
|
||||
@@ -264,17 +304,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AndroidDebugBridge.addDeviceChangeListener(myDeviceChangeListener);
|
||||
|
||||
updateDevices();
|
||||
updateLogConsole();
|
||||
updateConfiguredFilters();
|
||||
|
||||
myFiltersList.setSelectedValue(savedConfiguredFilterName, true);
|
||||
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
|
||||
myFiltersList.setSelectedIndex(0);
|
||||
}
|
||||
searchComponent.add(myLogConsole.getSearchComponent(), BorderLayout.CENTER);
|
||||
searchComponent.add(clearLogButton, BorderLayout.EAST);
|
||||
return searchComponent;
|
||||
}
|
||||
|
||||
protected abstract boolean isActive();
|
||||
@@ -325,8 +357,14 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
updateDevices();
|
||||
updateLogConsole();
|
||||
if (isActive()) {
|
||||
updateDevices();
|
||||
updateLogConsole();
|
||||
updateConfiguredFilters(AndroidLogcatFiltersPreferences.getInstance(myProject).TOOL_WINDOW_CONFIGURED_FILTER);
|
||||
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
|
||||
myFiltersList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
if (myLogConsole != null) {
|
||||
myLogConsole.activate();
|
||||
}
|
||||
@@ -371,7 +409,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
|
||||
@Nullable
|
||||
public IDevice getSelectedDevice() {
|
||||
return (IDevice)myDeviceCombo.getSelectedItem();
|
||||
return myPreselectedDevice != null ? myPreselectedDevice : (IDevice)myDeviceCombo.getSelectedItem();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -386,8 +424,10 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateConfiguredFilters() {
|
||||
final String selectedFilterName = (String)myFiltersList.getSelectedValue();
|
||||
private void updateConfiguredFilters(String defaultSelection) {
|
||||
final String selectedFilterName = defaultSelection != null
|
||||
? defaultSelection
|
||||
: (String)myFiltersList.getSelectedValue();
|
||||
|
||||
final AndroidConfiguredLogFilters filters = AndroidConfiguredLogFilters.getInstance(myProject);
|
||||
final List<AndroidConfiguredLogFilters.MyFilterEntry> entries = filters.getFilterEntries();
|
||||
@@ -425,7 +465,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
if (devices.length > 0 && temp == null) {
|
||||
temp = devices[0];
|
||||
}
|
||||
myDeviceCombo.setSelectedItem(temp);
|
||||
if (temp != null) {
|
||||
myDeviceCombo.setSelectedItem(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -502,7 +544,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
entries.add(newEntry);
|
||||
configuredLogFilters.setFilterEntries(entries);
|
||||
|
||||
updateConfiguredFilters();
|
||||
updateConfiguredFilters(null);
|
||||
myFiltersList.setSelectedValue(newEntry.getName(), true);
|
||||
}
|
||||
}
|
||||
@@ -534,7 +576,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
entries.remove(filterEntry);
|
||||
configuredLogFilters.setFilterEntries(entries);
|
||||
|
||||
updateConfiguredFilters();
|
||||
updateConfiguredFilters(null);
|
||||
final int index = selectedIndex < myFiltersList.getItemsCount()
|
||||
? selectedIndex
|
||||
: myFiltersList.getItemsCount() - 1;
|
||||
@@ -567,7 +609,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
|
||||
|
||||
if (dialog.isOK()) {
|
||||
final String newName = filterEntry.getName();
|
||||
updateConfiguredFilters();
|
||||
updateConfiguredFilters(null);
|
||||
myFiltersList.setSelectedValue(newName, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.jetbrains.android.run;
|
||||
|
||||
import com.android.ddmlib.IDevice;
|
||||
import com.intellij.debugger.engine.RemoteDebugProcessHandler;
|
||||
import com.intellij.debugger.ui.DebuggerContentInfo;
|
||||
import com.intellij.debugger.ui.DebuggerPanelsManager;
|
||||
import com.intellij.debugger.ui.DebuggerSessionTab;
|
||||
import com.intellij.execution.*;
|
||||
@@ -28,21 +29,32 @@ import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.DefaultProgramRunner;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.execution.ui.RunContentManager;
|
||||
import com.intellij.execution.ui.*;
|
||||
import com.intellij.execution.ui.layout.PlaceInGrid;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManagerAdapter;
|
||||
import com.intellij.ui.content.ContentManagerEvent;
|
||||
import com.intellij.xdebugger.XDebuggerBundle;
|
||||
import icons.AndroidIcons;
|
||||
import org.jetbrains.android.dom.manifest.Instrumentation;
|
||||
import org.jetbrains.android.dom.manifest.Manifest;
|
||||
import org.jetbrains.android.logcat.AndroidLogcatToolWindowView;
|
||||
import org.jetbrains.android.run.testing.AndroidTestRunConfiguration;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import static com.intellij.execution.process.ProcessOutputTypes.STDERR;
|
||||
|
||||
/**
|
||||
@@ -55,6 +67,8 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
private static final Object myReaderLock = new Object();
|
||||
|
||||
private static final Object myDebugLock = new Object();
|
||||
@NonNls private static final String ANDROID_DEBUG_SELECTED_TAB_PROPERTY = "ANDROID_DEBUG_SELECTED_TAB";
|
||||
public static final String ANDROID_LOGCAT_CONTENT_ID = "Android Logcat";
|
||||
|
||||
private static void tryToCloseOldSessions(final Executor executor, Project project) {
|
||||
final ExecutionManager manager = ExecutionManager.getInstance(project);
|
||||
@@ -133,17 +147,20 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
private final RunnerSettings myRunnerSettings;
|
||||
private final ConfigurationPerRunnerSettings myConfigurationSettings;
|
||||
private final AndroidRunningState myState;
|
||||
private final IDevice myDevice;
|
||||
|
||||
public AndroidDebugState(Project project,
|
||||
RemoteConnection connection,
|
||||
RunnerSettings runnerSettings,
|
||||
ConfigurationPerRunnerSettings configurationSettings,
|
||||
AndroidRunningState state) {
|
||||
AndroidRunningState state,
|
||||
IDevice device) {
|
||||
myProject = project;
|
||||
myConnection = connection;
|
||||
myRunnerSettings = runnerSettings;
|
||||
myConfigurationSettings = configurationSettings;
|
||||
myState = state;
|
||||
myDevice = device;
|
||||
}
|
||||
|
||||
public RunnerSettings getRunnerSettings() {
|
||||
@@ -157,7 +174,9 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
public ExecutionResult execute(final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException {
|
||||
RemoteDebugProcessHandler process = new RemoteDebugProcessHandler(myProject);
|
||||
myState.setProcessHandler(process);
|
||||
ConsoleView console = myState.attachConsole();
|
||||
final ConsoleView c = myState.getConfiguration().attachConsole(myState, executor);
|
||||
final boolean resetSelectedTab = myState.getConfiguration() instanceof AndroidRunConfiguration;
|
||||
final MyLogcatExecutionConsole console = new MyLogcatExecutionConsole(myProject, myDevice, process, c, resetSelectedTab);
|
||||
return new DefaultExecutionResult(console, process);
|
||||
}
|
||||
|
||||
@@ -175,6 +194,107 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
return DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) && profile instanceof AndroidRunConfigurationBase;
|
||||
}
|
||||
|
||||
private static class MyLogcatExecutionConsole implements ExecutionConsoleEx {
|
||||
private final Project myProject;
|
||||
private final AndroidLogcatToolWindowView myToolWindowView;
|
||||
private final ConsoleView myConsoleView;
|
||||
private final boolean myResetSelectedTab;
|
||||
|
||||
private MyLogcatExecutionConsole(Project project,
|
||||
IDevice device,
|
||||
RemoteDebugProcessHandler process,
|
||||
ConsoleView consoleView,
|
||||
boolean resetSelectedTab) {
|
||||
myProject = project;
|
||||
myConsoleView = consoleView;
|
||||
myResetSelectedTab = resetSelectedTab;
|
||||
myToolWindowView = new AndroidLogcatToolWindowView(project, device, true) {
|
||||
@Override
|
||||
protected boolean isActive() {
|
||||
final DebuggerSessionTab sessionTab = DebuggerPanelsManager.getInstance(myProject).getSessionTab();
|
||||
if (sessionTab == null) {
|
||||
return false;
|
||||
}
|
||||
final Content content = sessionTab.getUi().findContent(ANDROID_LOGCAT_CONTENT_ID);
|
||||
return content != null && content.isSelected();
|
||||
}
|
||||
};
|
||||
Disposer.register(this, myToolWindowView);
|
||||
myToolWindowView.getLogConsole().attachStopLogConsoleTrackingListener(process);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildUi(final RunnerLayoutUi layoutUi) {
|
||||
final Content consoleContent = layoutUi.createContent(DebuggerContentInfo.CONSOLE_CONTENT, getComponent(),
|
||||
XDebuggerBundle.message("debugger.session.tab.console.content.name"),
|
||||
AllIcons.Debugger.Console, getPreferredFocusableComponent());
|
||||
|
||||
consoleContent.setCloseable(false);
|
||||
layoutUi.addContent(consoleContent, 1, PlaceInGrid.bottom, false);
|
||||
|
||||
// todo: provide other icon
|
||||
final Content logcatContent = layoutUi.createContent(ANDROID_LOGCAT_CONTENT_ID, myToolWindowView.getContentPanel(), "Logcat",
|
||||
AndroidIcons.Android, getPreferredFocusableComponent());
|
||||
logcatContent.setCloseable(false);
|
||||
logcatContent.setSearchComponent(myToolWindowView.createSearchComponent(myProject));
|
||||
layoutUi.addContent(logcatContent, 2, PlaceInGrid.bottom, false);
|
||||
|
||||
if (myResetSelectedTab) {
|
||||
final String tabName = PropertiesComponent.getInstance().getValue(ANDROID_DEBUG_SELECTED_TAB_PROPERTY);
|
||||
Content selectedContent = logcatContent;
|
||||
|
||||
if (tabName != null) {
|
||||
for (Content content : layoutUi.getContents()) {
|
||||
if (tabName.equals(content.getDisplayName())) {
|
||||
selectedContent = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
layoutUi.getContentManager().setSelectedContent(selectedContent);
|
||||
}
|
||||
|
||||
layoutUi.addListener(new ContentManagerAdapter() {
|
||||
public void selectionChanged(final ContentManagerEvent event) {
|
||||
if (myResetSelectedTab) {
|
||||
final Content content = event.getContent();
|
||||
|
||||
if (content.isSelected()) {
|
||||
PropertiesComponent.getInstance().setValue(ANDROID_DEBUG_SELECTED_TAB_PROPERTY, content.getDisplayName());
|
||||
}
|
||||
}
|
||||
myToolWindowView.activate();
|
||||
}
|
||||
}, myToolWindowView);
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myToolWindowView.activate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getExecutionConsoleId() {
|
||||
return "ANDROID_LOGCAT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return myConsoleView.getComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
return myConsoleView.getPreferredFocusableComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyDebugLauncher implements DebugLauncher {
|
||||
private final Project myProject;
|
||||
private final Executor myExecutor;
|
||||
@@ -203,7 +323,7 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
final DebuggerPanelsManager manager = DebuggerPanelsManager.getInstance(myProject);
|
||||
RemoteState st =
|
||||
new AndroidDebugState(myProject, new RemoteConnection(true, "localhost", debugPort, false), myEnvironment.getRunnerSettings(),
|
||||
myEnvironment.getConfigurationSettings(), myRunningState);
|
||||
myEnvironment.getConfigurationSettings(), myRunningState, device);
|
||||
RunContentDescriptor debugDescriptor = null;
|
||||
final ProcessHandler processHandler = myRunningState.getProcessHandler();
|
||||
try {
|
||||
@@ -227,9 +347,26 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
|
||||
|
||||
myRunningState.getProcessHandler().putUserData(ANDROID_PROCESS_HANDLER, debugDescriptor);
|
||||
|
||||
DebuggerSessionTab sessionTab = manager.getSessionTab();
|
||||
final DebuggerSessionTab sessionTab = manager.getSessionTab();
|
||||
assert sessionTab != null;
|
||||
sessionTab.setEnvironment(myEnvironment);
|
||||
|
||||
/*final String contentId = "Android Logcat";
|
||||
final AndroidLogcatTabComponent component = new AndroidLogcatTabComponent(myProject, device) {
|
||||
@Override
|
||||
public boolean isActivte() {
|
||||
final Content content = sessionTab.getUi().findContent(contentId);
|
||||
return content != null && content.isSelected();
|
||||
}
|
||||
};
|
||||
sessionTab.getUi().addListener(new ContentManagerAdapter() {
|
||||
public void selectionChanged(final ContentManagerEvent event) {
|
||||
component.activate();
|
||||
}
|
||||
}, component);
|
||||
component.getToolWindowView().getLogConsole().attachStopLogConsoleTrackingListener(newProcessHandler);
|
||||
sessionTab.addAdditionalTabComponent(component, contentId, AllIcons.Debugger.Console);*/
|
||||
|
||||
RunProfile profile = myEnvironment.getRunProfile();
|
||||
assert profile instanceof AndroidRunConfigurationBase;
|
||||
RunContentManager runContentManager = ExecutionManager.getInstance(myProject).getContentManager();
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
package org.jetbrains.android.run;
|
||||
|
||||
import com.android.ddmlib.AndroidDebugBridge;
|
||||
import com.android.ddmlib.Log;
|
||||
import com.android.sdklib.internal.avd.AvdInfo;
|
||||
import com.android.sdklib.internal.avd.AvdManager;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.diagnostic.logging.LogConsole;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.*;
|
||||
@@ -50,8 +48,6 @@ import org.jdom.Element;
|
||||
import org.jetbrains.android.dom.manifest.Manifest;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidFacetConfiguration;
|
||||
import org.jetbrains.android.logcat.AndroidLogFilterModel;
|
||||
import org.jetbrains.android.logcat.AndroidLogcatFiltersPreferences;
|
||||
import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
import org.jetbrains.android.sdk.AndroidSdkUtils;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
@@ -238,14 +234,7 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
|
||||
AndroidApplicationLauncher applicationLauncher = getApplicationLauncher(facet);
|
||||
if (applicationLauncher != null) {
|
||||
return new AndroidRunningState(env, facet, targetChooser, computeCommandLine(), aPackage, applicationLauncher,
|
||||
depModule2PackageName, supportMultipleDevices(), CLEAR_LOGCAT) {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ConsoleView attachConsole() throws ExecutionException {
|
||||
return AndroidRunConfigurationBase.this.attachConsole(this, executor);
|
||||
}
|
||||
};
|
||||
depModule2PackageName, supportMultipleDevices(), CLEAR_LOGCAT, this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -298,27 +287,6 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
|
||||
|
||||
protected abstract boolean supportMultipleDevices();
|
||||
|
||||
@Override
|
||||
public void customizeLogConsole(LogConsole console) {
|
||||
final Project project = getProject();
|
||||
console.setFilterModel(new AndroidLogFilterModel(AndroidLogcatFiltersPreferences.getInstance(project).TAB_LOG_LEVEL) {
|
||||
@Override
|
||||
protected void setCustomFilter(String filter) {
|
||||
AndroidLogcatFiltersPreferences.getInstance(project).TAB_CUSTOM_FILTER = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveLogLevel(Log.LogLevel logLevel) {
|
||||
AndroidLogcatFiltersPreferences.getInstance(project).TAB_LOG_LEVEL = logLevel.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomFilter() {
|
||||
return AndroidLogcatFiltersPreferences.getInstance(project).TAB_CUSTOM_FILTER;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
super.readExternal(element);
|
||||
readModule(element);
|
||||
|
||||
@@ -84,7 +84,7 @@ import static com.intellij.execution.process.ProcessOutputTypes.STDOUT;
|
||||
/**
|
||||
* @author coyote
|
||||
*/
|
||||
public abstract class AndroidRunningState implements RunProfileState, AndroidDebugBridge.IClientChangeListener {
|
||||
public class AndroidRunningState implements RunProfileState, AndroidDebugBridge.IClientChangeListener {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.run.AndroidRunningState");
|
||||
|
||||
@NonNls private static final String ANDROID_TARGET_DEVICES_PROPERTY = "AndroidTargetDevices";
|
||||
@@ -105,6 +105,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
|
||||
private final String myCommandLine;
|
||||
private final AndroidApplicationLauncher myApplicationLauncher;
|
||||
private final Map<AndroidFacet, String> myAdditionalFacet2PackageName;
|
||||
private final AndroidRunConfigurationBase myConfiguration;
|
||||
|
||||
private final Object myDebugLock = new Object();
|
||||
|
||||
@@ -173,7 +174,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
|
||||
}
|
||||
}
|
||||
else {
|
||||
console = attachConsole();
|
||||
console = myConfiguration.attachConsole(this, executor);
|
||||
}
|
||||
myConsole = console;
|
||||
|
||||
@@ -211,7 +212,9 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract ConsoleView attachConsole() throws ExecutionException;
|
||||
public AndroidRunConfigurationBase getConfiguration() {
|
||||
return myConfiguration;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RunnerSettings getRunnerSettings() {
|
||||
@@ -287,10 +290,12 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
|
||||
AndroidApplicationLauncher applicationLauncher,
|
||||
Map<AndroidFacet, String> additionalFacet2PackageName,
|
||||
boolean supportMultipleDevices,
|
||||
boolean clearLogcatBeforeStart) throws ExecutionException {
|
||||
boolean clearLogcatBeforeStart,
|
||||
@NotNull AndroidRunConfigurationBase configuration) throws ExecutionException {
|
||||
myFacet = facet;
|
||||
myCommandLine = commandLine;
|
||||
|
||||
myConfiguration = configuration;
|
||||
|
||||
myTargetChooser = targetChooser;
|
||||
mySupportMultipleDevices = supportMultipleDevices;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user