| /******************************************************************************* |
| * Copyright (c) 2009, 2016 Xored Software Inc and others. |
| * All rights reserved. This program and the accompanying materials |
| * are 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 |
| * |
| * Contributors: |
| * Xored Software Inc - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.rcptt.tesla.internal.ui.player; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.jobs.IJobChangeEvent; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.preference.ColorSelector; |
| import org.eclipse.jface.viewers.CellEditor; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.CheckboxTreeViewer; |
| import org.eclipse.jface.viewers.ColumnViewerEditor; |
| import org.eclipse.jface.viewers.ICellEditorListener; |
| import org.eclipse.jface.viewers.ListViewer; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerCell; |
| import org.eclipse.jface.wizard.ProgressMonitorPart; |
| import org.eclipse.jface.wizard.WizardDialog; |
| import org.eclipse.rcptt.tesla.internal.core.TeslaCore; |
| import org.eclipse.rcptt.tesla.swt.events.TimerUtils; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CCombo; |
| import org.eclipse.swt.custom.CTabFolder; |
| import org.eclipse.swt.custom.CTabFolderEvent; |
| import org.eclipse.swt.custom.CTabItem; |
| import org.eclipse.swt.custom.ControlEditor; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Synchronizer; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.swt.widgets.TypedListener; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.part.PageBook; |
| import org.eclipse.ui.progress.DeferredTreeContentManager; |
| |
| @SuppressWarnings("rawtypes") |
| public class TeslaSWTAccess { |
| |
| public static TreeViewer getTreeViewer(Tree tree) { |
| return getThis(TreeViewer.class, tree, SWT.Expand); |
| } |
| |
| public static TableViewer getTableViewer(Table tree) { |
| return getThis(TableViewer.class, tree, SWT.Dispose); |
| } |
| |
| public static CheckboxTableViewer getCheckboxTableViewer(Table tree) { |
| return getThis(CheckboxTableViewer.class, tree, SWT.Dispose); |
| } |
| |
| public static ListViewer getListViewer(org.eclipse.swt.widgets.List list) { |
| return getThis(ListViewer.class, list, SWT.Dispose); |
| } |
| |
| public static Viewer getViewer(org.eclipse.swt.widgets.Control w) { |
| return getThis(Viewer.class, w, SWT.Dispose); |
| } |
| |
| public static <T> T getThis(Class<T> clazz, Widget widget, int event) { |
| Listener[] listeners = widget.getListeners(event); |
| for (Listener listener : listeners) { |
| Object lookFor = listener; |
| if (listener instanceof TypedListener) { |
| lookFor = ((TypedListener) listener).getEventListener(); |
| } |
| Object viewer = getFromField(lookFor, "this$0"); |
| if (clazz.isInstance(viewer)) { |
| return clazz.cast(viewer); |
| } |
| viewer = getFromField(lookFor, "arg$1"); |
| if (clazz.isInstance(viewer)) { |
| return clazz.cast(viewer); |
| } |
| |
| } |
| return null; |
| } |
| |
| private static Object getFromField(Object lookFor, String arg) { |
| try { |
| Field this$0 = lookFor.getClass().getDeclaredField(arg); |
| if (this$0 != null) { |
| this$0.setAccessible(true); |
| Object viewer = this$0.get(lookFor); |
| return viewer; |
| } |
| } catch (Throwable e) { |
| // Ignore |
| } |
| return null; |
| } |
| |
| public static <T> T getThis(Class<T> clazz, Object object) { |
| try { |
| Field this$0 = object.getClass().getDeclaredField("this$0"); |
| this$0.setAccessible(true); |
| Object viewer = this$0.get(object); |
| if (clazz.isInstance(viewer)) |
| return clazz.cast(viewer); |
| } catch (Throwable e) { |
| // ignore exceptions |
| } |
| return null; |
| } |
| |
| private static Object getThis(String clazz, Control control, int event) { |
| Listener[] listeners = control.getListeners(event); |
| for (Listener listener : listeners) { |
| Object lookFor = listener; |
| if (listener instanceof TypedListener) { |
| lookFor = ((TypedListener) listener).getEventListener(); |
| } |
| try { |
| Field this$0 = lookFor.getClass().getDeclaredField("this$0"); |
| this$0.setAccessible(true); |
| Object viewer = this$0.get(lookFor); |
| if (viewer.getClass().getName().equals(clazz)) { |
| return viewer; |
| } |
| } catch (Throwable e) { |
| // ignore exceptions |
| } |
| } |
| return null; |
| } |
| |
| public static ColorSelector getColorSelector(Button widget) { |
| return getThis(ColorSelector.class, widget, SWT.Dispose); |
| } |
| |
| public static CheckboxTreeViewer getCheckBoxTreeViewer(SWTUIElement parent) { |
| return getThis(CheckboxTreeViewer.class, PlayerWrapUtils.unwrapWidget(parent), SWT.Expand); |
| } |
| |
| public static Object getPropertySheet(Control tree) { |
| return getThis("org.eclipse.ui.views.properties.PropertySheetViewer", tree, SWT.MouseDown); |
| } |
| |
| public static ControlEditor getControlEditor(Composite parent) { |
| return getThis(ControlEditor.class, parent, SWT.Resize); |
| } |
| |
| public static ColumnViewerEditor getColumnViewerEditor(CellEditor cellEditor) { |
| try { |
| Field listeners = CellEditor.class.getDeclaredField("listeners"); |
| listeners.setAccessible(true); |
| ListenerList listenersList = (ListenerList) listeners.get(cellEditor); |
| if (listenersList != null) { |
| Object[] objects = listenersList.getListeners(); |
| for (Object object : objects) { |
| if (object instanceof ICellEditorListener) { |
| ICellEditorListener list = (ICellEditorListener) object; |
| try { |
| Field this$0 = list.getClass().getDeclaredField("this$0"); |
| this$0.setAccessible(true); |
| Object viewer = this$0.get(list); |
| if (viewer instanceof ColumnViewerEditor) { |
| return (ColumnViewerEditor) viewer; |
| } |
| } catch (NoSuchFieldException e) { |
| // TeslaCore.log(e); |
| } |
| } |
| } |
| } |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static CellEditor getCellEditorFromColumnEditor(ColumnViewerEditor editor) { |
| Class<? extends ColumnViewerEditor> class1 = ColumnViewerEditor.class; |
| Field field; |
| CellEditor cEditor = null; |
| try { |
| field = class1.getDeclaredField("cellEditor"); |
| field.setAccessible(true); |
| cEditor = (CellEditor) field.get(editor); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return cEditor; |
| } |
| |
| public static Text getCComboText(CCombo combo) { |
| try { |
| Field field = CCombo.class.getDeclaredField("text"); |
| field.setAccessible(true); |
| return (Text) field.get(combo); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static Object getThis(Job job) { |
| Class<? extends Job> class1 = job.getClass(); |
| Field field; |
| try { |
| field = class1.getDeclaredField("this$0"); |
| field.setAccessible(true); |
| Object object = field.get(job); |
| return object; |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static Object call(Object object, String methodName, Object... args) { |
| try { |
| final Class<?> argTypes[] = new Class<?>[args.length]; |
| for (int i = 0; i < argTypes.length; i++) |
| argTypes[i] = args[i].getClass(); |
| |
| Class<?> class_ = object.getClass(); |
| while (true) { |
| try { |
| final Method method = class_.getDeclaredMethod(methodName, argTypes); |
| method.setAccessible(true); |
| return method.invoke(object, args); |
| } catch (NoSuchMethodException e) { |
| class_ = class_.getSuperclass(); |
| if (class_ == null) |
| return null; |
| } |
| } |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| public static <T> T getField(Class<T> targetClass, Object object, String fieldName) { |
| if (object == null) |
| return null; |
| try { |
| Class<?> class_ = object.getClass(); |
| |
| while (true) { |
| try { |
| Field field = class_.getDeclaredField(fieldName); |
| field.setAccessible(true); |
| Object value = field.get(object); |
| if (value == null) |
| return null; |
| if (targetClass.isInstance(value)) |
| return targetClass.cast(value); |
| else |
| return null; |
| |
| } catch (NoSuchFieldException e) { |
| class_ = class_.getSuperclass(); |
| if (class_ == null) |
| return null; |
| } |
| } |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| public static void setField(Object object, String fieldName, Object value) { |
| try { |
| Class<?> class_ = object.getClass(); |
| Field field = class_.getDeclaredField(fieldName); |
| field.setAccessible(true); |
| field.set(object, value); |
| } catch (Exception e) { |
| return; |
| } |
| } |
| |
| public static void setField(Class<?> class_, Object object, String fieldName, Object value) { |
| try { |
| Field field = class_.getDeclaredField(fieldName); |
| field.setAccessible(true); |
| field.set(object, value); |
| } catch (Exception e) { |
| return; |
| } |
| } |
| |
| public static boolean ignoreMarkersView(Object data) { |
| if (data != null) { |
| if (data.getClass().getName().equals("org.eclipse.ui.internal.views.markers.MarkerEntry")) { |
| return true; |
| // Avoild calling expand |
| // for MarkerEntry. This |
| // cause NPE. |
| } |
| } |
| return false; |
| } |
| |
| public static ViewerCell createUpdateCell(Object element) { |
| try { |
| Class<?> cl = Class.forName("org.eclipse.jface.UpdateViewerCell"); |
| Constructor<?> constructor = cl.getConstructor(Object.class); |
| return (ViewerCell) constructor.newInstance(element); |
| |
| } catch (ClassNotFoundException e) { |
| TeslaCore.log(e); |
| } |
| // ViewerCell cell = new |
| // provider.update(cell); |
| catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static void fireCheckStateChanged(final CheckboxTreeViewer viewer, final boolean state, |
| Object elementToCheck) { |
| Method method; |
| try { |
| method = CheckboxTreeViewer.class.getDeclaredMethod("fireCheckStateChanged", CheckStateChangedEvent.class); |
| method.setAccessible(true); |
| method.invoke(viewer, new CheckStateChangedEvent(viewer, elementToCheck, !state)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static void fireCheckStateChanged(final CheckboxTableViewer viewer, final boolean newState, Object cur) { |
| Method method; |
| try { |
| method = CheckboxTableViewer.class.getDeclaredMethod("fireCheckStateChanged", CheckStateChangedEvent.class); |
| method.setAccessible(true); |
| method.invoke(viewer, new CheckStateChangedEvent(viewer, cur, newState)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static boolean isDefferedTreeContentProvider(Job job) { |
| if (!job.isSystem()) { |
| // Deferred tree content update job is system |
| return false; |
| } |
| // Check for deferred tree job update |
| try { |
| Class<? extends Job> class1 = job.getClass(); |
| Field field = class1.getDeclaredField("this$0"); |
| field.setAccessible(true); |
| Object object = field.get(job); |
| if (object instanceof DeferredTreeContentManager) { |
| return true; |
| } |
| return false; |
| } catch (Throwable e) { |
| } |
| return false; |
| } |
| |
| public static void callMethod(final Object vv, final String name, final Object... args) { |
| callMethod(CellEditor.class, vv, name, args); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static Object callMethod(Class clazz, final Object vv, final String name, final Object... args) { |
| try { |
| final Class<?> argTypes[] = new Class<?>[args.length]; |
| for (int i = 0; i < argTypes.length; i++) { |
| argTypes[i] = args[i].getClass(); |
| } |
| final Method method = clazz.getDeclaredMethod(name, argTypes); |
| method.setAccessible(true); |
| return method.invoke(vv, args); |
| } catch (final Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static Object callMethod(Class clazz, final Object vv, final String name, final Class[] argTypes, |
| final Object... args) { |
| try { |
| final Method method = clazz.getDeclaredMethod(name, argTypes); |
| method.setAccessible(true); |
| return method.invoke(vv, args); |
| } catch (final Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static void callMethodValueChanged(final Object vv, final String name, final boolean val1, |
| final boolean val2) { |
| try { |
| final Method method = CellEditor.class.getDeclaredMethod(name, |
| new Class<?>[] { boolean.class, boolean.class }); |
| method.setAccessible(true); |
| method.invoke(vv, val1, val2); |
| } catch (final Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static void callHandleSelect(final Object vv, final TreeItem[] selection) { |
| try { |
| final Method method = vv.getClass().getDeclaredMethod("handleSelect", new Class[] { TreeItem.class }); |
| method.setAccessible(true); |
| method.invoke(vv, selection[0]); |
| } catch (final Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static void callHandleSelect(final Object vv, final TableItem[] selection) { |
| try { |
| final Method method = vv.getClass().getDeclaredMethod("handleSelect", new Class[] { TreeItem.class }); |
| method.setAccessible(true); |
| method.invoke(vv, selection[0]); |
| } catch (final Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static Runnable[] getTimers(Display display) { |
| try { |
| return TimerUtils.getTimers(display); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return new Runnable[0]; |
| } |
| |
| public static Object getThis(Object job) { |
| Class class1 = job.getClass(); |
| Field field; |
| try { |
| field = class1.getDeclaredField("this$0"); |
| field.setAccessible(true); |
| Object object = field.get(job); |
| return object; |
| } catch (Throwable e) { |
| // Ignore |
| // TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static Control getBookPage(PageBook book) { |
| Class<? extends PageBook> class1 = book.getClass(); |
| try { |
| Field field = class1.getDeclaredField("currentPage"); |
| field.setAccessible(true); |
| return (Control) field.get(book); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static boolean getHasLocation(Menu menu) { |
| try { |
| Field locationField = Menu.class.getDeclaredField("hasLocation"); |
| locationField.setAccessible(true); |
| return ((Boolean) locationField.get(menu)).booleanValue(); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return false; |
| } |
| |
| public static void setHasLocation(Menu menu, boolean oldHasLocation) { |
| try { |
| Field locationField = Menu.class.getDeclaredField("hasLocation"); |
| locationField.setAccessible(true); |
| locationField.set(menu, Boolean.valueOf(oldHasLocation)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static Rectangle getCTabItemCloseRect(CTabItem tabItem) { |
| try { |
| Field locationField = CTabItem.class.getDeclaredField("closeRect"); |
| locationField.setAccessible(true); |
| return ((Rectangle) locationField.get(tabItem)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| |
| } |
| |
| public static Menu getCTabFolderItemListMenu(CTabFolder tabFolder) { |
| try { |
| Field menuField = CTabFolder.class.getDeclaredField("showMenu"); |
| menuField.setAccessible(true); |
| return ((Menu) menuField.get(tabFolder)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| |
| } |
| |
| public static int getRunnables(Synchronizer synchronizer) { |
| try { |
| Field locationField = Synchronizer.class.getDeclaredField("messageCount"); |
| locationField.setAccessible(true); |
| return ((Integer) locationField.get(synchronizer)).intValue(); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return 0; |
| } |
| |
| public static boolean getWizardDialogHasActiveOperations(WizardDialog dialog) { |
| try { |
| Field locationField = WizardDialog.class.getDeclaredField("activeRunningOperations"); |
| locationField.setAccessible(true); |
| return ((Long) locationField.get(dialog)).longValue() > 0; |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return false; |
| } |
| |
| public static void setWizardDialogHasActiveOperations(WizardDialog dialog, long count) { |
| try { |
| Field locationField = WizardDialog.class.getDeclaredField("activeRunningOperations"); |
| locationField.setAccessible(true); |
| locationField.set(dialog, count); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| } |
| |
| public static ProgressMonitorPart getProgressMonitorPart(WizardDialog dialog) { |
| try { |
| Field locationField = WizardDialog.class.getDeclaredField("progressMonitorPart"); |
| locationField.setAccessible(true); |
| return ((ProgressMonitorPart) locationField.get(dialog)); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| public static Button getWizardDialogButton(WizardDialog dialog, int buttonId) { |
| try { |
| final Method method = WizardDialog.class.getDeclaredMethod("getButton", int.class); |
| method.setAccessible(true); |
| return (Button) method.invoke(dialog, buttonId); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static boolean getJobEventReSchedule(IJobChangeEvent event) { |
| try { |
| Field field = org.eclipse.core.internal.jobs.JobChangeEvent.class.getDeclaredField("reschedule"); |
| field.setAccessible(true); |
| Boolean reschedule = (Boolean) field.get(event); |
| return reschedule.booleanValue(); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return false; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static org.eclipse.ui.internal.decorators.DecorationScheduler getDecorationScheduler( |
| org.eclipse.ui.internal.decorators.DecoratorManager manager) { |
| try { |
| Field field = org.eclipse.ui.internal.decorators.DecoratorManager.class.getDeclaredField("scheduler"); |
| field.setAccessible(true); |
| return (org.eclipse.ui.internal.decorators.DecorationScheduler) field.get(manager); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static Map getDecorationResultMap(org.eclipse.ui.internal.decorators.DecorationScheduler manager) { |
| try { |
| Field field = org.eclipse.ui.internal.decorators.DecorationScheduler.class.getDeclaredField("resultCache"); |
| field.setAccessible(true); |
| return (Map) field.get(manager); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static Object getDecoratorManagerFamily() { |
| return org.eclipse.ui.internal.decorators.DecoratorManager.FAMILY_DECORATE; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static int getJobFlags(Job job) { |
| try { |
| Field field = org.eclipse.core.internal.jobs.InternalJob.class.getDeclaredField("flags"); |
| field.setAccessible(true); |
| return (Integer) field.get(job); |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return 0; |
| } |
| |
| public static CTabFolderEvent createCTabFolderEvent(Widget widget) { |
| try { |
| Class<?> eventClassDefinition = Class.forName("org.eclipse.swt.custom.CTabFolderEvent"); |
| Class<?>[] ArgsClass = new Class<?>[] { Widget.class }; |
| Object[] Args = new Object[] { widget }; |
| Constructor<?> classConstructor = eventClassDefinition.getDeclaredConstructor(ArgsClass); |
| classConstructor.setAccessible(true); |
| return (CTabFolderEvent) classConstructor.newInstance(Args); |
| |
| } catch (Throwable e) { |
| TeslaCore.log(e); |
| } |
| return null; |
| |
| } |
| |
| } |