### Eclipse Workspace Patch 1.0 #P org.jboss.tools.vpe.browsersim Index: src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java (revision 0) +++ src/org/jboss/tools/vpe/browsersim/ui/MessageBoxWithLinks.java (working copy) @@ -0,0 +1,137 @@ +/******************************************************************************* + + * 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; //$NON-NLS-1$ + + 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; + + } + +} \ No newline at end of file Index: src/org/jboss/tools/vpe/browsersim/ui/messages.properties =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/messages.properties (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/messages.properties (working copy) @@ -3,6 +3,8 @@ BrowserSim_COULD_NOT_OPEN_DEFAULT_BROWSER=Could not open default browser: BrowserSim_DEVICES=Devices BrowserSim_ERROR=Error +BrowserSim_HELP=Help +BrowserSim_ABOUT=About BrowserSim_EXIT=Exit BrowserSim_FILE=File BrowserSim_PREFERENCES=Preferences... @@ -11,6 +13,7 @@ BrowserSim_TURN_RIGHT=Turn Right BrowserSim_USE_SKINS=Use Skins BrowserSim_VIEW_PAGE_SOURCE=View page source +BrowserSim_ABOUT_MESSAGE=BrowserSim\n\Version: {0}\n\This application is a part of JBoss Tools. EditDeviceDialog_CANCEL=Cancel EditDeviceDialog_EDIT_DEVICE=Edit Device EditDeviceDialog_HEIGHT=Height: Index: src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/BrowserSim.java (working copy) @@ -11,13 +11,22 @@ package org.jboss.tools.vpe.browsersim.ui; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.Enumeration; import java.util.List; import java.util.Observable; import java.util.Observer; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; import javax.xml.bind.DatatypeConverter; @@ -44,6 +53,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; @@ -67,6 +78,7 @@ public class BrowserSim { 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$ @@ -99,8 +111,8 @@ } else { homeUrl = DEFAULT_URL; } - + DevicesList devicesList = DevicesListStorage.loadUserDefinedDevicesList(); if (devicesList == null) { devicesList = DevicesListStorage.loadDefaultDevicesList(); @@ -114,6 +126,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(browserSim); + } + + while (browserSim.skin!= null && browserSim.skin.getShell() != null && !browserSim.skin.getShell().isDisposed()) {//XXX if (!display.readAndDispatch()) display.sleep(); @@ -131,6 +150,7 @@ String iconLocation = BROWSERSIM_ICONS[i]; icons[i] = new Image(display, ResourcesUtil.getResourceAsStream(iconLocation)); } + } private void dispose() { @@ -303,12 +323,26 @@ for (MenuItem item : contextMenu.getItems()) { item.dispose(); } + 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); + } }); } @@ -317,6 +351,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) { @@ -324,53 +363,35 @@ 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(); - }; - }); + addViewSourceItem(menu); } private void addTurnMenuItems(Menu menu) { @@ -431,7 +452,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 devices = devicesList.getDevices(); for (int i = 0; i < devices.size(); i++) { @@ -636,6 +710,65 @@ } } + public String getManifestVersion() { + + URLClassLoader classLoader = (URLClassLoader) getClass().getClassLoader(); + String version = null; + + try { + // If Manifest Version is in jar + Enumeration urls = classLoader.getResources(JarFile.MANIFEST_NAME); + while (urls.hasMoreElements()) { + URL url = (URL) urls.nextElement(); + InputStream inputStream = url.openStream(); + if (inputStream != null) { + Manifest manifest = new Manifest(inputStream); + Attributes mainAttributes = manifest.getMainAttributes(); + String bundleId = mainAttributes.getValue("Bundle-SymbolicName"); + if (bundleId != null && bundleId.startsWith("org.jboss.tools.vpe.browsersim")) { + version = mainAttributes.getValue("Bundle-Version"); + return version; + + } + } + } + + // If Manifest Version is not in jar + URL url1 = getClass().getClassLoader().getResource("."); + if ("file".equals(url1.getProtocol())) { + File manifestFile; + File binDir = new File(url1.getFile()); + File browsersimDir = binDir.getParentFile(); + manifestFile = new File(browsersimDir, JarFile.MANIFEST_NAME); + FileInputStream inputStream = new FileInputStream(manifestFile); + Manifest manifestFromFile = new Manifest(inputStream); + + version = manifestFromFile.getMainAttributes().getValue("Bundle-version"); + } + } catch (IOException e) { + throw new RuntimeException(e); + + } + + return version; + + } + + public void showAboutDialog(Shell shell){ + String message; + String version = getManifestVersion(); + if (version != null) { + message = MessageFormat.format(Messages.BrowserSim_ABOUT_MESSAGE,getManifestVersion()); + } else { + message = MessageFormat.format(Messages.BrowserSim_ABOUT_MESSAGE, ""); + } + new MessageBoxWithLinks(shell, + message, + icons[BROWSERSIM_ICON_32PX_INDEX], + Messages.BrowserSim_ABOUT).open(); + } + + private ResizableSkinSizeAdvisor getSizeAdvisor() { if (sizeAdvisor == null) { sizeAdvisor = new ResizableSkinSizeAdvisor() { @@ -677,4 +810,67 @@ return sizeAdvisor; } + + public void addMacOsMenuApplicationHandler(final BrowserSim browserSim) { + + + CocoaUIEnhancer enhancer = new CocoaUIEnhancer("BrowserSim"); + + 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; + if (browserSim.skin != null && browserSim.skin != null + && browserSim.skin.getShell() != null) { + shell = browserSim.skin.getShell(); + } else { + shell = new Shell(); + } + + showAboutDialog(shell); + + } + }; + + Runnable macPreferencesAction = new Runnable() { + + @Override + public void run() { + + Shell shell; + if (browserSim != null && browserSim.skin != null + && browserSim.skin.getShell() != null) { + shell = browserSim.skin.getShell(); + } else { + shell = new Shell(); + } + + 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); + + + } + + } Index: src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java (revision 0) +++ src/org/jboss/tools/vpe/browsersim/ui/CocoaUIEnhancer.java (working copy) @@ -0,0 +1,284 @@ +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. + *

