blob: 21c91f0e09694c771385d85fa4c282d0da51b7ad [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 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.texteditor;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.HandlerEvent;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.ObjectUtils.ToStringBuilder;
@NonNullByDefault
public class ActionHandler extends AbstractHandler {
private final IAction action;
private boolean isDisposed;
private @Nullable IPropertyChangeListener propertyChangeListener;
public ActionHandler(final IAction action) {
this.action= action;
}
@Override
public void dispose() {
this.isDisposed= true;
detachListener();
super.dispose();
}
public final IAction getAction() {
return this.action;
}
@Override
public void addHandlerListener(final IHandlerListener handlerListener) {
if (this.isDisposed) {
return;
}
if (!hasListeners()) {
attachListener();
}
super.addHandlerListener(handlerListener);
}
private void attachListener() {
if (this.propertyChangeListener == null) {
final var listener= new IPropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent event) {
final String property= event.getProperty();
fireHandlerChanged(new HandlerEvent(ActionHandler.this,
IAction.ENABLED.equals(property),
IAction.HANDLED.equals(property) ));
}
};
this.propertyChangeListener= listener;
}
this.action.addPropertyChangeListener(this.propertyChangeListener);
}
private void detachListener() {
final var listener= this.propertyChangeListener;
if (listener != null) {
this.propertyChangeListener= null;
this.action.removePropertyChangeListener(listener);
}
}
@Override
public void setEnabled(final @Nullable Object evaluationContext) {
if (this.action instanceof IUpdate) {
((IUpdate)this.action).update();
}
setBaseEnabled(this.action.isEnabled());
}
@Override
public final @Nullable Object execute(final ExecutionEvent event)
throws ExecutionException {
if ((this.action.getStyle() == IAction.AS_CHECK_BOX)
|| (this.action.getStyle() == IAction.AS_RADIO_BUTTON)) {
this.action.setChecked(!this.action.isChecked());
}
try {
final Object trigger= event.getTrigger();
final Event swtEvent= (trigger instanceof Event) ? (Event)trigger : new Event();
this.action.runWithEvent(swtEvent);
return null;
}
catch (final Exception e) {
throw new ExecutionException(e.getMessage(), e);
}
}
@Override
public boolean isHandled() {
return this.action.isHandled();
}
@Override
public boolean isEnabled() {
return this.action.isEnabled();
}
@Override
public final String toString() {
final ToStringBuilder sb= new ToStringBuilder(ActionHandler.class);
sb.append(' ', this.action.toString());
return sb.toString();
}
}