From 2168a93a3988fc095fd5afe18ebf46eae51ef587 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Tue, 17 Mar 2026 14:25:52 +0100 Subject: [PATCH 1/2] Implement Cut action for resources in Project Explorer Added a new CutAction and integrated it into the Common Navigator's EditActionGroup. Modified PasteAction to support moves when a cut operation is pending. Key changes: - Created CutAction.java to handle clipboard 'Cut' operations. - Updated PasteAction.java to use MoveFilesAndFoldersOperation when CutAction.isCut is true. - Wired CutAction into EditActionGroup's context menu and action bars. - Added localized strings for the Cut action. - Expanded CopyPasteActionTest.java with comprehensive tests for Cut enablement, clipboard contents, and move behavior. The tests use a dedicated TEST_VIEWER to ensure navigator actions are tested without interference from JDT's action provider overrides. --- .../resources/actions/CopyAction.java | 2 + .../resources/actions/CutAction.java | 201 ++++++++++++++++++ .../resources/actions/EditActionGroup.java | 8 + .../resources/actions/PasteAction.java | 12 +- .../plugin/WorkbenchNavigatorMessages.java | 3 + .../resources/plugin/messages.properties | 2 + .../tests/navigator/CopyPasteActionTest.java | 128 +++++++++-- 7 files changed, 332 insertions(+), 24 deletions(-) create mode 100644 bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CutAction.java diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CopyAction.java b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CopyAction.java index 8eafda938050..d5d2a6eb579e 100644 --- a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CopyAction.java +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CopyAction.java @@ -130,6 +130,8 @@ public void run() { } setClipboard(resources, fileNames, buf.toString()); + CutAction.isCut = false; + // update the enablement of the paste action // workaround since the clipboard does not suppot callbacks if (pasteAction != null && pasteAction.getStructuredSelection() != null) { diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CutAction.java b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CutAction.java new file mode 100644 index 000000000000..ab629a69bde9 --- /dev/null +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/CutAction.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2026 vogella GmbH 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: + * vogella GmbH - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.navigator.resources.actions; + +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.SelectionListenerAction; +import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorMessages; +import org.eclipse.ui.part.ResourceTransfer; + +/** + * Standard action for cutting the currently selected resources to the clipboard. + * + * @since 3.10 + */ +/*package*/class CutAction extends SelectionListenerAction { + + /** + * The id of this action. + */ + public static final String ID = PlatformUI.PLUGIN_ID + ".CutAction"; //$NON-NLS-1$ + + /** + * Tracks whether the last clipboard operation was a cut. + */ + public static boolean isCut = false; + + /** + * The shell in which to show any dialogs. + */ + private final Shell shell; + + /** + * System clipboard + */ + private final Clipboard clipboard; + + /** + * Associated paste action. May be null + */ + private PasteAction pasteAction; + + /** + * Creates a new action. + * + * @param shell the shell for any dialogs + * @param clipboard a platform clipboard + */ + public CutAction(Shell shell, Clipboard clipboard) { + super(WorkbenchNavigatorMessages.CutAction_Cut); + Assert.isNotNull(shell); + Assert.isNotNull(clipboard); + this.shell = shell; + this.clipboard = clipboard; + setToolTipText(WorkbenchNavigatorMessages.CutAction_Cut_selected_resource_s_); + setId(CutAction.ID); + setActionDefinitionId(IWorkbenchCommandConstants.EDIT_CUT); + ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); + setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT)); + setDisabledImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT_DISABLED)); + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, "CutHelpId"); //$NON-NLS-1$ + } + + /** + * Creates a new action. + * + * @param shell the shell for any dialogs + * @param clipboard a platform clipboard + * @param pasteAction a paste action + */ + public CutAction(Shell shell, Clipboard clipboard, PasteAction pasteAction) { + this(shell, clipboard); + this.pasteAction = pasteAction; + } + + @Override + public void run() { + List selectedResources = getSelectedResources(); + IResource[] resources = selectedResources.toArray(new IResource[selectedResources.size()]); + + // Get the file names and a string representation + final int length = resources.length; + int actualLength = 0; + String[] fileNames = new String[length]; + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < length; i++) { + IPath location = resources[i].getLocation(); + if (location != null) { + fileNames[actualLength++] = location.toOSString(); + } + if (i > 0) { + buf.append("\n"); //$NON-NLS-1$ + } + buf.append(resources[i].getName()); + } + if (actualLength < length) { + String[] tempFileNames = fileNames; + fileNames = new String[actualLength]; + System.arraycopy(tempFileNames, 0, fileNames, 0, actualLength); + } + setClipboard(resources, fileNames, buf.toString()); + + isCut = true; + + if (pasteAction != null && pasteAction.getStructuredSelection() != null) { + pasteAction.selectionChanged(pasteAction.getStructuredSelection()); + } + } + + private void setClipboard(IResource[] resources, String[] fileNames, String names) { + try { + if (fileNames.length > 0) { + clipboard.setContents(new Object[] { resources, fileNames, names }, + new Transfer[] { ResourceTransfer.getInstance(), FileTransfer.getInstance(), + TextTransfer.getInstance() }); + } else { + clipboard.setContents(new Object[] { resources, names }, + new Transfer[] { ResourceTransfer.getInstance(), TextTransfer.getInstance() }); + } + } catch (SWTError e) { + if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { + throw e; + } + if (MessageDialog.openQuestion(shell, "Problem with cut title", "Problem with cut.")) { //$NON-NLS-1$ //$NON-NLS-2$ + setClipboard(resources, fileNames, names); + } + } + } + + @Override + protected boolean updateSelection(IStructuredSelection selection) { + if (!super.updateSelection(selection)) { + return false; + } + + if (getSelectedNonResources().size() > 0) { + return false; + } + + List selectedResources = getSelectedResources(); + if (selectedResources.isEmpty()) { + return false; + } + + boolean projSelected = selectionIsOfType(IResource.PROJECT); + boolean fileFoldersSelected = selectionIsOfType(IResource.FILE | IResource.FOLDER); + if (!projSelected && !fileFoldersSelected) { + return false; + } + + // selection must be homogeneous + if (projSelected && fileFoldersSelected) { + return false; + } + + // must have a common parent + IContainer firstParent = selectedResources.get(0).getParent(); + if (firstParent == null) { + return false; + } + + for (IResource currentResource : selectedResources) { + if (!currentResource.getParent().equals(firstParent)) { + return false; + } + // resource location must exist + if (currentResource.getLocationURI() == null) { + return false; + } + } + return true; + } + +} diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/EditActionGroup.java b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/EditActionGroup.java index 1114876e2091..134b65fa685e 100644 --- a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/EditActionGroup.java +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/EditActionGroup.java @@ -38,6 +38,8 @@ public class EditActionGroup extends ActionGroup { private Clipboard clipboard; + private CutAction cutAction; + private CopyAction copyAction; private DeleteResourceAction deleteAction; @@ -69,6 +71,8 @@ public void fillContextMenu(IMenuManager menu) { boolean anyResourceSelected = !selection.isEmpty() && ResourceSelectionUtil.allResourcesAreOfType(selection, IResource.PROJECT | IResource.FOLDER | IResource.FILE); + cutAction.selectionChanged(selection); + menu.appendToGroup(ICommonMenuConstants.GROUP_EDIT, cutAction); copyAction.selectionChanged(selection); menu.appendToGroup(ICommonMenuConstants.GROUP_EDIT, copyAction); pasteAction.selectionChanged(selection); @@ -89,6 +93,7 @@ public void fillActionBars(IActionBars actionBars) { textActionHandler = new TextActionHandler(actionBars); // hook // handlers } + textActionHandler.setCutAction(cutAction); textActionHandler.setCopyAction(copyAction); textActionHandler.setPasteAction(pasteAction); textActionHandler.setDeleteAction(deleteAction); @@ -124,6 +129,8 @@ protected void makeActions() { pasteAction.setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); pasteAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_PASTE); + cutAction = new CutAction(shell, clipboard, pasteAction); + copyAction = new CopyAction(shell, clipboard, pasteAction); copyAction.setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED)); copyAction.setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); @@ -140,6 +147,7 @@ protected void makeActions() { public void updateActionBars() { IStructuredSelection selection = (IStructuredSelection) getContext().getSelection(); + cutAction.selectionChanged(selection); copyAction.selectionChanged(selection); pasteAction.selectionChanged(selection); deleteAction.selectionChanged(selection); diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/PasteAction.java b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/PasteAction.java index 4285088cb773..ef001cc07d4c 100644 --- a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/PasteAction.java +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/PasteAction.java @@ -31,6 +31,7 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.CopyFilesAndFoldersOperation; import org.eclipse.ui.actions.CopyProjectOperation; +import org.eclipse.ui.actions.MoveFilesAndFoldersOperation; import org.eclipse.ui.actions.SelectionListenerAction; import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorMessages; import org.eclipse.ui.part.ResourceTransfer; @@ -155,9 +156,15 @@ public void run() { } else { // enablement should ensure that we always have access to a container IContainer container = getContainer(resourceData); - CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(shell); - operation.copyResources(resourceData, container); + if (CutAction.isCut) { + MoveFilesAndFoldersOperation operation = new MoveFilesAndFoldersOperation(shell); + operation.copyResources(resourceData, container); + } else { + CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(shell); + operation.copyResources(resourceData, container); + } } + CutAction.isCut = false; return; } @@ -171,6 +178,7 @@ public void run() { CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(shell); operation.copyFiles(fileData, container); } + CutAction.isCut = false; } /** diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/WorkbenchNavigatorMessages.java b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/WorkbenchNavigatorMessages.java index b0d511f4b3d5..c2b23525df29 100644 --- a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/WorkbenchNavigatorMessages.java +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/WorkbenchNavigatorMessages.java @@ -55,6 +55,9 @@ public class WorkbenchNavigatorMessages extends NLS { public static String WorkingSetRootModeActionGroup_Working_Set_; public static String WorkingSetActionProvider_multipleWorkingSets; + public static String CutAction_Cut; + public static String CutAction_Cut_selected_resource_s_; + public static String CopyAction_Cop_; public static String CopyAction_Copy_selected_resource_s_; diff --git a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/messages.properties b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/messages.properties index 8eb876cbd270..ed0b1b891f46 100644 --- a/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/messages.properties +++ b/bundles/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/plugin/messages.properties @@ -33,6 +33,8 @@ DropAdapter_canNotDropProjectIntoProject=Cannot drop a project into another proj DropAdapter_problemsMoving=Problems occurred while moving resources. DropAdapter_dropOperationErrorOther=An error occurred during the drop operation. NewActionProvider_NewMenu_label=&New +CutAction_Cut=Cut +CutAction_Cut_selected_resource_s_=Cut the selected resource(s) CopyAction_Cop_=Copy CopyAction_Copy_selected_resource_s_=Copy selected resource(s) PasteAction_Past_=Paste diff --git a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/CopyPasteActionTest.java b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/CopyPasteActionTest.java index c01e21a09b52..caa5727867f4 100644 --- a/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/CopyPasteActionTest.java +++ b/tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/CopyPasteActionTest.java @@ -30,20 +30,22 @@ import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.navigator.resources.ProjectExplorer; import org.eclipse.ui.part.ResourceTransfer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; /** - * Tests for Copy and Paste actions in the Project Explorer. + * Tests for Copy, Cut and Paste actions in the Project Explorer. + * + * Uses TEST_VIEWER instead of ProjectExplorer.VIEW_ID to avoid JDT's action + * providers overriding the navigator's edit actions. */ public class CopyPasteActionTest extends NavigatorTestBase { private Clipboard _clipboard; public CopyPasteActionTest() { - _navigatorInstanceId = ProjectExplorer.VIEW_ID; + _navigatorInstanceId = TEST_VIEWER; } @Override @@ -70,6 +72,8 @@ private ActionContributionItem getAction(IStructuredSelection sel, String label) return (ActionContributionItem) item; } + // --- Copy tests --- + @Test public void testCopyEnablement() throws Exception { IFile file = _project.getFile("model.properties"); @@ -82,7 +86,6 @@ public void testCopyEnablement() throws Exception { @Test public void testCopyDisabledForMixedSelection() throws Exception { - // Mixed selection (Project + File) should disable Copy action IFile file = _project.getFile("model.properties"); IStructuredSelection sel = new StructuredSelection(new Object[] { _project, file }); _viewer.setSelection(sel); @@ -97,8 +100,6 @@ public void testCopyDisabledForEmptySelection() throws Exception { _viewer.setSelection(sel); Object copyItem = verifyMenu(sel, "Copy"); - // For an empty selection, the Resource action provider is not even matched, - // so the action should be absent from the menu. assertNull(copyItem, "Copy action should be absent for empty selection"); } @@ -136,7 +137,6 @@ public void testCopyTextTransfer() throws Exception { public void testPasteEnablement() throws Exception { IFile file = _project.getFile("model.properties"); - // Manually put the file on the clipboard getClipboard().setContents(new Object[] { new IResource[] { file }, file.getName() }, new Transfer[] { ResourceTransfer.getInstance(), TextTransfer.getInstance() }); @@ -152,44 +152,128 @@ public void testCopyPasteRoundTrip() throws Exception { IFile file = _project.getFile("model.properties"); assertTrue(file.exists()); - // 1. Copy IStructuredSelection selCopy = new StructuredSelection(file); _viewer.setSelection(selCopy); - ActionContributionItem copyActionItem = getAction(selCopy, "Copy"); - copyActionItem.getAction().run(); + getAction(selCopy, "Copy").getAction().run(); - // 2. Paste into _p1 IStructuredSelection selPaste = new StructuredSelection(_p1); _viewer.setSelection(selPaste); ActionContributionItem pasteActionItem = getAction(selPaste, "Paste"); assertTrue(pasteActionItem.getAction().isEnabled()); pasteActionItem.getAction().run(); - // 3. Verify IFile pastedFile = _p1.getFile(file.getName()); waitForCondition("File should be pasted", () -> pastedFile.exists()); assertTrue(pastedFile.exists(), "Pasted file should exist in target project"); + assertTrue(file.exists(), "Original file should still exist after copy-paste"); } @Test - public void testContextMenuContainsCopyPasteDelete() throws Exception { + public void testCopyDisabledForWorkspaceRoot() throws Exception { + IStructuredSelection sel = new StructuredSelection(ResourcesPlugin.getWorkspace().getRoot()); + _viewer.setSelection(sel); + + ActionContributionItem copyActionItem = getAction(sel, "Copy"); + assertFalse(copyActionItem.getAction().isEnabled(), "Copy action should be disabled for Workspace Root"); + } + + // --- Cut tests --- + + @Test + public void testCutEnablement() throws Exception { IFile file = _project.getFile("model.properties"); IStructuredSelection sel = new StructuredSelection(file); _viewer.setSelection(sel); - getAction(sel, "Copy"); - getAction(sel, "Paste"); - getAction(sel, "Delete"); + ActionContributionItem cutActionItem = getAction(sel, "Cut"); + assertTrue(cutActionItem.getAction().isEnabled(), "Cut action should be enabled for a file"); } @Test - public void testCopyDisabledForWorkspaceRoot() throws Exception { - // Selecting the workspace root should enable the resource action provider - // but the Copy action itself should be disabled for the root. - IStructuredSelection sel = new StructuredSelection(ResourcesPlugin.getWorkspace().getRoot()); + public void testCutDisabledForMixedSelection() throws Exception { + IFile file = _project.getFile("model.properties"); + IStructuredSelection sel = new StructuredSelection(new Object[] { _project, file }); _viewer.setSelection(sel); - ActionContributionItem copyActionItem = getAction(sel, "Copy"); - assertFalse(copyActionItem.getAction().isEnabled(), "Copy action should be disabled for Workspace Root"); + ActionContributionItem cutActionItem = getAction(sel, "Cut"); + assertFalse(cutActionItem.getAction().isEnabled(), "Cut action should be disabled for mixed selection"); + } + + @Test + public void testCutToClipboard() throws Exception { + IFile file = _project.getFile("model.properties"); + IStructuredSelection sel = new StructuredSelection(file); + _viewer.setSelection(sel); + + ActionContributionItem cutActionItem = getAction(sel, "Cut"); + cutActionItem.getAction().run(); + + Object contents = getClipboard().getContents(ResourceTransfer.getInstance()); + assertNotNull(contents, "Clipboard should contain resources after cut"); + IResource[] resources = (IResource[]) contents; + assertEquals(1, resources.length); + assertEquals(file, resources[0]); + } + + @Test + public void testCutPasteMovesResource() throws Exception { + IFile file = _project.getFile("model.properties"); + assertTrue(file.exists()); + + IStructuredSelection selCut = new StructuredSelection(file); + _viewer.setSelection(selCut); + getAction(selCut, "Cut").getAction().run(); + + IStructuredSelection selPaste = new StructuredSelection(_p1); + _viewer.setSelection(selPaste); + ActionContributionItem pasteActionItem = getAction(selPaste, "Paste"); + assertTrue(pasteActionItem.getAction().isEnabled()); + pasteActionItem.getAction().run(); + + IFile movedFile = _p1.getFile(file.getName()); + waitForCondition("File should be moved", () -> movedFile.exists()); + assertTrue(movedFile.exists(), "Moved file should exist in target project"); + waitForCondition("Original file should be gone", () -> !file.exists()); + assertFalse(file.exists(), "Original file should no longer exist after cut-paste"); + } + + @Test + public void testCopyAfterCutResetsCutState() throws Exception { + IFile file1 = _project.getFile("model.properties"); + IFile file2 = _p2.getFile("file1.txt"); + + // Cut file1 + IStructuredSelection selCut = new StructuredSelection(file1); + _viewer.setSelection(selCut); + getAction(selCut, "Cut").getAction().run(); + + // Copy file2 (resets cut state) + IStructuredSelection selCopy = new StructuredSelection(file2); + _viewer.setSelection(selCopy); + getAction(selCopy, "Copy").getAction().run(); + + // Paste into _p1 + IStructuredSelection selPaste = new StructuredSelection(_p1); + _viewer.setSelection(selPaste); + getAction(selPaste, "Paste").getAction().run(); + + // Verify it was a copy, not a move + IFile pastedFile = _p1.getFile(file2.getName()); + waitForCondition("File should be pasted", () -> pastedFile.exists()); + assertTrue(pastedFile.exists()); + assertTrue(file2.exists(), "Source file should still exist (it was a copy)"); + assertTrue(file1.exists(), "Cut file should still exist (copy reset the cut state)"); + } + + @Test + public void testContextMenuContainsEditActions() throws Exception { + IFile file = _project.getFile("model.properties"); + IStructuredSelection sel = new StructuredSelection(file); + _viewer.setSelection(sel); + + getAction(sel, "Cut"); + getAction(sel, "Copy"); + getAction(sel, "Paste"); + getAction(sel, "Delete"); } } From c32a9c6aeacbebf85e0ba789211d19ea99a4a26f Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Wed, 18 Mar 2026 09:27:26 +0000 Subject: [PATCH 2/2] Version bump(s) for 4.40 stream --- bundles/org.eclipse.ui.navigator.resources/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.ui.navigator.resources/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.navigator.resources/META-INF/MANIFEST.MF index 3d9d65dfd1ed..a26be904ac0e 100644 --- a/bundles/org.eclipse.ui.navigator.resources/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.navigator.resources/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.ui.navigator.resources; singleton:=true -Bundle-Version: 3.10.0.qualifier +Bundle-Version: 3.10.100.qualifier Bundle-Activator: org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorPlugin Bundle-Vendor: %Plugin.providerName Bundle-Localization: plugin