blob: adeb348026da50d8dcd8d28f5fc39db72025d22e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.actions;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.jface.dialogs.*;
import java.util.ArrayList;
import java.util.List;
import java.text.MessageFormat;
/**
* The ReadOnlyStateChecker is a helper class that takes a set of resource
* some of which may be read only and queries the user as to whether or
* not they wish to continue the operation on it.
*/
public class ReadOnlyStateChecker {
private Shell shell;
private String titleMessage;
private String mainMessage;
private boolean yesToAllSelected = false;
private boolean cancelSelected = false;
private String READ_ONLY_EXCEPTION_MESSAGE = IDEWorkbenchMessages.getString("ReadOnlyCheck.problems"); //$NON-NLS-1$
/**
* Create a new checker that parents the dialog off of parent using the supplied
* title and message.
* @param parent the shell used for dialogs
* @param title the title for dialogs
* @param message the message for a dialog - this will be prefaced with the name of the resource.
*/
public ReadOnlyStateChecker(Shell parent, String title, String message) {
this.shell = parent;
this.titleMessage = title;
this.mainMessage = message;
}
/**
* Check an individual resource to see if it passed the read only query. If it is a file
* just add it, otherwise it is a container and the children need to be checked too.
* Return true if all items are selected and false if any are skipped.
*/
private boolean checkAcceptedResource(
IResource resourceToCheck,
List selectedChildren)
throws CoreException {
if (resourceToCheck.getType() == IResource.FILE)
selectedChildren.add(resourceToCheck);
else {
//Now check below
int childCheck =
checkReadOnlyResources(
((IContainer) resourceToCheck).members(),
selectedChildren);
//Add in the resource only if nothing was left out
if (childCheck == IDialogConstants.YES_TO_ALL_ID)
selectedChildren.add(resourceToCheck);
else //Something was left out - return false
return false;
}
return true;
}
/**
* Check the supplied resources to see if they are read only. If so then prompt
* the user to see if they can be deleted.Return those that were accepted.
* @return the resulting selected resources
*/
/*package*/
public IResource[] checkReadOnlyResources(IResource[] itemsToCheck) {
List selections = new ArrayList();
int result = IDialogConstants.CANCEL_ID;
try {
result = checkReadOnlyResources(itemsToCheck, selections);
} catch (final CoreException exception) {
shell.getDisplay().syncExec(new Runnable() {
public void run() {
ErrorDialog.openError(
shell,
READ_ONLY_EXCEPTION_MESSAGE,
null,
exception.getStatus());
}
});
}
if (result == IDialogConstants.CANCEL_ID)
return new IResource[0];
//All were selected so return the original items
if (result == IDialogConstants.YES_TO_ALL_ID)
return itemsToCheck;
IResource[] returnValue = new IResource[selections.size()];
selections.toArray(returnValue);
return returnValue;
}
/**
* Check the children of the container to see if they are read only.
* @return int
* one of
* YES_TO_ALL_ID - all elements were selected
* NO_ID - No was hit at some point
* CANCEL_ID - cancel was hit
* @param itemsToCheck IResource[]
* @param allSelected the List of currently selected resources to add to.
*/
private int checkReadOnlyResources(IResource[] itemsToCheck, List allSelected)
throws CoreException {
//Shortcut. If the user has already selected yes to all then just return it
if (yesToAllSelected)
return IDialogConstants.YES_TO_ALL_ID;
boolean noneSkipped = true;
List selectedChildren = new ArrayList();
for (int i = 0; i < itemsToCheck.length; i++) {
IResource resourceToCheck = itemsToCheck[i];
if (!yesToAllSelected && resourceToCheck.isReadOnly()) {
int action = queryYesToAllNoCancel(resourceToCheck);
if (action == IDialogConstants.YES_ID) {
boolean childResult = checkAcceptedResource(resourceToCheck, selectedChildren);
if (!childResult)
noneSkipped = false;
}
if (action == IDialogConstants.NO_ID)
noneSkipped = false;
if (action == IDialogConstants.CANCEL_ID) {
cancelSelected = true;
return IDialogConstants.CANCEL_ID;
}
if (action == IDialogConstants.YES_TO_ALL_ID) {
yesToAllSelected = true;
selectedChildren.add(resourceToCheck);
}
} else {
boolean childResult = checkAcceptedResource(resourceToCheck, selectedChildren);
if (cancelSelected)
return IDialogConstants.CANCEL_ID;
if (!childResult)
noneSkipped = false;
}
}
if (noneSkipped)
return IDialogConstants.YES_TO_ALL_ID;
else {
allSelected.addAll(selectedChildren);
return IDialogConstants.NO_ID;
}
}
/**
* Open a message dialog with Yes No, Yes To All and Cancel buttons. Return the
* code that indicates the selection.
* @return int
* one of
* YES_TO_ALL_ID
* YES_ID
* NO_ID
* CANCEL_ID
*
* @param resource - the resource being queried.
*/
private int queryYesToAllNoCancel(IResource resource) {
final MessageDialog dialog =
new MessageDialog(
this.shell,
this.titleMessage,
null,
MessageFormat.format(this.mainMessage, new Object[] {resource.getName()}),
MessageDialog.QUESTION,
new String[] {
IDialogConstants.YES_LABEL,
IDialogConstants.YES_TO_ALL_LABEL,
IDialogConstants.NO_LABEL,
IDialogConstants.CANCEL_LABEL },
0);
shell.getDisplay().syncExec(new Runnable() {
public void run() {
dialog.open();
}
});
int result = dialog.getReturnCode();
if (result == 0)
return IDialogConstants.YES_ID;
if (result == 1)
return IDialogConstants.YES_TO_ALL_ID;
if (result == 2)
return IDialogConstants.NO_ID;
return IDialogConstants.CANCEL_ID;
}
}