/******************************************************************************* * Copyright (c) 2005, 2013 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.debug.ui; import java.text.MessageFormat; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.IHandlerActivation; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.keys.IBindingService; import org.osgi.framework.FrameworkUtil; /** * A PopupDialog that is automatically positioned relative * to a specified anchor point. The popup can be dismissed in the same * manor as all popup dialogs, but additionally allows clients the option * of specifying a command id that can be used to persist the contents of * the dialog. *

* Clients may subclass this. * @since 3.2 */ public abstract class DebugPopup extends PopupDialog { private Point fAnchor; private IHandlerActivation fActivation; private IHandlerService fHandlerService; private String fCommandId; private boolean fPersisted = false; /** * Constructs a new popup dialog of type PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE * @param parent The parent shell * @param anchor point at which to anchor the popup dialog in Display coordinate space. * Since 3.3, null can be specified to use a default anchor point * @param commandId The command id to be used for persistence of * the dialog, or null */ public DebugPopup(Shell parent, Point anchor, String commandId) { super(parent, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE, true, true, false, true, false, null, null); fAnchor = anchor; fCommandId = commandId; } /** * Returns the text to be shown in the popups's information area. * May return null. *

* By default, if this dialog has a persistence command associated with it, * the text displayed is of the form "Press {key-sequence} to {action}". The * action text is specified by the method getActionText(). *

* @return The text to be shown in the popup's information area or null */ protected String getInfoText() { if (getCommandId() != null && getActionText() != null) { IWorkbench workbench = PlatformUI.getWorkbench(); IBindingService bindingService = workbench.getAdapter(IBindingService.class); String formattedBinding = bindingService.getBestActiveBindingFormattedFor(getCommandId()); String infoText = null; if (formattedBinding != null) { infoText = MessageFormat.format(DebugUIViewsMessages.InspectPopupDialog_1, new Object[] { formattedBinding, getActionText() }); } return infoText; } return null; } /** * Returns the text to be shown as the action performed when this dialog's * persist command is invoked, or null. *

* Subclasses should override as necessary. *

* @return the text to be shown as the action performed when this dialog's * persist command is invoked */ protected String getActionText() { return null; } /** * Returns the command id to be used for persisting the contents of the * dialog. If the contents should not be persisted, this method should * return null. * * @return The command id to be used for persisting the contents of the * dialog or null */ protected String getCommandId() { return fCommandId; } /** * Persists the contents of the dialog. Subclasses should override as required, * but also call super.persist(). */ protected void persist() { fPersisted = true; } /** * Returns whether the command handler was invoked to persist this popup's result. * * @return whether the command handler was invoked to persist this popup's result */ protected boolean wasPersisted() { return fPersisted; } @Override protected abstract Control createDialogArea(Composite parent); /** * Returns the initial location to use for the shell based upon the * current selection in the viewer. Bottom is preferred to top, and * right is preferred to left, therefore if possible the popup will * be located below and to the right of the selection. * * @param initialSize * the initial size of the shell, as returned by * getInitialSize. * @return the initial location of the shell */ @Override protected Point getInitialLocation(Point initialSize) { if (fAnchor == null) { return super.getInitialLocation(initialSize); } Point point = fAnchor; Rectangle monitor = getShell().getMonitor().getClientArea(); if (monitor.width < point.x + initialSize.x) { point.x = Math.max(0, point.x - initialSize.x); } if (monitor.height < point.y + initialSize.y) { point.y = Math.max(0, point.y - initialSize.y); } return point; } @Override protected IDialogSettings getDialogSettings() { return PlatformUI.getDialogSettingsProvider(FrameworkUtil.getBundle(DebugPopup.class)).getDialogSettings(); } @Override public int open() { IWorkbench workbench = PlatformUI.getWorkbench(); String commandId = getCommandId(); if (commandId != null) { IHandler fCloseHandler = new AbstractHandler() { @Override public Object execute(ExecutionEvent event) throws ExecutionException { persist(); close(); return null; } }; fHandlerService = workbench.getAdapter(IHandlerService.class); fActivation = fHandlerService.activateHandler(commandId, fCloseHandler); } String infoText = getInfoText(); if (infoText != null) { setInfoText(infoText); } return super.open(); } @Override public boolean close() { if (fActivation != null) { fHandlerService.deactivateHandler(fActivation); } return super.close(); } }