Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <code>null</code>
*/
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<? extends IResource> 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<? extends IResource> 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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class EditActionGroup extends ActionGroup {

private Clipboard clipboard;

private CutAction cutAction;

private CopyAction copyAction;

private DeleteResourceAction deleteAction;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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));
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -171,6 +178,7 @@ public void run() {
CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(shell);
operation.copyFiles(fileData, container);
}
CutAction.isCut = false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading