[jbosstools-commits] JBoss Tools SVN: r41634 - in trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim: util and 1 other directory.

jbosstools-commits at lists.jboss.org jbosstools-commits at lists.jboss.org
Fri Jun 1 10:32:34 EDT 2012


Author: yradtsevich
Date: 2012-06-01 10:32:33 -0400 (Fri, 01 Jun 2012)
New Revision: 41634

Added:
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/util/ManifestUtil.java
Modified:
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/Messages.java
   trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/messages.properties
Log:
https://issues.jboss.org/browse/JBIDE-11048 : BrowserSim: wrong application name in the Mac OS X menu-bar: 'SWT' instead of 'BrowserSim'
- applied patch created by Ilya Buziuk with some minor changes

Modified: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java	2012-06-01 14:30:30 UTC (rev 41633)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -15,6 +15,7 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.text.MessageFormat;
 import java.util.List;
 import java.util.Observable;
 import java.util.Observer;
@@ -44,6 +45,8 @@
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.program.Program;
 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 org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Monitor;
@@ -59,14 +62,17 @@
 import org.jboss.tools.vpe.browsersim.model.SkinMap;
 import org.jboss.tools.vpe.browsersim.ui.skin.BrowserSimSkin;
 import org.jboss.tools.vpe.browsersim.ui.skin.ResizableSkinSizeAdvisor;
+import org.jboss.tools.vpe.browsersim.util.ManifestUtil;
 import org.jboss.tools.vpe.browsersim.util.ResourcesUtil;
 
 /**
  * @author Yahor Radtsevich (yradtsevich)
  */
 public class BrowserSim {
+	public static final String BROWSERSIM_PLUGIN_ID = "org.jboss.tools.vpe.browsersim"; //$NON-NLS-1$
 	private static final String DEFAULT_URL = "about:blank"; //"http://www.w3schools.com/js/tryit_view.asp?filename=try_nav_useragent"; //$NON-NLS-1$
 	private static final String[] BROWSERSIM_ICONS = {"icons/browsersim_16px.png", "icons/browsersim_32px.png", "icons/browsersim_64px.png", "icons/browsersim_128px.png", "icons/browsersim_256px.png", }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$
+	private static int BROWSERSIM_ICON_32PX_INDEX = 2;
 	private static final String BROWSERSIM_CLASS_NAME = "org.jboss.tools.vpe.browsersim.ui.BrowserSim"; //$NON-NLS-1$
 	/** @see org.jboss.tools.vpe.browsersim.eclipse.callbacks.OpenFileCallback */
 	private static final String OPEN_FILE_COMMAND = BROWSERSIM_CLASS_NAME + ".command.openFile:"; //$NON-NLS-1$
@@ -83,10 +89,6 @@
 	private ResizableSkinSizeAdvisor sizeAdvisor;
 
 	public static void main(String[] args) {
-		if (PlatformUtil.OS_MACOSX.equals(PlatformUtil.getOs())) {
-			// set application name for Mac OS X menu-bar https://issues.jboss.org/browse/JBIDE-11048
-			System.setProperty("com.apple.mrj.application.apple.menu.about.name", Messages.BrowserSim_BROWSER_SIM);//$NON-NLS-1$
-		}
 		String homeUrl;
 		if (args.length > 0) {
 			String lastArg = args[args.length - 1];
@@ -99,8 +101,8 @@
 		} else {
 			homeUrl = DEFAULT_URL;
 		}
-
 		
+		
 		DevicesList devicesList = DevicesListStorage.loadUserDefinedDevicesList();
 		if (devicesList == null) {
 			devicesList = DevicesListStorage.loadDefaultDevicesList();
@@ -114,6 +116,13 @@
 		browserSim.devicesListHolder.notifyObservers();
 		browserSim.controlHandler.goHome();
 		
+
+		// set event handlers for Mac OS X Menu-bar
+		if (PlatformUtil.OS_MACOSX.equals(PlatformUtil.getOs())) {
+			browserSim.addMacOsMenuApplicationHandler();
+		}
+
+
 		while (browserSim.skin!= null && browserSim.skin.getShell() != null && !browserSim.skin.getShell().isDisposed()) {//XXX
 			if (!display.readAndDispatch())
 				display.sleep();
@@ -131,6 +140,7 @@
 			String iconLocation = BROWSERSIM_ICONS[i];
 			icons[i] = new Image(display, ResourcesUtil.getResourceAsStream(iconLocation));
 		}
+		
 	}
 	
 	private void dispose() {
@@ -306,10 +316,20 @@
 				}
 				
 				addDevicesMenuItems(contextMenu);
+				addUseSkinsItem(contextMenu);
+				addPreferencesItem(contextMenu);
+					
 				new MenuItem(contextMenu, SWT.BAR);
 				addTurnMenuItems(contextMenu);
+
 				new MenuItem(contextMenu, SWT.BAR);
 				addFileMenuItems(contextMenu);
+				
+				new MenuItem(contextMenu, SWT.BAR);
+				addAboutItem(contextMenu);
+				
+				new MenuItem(contextMenu, SWT.BAR);
+				addExitItem(contextMenu);
 			}
 		});
 	}
