diff options
4 files changed, 233 insertions, 56 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java index 9e17f0f..e08d7ea 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java @@ -1197,14 +1197,13 @@ public class AdtPlugin extends AbstractUIPlugin implements ILogger { } private void openSdkManager() { - // Windows only: open the standalone external SDK Manager since we know + // Open the standalone external SDK Manager since we know // that ADT on Windows is bound to be locking some SDK folders. - // Also when this is invoked becasue SdkManagerAction.run() fails, this + // + // Also when this is invoked because SdkManagerAction.run() fails, this // test will fail and we'll fallback on using the internal one. - if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { - if (SdkManagerAction.openExternalSdkManager()) { - return; - } + if (SdkManagerAction.openExternalSdkManager()) { + return; } // Otherwise open the regular SDK Manager bundled within ADT diff --git a/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java b/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java index 170603a..88d230f 100644 --- a/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java +++ b/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java @@ -234,7 +234,7 @@ public class MenuBarEnhancerCocoa implements IMenuBarEnhancer { // invoked. // // We don't need to set the target here as the current target is the - // SWTApplicationDelegate and we have registerd the new selectors on + // SWTApplicationDelegate and we have registered the new selectors on // it. So just set the new action to invoke the selector. invoke(nsMenuitemCls, prefMenuItem, "setAction", new Object[] { diff --git a/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java b/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java index 7ca6471..7575ecd 100644 --- a/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java +++ b/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java @@ -26,6 +26,8 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; +import com.android.menubar.IMenuBarEnhancer.MenuBarMode; + /** * On Mac, {@link MenuBarEnhancer#setupMenu} plugs a listener on the About and the @@ -55,7 +57,7 @@ public final class MenuBarEnhancer { * called "Tools". Must not be null. * @param callbacks Callbacks called when "About" and "Preferences" menu items are invoked. * Must not be null. - * @return A actual {@link IMenuBarEnhancer} implementation. Never null. + * @return An actual {@link IMenuBarEnhancer} implementation. Can be null on failure. * This is currently not of any use for the caller but is left in case * we want to expand the functionality later. */ @@ -64,61 +66,80 @@ public final class MenuBarEnhancer { final Menu swtMenu, IMenuBarCallback callbacks) { - IMenuBarEnhancer enhancer = getEnhancer(callbacks); + IMenuBarEnhancer enhancer = getEnhancer(callbacks, swtMenu.getDisplay()); // Default implementation for generic platforms if (enhancer == null) { - enhancer = new IMenuBarEnhancer() { + enhancer = getGenericEnhancer(swtMenu); + } - public MenuBarMode getMenuBarMode() { - return MenuBarMode.GENERIC; + try { + enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks); + } catch (Exception e) { + // If the enhancer failed, try to fall back on the generic one + if (enhancer.getMenuBarMode() != MenuBarMode.GENERIC) { + enhancer = getGenericEnhancer(swtMenu); + try { + enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks); + } catch (Exception e2) { + callbacks.printError("SWTMenuBar failed: %s", e2.toString()); + return null; } + } + } + return enhancer; + } - public void setupMenu( - String appName, - Display display, - final IMenuBarCallback callbacks) { - if (swtMenu.getItemCount() > 0) { - new MenuItem(swtMenu, SWT.SEPARATOR); - } + private static IMenuBarEnhancer getGenericEnhancer(final Menu swtMenu) { + IMenuBarEnhancer enhancer; + enhancer = new IMenuBarEnhancer() { - // Note: we use "Preferences" on Mac and "Options" on Windows/Linux. - final MenuItem pref = new MenuItem(swtMenu, SWT.NONE); - pref.setText("&Options..."); - - final MenuItem about = new MenuItem(swtMenu, SWT.NONE); - about.setText("&About..."); - - pref.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - try { - pref.setEnabled(false); - callbacks.onPreferencesMenuSelected(); - super.widgetSelected(e); - } finally { - pref.setEnabled(true); - } - } - }); - - about.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - try { - about.setEnabled(false); - callbacks.onAboutMenuSelected(); - super.widgetSelected(e); - } finally { - about.setEnabled(true); - } - } - }); + public MenuBarMode getMenuBarMode() { + return MenuBarMode.GENERIC; + } + + public void setupMenu( + String appName, + Display display, + final IMenuBarCallback callbacks) { + if (swtMenu.getItemCount() > 0) { + new MenuItem(swtMenu, SWT.SEPARATOR); } - }; - } - enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks); + // Note: we use "Preferences" on Mac and "Options" on Windows/Linux. + final MenuItem pref = new MenuItem(swtMenu, SWT.NONE); + pref.setText("&Options..."); + + final MenuItem about = new MenuItem(swtMenu, SWT.NONE); + about.setText("&About..."); + + pref.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + try { + pref.setEnabled(false); + callbacks.onPreferencesMenuSelected(); + super.widgetSelected(e); + } finally { + pref.setEnabled(true); + } + } + }); + + about.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + try { + about.setEnabled(false); + callbacks.onAboutMenuSelected(); + super.widgetSelected(e); + } finally { + about.setEnabled(true); + } + } + }); + } + }; return enhancer; } @@ -149,7 +170,7 @@ public final class MenuBarEnhancer { } }; - IMenuBarEnhancer enhancer = getEnhancer(callbacks); + IMenuBarEnhancer enhancer = getEnhancer(callbacks, display); // Default implementation for generic platforms if (enhancer == null) { @@ -187,12 +208,16 @@ public final class MenuBarEnhancer { return enhancer; } - private static IMenuBarEnhancer getEnhancer(IMenuBarCallback callbacks) { + private static IMenuBarEnhancer getEnhancer(IMenuBarCallback callbacks, Display display) { IMenuBarEnhancer enhancer = null; String p = SWT.getPlatform(); String className = null; if ("cocoa".equals(p)) { //$NON-NLS-1$ className = "com.android.menubar.internal.MenuBarEnhancerCocoa"; //$NON-NLS-1$ + + if (SWT.getVersion() >= 3700 && MenuBarEnhancer37.isSupported(display)) { + className = MenuBarEnhancer37.class.getName(); + } } if (System.getenv("DEBUG_SWTMENUBAR") != null) { diff --git a/swtmenubar/src/com/android/menubar/MenuBarEnhancer37.java b/swtmenubar/src/com/android/menubar/MenuBarEnhancer37.java new file mode 100644 index 0000000..8560bfa --- /dev/null +++ b/swtmenubar/src/com/android/menubar/MenuBarEnhancer37.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References: + * Based on the SWT snippet example at + * http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet354.java?view=co + */ + +package com.android.menubar; + + +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +import java.lang.reflect.Method; + +public class MenuBarEnhancer37 implements IMenuBarEnhancer { + + private static final int kAboutMenuItem = -1; // SWT.ID_ABOUT in SWT 3.7 + private static final int kPreferencesMenuItem = -2; // SWT.ID_PREFERENCES in SWT 3.7 + private static final int kQuitMenuItem = -6; // SWT.ID_QUIT in SWT 3.7 + + public MenuBarEnhancer37() { + } + + public MenuBarMode getMenuBarMode() { + return MenuBarMode.MAC_OS; + } + + /** + * Setup the About and Preferences native menut items with the + * given application name and links them to the callback. + * + * @param appName The application name. + * @param display The SWT display. Must not be null. + * @param callbacks The callbacks invoked by the menus. + */ + public void setupMenu( + String appName, + Display display, + IMenuBarCallback callbacks) { + + try { + // Initialize the menuItems. + initialize(display, appName, callbacks); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + // Schedule disposal of callback object + display.disposeExec(new Runnable() { + public void run() { + } + }); + } + + /** + * Checks whether the required SWT 3.7 APIs are available. + * <br/> + * Calling this will load the class, which is OK since this class doesn't + * directly use any SWT 3.7 API -- instead it uses reflection so that the + * code can be loaded under SWT 3.6. + * + * @param display The current SWT display. + * @return True if the SWT 3.7 API are available and this enhancer can be used. + */ + public static boolean isSupported(Display display) { + try { + Object sysMenu = call0(display, "getSystemMenu"); + if (sysMenu instanceof Menu) { + return findMenuById((Menu)sysMenu, kPreferencesMenuItem) != null && + findMenuById((Menu)sysMenu, kAboutMenuItem) != null; + } + } catch (Exception ignore) {} + return false; + } + + private void initialize( + Display display, + String appName, + final IMenuBarCallback callbacks) + throws Exception { + Object sysMenu = call0(display, "getSystemMenu"); + if (sysMenu instanceof Menu) { + MenuItem menu = findMenuById((Menu)sysMenu, kPreferencesMenuItem); + if (menu != null) { + menu.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + callbacks.onPreferencesMenuSelected(); + } + }); + } + + menu = findMenuById((Menu)sysMenu, kAboutMenuItem); + if (menu != null) { + menu.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + callbacks.onAboutMenuSelected(); + } + }); + menu.setText("About " + appName); + } + + menu = findMenuById((Menu)sysMenu, kQuitMenuItem); + if (menu != null) { + // We already support the "quit" operation, no need for an extra handler here. + menu.setText("Quit " + appName); + } + + } + } + + private static Object call0(Object obj, String method) { + try { + Method m = obj.getClass().getMethod(method, (Class<?>[])null); + if (m != null) { + return m.invoke(obj, (Object[])null); + } + } catch (Exception ignore) {} + return null; + } + + private static MenuItem findMenuById(Menu menu, int id) { + MenuItem[] items = menu.getItems(); + for (int i = items.length - 1; i >= 0; i--) { + MenuItem item = items[i]; + Object menuId = call0(item, "getID"); + if (menuId instanceof Integer) { + if (((Integer) menuId).intValue() == id) { + return item; + } + } + } + return null; + } +} |