1 /*******************************************************************************
2  * Copyright (c) 2009, 2015 EclipseSource Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     EclipseSource Corporation - initial API and implementation
13  *     Mickael Istria (Red Hat Inc.) - 434317
14  *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 482175
15  *******************************************************************************/
16 package org.eclipse.pde.internal.runtime.spy.handlers;
17 
18 import org.eclipse.core.commands.AbstractHandler;
19 import org.eclipse.core.commands.ExecutionEvent;
20 import org.eclipse.jface.dialogs.PopupDialog;
21 import org.eclipse.pde.internal.runtime.PDERuntimePluginImages;
22 import org.eclipse.pde.internal.runtime.spy.dialogs.MenuSpyDialog;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.graphics.Cursor;
25 import org.eclipse.swt.graphics.Image;
26 import org.eclipse.swt.widgets.*;
27 import org.eclipse.ui.handlers.HandlerUtil;
28 
29 public class MenuSpyHandler extends AbstractHandler implements Listener {
30 
31 	private PopupDialog popupDialog = null;
32 	private Cursor defaultCursor;
33 	private Cursor spyCursor;
34 
35 	@Override
execute(ExecutionEvent event)36 	public Object execute(ExecutionEvent event) {
37 		if (popupDialog != null && popupDialog.getShell() != null && !popupDialog.getShell().isDisposed()) {
38 			popupDialog.close();
39 		}
40 
41 		Shell shell = HandlerUtil.getActiveShell(event);
42 		if (shell != null) {
43 			Display display = shell.getDisplay();
44 			display.addFilter(SWT.Selection, this);
45 			display.addFilter(SWT.KeyDown, this);
46 			display.addFilter(SWT.Show, this);
47 			if (display.getActiveShell() != null) {
48 				defaultCursor = display.getActiveShell().getCursor();
49 				Image image = PDERuntimePluginImages.get(PDERuntimePluginImages.IMG_MENUSPY_OBJ);
50 				spyCursor = new Cursor(display, image.getImageData(), 7, 7);
51 				display.getActiveShell().setCursor(spyCursor);
52 			}
53 		}
54 		return null;
55 	}
56 
57 	// TODO clean up this code
58 	@Override
handleEvent(Event event)59 	public void handleEvent(Event event) {
60 		switch (event.type) {
61 		case SWT.KeyDown:
62 			if (event.keyCode == SWT.ESC)
63 				break;
64 		case SWT.Show:
65 			if (spyCursor != null) {
66 				Shell shell = event.display.getActiveShell();
67 				if (shell != null) {
68 					shell.setCursor(spyCursor);
69 				}
70 			}
71 			return;
72 		}
73 		event.display.removeFilter(SWT.Selection, this);
74 		event.display.removeFilter(SWT.KeyDown, this);
75 		event.display.removeFilter(SWT.Show, this);
76 		if (spyCursor != null) {
77 			if (event.display.getActiveShell() != null) {
78 				event.display.getActiveShell().setCursor(defaultCursor);
79 				defaultCursor = null;
80 				spyCursor.dispose();
81 				spyCursor = null;
82 			}
83 		}
84 
85 		if (event.type == SWT.Selection) {
86 			Shell shell = event.display.getActiveShell();
87 			if (shell == null) { // see bug 434317
88 				if (event.widget instanceof Menu) {
89 					shell = ((Menu) event.widget).getShell();
90 				} else if (event.widget instanceof MenuItem) {
91 					shell = ((MenuItem) event.widget).getParent().getShell();
92 				}
93 			}
94 			MenuSpyDialog dialog = new MenuSpyDialog(shell, event, shell.getDisplay().getCursorLocation());
95 			popupDialog = dialog;
96 			dialog.create();
97 			dialog.open();
98 			event.doit = false;
99 			event.type = SWT.None;
100 		}
101 	}
102 }
103