@@ -318,6 +338,11 @@
 		Menu file = createDropDownMenu(appMenuBar, Messages.BrowserSim_FILE);
 		addFileMenuItems(file);
 		
+		// If Platform is Mac OS X, application will have no duplicated menu items (Exit/Quit BrowserSim)
+		if (!PlatformUtil.OS_MACOSX.equals(PlatformUtil.getOs())) {
+			addExitItem(file);
+		}
+		
 		Menu devicesMenu = createDropDownMenu(appMenuBar, Messages.BrowserSim_DEVICES);
 		devicesMenu.addMenuListener(new MenuAdapter() {
 			public void menuShown(MenuEvent e) {
@@ -325,53 +350,34 @@
 				for (MenuItem item : devicesMenu.getItems()) {
 					item.dispose();
 				}
+				
 				addDevicesMenuItems(devicesMenu);
+				addUseSkinsItem(devicesMenu);
+				
+				// If Platform is Mac OS X, application will have no duplicated menu items (Preferences)
+				if (!PlatformUtil.OS_MACOSX.equals(PlatformUtil.getOs())) {
+					addPreferencesItem(devicesMenu);
+				}
+
 				new MenuItem(devicesMenu, SWT.BAR);
 				addTurnMenuItems(devicesMenu);
 			}
 		});
+		
+		// If Platform is Mac OS X, application will have no duplicated menu items (About) 
+		if (!PlatformUtil.OS_MACOSX.equals(PlatformUtil.getOs())) {
+			Menu help = createDropDownMenu(appMenuBar, Messages.BrowserSim_HELP);
+			addAboutItem(help);
+		}
 	}
 
 	private void addDevicesMenuItems(final Menu devicesMenu) {
 		addDevicesListForMenu(devicesListHolder.getDevicesList(), devicesMenu);
-		
-		MenuItem manageDevicesMenuItem = new MenuItem(devicesMenu, SWT.PUSH);
-		manageDevicesMenuItem.setText(Messages.BrowserSim_PREFERENCES);
-		manageDevicesMenuItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				DevicesList newDevicesList = new ManageDevicesDialog(e.display.getActiveShell(), SWT.APPLICATION_MODAL | SWT.SHELL_TRIM,
-						devicesListHolder.getDevicesList()).open();
-				if (newDevicesList != null) {
-					devicesListHolder.setDevicesList(newDevicesList);
-					devicesListHolder.notifyObservers();
-				}
-			}
-		});
-		
-		MenuItem useSkinsMenuItem = new MenuItem(devicesMenu, SWT.CHECK);
-		useSkinsMenuItem.setText(Messages.BrowserSim_USE_SKINS);
-		useSkinsMenuItem.setSelection(devicesListHolder.getDevicesList().getUseSkins());
-		useSkinsMenuItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				MenuItem menuItem = (MenuItem) e.widget; 
-				DevicesList devicesList = devicesListHolder.getDevicesList();
-				devicesList.setUseSkins(menuItem.getSelection());
-				devicesList.notifyObservers();
-			}
-		});
 	}
 
 	private void addFileMenuItems(Menu menu) {
 		addOpenInDefaultBrowserItem(menu);
 		addViewSourceItem(menu);
-		
-		MenuItem exit = new MenuItem(menu, SWT.PUSH);
-		exit.setText(Messages.BrowserSim_EXIT);
-		exit.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				display.dispose();
-			};
-		});
 	}
 	
 	private void addTurnMenuItems(Menu menu) {
@@ -432,7 +438,60 @@
 			}
 		});
 	}
