// ============================================================================ // // Copyright (C) 2006-2012 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.designer.core.ui.editor.palette; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.log4j.Logger; import org.eclipse.draw2d.PositionConstants; import org.eclipse.gef.ui.palette.FlyoutPaletteComposite; import org.eclipse.gef.ui.palette.PaletteMessages; import org.eclipse.gef.ui.palette.PaletteViewerProvider; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IWorkbenchPage; import org.talend.repository.ui.actions.ShowFavoriteAction; import org.talend.repository.ui.actions.ShowStandardAction; /** * DOC Administrator class global comment. Detailled comment */ public class TalendFlyoutPaletteComposite extends FlyoutPaletteComposite { private static Logger log = Logger.getLogger(TalendFlyoutPaletteComposite.class); private static Field paletteContainerField; private static Class paletteCompositeClass; private static Class changeDockActionClass, resizeActionClass; // reflection is used to work our way around some limitation in the FlyoutPaletteComposite upper class // retreive method and field in a static way to avoid doing it everytime they are called and improve perf static { try { paletteContainerField = FlyoutPaletteComposite.class.getDeclaredField("paletteContainer"); //$NON-NLS-1$ paletteContainerField.setAccessible(true); Class<?>[] classes = FlyoutPaletteComposite.class.getDeclaredClasses(); if (classes != null) { for (int i = 0; i < classes.length; i++) { if (classes[i].getSimpleName().equals("PaletteComposite")) { //$NON-NLS-1$ paletteCompositeClass = classes[i]; } else if (classes[i].getSimpleName().equals("ChangeDockAction")) { //$NON-NLS-1$ changeDockActionClass = classes[i]; } else if (classes[i].getSimpleName().equals("ResizeAction")) { //$NON-NLS-1$ resizeActionClass = classes[i]; } } } } catch (SecurityException e) { handleReflectionFailure(e); } catch (NoSuchFieldException e) { handleReflectionFailure(e); } } /** * DOC Administrator TalendFlyoutPaletteComposite constructor comment. * * @param parent * @param style * @param page * @param pvProvider * @param preferences */ public TalendFlyoutPaletteComposite(Composite parent, int style, IWorkbenchPage page, PaletteViewerProvider pvProvider, FlyoutPreferences preferences) { super(parent, style, page, pvProvider, preferences); // FIXME ggu // use the following codes to add two menu on the palette in Method init of class TitleCanvas try { // get paletteContainer field Object paletteContainer = paletteContainerField.get(this); /* * reflect the title field of PaletteComposite */ Field titleField = paletteCompositeClass.getDeclaredField("title"); //$NON-NLS-1$ titleField.setAccessible(true); Control title = (Control) titleField.get(paletteContainer); // set menu Menu titleCanvasMenu = createActionMenu((Control) paletteContainer); Method setMenuMethod = Control.class.getDeclaredMethod("setMenu", Menu.class); //$NON-NLS-1$ setMenuMethod.invoke(title, titleCanvasMenu); } catch (IllegalArgumentException e) { handleReflectionFailure(e); } catch (IllegalAccessException e) { handleReflectionFailure(e); } catch (SecurityException e) { handleReflectionFailure(e); } catch (NoSuchMethodException e) { handleReflectionFailure(e); } catch (InstantiationException e) { handleReflectionFailure(e); } catch (InvocationTargetException e) { handleReflectionFailure(e); } catch (NullPointerException e) { handleReflectionFailure(e); } catch (NoSuchFieldException e) { handleReflectionFailure(e); } } private Menu createActionMenu(Control parent) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { final MenuManager manager = new MenuManager(); MenuManager mgr = new MenuManager(PaletteMessages.DOCK_LABEL); changeDockActionClass.getDeclaredConstructors(); // reflect the constructor of ChangeDockAction Constructor changeDockActionConstructor = changeDockActionClass.getDeclaredConstructor(FlyoutPaletteComposite.class, String.class, int.class); changeDockActionConstructor.setAccessible(true); // instance of ChangeDockAction for left Object changeDockActionInstance = changeDockActionConstructor.newInstance(this, PaletteMessages.LEFT_LABEL, PositionConstants.WEST); if (changeDockActionInstance instanceof IAction) { mgr.add((IAction) changeDockActionInstance); } // instance of ChangeDockAction for right changeDockActionInstance = changeDockActionConstructor.newInstance(this, PaletteMessages.RIGHT_LABEL, PositionConstants.EAST); if (changeDockActionInstance instanceof IAction) { mgr.add((IAction) changeDockActionInstance); } // instance of ResizeAction Constructor resizeActionConstructor = resizeActionClass.getDeclaredConstructor(FlyoutPaletteComposite.class); resizeActionConstructor.setAccessible(true); Object resizeActionInstance = resizeActionConstructor.newInstance(this); if (resizeActionInstance instanceof IAction) { mgr.add((IAction) resizeActionInstance); } manager.add(mgr); mgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager menuMgr) { IContributionItem[] items = menuMgr.getItems(); for (int i = 0; i < items.length; i++) { ((ActionContributionItem) items[i]).update(); } } }); // ShowStandardAction showStandardAction = ShowStandardAction.getInstance(); ShowFavoriteAction showFavoriteAction = ShowFavoriteAction.getInstance(); manager.add(showStandardAction); manager.add(showFavoriteAction); showStandardAction.doSetEnable(); manager.add(mgr); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { manager.dispose(); } }); return manager.createContextMenu(this); } /** * log the exception and throw a Runtime exception cause this is serious. * * @param e */ private static void handleReflectionFailure(Exception e) { // our hook is not working so say it log.error("Talend Editor hook failed", e); throw new RuntimeException(e); } }