+ * 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. + *

+ *

+ * This code was influenced by the CarbonUIEnhancer from Agynami with the implementation being modified from the org.eclipse.ui.internal.cocoa.CocoaUIEnhancer. + *

+ */ +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 + * null 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 menu command + Object aboutMenuItem = + invoke( nsmenuCls, appMenu, "itemAtIndex", new Object[] { wrapPointer( kAboutMenuItem ) } ); + 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 ); + } + } +} Index: src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/ExceptionNotifier.java (working copy) @@ -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; - } -} Index: src/org/jboss/tools/vpe/browsersim/ui/CustomMessageBox.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/CustomMessageBox.java (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/CustomMessageBox.java (working copy) @@ -48,7 +48,7 @@ } protected void createWidgets() { - shell = new Shell(getParent(), SWT.DIALOG_TRIM); + shell = new Shell(getParent(), SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM); GridLayout shellLayout = new GridLayout(1, true); shellLayout.marginHeight = 0; shellLayout.marginWidth = 0; Index: src/org/jboss/tools/vpe/browsersim/ui/EditDeviceDialog.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/EditDeviceDialog.java (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/EditDeviceDialog.java (working copy) @@ -87,7 +87,7 @@ * Create contents of the dialog. */ private void createContents() { - shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.MIN | SWT.MAX); + shell = new Shell(getParent(), getStyle()); shell.setSize(450, 300); shell.setText(Messages.EditDeviceDialog_EDIT_DEVICE); shell.setLayout(new GridLayout(2, false)); Index: src/org/jboss/tools/vpe/browsersim/ui/Messages.java =================================================================== --- src/org/jboss/tools/vpe/browsersim/ui/Messages.java (revision 41070) +++ src/org/jboss/tools/vpe/browsersim/ui/Messages.java (working copy) @@ -23,6 +23,8 @@ public static String BrowserSim_COULD_NOT_OPEN_DEFAULT_BROWSER; public static String BrowserSim_DEVICES; public static String BrowserSim_ERROR; + public static String BrowserSim_HELP; + public static String BrowserSim_ABOUT; public static String BrowserSim_EXIT; public static String BrowserSim_FILE; public static String BrowserSim_OPEN_IN_DEFAULT_BROWSER; @@ -31,6 +33,7 @@ public static String BrowserSim_TURN_RIGHT; public static String BrowserSim_USE_SKINS; public static String BrowserSim_VIEW_PAGE_SOURCE; + public static String BrowserSim_ABOUT_MESSAGE; public static String EditDeviceDialog_CANCEL; public static String EditDeviceDialog_EDIT_DEVICE; public static String EditDeviceDialog_HEIGHT;