+	
+	public void addAboutItem(Menu menu) {
+		MenuItem about = new MenuItem(menu, SWT.PUSH);
+		about.setText(Messages.BrowserSim_ABOUT);
+		about.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				showAboutDialog(e.display.getActiveShell());
+			}
 
+		});
+	}
+	
+	public void addPreferencesItem(Menu menu){
+		MenuItem preferences = new MenuItem(menu, SWT.PUSH);
+		preferences.setText(Messages.BrowserSim_PREFERENCES);
+		preferences.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				DevicesList newDevicesList = new ManageDevicesDialog(e.display.getActiveShell(),
+						SWT.APPLICATION_MODAL | SWT.SHELL_TRIM,
+						devicesListHolder.getDevicesList()).open();
+				if (newDevicesList != null) {
+					devicesListHolder.setDevicesList(newDevicesList);
+					devicesListHolder.notifyObservers();
+				}
+		
+			}
+		});
+	}
+	
+	public void addUseSkinsItem(Menu menu){
+		MenuItem useSkinsMenuItem = new MenuItem(menu, SWT.CHECK);
+		useSkinsMenuItem.setText(Messages.BrowserSim_USE_SKINS);
+		useSkinsMenuItem.setSelection(devicesListHolder.getDevicesList().getUseSkins());
+		useSkinsMenuItem.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				MenuItem menuItem = (MenuItem) e.widget; 
+				DevicesList devicesList = devicesListHolder.getDevicesList();
+				devicesList.setUseSkins(menuItem.getSelection());
+				devicesList.notifyObservers();
+			}
+		});
+		
+	}
+	
+	public void addExitItem(Menu menu){
+		MenuItem exit = new MenuItem(menu, SWT.PUSH);
+		exit.setText(Messages.BrowserSim_EXIT);
+		exit.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				display.dispose();
+			};
+		});	
+	}
+
 	private void addDevicesListForMenu(final DevicesList devicesList, Menu devicesMenu) {
 		List<Device> devices = devicesList.getDevices();
 		for (int i = 0; i < devices.size(); i++) {
@@ -655,6 +714,21 @@
 		}
 	}
 	
