diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties index 368a29a8695..50f7482a9bf 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties @@ -157,7 +157,11 @@ MakeTargetDnD.message.createError=There were errors creating make targets in Mak MakeTargetDnD.title.createFromTextConfirm=Confirm Creating Make Targets MakeTargetDnD.message.createFromTextConfirm=Do you really want to create multiple make targets ({0}) from the multiline text?\n\n MakeTargetDnD.title.overwriteTargetConfirm=Confirm Overwriting Make Target -MakeTargetDnD.message.overwriteTargetConfirm=Make Target "{0}" exists in this folder. Do you want to overwrite it? +MakeTargetDnD.message.overwriteTargetConfirm=Make target "{0}" exists in this folder. Do you want to overwrite it? +MakeTargetDnD.toggle.applyToAll=Apply action to all conflicting targets +MakeTargetDnD.button.rename=&Rename +MakeTargetDnD.copyOf.uniqueName=Copy of {0} +MakeTargetDnD.countedCopyOf.uniqueName=Copy ({0}) of {1} SettingsBlock.title.selectLocationToBuildFrom=Selection Location to build from. SettingsBlock.label.missingBuilderInformation=Builder is missing or disabled on project. @@ -183,8 +187,8 @@ EditTargetAction.exception.errorEditingTarget=Error editing target. AddTargetAction.label=Add Make Target AddTargetAction.tooltip=Add Make Target -AddTargetAction.exception.internalError=Internal Error -AddTargetAction.=Internal Error +AddTargetAction.exception.title=Error Adding Make Target +AddTargetAction.exception.message=There was an error adding make target in Make Target View. See log for more details. CopyTargetAction.label=&Copy Target CopyTargetAction.tooltip=Copy Make Target diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/LocalTransferDropTargetListener.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/LocalTransferDropTargetListener.java index 7a84a3c4cee..9894f72ca58 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/LocalTransferDropTargetListener.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/LocalTransferDropTargetListener.java @@ -162,13 +162,18 @@ public class LocalTransferDropTargetListener extends AbstractContainerAreaDropAd List items = selection.toList(); for (Object item : items) { if (item instanceof IMakeTarget) { - // Looking for a target which is not being copying/moving to itself + // Looking for a target which is not being moving to itself IContainer container = ((IMakeTarget)item).getContainer(); // dropContainer==null means disregard the container if (dropContainer==null || !dropContainer.equals(container)) { if (bestOperation < DND.DROP_MOVE) { bestOperation = DND.DROP_MOVE; } + } else if (dropContainer.equals(container)) { + // Allow to copy/duplicate targets into the same folder + if (bestOperation < DND.DROP_COPY) { + bestOperation = DND.DROP_COPY; + } } } else if (isConvertibleToFile(item)) { // Files can be copied @@ -198,10 +203,7 @@ public class LocalTransferDropTargetListener extends AbstractContainerAreaDropAd List makeTargetsList= new ArrayList(elements.size()); for (Object element : elements) { if (element instanceof IMakeTarget) { - IMakeTarget makeTarget = (IMakeTarget)element; - if (!makeTarget.getContainer().equals(dropContainer)) { - makeTargetsList.add(makeTarget); - } + makeTargetsList.add((IMakeTarget)element); continue; } else if (isConvertibleToFile(element)) { IAdaptable a = (IAdaptable)element; diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/MakeTargetDndUtil.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/MakeTargetDndUtil.java index 67a1f8b44bd..767f9eccf82 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/MakeTargetDndUtil.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/dnd/MakeTargetDndUtil.java @@ -23,17 +23,20 @@ import org.eclipse.cdt.make.core.IMakeTargetManager; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.internal.core.MakeTarget; import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; +import org.eclipse.cdt.make.ui.dialogs.MakeTargetDialog; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.dnd.DND; @@ -43,16 +46,13 @@ import org.eclipse.swt.widgets.Shell; * A collection of various functions for Make Target View drag and drop support. */ public class MakeTargetDndUtil { - private static final int ANSWER_YES_ID = 0; - private static final int ANSWER_YES_TO_ALL_ID = 1; - private static final int ANSWER_NO_ID = 2; - private static final int ANSWER_NO_TO_ALL_ID = 3; - private static final int ANSWER_CANCEL_ID = 4; + private static final int RENAME_ID = IDialogConstants.INTERNAL_ID; + private static final int RENAME_TO_ALL_ID = IDialogConstants.INTERNAL_ID + 1; /** * The previous answer to the question of overwriting all targets. */ - protected static int lastUserAnswer = ANSWER_YES_ID; + protected static int lastUserAnswer = IDialogConstants.YES_ID; /** * Default build command. @@ -137,12 +137,12 @@ public class MakeTargetDndUtil { return; } - lastUserAnswer = ANSWER_YES_ID; + lastUserAnswer = IDialogConstants.YES_ID; if (makeTargets.length == 1) { try { // Do not slow down generating modal window for a single target - copyOneTarget(makeTargets[0], container, operation, shell); + copyOneTarget(makeTargets[0], container, operation, shell, false); } catch (CoreException e) { // log any problem then ignore it MakeUIPlugin.log(e); @@ -160,6 +160,7 @@ public class MakeTargetDndUtil { * @param operation - copying operation. Should be one of * {@link org.eclipse.swt.dnd.DND} operations. * @param shell - shell to display user warnings. + * @param offerOverwriteDialog - whether overwrite dialog is provided. * @throws CoreException on the failure of {@link IMakeTargetManager} or * {@link IMakeTarget} operation. * @@ -170,28 +171,83 @@ public class MakeTargetDndUtil { * @see DND#DROP_DEFAULT */ public static void copyOneTarget(IMakeTarget makeTarget, IContainer container, - final int operation, Shell shell) throws CoreException { + final int operation, Shell shell, boolean offerOverwriteDialog) throws CoreException { IMakeTargetManager makeTargetManager = MakeCorePlugin.getDefault().getTargetManager(); IMakeTarget exists = makeTargetManager.findTarget(container, makeTarget.getName()); if (exists != null) { - int userAnswer = overwriteMakeTargetDialog(makeTarget.getName(), shell); - if (userAnswer == ANSWER_YES_ID || userAnswer == ANSWER_YES_TO_ALL_ID) { + int userAnswer = IDialogConstants.CANCEL_ID; + if (offerOverwriteDialog) { + userAnswer = overwriteMakeTargetDialog(makeTarget.getName(), shell); + } else { + userAnswer = RENAME_ID; + } + if (userAnswer == IDialogConstants.YES_ID || userAnswer == IDialogConstants.YES_TO_ALL_ID) { copyTargetData(makeTarget, exists); if (operation == DND.DROP_MOVE) { makeTargetManager.removeTarget(makeTarget); } - } else if (userAnswer == ANSWER_NO_ID || userAnswer == ANSWER_NO_TO_ALL_ID) { - // no action + } else if (userAnswer == RENAME_ID || userAnswer == RENAME_TO_ALL_ID) { + String name = generateUniqueName(makeTarget.getName(), container); + IMakeTarget newMakeTarget = cloneTarget(name, makeTarget, container.getProject()); + newMakeTarget.setContainer(container); + int dialogReturnCode = Window.OK; + if (userAnswer == RENAME_ID) { + MakeTargetDialog dialog; + try { + dialog = new MakeTargetDialog(shell, newMakeTarget); + dialogReturnCode = dialog.open(); + } catch (CoreException e) { + MakeUIPlugin.errorDialog(shell, MakeUIPlugin.getResourceString("AddBuildTargetAction.exception.internal"), e.toString(), e); //$NON-NLS-1$ + } + } else if (userAnswer == RENAME_TO_ALL_ID) { + makeTargetManager.addTarget(container, newMakeTarget); + } + if (operation == DND.DROP_MOVE && dialogReturnCode != Window.CANCEL) { + makeTargetManager.removeTarget(makeTarget); + } } } else { - makeTargetManager.addTarget(container, cloneTarget(makeTarget, container.getProject())); + makeTargetManager.addTarget(container, cloneTarget(makeTarget.getName(), makeTarget, container.getProject())); if (operation == DND.DROP_MOVE) { makeTargetManager.removeTarget(makeTarget); } } } + /** + * Generate a new unique non-existent name of the kind of "Copy (2) of name". + * + * @param targetName - name from where generate unique name. + * @param container - container where the target belongs. + * @return generated name. + * @throws CoreException if {@code findTarget} having a problem. + */ + private static String generateUniqueName(String targetName, IContainer container) throws CoreException { + IMakeTargetManager makeTargetManager = MakeCorePlugin.getDefault().getTargetManager(); + // Try "name" + String newName = targetName; + if (makeTargetManager.findTarget(container, newName) == null) { + return newName; + } + + // Try "Copy of name" + newName = MessageFormat.format(MakeUIPlugin.getResourceString("MakeTargetDnD.copyOf.uniqueName"), //$NON-NLS-1$ + new Object[] { targetName }); + if (makeTargetManager.findTarget(container, newName) == null) { + return newName; + } + + // Try "Copy (2) of name" + for (int counter = 1;;counter++) { + newName = MessageFormat.format(MakeUIPlugin.getResourceString("MakeTargetDnD.countedCopyOf.uniqueName"), //$NON-NLS-1$ + new Object[] { counter, targetName }); + if (makeTargetManager.findTarget(container, newName) == null) { + return newName; + } + } + } + /** * Copy/move make targets to a given container. Displays progress bar. * @@ -224,12 +280,12 @@ public class MakeTargetDndUtil { if (makeTarget != null) { monitor.subTask(textAction + ' ' + makeTarget.getName()); try { - copyOneTarget(makeTarget, container, operation, shell); + copyOneTarget(makeTarget, container, operation, shell, true); } catch (CoreException e) { // log failures but ignore all targets which failed MakeUIPlugin.log(e); } - if (lastUserAnswer == ANSWER_CANCEL_ID) { + if (lastUserAnswer == IDialogConstants.CANCEL_ID) { break; } } @@ -239,7 +295,7 @@ public class MakeTargetDndUtil { } } monitor.done(); - lastUserAnswer = ANSWER_YES_ID; + lastUserAnswer = IDialogConstants.YES_ID; } }; @@ -263,54 +319,69 @@ public class MakeTargetDndUtil { */ private static int overwriteMakeTargetDialog(String name, Shell shell) { - if (lastUserAnswer == ANSWER_YES_TO_ALL_ID || lastUserAnswer == ANSWER_NO_TO_ALL_ID) { + if ( lastUserAnswer == IDialogConstants.YES_TO_ALL_ID + || lastUserAnswer == IDialogConstants.NO_TO_ALL_ID + || lastUserAnswer == RENAME_TO_ALL_ID ) { + return lastUserAnswer; } - String labels[] = new String[] { IDialogConstants.YES_LABEL, - IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, - IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.CANCEL_LABEL, }; + String labels[] = new String[] { + IDialogConstants.YES_LABEL, + IDialogConstants.NO_LABEL, + MakeUIPlugin.getResourceString("MakeTargetDnD.button.rename"), //$NON-NLS-1$ + IDialogConstants.CANCEL_LABEL, }; + String title = MakeUIPlugin.getResourceString("MakeTargetDnD.title.overwriteTargetConfirm"); //$NON-NLS-1$ String question = MessageFormat.format(MakeUIPlugin .getResourceString("MakeTargetDnD.message.overwriteTargetConfirm"), //$NON-NLS-1$ new Object[] { name }); + String toggleApplyToAll = MakeUIPlugin.getResourceString("MakeTargetDnD.toggle.applyToAll"); //$NON-NLS-1$ - MessageDialog dialog = new MessageDialog(shell, title, null, question, - MessageDialog.QUESTION, labels, 0); + MessageDialogWithToggle dialog = new MessageDialogWithToggle(shell, title, null, question, + MessageDialog.QUESTION, labels, 0, toggleApplyToAll, false); try { dialog.open(); lastUserAnswer = dialog.getReturnCode(); + boolean toAll = dialog.getToggleState(); + if (toAll && lastUserAnswer==IDialogConstants.YES_ID) { + lastUserAnswer = IDialogConstants.YES_TO_ALL_ID; + } else if (toAll && lastUserAnswer==IDialogConstants.NO_ID) { + lastUserAnswer = IDialogConstants.NO_TO_ALL_ID; + } else if (toAll && lastUserAnswer==RENAME_ID) { + lastUserAnswer = RENAME_TO_ALL_ID; + } } catch (SWTException e) { MakeUIPlugin.log(e); - lastUserAnswer = ANSWER_CANCEL_ID; + lastUserAnswer = IDialogConstants.CANCEL_ID; } if (lastUserAnswer == SWT.DEFAULT) { // A window close returns SWT.DEFAULT, which has to be // mapped to a cancel - lastUserAnswer = ANSWER_CANCEL_ID; + lastUserAnswer = IDialogConstants.CANCEL_ID; } return lastUserAnswer; } /** * Creating a copy of IMakeTarget in a different project. - * + * @param name - name of new target. * @param makeTarget - make target. * @param project - project where to assign the make target. + * * @return newly created make target. * @throws CoreException if there is a problem with creating or copying the * target. */ - private static IMakeTarget cloneTarget(IMakeTarget makeTarget, IProject project) + private static IMakeTarget cloneTarget(String name, IMakeTarget makeTarget, IProject project) throws CoreException { IMakeTargetManager makeTargetManager = MakeCorePlugin.getDefault().getTargetManager(); String[] ids = makeTargetManager.getTargetBuilders(project); String builderId = ids[0]; - IMakeTarget newMakeTarget = makeTargetManager.createTarget(project, makeTarget.getName(), - builderId); + IMakeTarget newMakeTarget = makeTargetManager.createTarget(project, name, builderId); copyTargetData(makeTarget, newMakeTarget); return newMakeTarget; } diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/views/AddTargetAction.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/views/AddTargetAction.java index 526b0d46da5..8b6b3cf424a 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/views/AddTargetAction.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/views/AddTargetAction.java @@ -11,14 +11,15 @@ package org.eclipse.cdt.make.ui.views; -import java.util.List; - +import org.eclipse.cdt.make.core.IMakeTarget; import org.eclipse.cdt.make.internal.ui.MakeUIImages; import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; +import org.eclipse.cdt.make.internal.ui.dnd.MakeTargetDndUtil; import org.eclipse.cdt.make.ui.dialogs.MakeTargetDialog; import org.eclipse.core.resources.IContainer; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.dnd.DND; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.actions.SelectionListenerAction; @@ -35,28 +36,33 @@ public class AddTargetAction extends SelectionListenerAction { @Override public void run() { - if (canAdd()) { - try { - MakeTargetDialog dialog = new MakeTargetDialog(shell, (IContainer) getStructuredSelection().getFirstElement()); + Object selection = getSelectedElement(); + try { + if (selection instanceof IContainer) { + MakeTargetDialog dialog = new MakeTargetDialog(shell, (IContainer) selection); dialog.open(); - } catch (CoreException e) { - MakeUIPlugin.errorDialog(shell, MakeUIPlugin.getResourceString("AddTargetAction.exception.internalError"), e.toString(), e); //$NON-NLS-1$ + } else if (selection instanceof IMakeTarget) { + IMakeTarget makeTarget = (IMakeTarget)selection; + MakeTargetDndUtil.copyOneTarget(makeTarget, makeTarget.getContainer(), DND.DROP_COPY, shell, false); } + } catch (CoreException e) { + MakeUIPlugin.errorDialog(shell, MakeUIPlugin.getResourceString("AddTargetAction.exception.title"), //$NON-NLS-1$ + MakeUIPlugin.getResourceString("AddTargetAction.exception.message"), e); //$NON-NLS-1$ } } @Override protected boolean updateSelection(IStructuredSelection selection) { - return super.updateSelection(selection) && canAdd(); + return super.updateSelection(selection) && getSelectedElement()!=null; } - private boolean canAdd() { - List elements = getStructuredSelection().toList(); - if (elements.size()==1 && (elements.get(0) instanceof IContainer)) { - return true; + private Object getSelectedElement() { + Object element = getStructuredSelection().getFirstElement(); + if (element instanceof IContainer || element instanceof IMakeTarget) { + return element; } - return false; + return null; } }