Go to problem in source from Logcat via Double-click.
The user can choose in the LogCat Preference Page what
will be the default behaviour (go to method declaration
or go to error line).
There are now 2 available actions in the LogCat View
instead of the unique "Go to Problem" (which is now
called "Go to Problem (method declaration)").
Change-Id: I769771b29d26b625cfd0250fa23e6627821be16d
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
index 180af4c..80e24d3 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
@@ -195,6 +195,8 @@
private ITableFocusListener mGlobalListener;
+ private LogCatViewInterface mLogCatViewInterface = null;
+
/** message data, separated from content for multi line messages */
protected static class LogMessage {
public LogMessageInfo data;
@@ -313,6 +315,12 @@
}
+ /**
+ * Interface implemented by the LogCatView in Eclipse for particular action on double-click.
+ */
+ public interface LogCatViewInterface {
+ public void onDoubleClick();
+ }
/**
* Create the log view with some default parameters
@@ -910,6 +918,14 @@
// create the ui, first the table
final Table t = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
+ t.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ if (mLogCatViewInterface != null) {
+ mLogCatViewInterface.onDoubleClick();
+ }
+ }
+ });
if (mDisplayFont != null) {
t.setFont(mDisplayFont);
@@ -1581,4 +1597,8 @@
}
return null;
}
+
+ public void setLogCatViewInterface(LogCatViewInterface i) {
+ mLogCatViewInterface = i;
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
index 909207d..6c1ae4f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
@@ -22,6 +22,7 @@
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FontFieldEditor;
import org.eclipse.swt.SWTError;
@@ -67,6 +68,13 @@
}
}
});
+
+ ComboFieldEditor cfe = new ComboFieldEditor(PreferenceInitializer.ATTR_LOGCAT_GOTO_PROBLEM,
+ "Double-click Action:", new String[][] {
+ { "Go to Problem (method declaration)", LogCatView.CHOICE_METHOD_DECLARATION },
+ { "Go to Problem (error line)", LogCatView.CHOICE_ERROR_LINE },
+ }, getFieldEditorParent());
+ addField(cfe);
}
public void init(IWorkbench workbench) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
index 751bc4f..95571fc 100644
--- a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
@@ -18,6 +18,7 @@
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.ide.eclipse.ddms.views.DeviceView.HProfHandler;
+import com.android.ide.eclipse.ddms.views.LogCatView;
import com.android.ddmlib.DdmPreferences;
import com.android.ddmuilib.DdmUiPreferences;
@@ -64,6 +65,9 @@
public final static String ATTR_TIME_OUT =
DdmsPlugin.PLUGIN_ID + ".timeOut"; //$NON-NLS-1$
+ public final static String ATTR_LOGCAT_GOTO_PROBLEM =
+ DdmsPlugin.PLUGIN_ID + ".logcatGoToProblem"; //$NON-NLS-1$
+
/*
* (non-Javadoc)
*
@@ -95,6 +99,8 @@
store.setDefault(ATTR_HPROF_ACTION, HProfHandler.ACTION_OPEN);
store.setDefault(ATTR_TIME_OUT, DdmPreferences.DEFAULT_TIMEOUT);
+
+ store.setDefault(ATTR_LOGCAT_GOTO_PROBLEM, LogCatView.CHOICE_ERROR_LINE);
}
/**
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
index af3d46f..a53a7c9 100644
--- a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
@@ -22,6 +22,7 @@
import com.android.ddmuilib.logcat.LogFilter;
import com.android.ddmuilib.logcat.LogPanel;
import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
+import com.android.ddmuilib.logcat.LogPanel.LogCatViewInterface;
import com.android.ide.eclipse.ddms.CommonAction;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
@@ -42,6 +43,7 @@
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
@@ -66,7 +68,7 @@
* The log cat view displays log output from the current device selection.
*
*/
-public final class LogCatView extends SelectionDependentViewPart {
+public final class LogCatView extends SelectionDependentViewPart implements LogCatViewInterface {
public static final String ID =
"com.android.ide.eclipse.ddms.views.LogCatView"; // $NON-NLS-1$
@@ -85,6 +87,11 @@
private static final String PREFS_FILTERS =
DdmsPlugin.PLUGIN_ID + ".logcat.filters"; // $NON-NLS-1$
+ public static final String CHOICE_METHOD_DECLARATION =
+ DdmsPlugin.PLUGIN_ID + ".logcat.MethodDeclaration"; // $NON-NLS-1$
+ public static final String CHOICE_ERROR_LINE =
+ DdmsPlugin.PLUGIN_ID + ".logcat.ErrorLine"; // $NON-NLS-1$
+
private static LogCatView sThis;
private LogPanel mLogPanel;
@@ -92,7 +99,8 @@
private CommonAction mDeleteFilterAction;
private CommonAction mEditFilterAction;
private CommonAction mExportAction;
- private CommonAction gotoLineAction;
+ private CommonAction mGotoMethodDeclarationAction;
+ private CommonAction mGotoErrorLineAction;
private CommonAction[] mLogLevelActions;
private String[] mLogLevelIcons = {
@@ -151,6 +159,59 @@
}
}
+ /**
+ * This class defines what to do with the search match returned by a double-click or by the
+ * Go to Problem action.
+ */
+ private class LogCatViewSearchRequestor extends SearchRequestor {
+
+ private boolean mFoundFirstMatch = false;
+ private String mChoice;
+ private int mLineNumber;
+
+ public LogCatViewSearchRequestor(String choice, int lineNumber) {
+ super();
+ mChoice = choice;
+ mLineNumber = lineNumber;
+ }
+
+ IMarker createMarkerFromSearchMatch(IFile file, SearchMatch match) {
+ IMarker marker = null;
+ try {
+ if (CHOICE_METHOD_DECLARATION.equals(mChoice)) {
+ HashMap<String, Object> map = new HashMap<String, Object>();
+ map.put(IMarker.CHAR_START, new Integer(match.getOffset()));
+ map.put(IMarker.CHAR_END, new Integer(match.getOffset()
+ + match.getLength()));
+ marker = file.createMarker(IMarker.TEXT);
+ marker.setAttributes(map);
+ } else if (CHOICE_ERROR_LINE.equals(mChoice)) {
+ marker = file.createMarker(IMarker.TEXT);
+ marker.setAttribute(IMarker.LINE_NUMBER, mLineNumber);
+ }
+ } catch (CoreException e) {
+ Status s = new Status(Status.ERROR, DdmsPlugin.PLUGIN_ID, e.getMessage(), e);
+ DdmsPlugin.getDefault().getLog().log(s);
+ }
+ return marker;
+ }
+
+ @Override
+ public void acceptSearchMatch(SearchMatch match) throws CoreException {
+ if (match.getResource() instanceof IFile && !mFoundFirstMatch) {
+ mFoundFirstMatch = true;
+ IFile matched_file = (IFile) match.getResource();
+ IMarker marker = createMarkerFromSearchMatch(matched_file, match);
+ // There should only be one exact match,
+ // so we go immediately to that one.
+ if (marker != null) {
+ switchPerspective();
+ openFile(matched_file, marker);
+ }
+ }
+ }
+ }
+
public LogCatView() {
sThis = this;
LogPanel.PREFS_TIME = PREFS_COL_TIME;
@@ -226,10 +287,17 @@
mExportAction.setToolTipText("Export Selection As Text...");
mExportAction.setImageDescriptor(loader.loadDescriptor("save.png")); // $NON-NLS-1$
- gotoLineAction = new CommonAction("Go to Problem") {
+ mGotoMethodDeclarationAction = new CommonAction("Go to Problem (method declaration)") {
@Override
public void run() {
- goToErrorLine();
+ goToErrorLine(CHOICE_METHOD_DECLARATION);
+ }
+ };
+
+ mGotoErrorLineAction = new CommonAction("Go to Problem (error line)") {
+ @Override
+ public void run() {
+ goToErrorLine(CHOICE_ERROR_LINE);
}
};
@@ -270,6 +338,7 @@
// now create the log view
mLogPanel = new LogPanel(colors, new FilterStorage(), LogPanel.FILTER_MANUAL);
+ mLogPanel.setLogCatViewInterface(this);
mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
// get the font
@@ -335,7 +404,8 @@
menuManager.add(mClearAction);
menuManager.add(new Separator());
menuManager.add(mExportAction);
- menuManager.add(gotoLineAction);
+ menuManager.add(mGotoMethodDeclarationAction);
+ menuManager.add(mGotoErrorLineAction);
// and then in the toolbar
IToolBarManager toolBarManager = actionBars.getToolBarManager();
@@ -350,22 +420,6 @@
toolBarManager.add(mClearAction);
}
- IMarker createMarkerFromSearchMatch(IFile file, SearchMatch match) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put(IMarker.CHAR_START, new Integer(match.getOffset()));
- map.put(IMarker.CHAR_END, new Integer(match.getOffset()
- + match.getLength()));
- IMarker marker = null;
- try {
- marker = file.createMarker(IMarker.TEXT);
- marker.setAttributes(map);
- } catch (CoreException e) {
- Status s = new Status(Status.ERROR, DdmsPlugin.PLUGIN_ID, e.getMessage(), e);
- DdmsPlugin.getDefault().getLog().log(s);
- }
- return marker;
- }
-
void openFile(IFile file, IMarker marker) {
try {
IWorkbenchPage page = getViewSite().getWorkbenchWindow()
@@ -396,57 +450,53 @@
}
void goToErrorLine() {
+ IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+ String value = store.getString(PreferenceInitializer.ATTR_LOGCAT_GOTO_PROBLEM);
+ goToErrorLine(value);
+ }
+
+ void goToErrorLine(String choice) {
try {
String msg = mLogPanel.getSelectedErrorLineMessage();
if (msg != null) {
- String error_line_matcher_string = "\\s*at\\ (.*)\\((.*\\.java)\\:(\\d+)\\)";
+ String error_line_matcher_string = "\\s*at\\ (.*)\\((.*)\\.java\\:(\\d+)\\)";
Matcher error_line_matcher = Pattern.compile(
error_line_matcher_string).matcher(msg);
if (error_line_matcher.find()) {
- String class_name = error_line_matcher.group(1);
+ String class_name_method = error_line_matcher.group(1);
// TODO: Search currently only matches the class declaration (using
// IJavaSearchConstants.DECLARATIONS). We may want to jump to the
// "reference" of the class instead (IJavaSearchConstants.REFERENCES)
// using the filename and line number to disambiguate the search results.
-// String filename = error_line_matcher.group(2);
-// int line_number = Integer.parseInt(error_line_matcher.group(3));
+ String class_name_line = error_line_matcher.group(2);
+ int line_number = Integer.parseInt(error_line_matcher.group(3));
SearchEngine se = new SearchEngine();
- se.search(SearchPattern.createPattern(class_name,
- IJavaSearchConstants.METHOD,
- IJavaSearchConstants.DECLARATIONS,
- SearchPattern.R_EXACT_MATCH
- | SearchPattern.R_CASE_SENSITIVE),
- new SearchParticipant[] { SearchEngine
- .getDefaultSearchParticipant() },
+ if (CHOICE_ERROR_LINE.equals(choice)) {
+ se.search(SearchPattern.createPattern(class_name_line,
+ IJavaSearchConstants.CLASS,
+ IJavaSearchConstants.DECLARATIONS,
+ SearchPattern.R_EXACT_MATCH
+ | SearchPattern.R_CASE_SENSITIVE),
+ new SearchParticipant[] { SearchEngine
+ .getDefaultSearchParticipant() },
SearchEngine.createWorkspaceScope(),
- new SearchRequestor() {
- boolean found_first_match = false;
-
- @Override
- public void acceptSearchMatch(
- SearchMatch match)
- throws CoreException {
-
- if (match.getResource() instanceof IFile
- && !found_first_match) {
- found_first_match = true;
-
- IFile matched_file = (IFile) match
- .getResource();
- IMarker marker = createMarkerFromSearchMatch(
- matched_file, match);
-
- // There should only be one exact match,
- // so we go immediately to that one.
- switchPerspective();
- openFile(matched_file, marker);
- }
- }
- }, new NullProgressMonitor());
-
+ new LogCatViewSearchRequestor(CHOICE_ERROR_LINE, line_number),
+ new NullProgressMonitor());
+ } else if (CHOICE_METHOD_DECLARATION.equals(choice)) {
+ se.search(SearchPattern.createPattern(class_name_method,
+ IJavaSearchConstants.METHOD,
+ IJavaSearchConstants.DECLARATIONS,
+ SearchPattern.R_EXACT_MATCH
+ | SearchPattern.R_CASE_SENSITIVE),
+ new SearchParticipant[] { SearchEngine
+ .getDefaultSearchParticipant() },
+ SearchEngine.createWorkspaceScope(),
+ new LogCatViewSearchRequestor(CHOICE_METHOD_DECLARATION, 0),
+ new NullProgressMonitor());
+ }
}
}
} catch (Exception e) {
@@ -454,5 +504,9 @@
DdmsPlugin.getDefault().getLog().log(s);
}
}
- }
+
+ public void onDoubleClick() {
+ goToErrorLine();
+ }
+}