+	public void showAboutDialog(Shell shell){
+		String message;
+		String version = ManifestUtil.getManifestVersion();
+		if (version != null) {
+			message = MessageFormat.format(Messages.BrowserSim_ABOUT_MESSAGE,ManifestUtil.getManifestVersion());
+		} else {
+			message = MessageFormat.format(Messages.BrowserSim_ABOUT_MESSAGE, ""); //$NON-NLS-1$
+		}
+		new MessageBoxWithLinks(shell,
+				message,
+				icons[BROWSERSIM_ICON_32PX_INDEX],
+				Messages.BrowserSim_ABOUT).open();	
+    }
+	
+	
 	private ResizableSkinSizeAdvisor getSizeAdvisor() {
 		if (sizeAdvisor == null) {
 			sizeAdvisor = new ResizableSkinSizeAdvisor() {
@@ -696,4 +770,57 @@
 		
 		return sizeAdvisor;
 	}
+	
+	/**
+	 * @return skin shell instance or new shell if there are no skin shell. Never returns {@code null}
+	 */
+	private Shell getParentShell() {
+		Shell shell;
+		if (skin != null && skin.getShell() != null) {
+			shell = skin.getShell();
+		} else {
+			shell = new Shell();
+		}
+		return shell;
+	}
+
+	
+	private void addMacOsMenuApplicationHandler() {
+		CocoaUIEnhancer enhancer = new CocoaUIEnhancer(Messages.BrowserSim_BROWSER_SIM);
+		
+		Listener quitListener = new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				// Quit Listener has no implementation, cause quit event is handled by  controlHandler, 
+				// but it must be in CocoaUIEnchancer released by EPL  
+			}
+		};
+		
+		Runnable macAboutAction = new Runnable() {
+			@Override
+			public void run() {
+				Shell shell = getParentShell();
+				
+				showAboutDialog(shell);
+			}
+		};
+
+		Runnable macPreferencesAction = new Runnable() {
+			@Override
+			public void run() {
+				Shell shell = getParentShell();
+
+				DevicesList newDevicesList = new ManageDevicesDialog(shell,
+						SWT.APPLICATION_MODAL | SWT.SHELL_TRIM,
+						devicesListHolder.getDevicesList()).open();
+				if (newDevicesList != null) {
+					devicesListHolder.setDevicesList(newDevicesList);
+					devicesListHolder.notifyObservers();
+				}
+
+			}
+		};
+        
+		enhancer.hookApplicationMenu(display, quitListener, macAboutAction, macPreferencesAction);
+	}
 }

