Fields Summary |
---|
private static final int | STRING_BUFFER_LENGTH |
public static final int | FILTER_NONEno filtering. Only one tab with everything. |
public static final int | FILTER_MANUALmanual mode for filter. all filters are manually created. |
public static final int | FILTER_AUTO_PIDautomatic mode for filter (pid mode).
All filters are automatically created. |
public static final int | FILTER_AUTO_TAGautomatic mode for filter (tag mode).
All filters are automatically created. |
public static final int | FILTER_DEBUGManual filtering mode + new filter for debug app, if needed |
public static final int | COLUMN_MODE_MANUAL |
public static final int | COLUMN_MODE_AUTO |
public static String | PREFS_TIME |
public static String | PREFS_LEVEL |
public static String | PREFS_PID |
public static String | PREFS_TAG |
public static String | PREFS_MESSAGE |
private static Pattern | sLogPatternThis pattern is meant to parse the first line of a log message with the option
'logcat -v long'. The first line represents the date, tag, severity, etc.. while the
following lines are the message (can be several line).
This first line looks something like
"[ 00-00 00:00:00.000 <pid>:0x<???> <severity>/<tag>]"
Note: severity is one of V, D, I, W, or EM
Note: the fraction of second value can have any number of digit.
Note the tag should be trim as it may have spaces at the end. |
private org.eclipse.swt.widgets.Composite | mParent |
private org.eclipse.jface.preference.IPreferenceStore | mStore |
private org.eclipse.swt.widgets.TabFolder | mFolderstop object in the view |
private LogColors | mColors |
private ILogFilterStorageManager | mFilterStorage |
private LogCatOuputReceiver | mCurrentLogCat |
private LogMessage[] | mBufferCircular buffer containing the logcat output. This is unfiltered.
The valid content goes from mBufferStart to
mBufferEnd - 1 . Therefore its number of item is
mBufferEnd - mBufferStart . |
private int | mBufferStartRepresents the oldest message in the buffer |
private int | mBufferEndRepresents the next usable item in the buffer to receive new message.
This can be equal to mBufferStart, but when used mBufferStart will be
incremented as well. |
private LogFilter[] | mFiltersFilter list |
private LogFilter | mDefaultFilterDefault filter |
private LogFilter | mCurrentFilterCurrent filter being displayed |
private int | mFilterModeFiltering mode |
private com.android.ddmlib.Device | mCurrentLoggedDeviceDevice currently running logcat |
private com.android.ddmuilib.actions.ICommonAction | mDeleteFilterAction |
private com.android.ddmuilib.actions.ICommonAction | mEditFilterAction |
private com.android.ddmuilib.actions.ICommonAction[] | mLogLevelActions |
private LogMessageInfo | mLastMessageInfopointer to the latest LogMessageInfo. this is used for multi line
log message, to reuse the info regarding level, pid, etc... |
private boolean | mPendingAsyncRefresh |
private com.android.ddmuilib.IImageLoader | mImageLoaderloader for the images. the implementation will varie between standalone
app and eclipse plugin app and eclipse plugin. |
private String | mDefaultLogSave |
private int | mColumnMode |
private org.eclipse.swt.graphics.Font | mDisplayFont |
private com.android.ddmuilib.ITableFocusListener | mGlobalListener |
Methods Summary |
---|
public void | addFilter()Adds a new Filter. This methods displays the UI to create the filter
and set up its parameters.
MUST be called from the ui thread.
EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
mFolders.getShell());
if (dlg.open()) {
synchronized (mBuffer) {
// get the new filter in the array
LogFilter filter = dlg.getFilter();
addFilterToArray(filter);
int index = mFilters.length - 1;
if (mDefaultFilter != null) {
index++;
}
if (false) {
for (LogFilter f : mFilters) {
if (f.uiReady()) {
f.dispose();
}
}
if (mDefaultFilter != null && mDefaultFilter.uiReady()) {
mDefaultFilter.dispose();
}
// for each filter, create a tab.
int i = 0;
if (mFilters != null) {
for (LogFilter f : mFilters) {
createTab(f, i++, true);
}
}
if (mDefaultFilter != null) {
createTab(mDefaultFilter, i++, true);
}
} else {
// create ui for the filter.
createTab(filter, index, true);
// reset the default as it shouldn't contain the content of
// this new filter.
if (mDefaultFilter != null) {
initDefaultFilter();
}
}
// select the new filter
if (mCurrentFilter != null) {
mCurrentFilter.setSelectedState(false);
}
mFolders.setSelection(index);
filter.setSelectedState(true);
mCurrentFilter = filter;
selectionChanged(filter);
// finally we update the filtering mode if needed
if (mFilterMode == FILTER_NONE) {
mFilterMode = FILTER_MANUAL;
}
mFilterStorage.saveFilters(mFilters);
}
}
|
private void | addFilterToArray(LogFilter newFilter)Adds a new filter to the current filter array, and set its colors
// set the colors
newFilter.setColors(mColors);
// add it to the array.
if (mFilters != null && mFilters.length > 0) {
LogFilter[] newFilters = new LogFilter[mFilters.length+1];
System.arraycopy(mFilters, 0, newFilters, 0, mFilters.length);
newFilters[mFilters.length] = newFilter;
mFilters = newFilters;
} else {
mFilters = new LogFilter[1];
mFilters[0] = newFilter;
}
|
private void | addTableToFocusListener(org.eclipse.swt.widgets.Table table)Sets up a Table object to notify the global Table Focus listener when it
gets or loses the focus.
// create the activator for this table
final IFocusedTableActivator activator = new IFocusedTableActivator() {
public void copy(Clipboard clipboard) {
copyTable(clipboard, table);
}
public void selectAll() {
table.selectAll();
}
};
// add the focus listener on the table to notify the global listener
table.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
mGlobalListener.focusGained(activator);
}
public void focusLost(FocusEvent e) {
mGlobalListener.focusLost(activator);
}
});
|
private void | asyncRefresh()Refreshes the UI with new messages.
if (mFolders.isDisposed() == false) {
synchronized (mBuffer) {
try {
// the circular buffer has been updated, let have the filter flush their
// display with the new messages.
if (mFilters != null) {
for (LogFilter f : mFilters) {
f.flush();
}
}
if (mDefaultFilter != null) {
mDefaultFilter.flush();
}
} finally {
// the pending refresh is done.
mPendingAsyncRefresh = false;
}
}
} else {
stopLogCat(true);
}
|
private boolean | checkFilter(com.android.ddmuilib.logcat.LogPanel$LogMessageInfo md)Checks if there's an automatic filter for this md and if not
adds the filter and the ui.
This must be called from the UI!
if (true)
return true;
// look for a filter that matches the pid
if (mFilterMode == FILTER_AUTO_PID) {
for (LogFilter f : mFilters) {
if (f.getPidFilter() == md.pid) {
return true;
}
}
} else if (mFilterMode == FILTER_AUTO_TAG) {
for (LogFilter f : mFilters) {
if (f.getTagFilter().equals(md.tag)) {
return true;
}
}
}
// if we reach this point, no filter was found.
// create a filter with a temporary name of the pid
final LogFilter newFilter = new LogFilter(md.pidString);
String name = null;
if (mFilterMode == FILTER_AUTO_PID) {
newFilter.setPidMode(md.pid);
// ask the monitor thread if it knows the pid.
name = mCurrentLoggedDevice.getClientName(md.pid);
} else {
newFilter.setTagMode(md.tag);
name = md.tag;
}
addFilterToArray(newFilter);
final String fname = name;
// create the tabitem
final TabItem newTabItem = createTab(newFilter, -1, true);
// if the name is unknown
if (fname == null) {
// we need to find the process running under that pid.
// launch a thread do a ps on the device
new Thread("remote PS") { //$NON-NLS-1$
@Override
public void run() {
// create the receiver
PsOutputReceiver psor = new PsOutputReceiver(md.pid,
newFilter, newTabItem);
// execute ps
try {
mCurrentLoggedDevice.executeShellCommand("ps", psor); //$NON-NLS-1$
} catch (IOException e) {
// hmm...
}
}
}.start();
}
return false;
|
public void | clear()Empty the current circular buffer.
synchronized (mBuffer) {
for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
mBuffer[i] = null;
}
mBufferStart = -1;
mBufferEnd = -1;
// now we clear the existing filters
for (LogFilter filter : mFilters) {
filter.clear();
}
// and the default one
if (mDefaultFilter != null) {
mDefaultFilter.clear();
}
}
|
public void | clientSelected()Sent when a new client is selected. The new client can be accessed
with {@link #getCurrentClient()}.
// pass
|
public void | copy(org.eclipse.swt.dnd.Clipboard clipboard)Copies the current selection of the current filter as multiline text.
// get the current table and its selection
Table currentTable = mCurrentFilter.getTable();
copyTable(clipboard, currentTable);
|
private static void | copyTable(org.eclipse.swt.dnd.Clipboard clipboard, org.eclipse.swt.widgets.Table table)Copies the current selection of a Table into the provided Clipboard, as
multi-line text.
int[] selection = table.getSelectionIndices();
// we need to sort the items to be sure.
Arrays.sort(selection);
// all lines must be concatenated.
StringBuilder sb = new StringBuilder();
// loop on the selection and output the file.
for (int i : selection) {
TableItem item = table.getItem(i);
LogMessage msg = (LogMessage)item.getData();
String line = msg.toString();
sb.append(line);
sb.append('\n");
}
// now add that to the clipboard
clipboard.setContents(new Object[] {
sb.toString()
}, new Transfer[] {
TextTransfer.getInstance()
});
|
protected org.eclipse.swt.widgets.Control | createControl(org.eclipse.swt.widgets.Composite parent)Creates a control capable of displaying some information. This is
called once, when the application is initializing, from the UI thread.
mParent = parent;
Composite top = new Composite(parent, SWT.NONE);
top.setLayoutData(new GridData(GridData.FILL_BOTH));
top.setLayout(new GridLayout(1, false));
// create the tab folder
mFolders = new TabFolder(top, SWT.NONE);
mFolders.setLayoutData(new GridData(GridData.FILL_BOTH));
mFolders.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mCurrentFilter != null) {
mCurrentFilter.setSelectedState(false);
}
mCurrentFilter = getCurrentFilter();
mCurrentFilter.setSelectedState(true);
updateColumns(mCurrentFilter.getTable());
if (mCurrentFilter.getTempFilterStatus()) {
initFilter(mCurrentFilter);
}
selectionChanged(mCurrentFilter);
}
});
Composite bottom = new Composite(top, SWT.NONE);
bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
bottom.setLayout(new GridLayout(3, false));
Label label = new Label(bottom, SWT.NONE);
label.setText("Filter:");
final Text filterText = new Text(bottom, SWT.SINGLE | SWT.BORDER);
filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
filterText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
updateFilteringWith(filterText.getText());
}
});
/*
Button addFilterBtn = new Button(bottom, SWT.NONE);
addFilterBtn.setImage(mImageLoader.loadImage("add.png", //$NON-NLS-1$
addFilterBtn.getDisplay()));
*/
// get the filters
createFilters();
// for each filter, create a tab.
int index = 0;
if (mDefaultFilter != null) {
createTab(mDefaultFilter, index++, false);
}
if (mFilters != null) {
for (LogFilter f : mFilters) {
createTab(f, index++, false);
}
}
return top;
|
private void | createFilters()
if (mFilterMode == FILTER_DEBUG || mFilterMode == FILTER_MANUAL) {
// unarchive the filters.
mFilters = mFilterStorage.getFilterFromStore();
// set the colors
if (mFilters != null) {
for (LogFilter f : mFilters) {
f.setColors(mColors);
}
}
if (mFilterStorage.requiresDefaultFilter()) {
mDefaultFilter = new LogFilter("Log");
mDefaultFilter.setColors(mColors);
mDefaultFilter.setSupportsDelete(false);
mDefaultFilter.setSupportsEdit(false);
}
} else if (mFilterMode == FILTER_NONE) {
// if the filtering mode is "none", we create a single filter that
// will receive all
mDefaultFilter = new LogFilter("Log");
mDefaultFilter.setColors(mColors);
mDefaultFilter.setSupportsDelete(false);
mDefaultFilter.setSupportsEdit(false);
}
|
private org.eclipse.swt.widgets.TabItem | createTab(LogFilter filter, int index, boolean fillTable)Creates a new tab in the folderTab item. Must be called from the ui
thread.
synchronized (mBuffer) {
TabItem item = null;
if (index != -1) {
item = new TabItem(mFolders, SWT.NONE, index);
} else {
item = new TabItem(mFolders, SWT.NONE);
}
item.setText(filter.getName());
// set the control (the parent is the TabFolder item, always)
Composite top = new Composite(mFolders, SWT.NONE);
item.setControl(top);
top.setLayout(new FillLayout());
// create the ui, first the table
final Table t = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
if (mDisplayFont != null) {
t.setFont(mDisplayFont);
}
// give the ui objects to the filters.
filter.setWidgets(item, t);
t.setHeaderVisible(true);
t.setLinesVisible(false);
if (mGlobalListener != null) {
addTableToFocusListener(t);
}
// create a controllistener that will handle the resizing of all the
// columns (except the last) and of the table itself.
ControlListener listener = null;
if (mColumnMode == COLUMN_MODE_AUTO) {
listener = new ControlListener() {
public void controlMoved(ControlEvent e) {
}
public void controlResized(ControlEvent e) {
Rectangle r = t.getClientArea();
// get the size of all but the last column
int total = t.getColumn(0).getWidth();
total += t.getColumn(1).getWidth();
total += t.getColumn(2).getWidth();
total += t.getColumn(3).getWidth();
if (r.width > total) {
t.getColumn(4).setWidth(r.width-total);
}
}
};
t.addControlListener(listener);
}
// then its column
TableColumn col = TableHelper.createTableColumn(t, "Time", SWT.LEFT,
"00-00 00:00:00", //$NON-NLS-1$
PREFS_TIME, mStore);
if (mColumnMode == COLUMN_MODE_AUTO) {
col.addControlListener(listener);
}
col = TableHelper.createTableColumn(t, "", SWT.CENTER,
"D", //$NON-NLS-1$
PREFS_LEVEL, mStore);
if (mColumnMode == COLUMN_MODE_AUTO) {
col.addControlListener(listener);
}
col = TableHelper.createTableColumn(t, "pid", SWT.LEFT,
"9999", //$NON-NLS-1$
PREFS_PID, mStore);
if (mColumnMode == COLUMN_MODE_AUTO) {
col.addControlListener(listener);
}
col = TableHelper.createTableColumn(t, "tag", SWT.LEFT,
"abcdefgh", //$NON-NLS-1$
PREFS_TAG, mStore);
if (mColumnMode == COLUMN_MODE_AUTO) {
col.addControlListener(listener);
}
col = TableHelper.createTableColumn(t, "Message", SWT.LEFT,
"abcdefghijklmnopqrstuvwxyz0123456789", //$NON-NLS-1$
PREFS_MESSAGE, mStore);
if (mColumnMode == COLUMN_MODE_AUTO) {
// instead of listening on resize for the last column, we make
// it non resizable.
col.setResizable(false);
}
if (fillTable) {
initFilter(filter);
}
return item;
}
|
public void | deleteFilter()Deletes the current filter.
synchronized (mBuffer) {
if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
// remove the filter from the list
removeFilterFromArray(mCurrentFilter);
mCurrentFilter.dispose();
// select the new filter
mFolders.setSelection(0);
if (mFilters.length > 0) {
mCurrentFilter = mFilters[0];
} else {
mCurrentFilter = mDefaultFilter;
}
selectionChanged(mCurrentFilter);
// update the content of the "other" filter to include what was filtered out
// by the deleted filter.
if (mDefaultFilter != null) {
initDefaultFilter();
}
mFilterStorage.saveFilters(mFilters);
}
}
|
public void | deviceSelected()Sent when a new device is selected. The new device can be accessed
with {@link #getCurrentDevice()}.
startLogCat(getCurrentDevice());
|
public void | editFilter()Edits the current filter. The method displays the UI to edit the filter.
if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
mFolders.getShell(),
mCurrentFilter);
if (dlg.open()) {
synchronized (mBuffer) {
// at this point the filter has been updated.
// so we update its content
initFilter(mCurrentFilter);
// and the content of the "other" filter as well.
if (mDefaultFilter != null) {
initDefaultFilter();
}
mFilterStorage.saveFilters(mFilters);
}
}
}
|
private void | emptyTables()
for (LogFilter f : mFilters) {
f.getTable().removeAll();
}
if (mDefaultFilter != null) {
mDefaultFilter.getTable().removeAll();
}
|
private LogFilter | getCurrentFilter()
int index = mFolders.getSelectionIndex();
// if mFilters is null or index is invalid, we return the default
// filter. It doesn't matter if that one is null as well, since we
// would return null anyway.
if (index == 0 || mFilters == null) {
return mDefaultFilter;
}
return mFilters[index-1];
|
private void | initDefaultFilter()Refill the default filter. Not to be called directly.
mDefaultFilter.clear();
if (mBufferStart != -1) {
int max = mBufferEnd;
if (mBufferEnd < mBufferStart) {
max += STRING_BUFFER_LENGTH;
}
for (int i = mBufferStart; i < max; i++) {
int realItemIndex = i % STRING_BUFFER_LENGTH;
LogMessage msg = mBuffer[realItemIndex];
// first we check that the other filters don't take this message
boolean filtered = false;
for (LogFilter f : mFilters) {
filtered |= f.accept(msg);
}
if (filtered == false) {
mDefaultFilter.addMessage(msg, null /* old message */);
}
}
}
mDefaultFilter.flush();
mDefaultFilter.resetTempFilteringStatus();
|
private void | initFilter(LogFilter filter)Initialize the filter with already existing buffer.
// is it empty
if (filter.uiReady() == false) {
return;
}
if (filter == mDefaultFilter) {
initDefaultFilter();
return;
}
filter.clear();
if (mBufferStart != -1) {
int max = mBufferEnd;
if (mBufferEnd < mBufferStart) {
max += STRING_BUFFER_LENGTH;
}
for (int i = mBufferStart; i < max; i++) {
int realItemIndex = i % STRING_BUFFER_LENGTH;
filter.addMessage(mBuffer[realItemIndex], null /* old message */);
}
}
filter.flush();
filter.resetTempFilteringStatus();
|
protected void | postCreation()
// pass
|
protected void | processLogLines(java.lang.String[] lines)Process new Log lines coming from {@link LogCatOuputReceiver}.
// WARNING: this will not work if the string contains more line than
// the buffer holds.
if (lines.length > STRING_BUFFER_LENGTH) {
Log.e("LogCat", "Receiving more lines than STRING_BUFFER_LENGTH");
}
// parse the lines and create LogMessage that are stored in a temporary list
final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
synchronized (mBuffer) {
for (String line : lines) {
// ignore empty lines.
if (line.length() > 0) {
// check for header lines.
Matcher matcher = sLogPattern.matcher(line);
if (matcher.matches()) {
// this is a header line, parse the header and keep it around.
mLastMessageInfo = new LogMessageInfo();
mLastMessageInfo.time = matcher.group(1);
mLastMessageInfo.pidString = matcher.group(2);
mLastMessageInfo.pid = Integer.valueOf(mLastMessageInfo.pidString);
mLastMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
mLastMessageInfo.tag = matcher.group(5).trim();
} else {
// This is not a header line.
// Create a new LogMessage and process it.
LogMessage mc = new LogMessage();
if (mLastMessageInfo == null) {
// The first line of output wasn't preceded
// by a header line; make something up so
// that users of mc.data don't NPE.
mLastMessageInfo = new LogMessageInfo();
mLastMessageInfo.time = "??-?? ??:??:??.???"; //$NON-NLS1$
mLastMessageInfo.pidString = "<unknown>"; //$NON-NLS1$
mLastMessageInfo.pid = 0;
mLastMessageInfo.logLevel = LogLevel.INFO;
mLastMessageInfo.tag = "<unknown>"; //$NON-NLS1$
}
// If someone printed a log message with
// embedded '\n' characters, there will
// one header line followed by multiple text lines.
// Use the last header that we saw.
mc.data = mLastMessageInfo;
// tabs seem to display as only 1 tab so we replace the leading tabs
// by 4 spaces.
mc.msg = line.replaceAll("\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
// process the new LogMessage.
processNewMessage(mc);
// store the new LogMessage
newMessages.add(mc);
}
}
}
// if we don't have a pending Runnable that will do the refresh, we ask the Display
// to run one in the UI thread.
if (mPendingAsyncRefresh == false) {
mPendingAsyncRefresh = true;
try {
Display display = mFolders.getDisplay();
// run in sync because this will update the buffer start/end indices
display.asyncExec(new Runnable() {
public void run() {
asyncRefresh();
}
});
} catch (SWTException e) {
// display is disposed, we're probably quitting. Let's stop.
stopLogCat(false);
}
}
}
|
private void | processNewMessage(com.android.ddmuilib.logcat.LogPanel$LogMessage newMessage)Processes a new Message.
This adds the new message to the buffer, and gives it to the existing filters.
// if we are in auto filtering mode, make sure we have
// a filter for this
if (mFilterMode == FILTER_AUTO_PID ||
mFilterMode == FILTER_AUTO_TAG) {
checkFilter(newMessage.data);
}
// compute the index where the message goes.
// was the buffer empty?
int messageIndex = -1;
if (mBufferStart == -1) {
messageIndex = mBufferStart = 0;
mBufferEnd = 1;
} else {
messageIndex = mBufferEnd;
// check we aren't overwriting start
if (mBufferEnd == mBufferStart) {
mBufferStart = (mBufferStart + 1) % STRING_BUFFER_LENGTH;
}
// increment the next usable slot index
mBufferEnd = (mBufferEnd + 1) % STRING_BUFFER_LENGTH;
}
LogMessage oldMessage = null;
// record the message that was there before
if (mBuffer[messageIndex] != null) {
oldMessage = mBuffer[messageIndex];
}
// then add the new one
mBuffer[messageIndex] = newMessage;
// give the new message to every filters.
boolean filtered = false;
if (mFilters != null) {
for (LogFilter f : mFilters) {
filtered |= f.addMessage(newMessage, oldMessage);
}
}
if (filtered == false && mDefaultFilter != null) {
mDefaultFilter.addMessage(newMessage, oldMessage);
}
|
private void | removeFilterFromArray(LogFilter oldFilter)
// look for the index
int index = -1;
for (int i = 0 ; i < mFilters.length ; i++) {
if (mFilters[i] == oldFilter) {
index = i;
break;
}
}
if (index != -1) {
LogFilter[] newFilters = new LogFilter[mFilters.length-1];
System.arraycopy(mFilters, 0, newFilters, 0, index);
System.arraycopy(mFilters, index + 1, newFilters, index,
newFilters.length-index);
mFilters = newFilters;
}
|
private void | resetFilters()Reset the filters, to handle change in device in automatic filter mode
// if we are in automatic mode, then we need to rmove the current
// filter.
if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
mFilters = null;
// recreate the filters.
createFilters();
}
|
public void | resetUI(boolean inUiThread)
if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
if (inUiThread) {
mFolders.dispose();
mParent.pack(true);
createControl(mParent);
} else {
Display d = mFolders.getDisplay();
// run sync as we need to update right now.
d.syncExec(new Runnable() {
public void run() {
mFolders.dispose();
mParent.pack(true);
createControl(mParent);
}
});
}
} else {
// the ui is static we just empty it.
if (mFolders.isDisposed() == false) {
if (inUiThread) {
emptyTables();
} else {
Display d = mFolders.getDisplay();
// run sync as we need to update right now.
d.syncExec(new Runnable() {
public void run() {
if (mFolders.isDisposed() == false) {
emptyTables();
}
}
});
}
}
}
|
public boolean | save()saves the current selection in a text file.
synchronized (mBuffer) {
FileDialog dlg = new FileDialog(mParent.getShell(), SWT.SAVE);
String fileName;
dlg.setText("Save log...");
dlg.setFileName("log.txt");
String defaultPath = mDefaultLogSave;
if (defaultPath == null) {
defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
}
dlg.setFilterPath(defaultPath);
dlg.setFilterNames(new String[] {
"Text Files (*.txt)"
});
dlg.setFilterExtensions(new String[] {
"*.txt"
});
fileName = dlg.open();
if (fileName != null) {
mDefaultLogSave = dlg.getFilterPath();
// get the current table and its selection
Table currentTable = mCurrentFilter.getTable();
int[] selection = currentTable.getSelectionIndices();
// we need to sort the items to be sure.
Arrays.sort(selection);
// loop on the selection and output the file.
try {
FileWriter writer = new FileWriter(fileName);
for (int i : selection) {
TableItem item = currentTable.getItem(i);
LogMessage msg = (LogMessage)item.getData();
String line = msg.toString();
writer.write(line);
writer.write('\n");
}
writer.flush();
} catch (IOException e) {
return false;
}
}
}
return true;
|
public void | selectAll()Selects all lines.
Table currentTable = mCurrentFilter.getTable();
currentTable.selectAll();
|
private void | selectionChanged(LogFilter selectedFilter)Called when the current filter selection changes.
if (mLogLevelActions != null) {
// get the log level
int level = selectedFilter.getLogLevel();
for (int i = 0 ; i < mLogLevelActions.length; i++) {
ICommonAction a = mLogLevelActions[i];
if (i == level - 2) {
a.setChecked(true);
} else {
a.setChecked(false);
}
}
}
if (mDeleteFilterAction != null) {
mDeleteFilterAction.setEnabled(selectedFilter.supportsDelete());
}
if (mEditFilterAction != null) {
mEditFilterAction.setEnabled(selectedFilter.supportsEdit());
}
|
public void | setActions(com.android.ddmuilib.actions.ICommonAction deleteAction, com.android.ddmuilib.actions.ICommonAction editAction, com.android.ddmuilib.actions.ICommonAction[] logLevelActions)
mDeleteFilterAction = deleteAction;
mEditFilterAction = editAction;
mLogLevelActions = logLevelActions;
|
public void | setColumnMode(int mode)Sets the column mode. Must be called before creatUI
mColumnMode = mode;
|
public void | setCurrentFilterLogLevel(int i)Sets the log level for the current filter, but does not save it.
LogFilter filter = getCurrentFilter();
filter.setLogLevel(i);
initFilter(filter);
|
public void | setFocus()Sets the focus to the proper object.
mFolders.setFocus();
|
public void | setFont(org.eclipse.swt.graphics.Font font)Sets the display font.
mDisplayFont = font;
if (mFilters != null) {
for (LogFilter f : mFilters) {
Table table = f.getTable();
if (table != null) {
table.setFont(font);
}
}
}
if (mDefaultFilter != null) {
Table table = mDefaultFilter.getTable();
if (table != null) {
table.setFont(font);
}
}
|
public void | setTableFocusListener(com.android.ddmuilib.ITableFocusListener listener)Sets a TableFocusListener which will be notified when one of the tables
gets or loses focus.
// record the global listener, to make sure table created after
// this call will still be setup.
mGlobalListener = listener;
// now we setup the existing filters
for (LogFilter filter : mFilters) {
Table table = filter.getTable();
addTableToFocusListener(table);
}
// and the default one
if (mDefaultFilter != null) {
addTableToFocusListener(mDefaultFilter.getTable());
}
|
public void | startLogCat(com.android.ddmlib.Device device)Starts a new logcat and set mCurrentLogCat as the current receiver.
if (device == mCurrentLoggedDevice) {
return;
}
// if we have a logcat already running
if (mCurrentLoggedDevice != null) {
stopLogCat(false);
mCurrentLoggedDevice = null;
}
resetUI(false);
if (device != null) {
// create a new output receiver
mCurrentLogCat = new LogCatOuputReceiver();
// start the logcat in a different thread
new Thread("Logcat") { //$NON-NLS-1$
@Override
public void run() {
while (device.isOnline() == false &&
mCurrentLogCat != null &&
mCurrentLogCat.isCancelled == false) {
try {
sleep(2000);
} catch (InterruptedException e) {
return;
}
}
if (mCurrentLogCat == null || mCurrentLogCat.isCancelled) {
// logcat was stopped/cancelled before the device became ready.
return;
}
try {
mCurrentLoggedDevice = device;
device.executeShellCommand("logcat -v long", mCurrentLogCat); //$NON-NLS-1$
} catch (Exception e) {
Log.e("Logcat", e);
} finally {
// at this point the command is terminated.
mCurrentLogCat = null;
mCurrentLoggedDevice = null;
}
}
}.start();
}
|
public void | stopLogCat(boolean inUiThread)Stop the current logcat
if (mCurrentLogCat != null) {
mCurrentLogCat.isCancelled = true;
// when the thread finishes, no one will reference that object
// and it'll be destroyed
mCurrentLogCat = null;
// reset the content buffer
for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
mBuffer[i] = null;
}
// because it's a circular buffer, it's hard to know if
// the array is empty with both start/end at 0 or if it's full
// with both start/end at 0 as well. So to mean empty, we use -1
mBufferStart = -1;
mBufferEnd = -1;
resetFilters();
resetUI(inUiThread);
}
|
protected void | updateColumns(org.eclipse.swt.widgets.Table table)
if (table != null) {
int index = 0;
TableColumn col;
col = table.getColumn(index++);
col.setWidth(mStore.getInt(PREFS_TIME));
col = table.getColumn(index++);
col.setWidth(mStore.getInt(PREFS_LEVEL));
col = table.getColumn(index++);
col.setWidth(mStore.getInt(PREFS_PID));
col = table.getColumn(index++);
col.setWidth(mStore.getInt(PREFS_TAG));
col = table.getColumn(index++);
col.setWidth(mStore.getInt(PREFS_MESSAGE));
}
|
protected void | updateFilteringWith(java.lang.String text)
synchronized (mBuffer) {
// reset the temp filtering for all the filters
for (LogFilter f : mFilters) {
f.resetTempFiltering();
}
if (mDefaultFilter != null) {
mDefaultFilter.resetTempFiltering();
}
// now we need to figure out the new temp filtering
// split each word
String[] segments = text.split(" "); //$NON-NLS-1$
ArrayList<String> keywords = new ArrayList<String>(segments.length);
// loop and look for temp id/tag
int tempPid = -1;
String tempTag = null;
for (int i = 0 ; i < segments.length; i++) {
String s = segments[i];
if (tempPid == -1 && s.startsWith("pid:")) { //$NON-NLS-1$
// get the pid
String[] seg = s.split(":"); //$NON-NLS-1$
if (seg.length == 2) {
if (seg[1].matches("^[0-9]*$")) { //$NON-NLS-1$
tempPid = Integer.valueOf(seg[1]);
}
}
} else if (tempTag == null && s.startsWith("tag:")) { //$NON-NLS-1$
String seg[] = segments[i].split(":"); //$NON-NLS-1$
if (seg.length == 2) {
tempTag = seg[1];
}
} else {
keywords.add(s);
}
}
// set the temp filtering in the filters
if (tempPid != -1 || tempTag != null || keywords.size() > 0) {
String[] keywordsArray = keywords.toArray(
new String[keywords.size()]);
for (LogFilter f : mFilters) {
if (tempPid != -1) {
f.setTempPidFiltering(tempPid);
}
if (tempTag != null) {
f.setTempTagFiltering(tempTag);
}
f.setTempKeywordFiltering(keywordsArray);
}
if (mDefaultFilter != null) {
if (tempPid != -1) {
mDefaultFilter.setTempPidFiltering(tempPid);
}
if (tempTag != null) {
mDefaultFilter.setTempTagFiltering(tempTag);
}
mDefaultFilter.setTempKeywordFiltering(keywordsArray);
}
}
initFilter(mCurrentFilter);
}
|