import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmuilib.AllocationPanel;
+import com.android.ddmuilib.DdmUiPreferences;
import com.android.ddmuilib.DevicePanel;
import com.android.ddmuilib.EmulatorControlPanel;
import com.android.ddmuilib.HeapPanel;
import com.android.ddmuilib.handler.BaseFileHandler;
import com.android.ddmuilib.handler.MethodProfilingHandler;
import com.android.ddmuilib.log.event.EventLogPanel;
+import com.android.ddmuilib.logcat.LogCatPanel;
+import com.android.ddmuilib.logcat.LogCatReceiver;
import com.android.ddmuilib.logcat.LogColors;
import com.android.ddmuilib.logcat.LogFilter;
import com.android.ddmuilib.logcat.LogPanel;
import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
+import com.android.menubar.IMenuBarCallback;
+import com.android.menubar.IMenuBarEnhancer;
+import com.android.menubar.IMenuBarEnhancer.MenuBarMode;
+import com.android.menubar.MenuBarEnhancer;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
* when {@link IDevice} / {@link Client} selection changes.
*/
public class UIThread implements IUiSelectionListener, IClientChangeListener {
+ private static final String APP_NAME = "DDMS";
+
/*
* UI tab panel definitions. The constants here must match up with the array
* indices in mPanels. PANEL_CLIENT_LIST is a "virtual" panel representing
}
- private LogPanel mLogPanel;
+ /**
+ * Flag to indicate whether to use the old or the new logcat view. This is a
+ * temporary workaround that will be removed once the new view is complete.
+ */
+ private static final String USE_NEW_LOGCAT_VIEW =
+ System.getenv("ANDROID_USE_NEW_LOGCAT_VIEW");
+ private boolean useOldLogCatView() {
+ return USE_NEW_LOGCAT_VIEW == null;
+ }
+
+ private LogPanel mLogPanel; /* only valid when useOldLogCatView() == true */
+ private LogCatPanel mLogCatPanel; /* only valid when useOldLogCatView() == false */
private ToolItemAction mCreateFilterAction;
private ToolItemAction mDeleteFilterAction;
/**
* Create SWT objects and drive the user interface event loop.
- * @param location location of the folder that contains ddms.
+ * @param ddmsParentLocation location of the folder that contains ddms.
*/
public void runUI(String ddmsParentLocation) {
- Display.setAppName("ddms");
+ Display.setAppName(APP_NAME);
mDisplay = new Display();
final Shell shell = new Shell(mDisplay);
mDdmUiLibLoader = ImageLoader.getDdmUiLibLoader();
shell.setImage(ImageLoader.getLoader(this.getClass()).loadImage(mDisplay,
- "ddms-icon.png", //$NON-NLS-1$
+ "ddms-128.png", //$NON-NLS-1$
100, 50, null));
Log.setLogOutput(new ILogOutput() {
// dialog box only run in UI thread..
mDisplay.asyncExec(new Runnable() {
public void run() {
- Shell shell = mDisplay.getActiveShell();
+ Shell activeShell = mDisplay.getActiveShell();
if (logLevel == LogLevel.ERROR) {
- MessageDialog.openError(shell, tag, message);
+ MessageDialog.openError(activeShell, tag, message);
} else {
- MessageDialog.openWarning(shell, tag, message);
+ MessageDialog.openWarning(activeShell, tag, message);
}
}
});
if (!mDisplay.readAndDispatch())
mDisplay.sleep();
}
- mLogPanel.stopLogCat(true);
+ if (useOldLogCatView()) {
+ mLogPanel.stopLogCat(true);
+ }
mDevicePanel.dispose();
for (TablePanel panel : mPanels) {
shell.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {
// get the new x/y
- Rectangle rect = shell.getBounds();
+ Rectangle controlBounds = shell.getBounds();
// store in pref file
- PreferenceStore prefs = PrefsDialog.getStore();
- prefs.setValue(PrefsDialog.SHELL_X, rect.x);
- prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
+ PreferenceStore currentPrefs = PrefsDialog.getStore();
+ currentPrefs.setValue(PrefsDialog.SHELL_X, controlBounds.x);
+ currentPrefs.setValue(PrefsDialog.SHELL_Y, controlBounds.y);
}
public void controlResized(ControlEvent e) {
// get the new w/h
- Rectangle rect = shell.getBounds();
+ Rectangle controlBounds = shell.getBounds();
// store in pref file
- PreferenceStore prefs = PrefsDialog.getStore();
- prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
- prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
+ PreferenceStore currentPrefs = PrefsDialog.getStore();
+ currentPrefs.setValue(PrefsDialog.SHELL_WIDTH, controlBounds.width);
+ currentPrefs.setValue(PrefsDialog.SHELL_HEIGHT, controlBounds.height);
}
});
}
shell.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {
// get the new x/y
- Rectangle rect = shell.getBounds();
+ Rectangle controlBounds = shell.getBounds();
// store in pref file
- PreferenceStore prefs = PrefsDialog.getStore();
- prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
- prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
+ PreferenceStore currentPrefs = PrefsDialog.getStore();
+ currentPrefs.setValue(PrefsDialog.EXPLORER_SHELL_X, controlBounds.x);
+ currentPrefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, controlBounds.y);
}
public void controlResized(ControlEvent e) {
// get the new w/h
- Rectangle rect = shell.getBounds();
+ Rectangle controlBounds = shell.getBounds();
// store in pref file
- PreferenceStore prefs = PrefsDialog.getStore();
- prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
- prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
+ PreferenceStore currentPrefs = PrefsDialog.getStore();
+ currentPrefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, controlBounds.width);
+ currentPrefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, controlBounds.height);
}
});
}
/*
- * Set the confirm-before-close dialog. TODO: enable/disable in prefs. TODO:
- * is there any point in having this?
+ * Set the confirm-before-close dialog.
*/
private void setConfirmClose(final Shell shell) {
- if (true)
- return;
-
- shell.addListener(SWT.Close, new Listener() {
- public void handleEvent(Event event) {
- int style = SWT.APPLICATION_MODAL | SWT.YES | SWT.NO;
- MessageBox msgBox = new MessageBox(shell, style);
- msgBox.setText("Confirm...");
- msgBox.setMessage("Close DDM?");
- event.doit = (msgBox.open() == SWT.YES);
- }
- });
+ // Note: there was some commented out code to display a confirmation box
+ // when closing. The feature seems unnecessary and the code was not being
+ // used, so it has been removed.
}
/*
actionItem.setText("&Actions");
MenuItem deviceItem = new MenuItem(menuBar, SWT.CASCADE);
deviceItem.setText("&Device");
- MenuItem helpItem = new MenuItem(menuBar, SWT.CASCADE);
- helpItem.setText("&Help");
// create top-level menus
Menu fileMenu = new Menu(menuBar);
actionItem.setMenu(actionMenu);
Menu deviceMenu = new Menu(menuBar);
deviceItem.setMenu(deviceMenu);
- Menu helpMenu = new Menu(menuBar);
- helpItem.setMenu(helpMenu);
MenuItem item;
// create File menu items
item = new MenuItem(fileMenu, SWT.NONE);
- item.setText("&Preferences...");
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- PrefsDialog.run(shell);
- }
- });
-
- item = new MenuItem(fileMenu, SWT.NONE);
item.setText("&Static Port Configuration...");
item.addSelectionListener(new SelectionAdapter() {
@Override
}
});
- new MenuItem(fileMenu, SWT.SEPARATOR);
+ IMenuBarEnhancer enhancer = MenuBarEnhancer.setupMenu(APP_NAME, fileMenu,
+ new IMenuBarCallback() {
+ public void printError(String format, Object... args) {
+ Log.e("DDMS Menu Bar", String.format(format, args));
+ }
- item = new MenuItem(fileMenu, SWT.NONE);
- item.setText("E&xit\tCtrl-Q");
- item.setAccelerator('Q' | SWT.CONTROL);
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- shell.close();
+ public void onPreferencesMenuSelected() {
+ PrefsDialog.run(shell);
+ }
+
+ public void onAboutMenuSelected() {
+ AboutDialog dlg = new AboutDialog(shell);
+ dlg.open();
}
});
+ if (enhancer.getMenuBarMode() == MenuBarMode.GENERIC) {
+ new MenuItem(fileMenu, SWT.SEPARATOR);
+
+ item = new MenuItem(fileMenu, SWT.NONE);
+ item.setText("E&xit\tCtrl-Q");
+ item.setAccelerator('Q' | (Main.isMac() ? SWT.COMMAND : SWT.CONTROL));
+ item.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ shell.close();
+ }
+ });
+ }
+
// create edit menu items
mCopyMenuItem = new MenuItem(editMenu, SWT.NONE);
mCopyMenuItem.setText("&Copy\tCtrl-C");
}
});
+ final MenuItem actionResetAdb = new MenuItem(actionMenu, SWT.NONE);
+ actionResetAdb.setText("&Reset adb");
+ actionResetAdb.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+ if (bridge != null) {
+ bridge.restart();
+ }
+ }
+ });
+
// configure Action items based on current state
actionMenu.addMenuListener(new MenuAdapter() {
@Override
public void menuShown(MenuEvent e) {
actionHaltItem.setEnabled(mTBHalt.getEnabled() && mCurrentClient != null);
actionCauseGcItem.setEnabled(mTBCauseGc.getEnabled() && mCurrentClient != null);
+ actionResetAdb.setEnabled(true);
}
});
// create Device menu items
final MenuItem screenShotItem = new MenuItem(deviceMenu, SWT.NONE);
+
+ // The \tCtrl-S "keybinding text" here isn't right for the Mac - but
+ // it's stripped out and replaced by the proper keyboard accelerator
+ // text (e.g. the unicode symbol for the command key + S) anyway
+ // so it's fine to leave it there for the other platforms.
screenShotItem.setText("&Screen capture...\tCtrl-S");
- screenShotItem.setAccelerator('S' | SWT.CONTROL);
+ screenShotItem.setAccelerator('S' | (Main.isMac() ? SWT.COMMAND : SWT.CONTROL));
screenShotItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
}
});
- // create Help menu items
- item = new MenuItem(helpMenu, SWT.NONE);
- item.setText("&Contents...");
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- int style = SWT.APPLICATION_MODAL | SWT.OK;
- MessageBox msgBox = new MessageBox(shell, style);
- msgBox.setText("Help!");
- msgBox.setMessage("Help wanted.");
- msgBox.open();
- }
- });
-
- new MenuItem(helpMenu, SWT.SEPARATOR);
-
- item = new MenuItem(helpMenu, SWT.NONE);
- item.setText("&About...");
- item.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- AboutDialog dlg = new AboutDialog(shell);
- dlg.open();
- }
- });
-
// tell the shell to use this menu
shell.setMenuBar(menuBar);
}
panelArea.setLayout(new FormLayout());
createTopPanel(topPanel, darkGray);
- createBottomPanel(bottomPanel);
+
+ if (useOldLogCatView()) {
+ createBottomPanel(bottomPanel);
+ } else {
+ createLogCatView(bottomPanel);
+ }
// form layout data
FormData data = new FormData();
e.y = Math.max(Math.min(e.y, bottom), 100);
if (e.y != sashRect.y) {
sashData.top = new FormAttachment(0, e.y);
- prefs.setValue(PREFERENCE_LOGSASH, e.y);
+ if (prefs != null) {
+ prefs.setValue(PREFERENCE_LOGSASH, e.y);
+ }
panelArea.layout();
}
}
mTableListener = new TableFocusListener();
// now set up the listener in the various panels
- mLogPanel.setTableFocusListener(mTableListener);
+ if (useOldLogCatView()) {
+ mLogPanel.setTableFocusListener(mTableListener);
+ }
mEventLogPanel.setTableFocusListener(mTableListener);
for (TablePanel p : mPanels) {
if (p != null) {
e.x = Math.max(Math.min(e.x, right), minPanelWidth);
if (e.x != sashRect.x) {
sashData.left = new FormAttachment(0, e.x);
- prefs.setValue(PREFERENCE_SASH, e.x);
+ if (prefs != null) {
+ prefs.setValue(PREFERENCE_SASH, e.x);
+ }
comp.layout();
}
}
@Override
public void widgetSelected(SelectionEvent e) {
// disable the other actions and record current index
- for (int i = 0 ; i < mLogLevelActions.length; i++) {
- ToolItemAction a = mLogLevelActions[i];
+ for (int k = 0 ; k < mLogLevelActions.length; k++) {
+ ToolItemAction a = mLogLevelActions[k];
if (a == newAction) {
a.setChecked(true);
// set the log level
- mLogPanel.setCurrentFilterLogLevel(i+2);
+ mLogPanel.setCurrentFilterLogLevel(k+2);
} else {
a.setChecked(false);
}
mLogPanel.startLogCat(mCurrentDevice);
}
+ private void createLogCatView(Composite parent) {
+ mLogCatPanel = new LogCatPanel(new LogCatReceiver(), DdmUiPreferences.getStore());
+ mLogCatPanel.createPanel(parent);
+
+ if (mCurrentDevice != null) {
+ mLogCatPanel.deviceSelected(mCurrentDevice);
+ }
+ }
+
/*
* Create the contents of the left panel: a table of VMs.
*/
deleteAction.item.setText("Delete"); //$NON-NLS-1$
}
+ ToolItemAction createNewFolderAction = new ToolItemAction(toolBar, SWT.PUSH);
+ createNewFolderAction.item.setToolTipText("New Folder");
+ image = mDdmUiLibLoader.loadImage("add.png", mDisplay); //$NON-NLS-1$
+ if (image != null) {
+ createNewFolderAction.item.setImage(image);
+ } else {
+ // this is for debugging purpose when the icon is missing
+ createNewFolderAction.item.setText("New Folder"); //$NON-NLS-1$
+ }
+
// device explorer
mExplorer = new DeviceExplorer();
- mExplorer.setActions(pushAction, pullAction, deleteAction);
+ mExplorer.setActions(pushAction, pullAction, deleteAction, createNewFolderAction);
pullAction.item.addSelectionListener(new SelectionAdapter() {
@Override
});
deleteAction.setEnabled(false);
+ createNewFolderAction.item.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ mExplorer.createNewFolderInSelection();
+ }
+ });
+ createNewFolderAction.setEnabled(false);
+
Composite parent = new Composite(mExplorerShell, SWT.NONE);
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
}
mEmulatorPanel.deviceSelected(mCurrentDevice);
- mLogPanel.deviceSelected(mCurrentDevice);
+ if (useOldLogCatView()) {
+ mLogPanel.deviceSelected(mCurrentDevice);
+ } else {
+ mLogCatPanel.deviceSelected(mCurrentDevice);
+ }
if (mEventLogPanel != null) {
mEventLogPanel.deviceSelected(mCurrentDevice);
}