Added: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java	                        (rev 0)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -0,0 +1,289 @@
+package org.jboss.tools.vpe.browsersim.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+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.Listener;
+
+/**
+ * Provide a hook to connecting the Preferences, About and Quit menu items of the Mac OS X
+ * Application menu when using the SWT Cocoa bindings.
+ * <p>
+ * This code does not require the Cocoa SWT JAR in order to be compiled as it uses reflection to
+ * access the Cocoa specific API methods. It does, however, depend on JFace (for IAction), but you
+ * could easily modify the code to use SWT Listeners instead in order to use this class in SWT only
+ * applications.
+ * </p>
+ * <p>
+ * This code was influenced 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>.
+ * </p>
+ */
+public class CocoaUIEnhancer {
+
+    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;
+
+    static long sel_toolbarButtonClicked_;
+    static long sel_preferencesMenuItemSelected_;
+    static long sel_aboutMenuItemSelected_;
+
+    static Callback proc3Args;
+
+    final private String appName;
+
+    /**
+     * Construct a new CocoaUIEnhancer.
+     * 
+     * @param appName
+     *            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 CocoaUIEnhancer( String appName ) {
+        this.appName = appName;
+    }
+
+    /**
+     * Hook the given Listener to the Mac OS X application Quit menu and the IActions to the About
+     * and Preferences menus.
+     * 
+     * @param display
+     *            The Display to use.
+     * @param quitListener
+     *            The listener to invoke when the Quit menu is invoked.
+     * @param aboutAction
+     *            The action to run when the About menu is invoked.
+     * @param preferencesAction
+     *            The action to run when the Preferences menu is invoked.
+     */
+    public void hookApplicationMenu( Display display, Listener quitListener, final Runnable aboutAction,
+                                     final Runnable preferencesAction ) {
+        // This is our callbackObject whose 'actionProc' method will be called when the About or
+        // Preferences menuItem is invoked.
+        //
+        // Connect the given IAction objects to the actionProce method.
+        //
+        Object target = new Object() {
+            @SuppressWarnings( "unused" )
+            int actionProc( int id, int sel, int arg0 ) {
+                if ( sel == sel_aboutMenuItemSelected_ ) {
+                    aboutAction.run();
+                } else if ( sel == sel_preferencesMenuItemSelected_ ) {
+                    preferencesAction.run();
+                } else {
+                    // Unknown selection!
+                }
+                // Return value is not used.
+                return 99;
+            }
+        };
+
+        try {
+            // Initialize the menuItems.
+            initialize( target );
+        } catch ( Exception e ) {
+            throw new IllegalStateException( e );
+        }
+
+        // Connect the quit/exit menu.
+        if ( !display.isDisposed() ) {
+//            display.addListener( SWT.Close, quitListener );
+        }
+
+        // Schedule disposal of callback object
+        display.disposeExec( new Runnable() {
+            public void run() {
+                invoke( proc3Args, "dispose" );
+            }
+        } );
+    }
+
+    private void initialize( Object callbackObject )
+            throws Exception {
+
+        Class<?> osCls = classForName( "org.eclipse.swt.internal.cocoa.OS" );
+        
+        // Register names in objective-c.
+        if ( sel_toolbarButtonClicked_ == 0 ) {
+            // sel_toolbarButtonClicked_ = registerName( osCls, "toolbarButtonClicked:" ); //$NON-NLS-1$
+            sel_preferencesMenuItemSelected_ = registerName( osCls, "preferencesMenuItemSelected:" ); //$NON-NLS-1$
+            sel_aboutMenuItemSelected_ = registerName( osCls, "aboutMenuItemSelected:" ); //$NON-NLS-1$
+        }
+
+        // Create an SWT Callback object that will invoke the actionProc method of our internal
+        // callbackObject.
+        proc3Args = new Callback( callbackObject, "actionProc", 3 ); //$NON-NLS-1$
+        Method getAddress = Callback.class.getMethod( "getAddress", new Class[0] );
+        Object object = getAddress.invoke( proc3Args, (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( sel_preferencesMenuItemSelected_ ),
+                                                        wrapPointer( proc3 ),
+                                                        "@:@" } ); //$NON-NLS-1$
+        invoke( osCls, "class_addMethod", new Object[] {
+                                                        wrapPointer( cls ),
+                                                        wrapPointer( sel_aboutMenuItemSelected_ ),
+                                                        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 ) } );
+        
+        /*  yradtsevich: The following lines in the original source are
+         *  replaced by the call of System.getProperty, which does the same job.
+         *  See https://issues.jboss.org/browse/JBIDE-11048 */
+        System.setProperty("com.apple.mrj.application.apple.menu.about.name", appName);//$NON-NLS-1$
+//        if ( appName != null ) {
+//            Object nsStr = invoke( nsstringCls, "stringWith", new Object[] { "About " + appName } );
+//            invoke( nsmenuitemCls, aboutMenuItem, "setTitle", new Object[] { nsStr } );
+//        }
+//        // Rename the quit action.
+//        if ( appName != null ) {
+//            Object quitMenuItem =
+//                invoke( nsmenuCls, appMenu, "itemAtIndex", new Object[] { wrapPointer( kQuitMenuItem ) } );
+//            Object nsStr = invoke( nsstringCls, "stringWith", new Object[] { "Quit " + appName } );
+//            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( sel_preferencesMenuItemSelected_ ) } );
+        invoke( nsmenuitemCls, aboutMenuItem, "setAction",
+                new Object[] { wrapPointer( sel_aboutMenuItemSelected_ ) } );
+    }
+
+    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 );
+        }
+    }
+}

Modified: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java	2012-06-01 14:30:30 UTC (rev 41633)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -14,14 +14,6 @@
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTError;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.program.Program;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.MessageBox;
 import org.eclipse.swt.widgets.Shell;
 import org.jboss.tools.vpe.browsersim.browser.PlatformUtil;
@@ -50,70 +42,25 @@
 		}
 		showErrorMessageWithLinks(parentShell, message);
 	}
-	
+
 	public static void showErrorMessage(Shell shell, String message) {
 		System.err.println(message);
-		
+
 		MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
 		messageBox.setText(Messages.BrowserSim_ERROR);
 		messageBox.setMessage(message);
 		messageBox.open();
 	}
-	
+
 	public static void showErrorMessageWithLinks(Shell shell, String message) {
 		System.err.println(message);
-		
-		ErrorMessageBoxWithLinks messageBox = new ErrorMessageBoxWithLinks(shell);
-		messageBox.setText(Messages.BrowserSim_ERROR);
-		messageBox.setMessage(message);
+
+		MessageBoxWithLinks messageBox = new MessageBoxWithLinks(shell,
+				message, shell.getDisplay().getSystemImage(SWT.ICON_ERROR),
+				Messages.BrowserSim_ERROR);
 		messageBox.open();
 	}
 }
 
 
