blob: b0288dabdc0b6e318bf85ba088b739954a108720 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2008, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.ui.workbench;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.jcommons.collections.IdentityList;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
/**
* Util methods for Eclipse workbench
*/
@NonNullByDefault
public class WorkbenchUIUtils {
public static final boolean IS_E4= (Platform.getBundle("org.eclipse.e4.ui.workbench") != null); //$NON-NLS-1$
public static @Nullable ISelection getCurrentSelection(final @Nullable Object context) {
if (context instanceof IEvaluationContext) {
final IEvaluationContext evaluationContext= (IEvaluationContext) context;
Object o;
o= evaluationContext.getVariable(ISources.ACTIVE_MENU_SELECTION_NAME);
if (o instanceof ISelection) {
return (ISelection) o;
}
o= evaluationContext.getVariable(ISources.ACTIVE_SITE_NAME);
if (o instanceof IWorkbenchSite) {
final IWorkbenchSite site= (IWorkbenchSite) o;
final ISelectionProvider selectionProvider= site.getSelectionProvider();
if (selectionProvider != null) {
return selectionProvider.getSelection();
}
return null;
}
else {
o= evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
if (o instanceof ISelection) {
return (ISelection) o;
}
}
}
return null;
}
public static @Nullable IWorkbenchPart getActivePart(final @Nullable Object context) {
if (context instanceof IEvaluationContext) {
final Object o= ((IEvaluationContext) context).getVariable(ISources.ACTIVE_PART_NAME);
if (o instanceof IWorkbenchPart) {
return (IWorkbenchPart) o;
}
}
return null;
}
public static @Nullable Control getActiveFocusControl(final @Nullable Object context) {
if (context instanceof IEvaluationContext) {
final Object o= ((IEvaluationContext) context).getVariable(ISources.ACTIVE_FOCUS_CONTROL_NAME);
if (o instanceof Control) {
return (Control) o;
}
}
return null;
}
public static @Nullable Shell getShell(final @Nullable Object context) {
if (context instanceof IEvaluationContext) {
final Object o= ((IEvaluationContext) context).getVariable(ISources.ACTIVE_SHELL_NAME);
if (o instanceof Shell) {
return (Shell) o;
}
}
final IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
return (window != null) ? window.getShell() : null;
}
public static IServiceLocator getServiceLocator(final @Nullable Object context) {
if (context instanceof IEvaluationContext) {
final Object o= ((IEvaluationContext) context).getVariable(ISources.ACTIVE_SITE_NAME);
if (o instanceof IServiceLocator) {
return (IServiceLocator) o;
}
}
return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
}
public static @Nullable KeySequence getBestKeyBinding(final String commandId) {
final IBindingService bindingSvc= PlatformUI.getWorkbench().getService(IBindingService.class);
if (bindingSvc == null) {
return null;
}
{ final TriggerSequence binding= bindingSvc.getBestActiveBindingFor(commandId);
if (binding instanceof KeySequence) {
return (KeySequence) binding;
}
}
{ final TriggerSequence[] bindings= bindingSvc.getActiveBindingsFor(commandId);
for (int i= 0; i < bindings.length; i++) {
if (bindings[i] instanceof KeySequence) {
return (KeySequence) bindings[i];
}
}
}
return null;
}
public static void activateContext(final IServiceLocator serviceLocator, String contextId) {
final IContextService contextService= serviceLocator.getService(IContextService.class);
try {
do {
final Context context= contextService.getContext(contextId);
if (context == null || !context.isDefined()) {
break;
}
contextService.activateContext(contextId);
contextId= context.getParentId();
} while (contextId != null
&& !contextId.equals(IContextService.CONTEXT_ID_DIALOG)
&& !contextId.equals(IContextService.CONTEXT_ID_DIALOG_AND_WINDOW)
&& !contextId.equals(IContextService.CONTEXT_ID_WINDOW) );
}
catch (final NotDefinedException e) {}
}
//-- Command UIElement ----
private static final Map<String, IdentityList<UIElement>> registeredElements= new HashMap<>();
private static int currentElementRefreshLevel;
private static final List<UIElement> currentUpdatedElements= new ArrayList<>();
private static @Nullable IHandler2 currentElementUpdater;
public static void registerCommandElement(final String commandId, final UIElement element) {
IdentityList<UIElement> elements= registeredElements.get(commandId);
if (elements == null) {
elements= ImCollections.newIdentityList(element);
}
else {
elements= ImCollections.addElement(elements, element);
}
registeredElements.put(commandId, elements);
}
public static void unregisterCommandElement(final String commandId, final UIElement element) {
IdentityList<UIElement> elements= registeredElements.get(commandId);
if (elements == null) {
return;
}
else {
elements= ImCollections.removeLastElement(elements, element);
}
registeredElements.put(commandId, elements);
}
public static boolean isElementUpdated(final UIElement element) {
final int l= currentUpdatedElements.size();
for (int i= 0; i < l; i++) {
if (currentUpdatedElements.get(i) == element) {
return true;
}
}
return false;
}
public static void refreshCommandElements(final String commandId,
final @Nullable IHandler2 handler, final @Nullable Map filter) {
if (currentElementRefreshLevel >= 10) {
return;
}
++currentElementRefreshLevel;
try {
final ICommandService commandService= PlatformUI.getWorkbench().getService(ICommandService.class);
if (commandId != null && commandService != null) {
commandService.refreshElements(commandId, filter);
}
if (handler instanceof IElementUpdater) {
final IElementUpdater updater= (IElementUpdater) handler;
final List<UIElement> elements= registeredElements.get(commandId);
if (elements != null) {
for (final UIElement element : elements) {
if (!isElementUpdated(element)) {
try {
updater.updateElement(element, null);
}
catch (final Exception e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR,
UIMiscellanyPlugin.BUNDLE_ID, "An error occurred when invoking elements updater.",
e ));
}
}
}
}
}
}
finally {
if (--currentElementRefreshLevel == 0) {
currentUpdatedElements.clear();
}
}
}
public static void aboutToUpdateCommandsElements(final IHandler2 handler, final UIElement element) {
currentElementUpdater= handler;
if (currentElementRefreshLevel > 0) {
currentUpdatedElements.add(element);
}
}
public static void finalizeUpdateCommandsElements(final IHandler2 handler) {
currentElementUpdater= null;
}
public static @Nullable IHandler2 getCommandElementsUpdater() {
return currentElementUpdater;
}
private WorkbenchUIUtils() {}
}