Bug 573692: [UI-Workbench] Add ActionHandler supporting IUpdate.update
Change-Id: I538000e28b64fb7782841932689de8ad0d60ac9d
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/ui/workbench/texteditor/ActionHandler.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/ui/workbench/texteditor/ActionHandler.java
new file mode 100644
index 0000000..21c91f0
--- /dev/null
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ecommons/ui/workbench/texteditor/ActionHandler.java
@@ -0,0 +1,141 @@
+/*=============================================================================#
+ # 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();
+ }
+
+}