-/**
- * Behaves like MessageBox with styles SWT.OK and SWT.ICON_ERROR, but allows HTML links is messages. 
- * @author Yahor Radtsevich (yradtsevich)
- *
- */
-class ErrorMessageBoxWithLinks extends CustomMessageBox {
 
-	private String message;
-
-	public ErrorMessageBoxWithLinks(Shell parent) {
-		super(parent, parent.getDisplay().getSystemImage(SWT.ICON_ERROR));
-		message = ""; //$NON-NLS-1$
-	}
-
-	@Override
-	protected void createWidgets() {
-		super.createWidgets();
-				
-		Link link = new Link(getMessageComposite(), SWT.WRAP);
-		link.setText(message);
-		link.setBackground(getMessageCompositeBackground());
-		link.addListener (SWT.Selection, new Listener () {
-			public void handleEvent(Event event) {
-				Program.launch(event.text);
-			}
-		});
-		
-		Button ok = new Button(getButtonsComposite(), SWT.PUSH);
-		ok.setText(Messages.ExceptionNotifier_OK);
-		ok.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				getShell().close();
-			}
-		});
-		GridData okLayoutData = new GridData(SWT.END, SWT.CENTER, true, true);
-		okLayoutData.widthHint = 88;
-		ok.setLayoutData(okLayoutData);
-		getShell().setDefaultButton(ok);
-		getShell().pack();
-	}
-
-	public void setMessage(String message) {
-		this.message = message;
-	}
-}

Added: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java	                        (rev 0)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2012 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributor:
+ *     Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.vpe.browsersim.ui;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Behaves like MessageBox with styles SWT.OK and SWT.ICON_ERROR, but allows
+ * HTML links is messages.
+ * 
+ * @author Yahor Radtsevich (yradtsevich)
+ */
+public class MessageBoxWithLinks extends CustomMessageBox {
+	private String message;
+	private String header;
+
+	public MessageBoxWithLinks(Shell parent, String message, Image icon,
+			String header) {
+		super(parent, icon);
+		this.message = message;
+		this.header = header;
+	}
+
+	@Override
+	protected void createWidgets() {
+		super.createWidgets();
+		Link link = new Link(getMessageComposite(), SWT.WRAP);
+		link.setText(message);
+		link.setBackground(getMessageCompositeBackground());
+		link.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				Program.launch(event.text);
+			}
+		});
+		Button ok = new Button(getButtonsComposite(), SWT.PUSH);
+		ok.setText(Messages.ExceptionNotifier_OK);
+		ok.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				getShell().close();
+			}
+		});
+		GridData okLayoutData = new GridData(SWT.END, SWT.CENTER, true, true);
+		okLayoutData.widthHint = 88;
+		ok.setLayoutData(okLayoutData);
+		getShell().setText(header);
+		getShell().setDefaultButton(ok);
+		getShell().pack();
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public void setHeader(String header) {
+		this.header = header;
+	}
+}

Modified: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/Messages.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/Messages.java	2012-06-01 14:30:30 UTC (rev 41633)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/Messages.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -19,6 +19,8 @@
 	private static final String BUNDLE_NAME = Messages.class.getName().toString().toLowerCase();
 
 	
+	public static String BrowserSim_ABOUT;
+	public static String BrowserSim_ABOUT_MESSAGE;
 	public static String BrowserSim_ADDRESS;
 	public static String BrowserSim_BROWSER_SIM;
 	public static String BrowserSim_COULD_NOT_OPEN_DEFAULT_BROWSER;
@@ -26,6 +28,7 @@
 	public static String BrowserSim_ERROR;
 	public static String BrowserSim_EXIT;
 	public static String BrowserSim_FILE;
