/* * Copyright (c) 2008 Stiftung Deutsches Elektronen-Synchrotron, * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY. * * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS. * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION, * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM */ package org.csstudio.sds.ui.internal.runmode; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.csstudio.sds.internal.runmode.RunModeBoxInput; import org.eclipse.gef.GraphicalViewer; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveListener2; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A box that manages a shell, which uses a GEF graphical viewer to display SDS * displays. * * @author Sven Wende * @version $Revision: 1.9 $ */ public final class ViewRunModeBox extends AbstractRunModeBox implements IPartListener2, IPerspectiveListener2 { private static final Logger LOG = LoggerFactory.getLogger(ViewRunModeBox.class); private DisplayViewPart _viewPart; /** * Constructor. * * @param input * the input * @param connectionService * @param view * optional {@link DisplayViewPart} instance */ public ViewRunModeBox(RunModeBoxInput input, DisplayViewPart view) { super(input); _viewPart = view; } /** * {@inheritDoc} */ @Override protected void handleWindowPositionChange(int x, int y, int width, int height) { } /** * {@inheritDoc} */ @Override public void bringToTop() { IWorkbenchPage currentPage = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); IWorkbenchPage page = _viewPart.getSite().getPage(); try { // find references to all open views Map<IPerspectiveDescriptor, IViewReference> viewReferences = WorkbenchManipulationHelper .findAllViewReferences(_viewPart); if (!viewReferences.isEmpty()) { // is there a view already open in the current perspective boolean openInSamePerspective = viewReferences .containsKey(currentPage.getPerspective()); if (openInSamePerspective) { // we just activate the view currentPage.activate(viewReferences.get( page.getPerspective()).getPart(false)); } else { // ask the user whether he wants to switch the perspective // or open another view instance in the current view boolean openPerspective = MessageDialog .openQuestion( Display.getCurrent().getActiveShell(), "View already open", "The view is already open in another perspective. Do you want to open the perspective instead?"); if (openPerspective) { IPerspectiveDescriptor perspective = viewReferences .keySet().iterator().next(); IViewReference viewReference = viewReferences .get(perspective); WorkbenchManipulationHelper.activateViewReference( perspective, viewReference); } else { // open another view instance in the current perspective currentPage.showView(DisplayViewPart.PRIMARY_ID, secId, IWorkbenchPage.VIEW_ACTIVATE); } } } else { // open view instance in the current view currentPage.showView(DisplayViewPart.PRIMARY_ID, secId, IWorkbenchPage.VIEW_ACTIVATE); } } catch (PartInitException e) { LOG.error(e.toString()); } } boolean isDisposing; /** * {@inheritDoc} */ @Override protected void doDispose() { if (_viewPart != null) { _viewPart.getViewSite().getPage().removePartListener(this); _viewPart = null; } } private String secId; /** * Note: View parts can be injected (see * {@link #setViewPart(DisplayViewPart)}). In this case the injected view * is used. Otherwise a new view will be created. */ @Override protected GraphicalViewer doOpen(int x, int y, boolean openRelative, int width, int height, String title) { if (_viewPart != null) { // the view was already instantiated by the workbench (this usually // happens on a perspective restore) return _viewPart.getGraphicalViewer(); } else { // create and open the view String secondaryId = "" + System.currentTimeMillis(); secId = secondaryId; final IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); try { _viewPart = (DisplayViewPart) page.showView( DisplayViewPart.PRIMARY_ID, secondaryId, IWorkbenchPage.VIEW_ACTIVATE); _viewPart.setPartName(title); _viewPart.getViewSite().getPage().addPartListener(this); _viewPart.setPartName(title); _viewPart.setTitleToolTip(title); PlatformUI.getWorkbench().getActiveWorkbenchWindow() .addPerspectiveListener(this); return _viewPart.getGraphicalViewer(); } catch (final PartInitException e) { _viewPart = null; } } return null; } public DisplayViewPart getView() { return _viewPart; } @Override public void partActivated(IWorkbenchPartReference partRef) { } @Override public void partBroughtToTop(IWorkbenchPartReference partRef) { } @Override public void partClosed(IWorkbenchPartReference partRef) { if (partRef.getPart(false) == _viewPart) { dispose(); } } @Override public void partDeactivated(IWorkbenchPartReference partRef) { } @Override public void partHidden(IWorkbenchPartReference partRef) { } @Override public void partInputChanged(IWorkbenchPartReference partRef) { } @Override public void partOpened(IWorkbenchPartReference partRef) { } @Override public void partVisible(IWorkbenchPartReference partRef) { } /** * {@inheritDoc} */ @Override public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) { // listen for views getting closed in the current perspective if (!isDisposing && partRef != null && partRef.getPart(false) == _viewPart && IWorkbenchPage.CHANGE_VIEW_HIDE.equals(changeId)) { // check for other view reference of the same view in other // perspectives Map<IPerspectiveDescriptor, IViewReference> viewRefs = WorkbenchManipulationHelper .findAllViewReferences(_viewPart); // when there are any view references in other perspectives we ask // the user for his preferred action (close all view references or // just this one) if (viewRefs.size() > 1) { // display a message dialog that asks the user whether he wants // to close all view references of the current view or not StringBuffer sb = new StringBuffer(); Iterator<IPerspectiveDescriptor> it = viewRefs.keySet() .iterator(); while (it.hasNext()) { sb.append(it.next().getLabel()); sb.append(it.hasNext() ? ", " : ""); } boolean closeAllViews = MessageDialog.openQuestion(Display .getCurrent().getActiveShell(), "Q", "The view is opened in different perspectives (" + sb.toString() + ") Should all instances get closed now?"); // close all view references if the user voted accordingly if (closeAllViews) { isDisposing = true; WorkbenchManipulationHelper .closeAllViewReferences(_viewPart); PlatformUI.getWorkbench().getActiveWorkbenchWindow() .removePerspectiveListener(this); isDisposing = false; } } else { PlatformUI.getWorkbench().getActiveWorkbenchWindow() .removePerspectiveListener(this); } } } @Override public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) { } @Override public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) { } protected static class WorkbenchManipulationHelper { public static Map<IPerspectiveDescriptor, IViewReference> findAllViewReferences( final IWorkbenchPart viewPart) { Map<IPerspectiveDescriptor, IViewReference> result = new HashMap<IPerspectiveDescriptor, IViewReference>(); IPerspectiveDescriptor currentPerspective = PlatformUI .getWorkbench().getActiveWorkbenchWindow().getActivePage() .getPerspective(); final IWorkbenchWindow[] windows = PlatformUI.getWorkbench() .getWorkbenchWindows(); // for all workbench windows for (int w = 0; w < windows.length; w++) { final IWorkbenchPage[] pages = windows[w].getPages(); // for all workbench pages // of a given workbench window for (int p = 0; p < pages.length; p++) { final IWorkbenchPage page = pages[p]; for (IPerspectiveDescriptor pd : page.getOpenPerspectives()) { page.setPerspective(pd); final IViewReference[] viewRefs = page .getViewReferences(); // for all view references // of a given workbench page // of a given workbench window for (int v = 0; v < viewRefs.length; v++) { final IViewReference viewRef = viewRefs[v]; if (viewRef.getPart(false) == viewPart) { result.put(pd, viewRef); } } } } } PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getActivePage().setPerspective(currentPerspective); return result; } public static void closeAllViewReferences(IWorkbenchPart viewPart) { Map<IPerspectiveDescriptor, IViewReference> viewRefs = findAllViewReferences(viewPart); for (IPerspectiveDescriptor pd : viewRefs.keySet()) { IViewReference viewRef = viewRefs.get(pd); IPerspectiveDescriptor currentPerspective = viewRef.getPage() .getPerspective(); viewRef.getPage().setPerspective(pd); viewRef.getPage().hideView(viewRef); viewRef.getPage().setPerspective(currentPerspective); } } public static void activateViewReference( IPerspectiveDescriptor perspective, IViewReference viewReference) { IWorkbenchPage p = viewReference.getPage(); PlatformUI.getWorkbench().getActiveWorkbenchWindow().setActivePage( p); p.setPerspective(perspective); p.activate(viewReference.getPart(false)); } } @Override public Point getCurrentLocation() { return _viewPart.getSite().getShell().getLocation(); } }