-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.diagram.symbollibrary.ui;\r
-\r
-import org.eclipse.jface.action.GroupMarker;\r
-import org.eclipse.jface.action.IMenuListener;\r
-import org.eclipse.jface.action.IMenuManager;\r
-import org.eclipse.jface.action.MenuManager;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.DisposeEvent;\r
-import org.eclipse.swt.events.DisposeListener;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.ui.IWorkbenchActionConstants;\r
-import org.eclipse.ui.part.IPageSite;\r
-import org.eclipse.ui.part.Page;\r
-import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;\r
-import org.simantics.diagram.symbollibrary.ISymbolGroup;\r
-import org.simantics.diagram.symbollibrary.ISymbolItem;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.gallery.GalleryViewer;\r
-import org.simantics.scenegraph.g2d.events.Event;\r
-import org.simantics.scenegraph.g2d.events.EventTypes;\r
-import org.simantics.scenegraph.g2d.events.IEventHandler;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.ui.SWTUtils;\r
-import org.simantics.utils.ui.jface.BaseSelectionProvider;\r
-\r
-/**\r
- * A page container for {@link SymbolLibraryComposite}.\r
- * \r
- * <p>\r
- * Supports context menu whose ID can be set with the\r
- * {@link #SymbolLibraryPage(SymbolProviderFactory, String)} constructor. By\r
- * default the page registers a context menu with name\r
- * {@value #DEFAULT_CONTEXT_MENU_ID}. The context menu selection provider\r
- * contain one of the following:\r
- * <ul>\r
- * <li>StructuredSelection of {@link ISymbolItem}s if the user clicks inside a\r
- * symbol group</li>\r
- * <li>StructuredSelection of a single {@link ISymbolGroup} if the user clicks a\r
- * single symbol group title</li>\r
- * <li>Empty selection if the user clicks on empty space</li>\r
- * </ul>\r
- * </p>\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class SymbolLibraryPage extends Page {\r
-\r
- public static final String DEFAULT_CONTEXT_MENU_ID = "#SymbolLibrary";\r
-\r
- SymbolProviderFactory symbolProviderFactory;\r
-\r
- SymbolLibraryComposite library;\r
-\r
- Display display;\r
-\r
- // Context menu stuff\r
- String contextMenuId = DEFAULT_CONTEXT_MENU_ID;\r
- MenuManager menuManager;\r
- Menu menu;\r
- BaseSelectionProvider selectionProvider = new BaseSelectionProvider();\r
-\r
- /**\r
- * An internal adapter from {@link IEventHandler} to\r
- * {@link SymbolLibraryEventHandler} interface.\r
- * \r
- * <p>\r
- * Attempts to retrieve the {@link ISymbolGroup} and the selection within\r
- * the corresponding GalleryViewer to give them to the possibly existing\r
- * external {@link SymbolLibraryEventHandler}.\r
- */\r
- IEventHandler internalEventAdapter = new IEventHandler() {\r
- @Override\r
- public int getEventMask() {\r
- return EventTypes.MouseButtonMask;\r
- }\r
- @Override\r
- public boolean handleEvent(Event e) {\r
- SymbolLibraryEventHandler h = externalEventHandler;\r
- if (h == null)\r
- return false;\r
-\r
-// MouseButtonEvent be = (MouseButtonEvent) e;\r
-// System.out.println("event:");\r
-// System.out.println("\tcontext: " + e.getContext());\r
-// System.out.println("\tscreen pos: " + be.screenPosition);\r
-\r
- if (e.context instanceof ICanvasContext) {\r
- // GalleryViewer clicked\r
- ICanvasContext ctx = (ICanvasContext) e.context;\r
- GalleryViewer viewer = ctx.getHintStack().getHint(GalleryViewer.KEY_VIEWER);\r
- ISymbolGroup group = null;\r
- if (viewer != null) {\r
- Object input = viewer.getInput();\r
- if (input instanceof ISymbolGroup)\r
- group = (ISymbolGroup) input;\r
- }\r
- h.handleEvent(e, group, viewer);\r
- } else if (e.context instanceof Control) {\r
- Control control = (Control) e.context;\r
- ISymbolGroup group = (ISymbolGroup) control.getData(SymbolLibraryKeys.KEY_GROUP);\r
- //GalleryViewer viewer = (GalleryViewer) control.getData(SymbolLibraryKeys.KEY_GALLERY);\r
- h.handleEvent(e, group, null);\r
- } else {\r
- // empty space event\r
- h.handleEvent(e, null, null);\r
- }\r
- return false;\r
- }\r
- };\r
-\r
- /**\r
- * Default event handler handler that shows the popup context menu of this\r
- * SymbolLibraryPage. It will set {@link #selectionProvider} selection to\r
- * provide Eclipse menu extensions the possibility to examine the clicked\r
- * selection.\r
- */\r
- volatile SymbolLibraryEventHandler externalEventHandler = new SymbolLibraryEventHandler() {\r
- @Override\r
- public boolean handleEvent(Event event, final ISymbolGroup group, final GalleryViewer viewer) {\r
- if (event instanceof MouseButtonReleasedEvent) {\r
- final MouseButtonEvent be = (MouseButtonEvent) event;\r
- if (be.button != MouseEvent.RIGHT_BUTTON)\r
- return false;\r
-\r
- // asyncExec to AWT to get proper selection from viewer\r
- AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- ISelection _selection = StructuredSelection.EMPTY;\r
- if (viewer != null)\r
- _selection = viewer.getSelection();\r
- if (_selection.isEmpty() && group != null)\r
- _selection = new StructuredSelection(group);\r
-\r
- final ISelection selection = _selection;\r
-\r
- // asyncExec to SWT to show popup\r
- SWTUtils.asyncExec(display, new Runnable() {\r
- @Override\r
- public void run() {\r
- if (library.isDisposed())\r
- return;\r
- selectionProvider.setAndFireNonEqualSelection(selection);\r
- menu.setLocation((int) be.screenPosition.getX(), (int) be.screenPosition.getY());\r
- menu.setVisible(true);\r
- }\r
- });\r
- }\r
- });\r
- }\r
- return false;\r
- }\r
- };\r
-\r
- public SymbolLibraryPage(SymbolProviderFactory symbolProviderFactory) {\r
- this.symbolProviderFactory = symbolProviderFactory;\r
- }\r
-\r
-// public SymbolLibraryPage(SymbolProviderFactory symbolProviderFactory, String contextMenuId) {\r
-// this.symbolProviderFactory = symbolProviderFactory;\r
-// this.contextMenuId = contextMenuId;\r
-// }\r
-\r
- /**\r
- * Set an event handler for the controls of this symbol library page (i.e.\r
- * SymbolLibraryComposite) that will receive all mouse events concerning the\r
- * symbol library controls. The events will be delivered in both SWT and AWT\r
- * threads since controls of both toolkits are involved in the UI of the\r
- * page. Actions performed in the event handler should be such that they are\r
- * scheduled to run in the according thread asynchronously and not handled\r
- * synchronously in the handler.\r
- * \r
- * <p>\r
- * This mechanism allows setting only a single event handler. Handler\r
- * chaining is possible.\r
- * \r
- * @param handler the handler to set for the page\r
- * @return \r
- * @see #getEventHandler()\r
- */\r
- public SymbolLibraryEventHandler setEventHandler(SymbolLibraryEventHandler handler) {\r
- SymbolLibraryEventHandler old = this.externalEventHandler;\r
- this.externalEventHandler = handler;\r
- return old;\r
- }\r
-\r
- public SymbolLibraryEventHandler getEventHandler() {\r
- return externalEventHandler;\r
- }\r
-\r
- @Override\r
- public void createControl(Composite parent) {\r
- display = parent.getDisplay();\r
- library = new SymbolLibraryComposite(parent, SWT.NONE, symbolProviderFactory);\r
- library.setEventHandler(internalEventAdapter);\r
- library.addDisposeListener(new DisposeListener() {\r
- @Override\r
- public void widgetDisposed(DisposeEvent e) {\r
- library = null;\r
- }\r
- });\r
-\r
- IPageSite site = getSite();\r
- if (site != null && contextMenuId != null) {\r
- menuManager = new MenuManager("Symbol Library", contextMenuId);\r
- menuManager.setRemoveAllWhenShown(true);\r
- menuManager.addMenuListener(new IMenuListener() {\r
- @Override\r
- public void menuAboutToShow(IMenuManager manager) {\r
- menuManager.add(new GroupMarker(IWorkbenchActionConstants.WB_START));\r
-\r
-// // FIXME: this is debug, remove\r
-// menuManager.add(new Action("Test") {\r
-// @Override\r
-// public void run() {\r
-// System.out.println("Selection: " + selectionProvider.getSelection());\r
-// MessageDialog.openInformation(null, "Symbol Library Action", selectionProvider.getSelection().toString());\r
-// }\r
-// });\r
- }\r
- });\r
-\r
- menu = menuManager.createContextMenu(library);\r
- library.setMenu(menu);\r
- site.registerContextMenu(menuManager.getId(), menuManager, selectionProvider);\r
- }\r
- }\r
-\r
- @Override\r
- public Control getControl() {\r
- return library;\r
- }\r
-\r
- public void setAllExpandedStates(boolean value) {\r
- library.setAllExpandedStates(value);\r
- }\r
- \r
- @Override\r
- public void setFocus() {\r
- if (library != null && !library.isDisposed())\r
- library.setFocus();\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.symbollibrary.ui;
+
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+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.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.part.Page;
+import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;
+import org.simantics.diagram.symbollibrary.ISymbolGroup;
+import org.simantics.diagram.symbollibrary.ISymbolItem;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.gallery.GalleryViewer;
+import org.simantics.scenegraph.g2d.events.Event;
+import org.simantics.scenegraph.g2d.events.EventTypes;
+import org.simantics.scenegraph.g2d.events.IEventHandler;
+import org.simantics.scenegraph.g2d.events.MouseEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.ui.SWTUtils;
+import org.simantics.utils.ui.jface.BaseSelectionProvider;
+
+/**
+ * A page container for {@link SymbolLibraryComposite}.
+ *
+ * <p>
+ * Supports context menu whose ID can be set with the
+ * {@link #SymbolLibraryPage(SymbolProviderFactory, String)} constructor. By
+ * default the page registers a context menu with name
+ * {@value #DEFAULT_CONTEXT_MENU_ID}. The context menu selection provider
+ * contain one of the following:
+ * <ul>
+ * <li>StructuredSelection of {@link ISymbolItem}s if the user clicks inside a
+ * symbol group</li>
+ * <li>StructuredSelection of a single {@link ISymbolGroup} if the user clicks a
+ * single symbol group title</li>
+ * <li>Empty selection if the user clicks on empty space</li>
+ * </ul>
+ * </p>
+ *
+ * @author Tuukka Lehtonen
+ */
+public class SymbolLibraryPage extends Page {
+
+ public static final String DEFAULT_CONTEXT_MENU_ID = "#SymbolLibrary";
+
+ SymbolProviderFactory symbolProviderFactory;
+
+ SymbolLibraryComposite library;
+
+ Display display;
+
+ // Context menu stuff
+ String contextMenuId = DEFAULT_CONTEXT_MENU_ID;
+ MenuManager menuManager;
+ Menu menu;
+ BaseSelectionProvider selectionProvider = new BaseSelectionProvider();
+
+ /**
+ * An internal adapter from {@link IEventHandler} to
+ * {@link SymbolLibraryEventHandler} interface.
+ *
+ * <p>
+ * Attempts to retrieve the {@link ISymbolGroup} and the selection within
+ * the corresponding GalleryViewer to give them to the possibly existing
+ * external {@link SymbolLibraryEventHandler}.
+ */
+ IEventHandler internalEventAdapter = new IEventHandler() {
+ @Override
+ public int getEventMask() {
+ return EventTypes.MouseButtonMask;
+ }
+ @Override
+ public boolean handleEvent(Event e) {
+ SymbolLibraryEventHandler h = externalEventHandler;
+ if (h == null)
+ return false;
+
+// MouseButtonEvent be = (MouseButtonEvent) e;
+// System.out.println("event:");
+// System.out.println("\tcontext: " + e.getContext());
+// System.out.println("\tscreen pos: " + be.screenPosition);
+
+ if (e.context instanceof ICanvasContext) {
+ // GalleryViewer clicked
+ ICanvasContext ctx = (ICanvasContext) e.context;
+ GalleryViewer viewer = ctx.getHintStack().getHint(GalleryViewer.KEY_VIEWER);
+ ISymbolGroup group = null;
+ if (viewer != null) {
+ Object input = viewer.getInput();
+ if (input instanceof ISymbolGroup)
+ group = (ISymbolGroup) input;
+ }
+ h.handleEvent(e, group, viewer);
+ } else if (e.context instanceof Control) {
+ Control control = (Control) e.context;
+ ISymbolGroup group = (ISymbolGroup) control.getData(SymbolLibraryKeys.KEY_GROUP);
+ //GalleryViewer viewer = (GalleryViewer) control.getData(SymbolLibraryKeys.KEY_GALLERY);
+ h.handleEvent(e, group, null);
+ } else {
+ // empty space event
+ h.handleEvent(e, null, null);
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Default event handler handler that shows the popup context menu of this
+ * SymbolLibraryPage. It will set {@link #selectionProvider} selection to
+ * provide Eclipse menu extensions the possibility to examine the clicked
+ * selection.
+ */
+ volatile SymbolLibraryEventHandler externalEventHandler = new SymbolLibraryEventHandler() {
+ @Override
+ public boolean handleEvent(Event event, final ISymbolGroup group, final GalleryViewer viewer) {
+ if (event instanceof MouseButtonReleasedEvent) {
+ final MouseButtonEvent be = (MouseButtonEvent) event;
+ if (be.button != MouseEvent.RIGHT_BUTTON)
+ return false;
+
+ // asyncExec to AWT to get proper selection from viewer
+ AWTThread.getThreadAccess().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ ISelection _selection = StructuredSelection.EMPTY;
+ if (viewer != null)
+ _selection = viewer.getSelection();
+ if (_selection.isEmpty() && group != null)
+ _selection = new StructuredSelection(group);
+
+ final ISelection selection = _selection;
+
+ // asyncExec to SWT to show popup
+ SWTUtils.asyncExec(display, new Runnable() {
+ @Override
+ public void run() {
+ if (library.isDisposed())
+ return;
+ selectionProvider.setAndFireNonEqualSelection(selection);
+ menu.setLocation((int) be.screenPosition.getX(), (int) be.screenPosition.getY());
+ menu.setVisible(true);
+ }
+ });
+ }
+ });
+ }
+ return false;
+ }
+ };
+
+ public SymbolLibraryPage(SymbolProviderFactory symbolProviderFactory) {
+ this.symbolProviderFactory = symbolProviderFactory;
+ }
+
+// public SymbolLibraryPage(SymbolProviderFactory symbolProviderFactory, String contextMenuId) {
+// this.symbolProviderFactory = symbolProviderFactory;
+// this.contextMenuId = contextMenuId;
+// }
+
+ /**
+ * Set an event handler for the controls of this symbol library page (i.e.
+ * SymbolLibraryComposite) that will receive all mouse events concerning the
+ * symbol library controls. The events will be delivered in both SWT and AWT
+ * threads since controls of both toolkits are involved in the UI of the
+ * page. Actions performed in the event handler should be such that they are
+ * scheduled to run in the according thread asynchronously and not handled
+ * synchronously in the handler.
+ *
+ * <p>
+ * This mechanism allows setting only a single event handler. Handler
+ * chaining is possible.
+ *
+ * @param handler the handler to set for the page
+ * @return
+ * @see #getEventHandler()
+ */
+ public SymbolLibraryEventHandler setEventHandler(SymbolLibraryEventHandler handler) {
+ SymbolLibraryEventHandler old = this.externalEventHandler;
+ this.externalEventHandler = handler;
+ return old;
+ }
+
+ public SymbolLibraryEventHandler getEventHandler() {
+ return externalEventHandler;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ display = parent.getDisplay();
+ library = new SymbolLibraryComposite(parent, SWT.NONE, symbolProviderFactory);
+ library.setEventHandler(internalEventAdapter);
+ library.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ library = null;
+ }
+ });
+
+ IPageSite site = getSite();
+ if (site != null && contextMenuId != null) {
+ menuManager = new MenuManager("Symbol Library", contextMenuId);
+ menuManager.setRemoveAllWhenShown(true);
+ menuManager.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ menuManager.add(new GroupMarker(IWorkbenchActionConstants.WB_START));
+
+// // FIXME: this is debug, remove
+// menuManager.add(new Action("Test") {
+// @Override
+// public void run() {
+// System.out.println("Selection: " + selectionProvider.getSelection());
+// MessageDialog.openInformation(null, "Symbol Library Action", selectionProvider.getSelection().toString());
+// }
+// });
+ }
+ });
+
+ menu = menuManager.createContextMenu(library);
+ library.setMenu(menu);
+ site.registerContextMenu(menuManager.getId(), menuManager, selectionProvider);
+ }
+ }
+
+ @Override
+ public Control getControl() {
+ return library;
+ }
+
+ public void setAllExpandedStates(boolean value) {
+ library.setAllExpandedStates(value);
+ }
+
+ @Override
+ public void setFocus() {
+ if (library != null && !library.isDisposed())
+ library.setFocus();
+ }
+
+}