+	public static String BrowserSim_HELP;
 	public static String BrowserSim_OPEN_IN_DEFAULT_BROWSER;
 	public static String BrowserSim_PREFERENCES;
 	public static String BrowserSim_TURN_LEFT;

Modified: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/messages.properties
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/messages.properties	2012-06-01 14:30:30 UTC (rev 41633)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/ui/messages.properties	2012-06-01 14:32:33 UTC (rev 41634)
@@ -1,3 +1,5 @@
+BrowserSim_ABOUT=About
+BrowserSim_ABOUT_MESSAGE=BrowserSim\n\Version: {0}\n\This application is a part of <a href="https\://jboss.org/tools">JBoss Tools</a>.  
 BrowserSim_ADDRESS=Address
 BrowserSim_BROWSER_SIM=BrowserSim
 BrowserSim_COULD_NOT_OPEN_DEFAULT_BROWSER=Could not open default browser: 
@@ -5,6 +7,7 @@
 BrowserSim_ERROR=Error
 BrowserSim_EXIT=Exit
 BrowserSim_FILE=File
+BrowserSim_HELP=Help
 BrowserSim_PREFERENCES=Preferences...
 BrowserSim_OPEN_IN_DEFAULT_BROWSER=Open in default browser
 BrowserSim_TURN_LEFT=Turn Left

Added: trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/util/ManifestUtil.java
===================================================================
--- trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/util/ManifestUtil.java	                        (rev 0)
+++ trunk/vpe/plugins/org.jboss.tools.vpe.browsersim/src/org/jboss/tools/vpe/browsersim/util/ManifestUtil.java	2012-06-01 14:32:33 UTC (rev 41634)
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2011 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributor:
+ *     Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.vpe.browsersim.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.jboss.tools.vpe.browsersim.ui.BrowserSim;
+
+/**
+ * @author Ilya Buizuk (ibuizuk)
+ */
+public class ManifestUtil {
+
+	private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName"; //$NON-NLS-1$
+	private static final String BUNDLE_VERSION = "Bundle-Version"; //$NON-NLS-1$
+
+	public static String getManifestVersion() {
+		URLClassLoader classLoader = (URLClassLoader) BrowserSim.class.getClassLoader();
+		String version = null;
+
+		try {
+	        // If Manifest Version is in jar
+			Enumeration<URL> manifestUrls = classLoader.getResources(JarFile.MANIFEST_NAME);
+			while (manifestUrls.hasMoreElements()) {
+				URL manifestUrl = (URL) manifestUrls.nextElement();
+				InputStream inputStream = manifestUrl.openStream();
+				if (inputStream != null) {
+					Manifest manifest = new Manifest(inputStream);
+					version = getManifestVersion(manifest);
+				}
+			}
+
+			if (version == null) {
+				// If Manifest Version is not in jar
+				URL browserSimBaseUrl = BrowserSim.class.getClassLoader().getResource("."); //$NON-NLS-1$
+				if ("file".equals(browserSimBaseUrl.getProtocol())) { //$NON-NLS-1$
+					File binDir = new File(browserSimBaseUrl.getFile());
+					File browsersimDir = binDir.getParentFile();
+					File manifestFile = new File(browsersimDir, JarFile.MANIFEST_NAME);
+					FileInputStream inputStream = new FileInputStream(manifestFile);
+					Manifest manifestFromFile = new Manifest(inputStream);
+					version = getManifestVersion(manifestFromFile);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+			version = null;
+		}
+	
+		return version;
+	}
+
+	private static String getManifestVersion(Manifest manifest) {
+		Attributes mainAttributes = manifest.getMainAttributes();
+		String version = null;
+		String bundleId = mainAttributes.getValue(BUNDLE_SYMBOLIC_NAME);
+		if (bundleId != null && bundleId.startsWith(BrowserSim.BROWSERSIM_PLUGIN_ID)) {
+			version = mainAttributes.getValue(BUNDLE_VERSION);
+		}
+		return version;
+	}
+
+}



More information about the jbosstools-commits mailing list