diff options
Diffstat (limited to 'swtmenubar')
-rw-r--r-- | swtmenubar/.classpath | 2 | ||||
-rwxr-xr-x | swtmenubar/README | 21 | ||||
-rw-r--r-- | swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java | 338 | ||||
-rwxr-xr-x | swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java.txt | 334 | ||||
-rw-r--r-- | swtmenubar/src/com/android/menubar/MenuBarEnhancer.java | 11 |
5 files changed, 363 insertions, 343 deletions
diff --git a/swtmenubar/.classpath b/swtmenubar/.classpath index 827ba88..0f69dc5 100644 --- a/swtmenubar/.classpath +++ b/swtmenubar/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry excluding="org/eclipse/ui/internal/cocoa/CocoaUIEnhancer.java" kind="src" path="src"/> + <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/> <classpathentry kind="output" path="bin"/> diff --git a/swtmenubar/README b/swtmenubar/README index cc9fa61..ba7c25a 100755 --- a/swtmenubar/README +++ b/swtmenubar/README @@ -57,9 +57,24 @@ Then add a variable to the Build Path of the target project: - Select swtmenubar.jar (which you previously built at step 1) -Remember that if you then edit the SwtMenuBar project in Eclipse -you will need to rebuild it using the command-line before the -changes are propagated in the target applications that uses it. +3- Tip for developing this library: + +Keep in mind that src-darwin folder must not be added to the +source folder list, otherwise the library would not compile +on Windows or Linux. + +If you change anything to IMenuBarCallback, make sure to test +on a Mac to be sure you're not breaking the API. + +To work on this on a Mac, you can either: +a- simply temporarily add src-darwin as a source folder to the + build path and remove it before submitting. +b- or directly edit the java files and rebuild the library using + 'make swtmenubar' from a shell. + +To test the library, use 'make swtmenubar'. This will build the +library in out/... and the sdkmanager project is already setup +to find it there. -- EOF diff --git a/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java b/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java new file mode 100644 index 0000000..be23680 --- /dev/null +++ b/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2011 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. + * + * History: + * Original code by the <a href="http://www.simidude.com/blog/2008/macify-a-swt-application-in-a-cross-platform-way/">CarbonUIEnhancer from Agynami</a> + * with the implementation being modified from the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.cocoa/src/org/eclipse/ui/internal/cocoa/CocoaUIEnhancer.java">org.eclipse.ui.internal.cocoa.CocoaUIEnhancer</a>, + * then modified by http://www.transparentech.com/opensource/cocoauienhancer to use reflection + * rather than 'link' to SWT cocoa, and finally modified to be usable by the SwtMenuBar project. + */ + +package com.android.menubar.internal; + +import com.android.menubar.IMenuBarCallback; +import com.android.menubar.IMenuBarEnhancer; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.internal.C; +import org.eclipse.swt.internal.Callback; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class MenuBarEnhancerCocoa implements IMenuBarEnhancer { + + private static final long kAboutMenuItem = 0; + private static final long kPreferencesMenuItem = 2; + // private static final long kServicesMenuItem = 4; + // private static final long kHideApplicationMenuItem = 6; + private static final long kQuitMenuItem = 10; + + static long mSelPreferencesMenuItemSelected; + static long mSelAboutMenuItemSelected; + static Callback mProc3Args; + + private String mAppName; + + /** + * Class invoked via the Callback object to run the about and preferences + * actions. + * <p> + * If you don't use JFace in your application (SWT only), change the + * {@link org.eclipse.jface.action.IAction}s to + * {@link org.eclipse.swt.widgets.Listener}s. + * </p> + */ + private static class ActionProctarget { + private final IMenuBarCallback mCallbacks; + + public ActionProctarget(IMenuBarCallback callbacks) { + mCallbacks = callbacks; + } + + /** + * Will be called on 32bit SWT. + */ + @SuppressWarnings("unused") + public int actionProc(int id, int sel, int arg0) { + return (int) actionProc((long) id, (long) sel, (long) arg0); + } + + /** + * Will be called on 64bit SWT. + */ + public long actionProc(long id, long sel, long arg0) { + if (sel == mSelAboutMenuItemSelected) { + mCallbacks.onAboutMenuSelected(); + } else if (sel == mSelPreferencesMenuItemSelected) { + mCallbacks.onPreferencesMenuSelected(); + } else { + // Unknown selection! + } + // Return value is not used. + return 0; + } + } + + /** + * Construct a new CocoaUIEnhancer. + * + * @param mAppName The name of the application. It will be used to customize + * the About and Quit menu items. If you do not wish to customize + * the About and Quit menu items, just pass <tt>null</tt> here. + */ + public MenuBarEnhancerCocoa() { + } + + /** + * 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 swtMenu The tools menu. Not used here. + * @param callbacks The callbacks invoked by the menus. + */ + public void setupMenu( + String appName, + Menu swtMenu, + IMenuBarCallback callbacks) { + + mAppName = appName; + final Display display = swtMenu.getDisplay(); + + // This is our callback object whose 'actionProc' method will be called + // when the About or Preferences menuItem is invoked. + ActionProctarget target = new ActionProctarget(callbacks); + + try { + // Initialize the menuItems. + initialize(target); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + // Schedule disposal of callback object + display.disposeExec(new Runnable() { + public void run() { + invoke(mProc3Args, "dispose"); + } + }); + } + + private void initialize(Object callbackObject) + throws Exception { + + Class<?> osCls = classForName("org.eclipse.swt.internal.cocoa.OS"); + + // Register names in objective-c. + if (mSelAboutMenuItemSelected == 0) { + mSelPreferencesMenuItemSelected = registerName(osCls, "preferencesMenuItemSelected:"); //$NON-NLS-1$ + mSelAboutMenuItemSelected = registerName(osCls, "aboutMenuItemSelected:"); //$NON-NLS-1$ + } + + // Create an SWT Callback object that will invoke the actionProc method + // of our internal callback Object. + mProc3Args = new Callback(callbackObject, "actionProc", 3); //$NON-NLS-1$ + Method getAddress = Callback.class.getMethod("getAddress", new Class[0]); + Object object = getAddress.invoke(mProc3Args, (Object[]) null); + long proc3 = convertToLong(object); + if (proc3 == 0) { + SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); + } + + Class<?> nsMenuCls = classForName("org.eclipse.swt.internal.cocoa.NSMenu"); + Class<?> nsMenuitemCls = classForName("org.eclipse.swt.internal.cocoa.NSMenuItem"); + Class<?> nsStringCls = classForName("org.eclipse.swt.internal.cocoa.NSString"); + Class<?> nsApplicationCls = classForName("org.eclipse.swt.internal.cocoa.NSApplication"); + + // Instead of creating a new delegate class in objective-c, + // just use the current SWTApplicationDelegate. An instance of this + // is a field of the Cocoa Display object and is already the target + // for the menuItems. So just get this class and add the new methods + // to it. + object = invoke(osCls, "objc_lookUpClass", new Object[] { + "SWTApplicationDelegate" + }); + long cls = convertToLong(object); + + // Add the action callbacks for Preferences and About menu items. + invoke(osCls, "class_addMethod", + new Object[] { + wrapPointer(cls), + wrapPointer(mSelPreferencesMenuItemSelected), + wrapPointer(proc3), "@:@"}); //$NON-NLS-1$ + invoke(osCls, "class_addMethod", + new Object[] { + wrapPointer(cls), + wrapPointer(mSelAboutMenuItemSelected), + wrapPointer(proc3), "@:@"}); //$NON-NLS-1$ + + // Get the Mac OS X Application menu. + Object sharedApplication = invoke(nsApplicationCls, "sharedApplication"); + Object mainMenu = invoke(sharedApplication, "mainMenu"); + Object mainMenuItem = invoke(nsMenuCls, mainMenu, "itemAtIndex", new Object[] { + wrapPointer(0) + }); + Object appMenu = invoke(mainMenuItem, "submenu"); + + // Create the About <application-name> menu command + Object aboutMenuItem = + invoke(nsMenuCls, appMenu, "itemAtIndex", new Object[] { + wrapPointer(kAboutMenuItem) + }); + if (mAppName != null) { + Object nsStr = invoke(nsStringCls, "stringWith", new Object[] { + "About " + mAppName + }); + invoke(nsMenuitemCls, aboutMenuItem, "setTitle", new Object[] { + nsStr + }); + } + // Rename the quit action. + if (mAppName != null) { + Object quitMenuItem = + invoke(nsMenuCls, appMenu, "itemAtIndex", new Object[] { + wrapPointer(kQuitMenuItem) + }); + Object nsStr = invoke(nsStringCls, "stringWith", new Object[] { + "Quit " + mAppName + }); + invoke(nsMenuitemCls, quitMenuItem, "setTitle", new Object[] { + nsStr + }); + } + + // Enable the Preferences menuItem. + Object prefMenuItem = + invoke(nsMenuCls, appMenu, "itemAtIndex", new Object[] { + wrapPointer(kPreferencesMenuItem) + }); + invoke(nsMenuitemCls, prefMenuItem, "setEnabled", new Object[] { + true + }); + + // Set the action to execute when the About or Preferences menuItem is + // 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 + // it. So just set the new action to invoke the selector. + invoke(nsMenuitemCls, prefMenuItem, "setAction", + new Object[] { + wrapPointer(mSelPreferencesMenuItemSelected) + }); + invoke(nsMenuitemCls, aboutMenuItem, "setAction", + new Object[] { + wrapPointer(mSelAboutMenuItemSelected) + }); + } + + private long registerName(Class<?> osCls, String name) + throws IllegalArgumentException, SecurityException, IllegalAccessException, + InvocationTargetException, NoSuchMethodException { + Object object = invoke(osCls, "sel_registerName", new Object[] { + name + }); + return convertToLong(object); + } + + private long convertToLong(Object object) { + if (object instanceof Integer) { + Integer i = (Integer) object; + return i.longValue(); + } + if (object instanceof Long) { + Long l = (Long) object; + return l.longValue(); + } + return 0; + } + + private static Object wrapPointer(long value) { + Class<?> PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class; + if (PTR_CLASS == long.class) { + return new Long(value); + } else { + return new Integer((int) value); + } + } + + private static Object invoke(Class<?> clazz, String methodName, Object[] args) { + return invoke(clazz, null, methodName, args); + } + + private static Object invoke(Class<?> clazz, Object target, String methodName, Object[] args) { + try { + Class<?>[] signature = new Class<?>[args.length]; + for (int i = 0; i < args.length; i++) { + Class<?> thisClass = args[i].getClass(); + if (thisClass == Integer.class) + signature[i] = int.class; + else if (thisClass == Long.class) + signature[i] = long.class; + else if (thisClass == Byte.class) + signature[i] = byte.class; + else if (thisClass == Boolean.class) + signature[i] = boolean.class; + else + signature[i] = thisClass; + } + Method method = clazz.getMethod(methodName, signature); + return method.invoke(target, args); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + private Class<?> classForName(String classname) { + try { + Class<?> cls = Class.forName(classname); + return cls; + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + } + + private Object invoke(Class<?> cls, String methodName) { + return invoke(cls, methodName, (Class<?>[]) null, (Object[]) null); + } + + private Object invoke(Class<?> cls, String methodName, Class<?>[] paramTypes, + Object... arguments) { + try { + Method m = cls.getDeclaredMethod(methodName, paramTypes); + return m.invoke(null, arguments); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + private Object invoke(Object obj, String methodName) { + return invoke(obj, methodName, (Class<?>[]) null, (Object[]) null); + } + + private Object invoke(Object obj, String methodName, Class<?>[] paramTypes, Object... arguments) { + try { + Method m = obj.getClass().getDeclaredMethod(methodName, paramTypes); + return m.invoke(obj, arguments); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } +} diff --git a/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java.txt b/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java.txt deleted file mode 100755 index 591f253..0000000 --- a/swtmenubar/src-darwin/com/android/menubar/internal/MenuBarEnhancerCocoa.java.txt +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -package com.android.menubar.internal; - -import com.android.menubar.IMenuBarCallback; -import com.android.menubar.IMenuBarEnhancer; -import com.android.menubar.MenuBarEnhancer; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.internal.C; -import org.eclipse.swt.internal.Callback; -import org.eclipse.swt.internal.cocoa.NSApplication; -import org.eclipse.swt.internal.cocoa.NSMenu; -import org.eclipse.swt.internal.cocoa.NSMenuItem; -import org.eclipse.swt.internal.cocoa.NSObject; -import org.eclipse.swt.internal.cocoa.OS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - - -/** - * Implementation of IMenuBarEnhancer for MacOS Cocoa SWT - * <p/> - * Note: this is currently deactivated since we are not currently - * shipping a version of SWT.jar that has cocoa support (only carbon). - */ -public final class MenuBarEnhancerCocoa implements IMenuBarEnhancer { - - private static final int kAboutMenuItem = 0; - private static final int kPreferencesMenuItem = 2; - private static final int kServicesMenuItem = 4; - private static final int kHideApplicationMenuItem = 6; - private static final int kQuitMenuItem = 10; - - private EnhancerDelegate mDelegate; - private long mDelegateJniRef; - private IMenuBarCallback mCallbacks; - - public static class EnhancerDelegate extends NSObject { - public EnhancerDelegate() { - super(); - } - public EnhancerDelegate(int id) { - super(id); - } - - } - static long sel_preferencesMenuItemSelected_; - static long sel_aboutMenuItemSelected_; - - /* This callback is not freed */ - static Callback proc3Args; - static final byte[] SWT_OBJECT = { 'S', 'W', 'T', '_', 'O', 'B', 'J', 'E', 'C', 'T', '\0' }; - - public MenuBarEnhancerCocoa() { - } - - public void setupMenu( - String appName, - Menu swtMenu, - IMenuBarCallback callbacks) { - mCallbacks = callbacks; - final Display display = swtMenu.getDisplay(); - - init1(); - - try { - mDelegate = new EnhancerDelegate(); - mDelegate.alloc().init(); - //call OS.NewGlobalRef - Method method = OS.class.getMethod("NewGlobalRef", new Class[] { Object.class }); - Object object = method.invoke(OS.class, new Object[] { this }); - mDelegateJniRef = convertToLong(object); - } catch (Exception e) { - // theoretically, one of SecurityException, Illegal*Exception, - // InvocationTargetException, NoSuch*Exception - // not expected to happen at all. - log(e); - } - - if (mDelegateJniRef == 0) { - SWT.error(SWT.ERROR_NO_HANDLES); - } - - try { - Field idField = EnhancerDelegate.class.getField("id"); - Object idValue = idField.get(mDelegate); - invokeMethod(OS.class, "object_setInstanceVariable", - new Object[] { idValue, SWT_OBJECT, wrapPointer(mDelegateJniRef) }); - - hookApplicationMenu(appName); - - // schedule disposal of callback object - display.disposeExec(new Runnable() { - public void run() { - if (mDelegateJniRef != 0) { - try { - invokeMethod(OS.class, "DeleteGlobalRef", new Object[] { wrapPointer(mDelegateJniRef) }); - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - mDelegateJniRef = 0; - - if (mDelegate != null) { - mDelegate.release(); - mDelegate = null; - } - } - }); - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - - private long registerName(String name) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - Class clazz = OS.class; - Object object = invokeMethod(clazz, "sel_registerName", new Object[] {name}); - return convertToLong(object); - } - - private void init1() { - try { - if (sel_aboutMenuItemSelected_ == 0) { - sel_preferencesMenuItemSelected_ = registerName("preferencesMenuItemSelected:"); //$NON-NLS-1$ - sel_aboutMenuItemSelected_ = registerName("aboutMenuItemSelected:"); //$NON-NLS-1$ - init2(); - } - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - - private void init2() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { - // TODO: These should either move out of Display or be accessible to this class. - byte[] types = {'*','\0'}; - int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF == 4 ? 2 : 3; - - Class clazz = this.getClass(); - - proc3Args = new Callback(clazz, "actionProc", 3); //$NON-NLS-1$ - //call getAddress - Method getAddress = Callback.class.getMethod("getAddress", new Class[0]); //$NON-NLS-1$ - Object object = getAddress.invoke(proc3Args, null); - long proc3 = convertToLong(object); - if (proc3 == 0) { - SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); - } - - //call objc_allocateClassPair - Field field = OS.class.getField("class_NSObject"); //$NON-NLS-1$ - Object fieldObj = field.get(OS.class); - object = invokeMethod(OS.class, "objc_allocateClassPair", //$NON-NLS-1$ - new Object[] { fieldObj, "SWTCocoaEnhancerDelegate", wrapPointer(0) }); //$NON-NLS-1$ - long cls = convertToLong(object); - - invokeMethod(OS.class, "class_addIvar", new Object[] { //$NON-NLS-1$ - wrapPointer(cls), SWT_OBJECT, wrapPointer(size), - new Byte((byte) align), types }); - - // Add the action callback - invokeMethod(OS.class, "class_addMethod", new Object[] { //$NON-NLS-1$ - wrapPointer(cls), - wrapPointer(sel_preferencesMenuItemSelected_), - wrapPointer(proc3), "@:@" }); //$NON-NLS-1$ - invokeMethod(OS.class, "class_addMethod", new Object[] { //$NON-NLS-1$ - wrapPointer(cls), - wrapPointer(sel_aboutMenuItemSelected_), - wrapPointer(proc3), "@:@" }); //$NON-NLS-1$ - - invokeMethod(OS.class, "objc_registerClassPair", //$NON-NLS-1$ - new Object[] { wrapPointer(cls) }); - } - - private void log(Exception e) { - mCallbacks.printError("%1$s: %2$s", getClass().getSimpleName(), e.toString()); //$NON-NLS-1$ - } - - private void hookApplicationMenu(String appName) { - try { - // create About Eclipse menu command - NSMenu mainMenu = NSApplication.sharedApplication().mainMenu(); - NSMenuItem mainMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, mainMenu, - "itemAtIndex", new Object[] {wrapPointer(0)}); //$NON-NLS-1$ - NSMenu appMenu = mainMenuItem.submenu(); - - // add the about action - NSMenuItem aboutMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, - "itemAtIndex", new Object[] {wrapPointer(kAboutMenuItem)}); - aboutMenuItem.setTitle(NSString.stringWith("About " + appName)); //$NON-NLS-1$ - - // enable pref menu - NSMenuItem prefMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, - "itemAtIndex", new Object[] {wrapPointer(kPreferencesMenuItem)}); //$NON-NLS-1$ - prefMenuItem.setEnabled(true); - - // disable services menu - NSMenuItem servicesMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, - "itemAtIndex", new Object[] {wrapPointer(kServicesMenuItem)}); //$NON-NLS-1$ - servicesMenuItem.setEnabled(false); - - // Register as a target on the prefs and quit items. - prefMenuItem.setTarget(mDelegate); - invokeMethod(NSMenuItem.class, prefMenuItem, - "setAction", new Object[] {wrapPointer(sel_preferencesMenuItemSelected_)}); //$NON-NLS-1$ - aboutMenuItem.setTarget(mDelegate); - invokeMethod(NSMenuItem.class, aboutMenuItem, - "setAction", new Object[] {wrapPointer(sel_aboutMenuItemSelected_)}); //$NON-NLS-1$ - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - - void preferencesMenuItemSelected() { - try { - NSMenu mainMenu = NSApplication.sharedApplication().mainMenu(); - NSMenuItem mainMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, mainMenu, - "itemAtIndex", new Object[] {wrapPointer(0)}); //$NON-NLS-1$ - NSMenu appMenu = mainMenuItem.submenu(); - NSMenuItem prefMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "" + //$NON-NLS-1$ - "itemAtIndex", new Object[] {wrapPointer(kPreferencesMenuItem)}); //$NON-NLS-1$ - try { - prefMenuItem.setEnabled(false); - - mCallbacks.onPreferencesMenuSelected(); - } - finally { - prefMenuItem.setEnabled(true); - } - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - - void aboutMenuItemSelected() { - try { - NSMenu mainMenu = NSApplication.sharedApplication().mainMenu(); - NSMenuItem mainMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, mainMenu, - "itemAtIndex", new Object[] {wrapPointer(0)}); //$NON-NLS-1$ - NSMenu appMenu = mainMenuItem.submenu(); - NSMenuItem aboutMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, - "itemAtIndex", new Object[] {wrapPointer(kAboutMenuItem)}); //$NON-NLS-1$ - try { - aboutMenuItem.setEnabled(false); - - mCallbacks.onAboutMenuSelected(); - } - finally { - aboutMenuItem.setEnabled(true); - } - } catch (Exception e) { - // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception - // not expected to happen at all. - log(e); - } - } - - private long convertToLong(Object object) { - if (object instanceof Integer) { - Integer i = (Integer) object; - return i.longValue(); - } - if (object instanceof Long) { - Long l = (Long) object; - return l.longValue(); - } - return 0; - } - - private static Object invokeMethod(Class clazz, String methodName, - Object[] args) throws IllegalArgumentException, - IllegalAccessException, InvocationTargetException, - SecurityException, NoSuchMethodException { - return invokeMethod(clazz, null, methodName, args); - } - - private static Object invokeMethod(Class clazz, Object target, - String methodName, Object[] args) throws IllegalArgumentException, - IllegalAccessException, InvocationTargetException, - SecurityException, NoSuchMethodException { - Class[] signature = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - Class thisClass = args[i].getClass(); - if (thisClass == Integer.class) { - signature[i] = int.class; - } else if (thisClass == Long.class) { - signature[i] = long.class; - } else if (thisClass == Byte.class) { - signature[i] = byte.class; - } else { - signature[i] = thisClass; - } - } - Method method = clazz.getMethod(methodName, signature); - return method.invoke(target, args); - } - - private static Object wrapPointer(long value) { - Class PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class; - if (PTR_CLASS == long.class) { - return new Long(value); - } else { - return new Integer((int)value); - } - } -} diff --git a/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java b/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java index e40fbe0..dba4f32 100644 --- a/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java +++ b/swtmenubar/src/com/android/menubar/MenuBarEnhancer.java @@ -66,15 +66,16 @@ public final class MenuBarEnhancer { if ("carbon".equals(p)) { //$NON-NLS-1$ className = "com.android.menubar.internal.MenuBarEnhancerCarbon"; //$NON-NLS-1$ } else if ("cocoa".equals(p)) { //$NON-NLS-1$ - // Note: we have a Cocoa implementation that is currently disabled - // since the SWT.jar that we use only contain Carbon implementations. - // - // className = "com.android.menubar.internal.MenuBarEnhancerCocoa"; //$NON-NLS-1$ + className = "com.android.menubar.internal.MenuBarEnhancerCocoa"; //$NON-NLS-1$ + } + + if (System.getenv("DEBUG_SWTMENUBAR") != null) { + callbacks.printError("DEBUG SwtMenuBar: SWT=%1$s, class=%2$s", p, className); } if (className != null) { try { - Class<?> clazz = p.getClass().forName(className); + Class<?> clazz = Class.forName(className); enhancer = (IMenuBarEnhancer) clazz.newInstance(); } catch (Exception e) { // Log an error and fallback on the default implementation. |