diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF b/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF index bfcfe703601..5a30b2479ff 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF +++ b/terminal/bundles/org.eclipse.terminal.view.ui/META-INF/MANIFEST.MF @@ -14,7 +14,12 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.9.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.22.0,4.0.0)";resolution:=optional, org.eclipse.ui.editors;bundle-version="[3.20.0,4.0.0)";resolution:=optional, org.eclipse.text;bundle-version="[3.14.0,4.0.0)";resolution:=optional, - org.eclipse.terminal.view.core;bundle-version="[1.0.0,2.0.0)" + org.eclipse.terminal.view.core;bundle-version="[1.0.0,2.0.0)", + org.eclipse.e4.core.contexts;bundle-version="[1.10.0,2.0.0)", + org.eclipse.e4.core.di;bundle-version="[1.9.0,2.0.0)", + org.eclipse.e4.ui.di;bundle-version="[1.5.0,2.0.0)", + org.eclipse.e4.ui.model.workbench;bundle-version="[2.4.0,3.0.0)", + org.eclipse.e4.ui.workbench;bundle-version="[1.15.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin @@ -32,7 +37,9 @@ Export-Package: org.eclipse.terminal.view.ui;version="1.0.100", org.eclipse.terminal.view.ui.launcher;version="1.0.100", org.eclipse.terminal.view.ui.streams;version="1.0.100" Automatic-Module-Name: org.eclipse.terminal.view.ui -Import-Package: org.eclipse.terminal.connector;version="[1.0.0,2.0.0)", +Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)", + jakarta.inject;version="[2.0.0,3.0.0)", + org.eclipse.terminal.connector;version="[1.0.0,2.0.0)", org.eclipse.terminal.connector.provider;version="[1.0.0,2.0.0)", org.eclipse.terminal.control;version="[1.0.0,2.0.0)", org.eclipse.terminal.model;version="[1.0.0,2.0.0)" diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/build.properties b/terminal/bundles/org.eclipse.terminal.view.ui/build.properties index 61326dd9695..dd130e9d663 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/build.properties +++ b/terminal/bundles/org.eclipse.terminal.view.ui/build.properties @@ -18,6 +18,7 @@ bin.includes = META-INF/,\ about.html,\ icons/,\ contexts.xml,\ - OSGI-INF/ + OSGI-INF/,\ + fragment.e4xmi src.includes = schema/,\ about.html diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/fragment.e4xmi b/terminal/bundles/org.eclipse.terminal.view.ui/fragment.e4xmi new file mode 100644 index 00000000000..dc5719e8ac4 --- /dev/null +++ b/terminal/bundles/org.eclipse.terminal.view.ui/fragment.e4xmi @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/plugin.xml b/terminal/bundles/org.eclipse.terminal.view.ui/plugin.xml index 5337e891c2e..228230f99fc 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/plugin.xml +++ b/terminal/bundles/org.eclipse.terminal.view.ui/plugin.xml @@ -12,6 +12,15 @@ + + + + + + @@ -309,43 +318,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/AbstractTriggerCommandHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/AbstractTriggerCommandHandler.java index e948c85efc7..6b553f12b8c 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/AbstractTriggerCommandHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/AbstractTriggerCommandHandler.java @@ -40,6 +40,16 @@ public abstract class AbstractTriggerCommandHandler extends AbstractHandler { * @param selection The selection to pass on to the command or null. */ protected void triggerCommand(String commandId, ISelection selection) { + triggerCommandStatic(commandId, selection); + } + + /** + * Static method to trigger a command to be executed. Can be used from E4 handlers. + * + * @param commandId The command id. Must not be null. + * @param selection The selection to pass on to the command or null. + */ + protected static void triggerCommandStatic(String commandId, ISelection selection) { Assert.isNotNull(commandId); ICommandService service = PlatformUI.getWorkbench().getService(ICommandService.class); diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/DisconnectTerminalCommandHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/DisconnectTerminalCommandHandler.java index ee4ae0cdbcb..0fa26d7366d 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/DisconnectTerminalCommandHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/DisconnectTerminalCommandHandler.java @@ -11,27 +11,29 @@ *******************************************************************************/ package org.eclipse.terminal.view.ui.internal.handler; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; +import jakarta.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.custom.CTabItem; import org.eclipse.terminal.control.ITerminalViewControl; import org.eclipse.terminal.view.ui.ITerminalsView; import org.eclipse.terminal.view.ui.internal.tabs.TabFolderManager; -import org.eclipse.ui.handlers.HandlerUtil; /** * Disconnect terminal connection command handler implementation. */ -public class DisconnectTerminalCommandHandler extends AbstractHandler { +public class DisconnectTerminalCommandHandler { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection, + @Named(IServiceConstants.ACTIVE_PART) MPart activePart) { CTabItem item = null; - ISelection selection = HandlerUtil.getCurrentSelection(event); if (selection instanceof IStructuredSelection && !selection.isEmpty()) { Object element = ((IStructuredSelection) selection).getFirstElement(); if (element instanceof CTabItem && ((CTabItem) element).getData() instanceof ITerminalViewControl) { @@ -39,8 +41,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException { } } - if (item == null && HandlerUtil.getActivePart(event) instanceof ITerminalsView) { - ITerminalsView view = (ITerminalsView) HandlerUtil.getActivePart(event); + if (item == null && activePart != null && activePart.getObject() instanceof ITerminalsView) { + ITerminalsView view = (ITerminalsView) activePart.getObject(); TabFolderManager mgr = view.getAdapter(TabFolderManager.class); if (mgr != null && mgr.getActiveTabItem() != null) { item = mgr.getActiveTabItem(); @@ -53,8 +55,22 @@ public Object execute(ExecutionEvent event) throws ExecutionException { terminal.disconnectTerminal(); } } + } - return null; + @CanExecute + public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart activePart) { + if (activePart != null && activePart.getObject() instanceof ITerminalsView) { + ITerminalsView view = (ITerminalsView) activePart.getObject(); + TabFolderManager mgr = view.getAdapter(TabFolderManager.class); + if (mgr != null && mgr.getActiveTabItem() != null) { + CTabItem item = mgr.getActiveTabItem(); + if (item != null && item.getData() instanceof ITerminalViewControl) { + ITerminalViewControl terminal = (ITerminalViewControl) item.getData(); + return terminal != null && !terminal.isDisposed(); + } + } + } + return false; } } diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/LaunchTerminalCommandHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/LaunchTerminalCommandHandler.java index 09bd9670b57..5e27370ff04 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/LaunchTerminalCommandHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/LaunchTerminalCommandHandler.java @@ -19,11 +19,13 @@ import java.util.Map; import java.util.Optional; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; +import jakarta.inject.Named; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ILog; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; @@ -37,16 +39,18 @@ import org.eclipse.terminal.view.ui.internal.UIPlugin; import org.eclipse.terminal.view.ui.internal.dialogs.LaunchTerminalSettingsDialog; import org.eclipse.terminal.view.ui.launcher.ILauncherDelegate; -import org.eclipse.ui.handlers.HandlerUtil; /** * Launch terminal command handler implementation. */ -public class LaunchTerminalCommandHandler extends AbstractHandler { - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - String commandId = event.getCommand().getId(); +public class LaunchTerminalCommandHandler { + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, + @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection, + @Named(IServiceConstants.ACTIVE_PART) MPart activePart) { + // Determine which command variant is being executed based on the active part context + String commandId = determineCommandId(activePart); long start = System.currentTimeMillis(); if (UIPlugin.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER)) { @@ -54,29 +58,29 @@ public Object execute(ExecutionEvent event) throws ExecutionException { String date = format.format(new Date(start)); UIPlugin.getTraceHandler().trace("Started at " + date + " (" + start + ")", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, LaunchTerminalCommandHandler.this); + ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, this); } - // Get the active shell - Shell shell = HandlerUtil.getActiveShell(event); - // Get the current selection - ISelection selection = HandlerUtil.getCurrentSelection(event); if (commandId.equals("org.eclipse.terminal.view.ui.command.launchConsole")) { //$NON-NLS-1$ LaunchTerminalSettingsDialog dialog = new LaunchTerminalSettingsDialog(shell, start); if (dialog.open() == Window.OK) { Optional delegate = findDelegate(dialog); if (delegate.isEmpty()) { - return null; + return; + } + try { + createConnector(delegate.get(), dialog.getSettings()); + } catch (Exception e) { + ILog.get().error("Error creating terminal connector", e); //$NON-NLS-1$ } - return createConnector(delegate.get(), dialog.getSettings()); } - return null; + return; } if (commandId.equals("org.eclipse.terminal.view.ui.command.launchToolbar")) { //$NON-NLS-1$ if (UIPlugin.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER)) { UIPlugin.getTraceHandler().trace("(a) Attempt to open launch terminal settings dialog after " //$NON-NLS-1$ + (System.currentTimeMillis() - start) + " ms.", //$NON-NLS-1$ - ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, LaunchTerminalCommandHandler.this); + ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, this); } LaunchTerminalSettingsDialog dialog = new LaunchTerminalSettingsDialog(shell, start); @@ -94,7 +98,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { if (UIPlugin.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER)) { UIPlugin.getTraceHandler().trace( "Getting applicable launcher delegates after " + (System.currentTimeMillis() - start) + " ms.", //$NON-NLS-1$ //$NON-NLS-2$ - ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, LaunchTerminalCommandHandler.this); + ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, this); } // Check if the dialog needs to be shown at all @@ -104,14 +108,14 @@ public Object execute(ExecutionEvent event) throws ExecutionException { if (UIPlugin.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER)) { UIPlugin.getTraceHandler().trace( "Got applicable launcher delegates after " + (System.currentTimeMillis() - start) + " ms.", //$NON-NLS-1$ //$NON-NLS-2$ - ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, LaunchTerminalCommandHandler.this); + ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, this); } if (delegates.size() > 1 || (delegates.size() == 1 && delegates.get(0).needsUserConfiguration())) { if (UIPlugin.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER)) { UIPlugin.getTraceHandler().trace("(b) Attempt to open launch terminal settings dialog after " //$NON-NLS-1$ + (System.currentTimeMillis() - start) + " ms.", //$NON-NLS-1$ - ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, LaunchTerminalCommandHandler.this); + ITraceIds.TRACE_LAUNCH_TERMINAL_COMMAND_HANDLER, this); } // Create the launch terminal settings dialog @@ -130,8 +134,20 @@ public Object execute(ExecutionEvent event) throws ExecutionException { executeDelegate(selection, delegate); } } + } - return null; + /** + * Determines the command ID based on the active part context. + * In E4, we can't directly access the command ID from the event, so we use + * a default behavior. + * + * @param activePart the active part + * @return the command ID + */ + private String determineCommandId(MPart activePart) { + // Default to launch command - this will be differentiated by the E4 model + // which can bind different instances of this handler to different commands + return "org.eclipse.terminal.view.ui.command.launch"; //$NON-NLS-1$ } private Optional findDelegate(LaunchTerminalSettingsDialog dialog) { @@ -142,12 +158,8 @@ private Optional findDelegate(LaunchTerminalSettingsDialog di } private ITerminalConnector createConnector(ILauncherDelegate delegate, Map settings) - throws ExecutionException { - try { - return delegate.createTerminalConnector(settings); - } catch (CoreException e) { - throw new ExecutionException(e.getStatus().getMessage(), e); - } + throws CoreException { + return delegate.createTerminalConnector(settings); } private boolean isValidSelection(ISelection selection) { @@ -165,14 +177,14 @@ private boolean isValidSelection(ISelection selection) { return false; } - private void executeDelegate(ISelection selection, ILauncherDelegate delegate) throws ExecutionException { + private void executeDelegate(ISelection selection, ILauncherDelegate delegate) { Map properties = new HashMap<>(); properties.put(ITerminalsConnectorConstants.PROP_DELEGATE_ID, delegate.getId()); properties.put(ITerminalsConnectorConstants.PROP_SELECTION, selection); executeDelegate(properties, delegate); } - private void executeDelegate(Map properties, ILauncherDelegate delegate) throws ExecutionException { + private void executeDelegate(Map properties, ILauncherDelegate delegate) { delegate.execute(properties).whenComplete((r, e) -> { if (e != null) { ILog.get().error("Error occurred while running delegate to open console", e); //$NON-NLS-1$ diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/MaximizeViewHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/MaximizeViewHandler.java index 3a80a14680e..1e351a155db 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/MaximizeViewHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/MaximizeViewHandler.java @@ -11,18 +11,30 @@ *******************************************************************************/ package org.eclipse.terminal.view.ui.internal.handler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; +import jakarta.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.di.annotations.Execute; /** * Maximize view handler implementation. */ -public class MaximizeViewHandler extends AbstractTriggerCommandHandler { +public class MaximizeViewHandler { + + @Inject + private ECommandService commandService; + + @Inject + private EHandlerService handlerService; - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - triggerCommand("org.eclipse.ui.window.maximizePart", null); //$NON-NLS-1$ - return null; + @Execute + public void execute() { + ParameterizedCommand command = commandService.createCommand("org.eclipse.ui.window.maximizePart", null); //$NON-NLS-1$ + if (command != null) { + handlerService.executeHandler(command); + } } } diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/NewTerminalViewHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/NewTerminalViewHandler.java index 0a4d4f6e74f..fd24f0ab236 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/NewTerminalViewHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/NewTerminalViewHandler.java @@ -12,26 +12,39 @@ *******************************************************************************/ package org.eclipse.terminal.view.ui.internal.handler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; +import jakarta.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.terminal.view.ui.TerminalViewId; import org.eclipse.terminal.view.ui.internal.UIPlugin; /** * New Terminal View handler implementation */ -public class NewTerminalViewHandler extends AbstractTriggerCommandHandler { +public class NewTerminalViewHandler { + + @Inject + private ECommandService commandService; + + @Inject + private EHandlerService handlerService; - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { + @Execute + public void execute() { try { UIPlugin.getConsoleManager().showConsoleView(new TerminalViewId().next()); - triggerCommand("org.eclipse.terminal.view.ui.command.launchToolbar", null); //$NON-NLS-1$ + ParameterizedCommand command = commandService.createCommand("org.eclipse.terminal.view.ui.command.launchToolbar", null); //$NON-NLS-1$ + if (command != null) { + handlerService.executeHandler(command); + } } catch (CoreException e) { - throw new ExecutionException(e.getStatus().getMessage(), e); + ILog.get().error("Error creating new terminal view", e); //$NON-NLS-1$ } - return null; } } diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/QuickAccessHandler.java b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/QuickAccessHandler.java index 307c491da8d..f207dfc6761 100644 --- a/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/QuickAccessHandler.java +++ b/terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/handler/QuickAccessHandler.java @@ -11,18 +11,30 @@ *******************************************************************************/ package org.eclipse.terminal.view.ui.internal.handler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; +import jakarta.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.di.annotations.Execute; /** * Quick access handler implementation. */ -public class QuickAccessHandler extends AbstractTriggerCommandHandler { +public class QuickAccessHandler { + + @Inject + private ECommandService commandService; + + @Inject + private EHandlerService handlerService; - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - triggerCommand("org.eclipse.ui.window.quickAccess", null); //$NON-NLS-1$ - return null; + @Execute + public void execute() { + ParameterizedCommand command = commandService.createCommand("org.eclipse.ui.window.quickAccess", null); //$NON-NLS-1$ + if (command != null) { + handlerService.executeHandler(command); + } } }