summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorSzymon Ptaszkiewicz2011-08-31 15:02:30 (EDT)
committer Oleg Besedin2011-08-31 15:40:21 (EDT)
commit7e4fb75a060e47c7f39a8dfdf0afc002b9fc0835 (patch)
tree8ef4a62c69aca4053a9994053b90266ce6aa3714
parentcfc788c32ad32010bd59e415218ac294dc44e0d3 (diff)
downloadeclipse.platform.ui-7e4fb75a060e47c7f39a8dfdf0afc002b9fc0835.zip
eclipse.platform.ui-7e4fb75a060e47c7f39a8dfdf0afc002b9fc0835.tar.gz
eclipse.platform.ui-7e4fb75a060e47c7f39a8dfdf0afc002b9fc0835.tar.bz2
Bug 349993 - [IDE] Allow to apply file attribute changes recursively
-rw-r--r--bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java8
-rw-r--r--bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java219
-rw-r--r--bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties8
3 files changed, 230 insertions, 5 deletions
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
index 7a90233..ac7ddb4 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
@@ -642,6 +642,14 @@ public class IDEWorkbenchMessages extends NLS {
public static String ResourceInfo_read;
public static String ResourceInfo_write;
public static String ResourceInfo_execute;
+ public static String ResourceInfo_recursiveChangesTitle;
+ public static String ResourceInfo_recursiveChangesSummary;
+ public static String ResourceInfo_recursiveChangesSet;
+ public static String ResourceInfo_recursiveChangesUnset;
+ public static String ResourceInfo_recursiveChangesQuestion;
+ public static String ResourceInfo_recursiveChangesJobName;
+ public static String ResourceInfo_recursiveChangesSubTaskName;
+ public static String ResourceInfo_recursiveChangesError;
// --- Project References ---
public static String ProjectReferencesPage_label;
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java
index 1be93f5..18f3839 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java
@@ -13,6 +13,11 @@
package org.eclipse.ui.internal.ide.dialogs;
import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
@@ -23,15 +28,24 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
@@ -57,6 +71,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.ide.dialogs.ResourceEncodingFieldEditor;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.LineDelimiterEditor;
@@ -65,6 +80,11 @@ import org.eclipse.ui.internal.ide.LineDelimiterEditor;
* resource.
*/
public class ResourceInfoPage extends PropertyPage {
+ private interface IResourceChange {
+ public String getMessage();
+
+ public void performChange(IResource resource) throws CoreException;
+ }
private Button editableBox;
@@ -915,6 +935,177 @@ public class ResourceInfoPage extends PropertyPage {
}
+ private String getSimpleChangeName(boolean isSet, String name) {
+ String message = "\t"; //$NON-NLS-1$
+ message += isSet ? IDEWorkbenchMessages.ResourceInfo_recursiveChangesSet
+ : IDEWorkbenchMessages.ResourceInfo_recursiveChangesUnset;
+ message += " " + name + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+ return message;
+ }
+
+ private IResourceChange getAttributesChange(final boolean changedAttrs[],
+ final boolean finalAttrs[]) {
+ return new IResourceChange() {
+ public String getMessage() {
+ String message = ""; //$NON-NLS-1$
+ if (changedAttrs[0])
+ message += getSimpleChangeName(finalAttrs[0],
+ IDEWorkbenchMessages.ResourceInfo_readOnly);
+ if (changedAttrs[1])
+ message += getSimpleChangeName(finalAttrs[1],
+ IDEWorkbenchMessages.ResourceInfo_executable);
+ if (changedAttrs[2])
+ message += getSimpleChangeName(finalAttrs[2],
+ IDEWorkbenchMessages.ResourceInfo_archive);
+ return message;
+ }
+
+ public void performChange(IResource resource) throws CoreException {
+ ResourceAttributes attrs = resource.getResourceAttributes();
+ if (attrs != null) {
+ if (changedAttrs[0])
+ attrs.setReadOnly(finalAttrs[0]);
+ if (changedAttrs[1])
+ attrs.setExecutable(finalAttrs[1]);
+ if (changedAttrs[2])
+ attrs.setArchive(finalAttrs[2]);
+ resource.setResourceAttributes(attrs);
+ }
+ }
+ };
+ }
+
+ private IResourceChange getPermissionsChange(final int changedPermissions,
+ final int finalPermissions) {
+ return new IResourceChange() {
+ public String getMessage() {
+ // iterated with [j][i]
+ int permissionMasks[][] = new int[][] {
+ { EFS.ATTRIBUTE_OWNER_READ, EFS.ATTRIBUTE_OWNER_WRITE,
+ EFS.ATTRIBUTE_OWNER_EXECUTE },
+ { EFS.ATTRIBUTE_GROUP_READ, EFS.ATTRIBUTE_GROUP_WRITE,
+ EFS.ATTRIBUTE_GROUP_EXECUTE },
+ { EFS.ATTRIBUTE_OTHER_READ, EFS.ATTRIBUTE_OTHER_WRITE,
+ EFS.ATTRIBUTE_OTHER_EXECUTE } };
+ // iterated with [j]
+ String groupNames[] = new String[] {
+ IDEWorkbenchMessages.ResourceInfo_owner,
+ IDEWorkbenchMessages.ResourceInfo_group,
+ IDEWorkbenchMessages.ResourceInfo_other };
+ // iterated with [i]
+ String permissionNames[] = new String[] {
+ IDEWorkbenchMessages.ResourceInfo_read,
+ IDEWorkbenchMessages.ResourceInfo_write,
+ IDEWorkbenchMessages.ResourceInfo_execute };
+
+ String message = ""; //$NON-NLS-1$
+ if ((changedPermissions & EFS.ATTRIBUTE_IMMUTABLE) != 0)
+ message += getSimpleChangeName(
+ (finalPermissions & EFS.ATTRIBUTE_IMMUTABLE) != 0,
+ IDEWorkbenchMessages.ResourceInfo_locked);
+
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ if ((changedPermissions & permissionMasks[j][i]) != 0)
+ message += getSimpleChangeName(
+ (finalPermissions & permissionMasks[j][i]) != 0,
+ groupNames[j] + " " + permissionNames[i]); //$NON-NLS-1$
+ }
+ }
+ return message;
+ }
+
+ public void performChange(IResource resource) {
+ int permissions = fetchPermissions(resource);
+ // add permissions
+ permissions |= changedPermissions & finalPermissions;
+ // remove permissions
+ permissions &= ~changedPermissions | finalPermissions;
+ putPermissions(resource, permissions);
+ }
+ };
+ }
+
+ private List/*<IResource>*/ getResourcesToVisit(IResource resource) throws CoreException {
+ // use set for fast lookup
+ final Set/*<URI>*/ visited = new HashSet/*<URI>*/();
+ // use list to preserve the order of visited resources
+ final List/*<IResource>*/ toVisit = new ArrayList/*<IResource>*/();
+ visited.add(resource.getLocationURI());
+ resource.accept(new IResourceProxyVisitor() {
+ public boolean visit(IResourceProxy proxy) {
+ IResource childResource = proxy.requestResource();
+ URI uri = childResource.getLocationURI();
+ if (!visited.contains(uri)) {
+ visited.add(uri);
+ toVisit.add(childResource);
+ }
+ return true;
+ }
+ }, IResource.NONE);
+ return toVisit;
+ }
+
+ private boolean shouldPerformRecursiveChanges(List/*<IResourceChange>*/ changes) {
+ if (!changes.isEmpty()) {
+ String message = IDEWorkbenchMessages.ResourceInfo_recursiveChangesSummary
+ + "\n"; //$NON-NLS-1$
+ for (int i = 0; i < changes.size(); i++) {
+ message += ((IResourceChange) changes.get(i)).getMessage();
+ }
+ message += IDEWorkbenchMessages.ResourceInfo_recursiveChangesQuestion;
+
+ MessageDialog dialog = new MessageDialog(getShell(),
+ IDEWorkbenchMessages.ResourceInfo_recursiveChangesTitle,
+ null, message, MessageDialog.QUESTION, new String[] {
+ IDialogConstants.YES_LABEL,
+ IDialogConstants.NO_LABEL }, 1);
+
+ return dialog.open() == 0;
+ }
+ return false;
+ }
+
+ private void scheduleRecursiveChangesJob(final IResource resource, final List/*<IResourceChange>*/ changes) {
+ new Job(IDEWorkbenchMessages.ResourceInfo_recursiveChangesJobName) {
+ protected IStatus run(final IProgressMonitor monitor) {
+ try {
+ List/*<IResource>*/ toVisit = getResourcesToVisit(resource);
+
+ // Prepare the monitor for the given amount of work
+ monitor.beginTask(
+ IDEWorkbenchMessages.ResourceInfo_recursiveChangesJobName,
+ toVisit.size());
+
+ // Apply changes recursively
+ for (Iterator/*<IResource>*/ it = toVisit.iterator(); it.hasNext();) {
+ if (monitor.isCanceled())
+ throw new OperationCanceledException();
+ IResource childResource = (IResource) it.next();
+ monitor.subTask(NLS
+ .bind(IDEWorkbenchMessages.ResourceInfo_recursiveChangesSubTaskName,
+ childResource.getFullPath()));
+ for (int i = 0; i < changes.size(); i++) {
+ ((IResourceChange) changes.get(i))
+ .performChange(childResource);
+ }
+ monitor.worked(1);
+ }
+ } catch (CoreException e) {
+ IDEWorkbenchPlugin
+ .log(IDEWorkbenchMessages.ResourceInfo_recursiveChangesError,
+ e.getStatus());
+ return e.getStatus();
+ } catch (OperationCanceledException e) {
+ return Status.CANCEL_STATUS;
+ } finally {
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+
/**
* Apply the read only state and the encoding to the resource.
*/
@@ -940,26 +1131,32 @@ public class ResourceInfoPage extends PropertyPage {
new NullProgressMonitor());
}
+ List/*<IResourceChange>*/ changes = new ArrayList/*<IResourceChange>*/();
+
ResourceAttributes attrs = resource.getResourceAttributes();
if (attrs != null) {
- boolean hasChange = false;
+ boolean finalValues[] = new boolean[] { false, false, false };
+ boolean changedAttrs[] = new boolean[] { false, false, false };
// Nothing to update if we never made the box
if (editableBox != null
&& editableBox.getSelection() != previousReadOnlyValue) {
attrs.setReadOnly(editableBox.getSelection());
- hasChange = true;
+ finalValues[0] = editableBox.getSelection();
+ changedAttrs[0] = true;
}
if (executableBox != null
&& executableBox.getSelection() != previousExecutableValue) {
attrs.setExecutable(executableBox.getSelection());
- hasChange = true;
+ finalValues[1] = executableBox.getSelection();
+ changedAttrs[1] = true;
}
if (archiveBox != null
&& archiveBox.getSelection() != previousArchiveValue) {
attrs.setArchive(archiveBox.getSelection());
- hasChange = true;
+ finalValues[2] = archiveBox.getSelection();
+ changedAttrs[2] = true;
}
- if (hasChange) {
+ if (changedAttrs[0] || changedAttrs[1] || changedAttrs[2]) {
resource.setResourceAttributes(attrs);
attrs = resource.getResourceAttributes();
if (attrs != null) {
@@ -975,6 +1172,10 @@ public class ResourceInfoPage extends PropertyPage {
if (archiveBox != null) {
archiveBox.setSelection(attrs.isArchive());
}
+ if (resource.getType() == IResource.FOLDER) {
+ changes.add(getAttributesChange(changedAttrs,
+ finalValues));
+ }
}
}
}
@@ -982,15 +1183,23 @@ public class ResourceInfoPage extends PropertyPage {
if (permissionBoxes != null) {
int permissionValues = getPermissionsSelection();
if (previousPermissionsValue != permissionValues) {
+ int changedPermissions = previousPermissionsValue ^ permissionValues;
putPermissions(resource, permissionValues);
previousPermissionsValue = fetchPermissions(resource);
if (previousPermissionsValue != permissionValues) {
// We failed to set some of the permissions
setPermissionsSelection(previousPermissionsValue);
}
+ if (resource.getType() == IResource.FOLDER) {
+ changes.add(getPermissionsChange(changedPermissions,
+ permissionValues));
+ }
}
}
+ if (shouldPerformRecursiveChanges(changes))
+ scheduleRecursiveChangesJob(resource, changes);
+
// Nothing to update if we never made the box
if (this.derivedBox != null) {
boolean localDerivedValue = derivedBox.getSelection();
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
index a8e9009..a7a3fd4 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
@@ -661,6 +661,14 @@ ResourceInfo_other=Other
ResourceInfo_read=Read
ResourceInfo_write=Write
ResourceInfo_execute=Execute
+ResourceInfo_recursiveChangesTitle = Confirm recursive changes
+ResourceInfo_recursiveChangesSummary = The following changes have been made:
+ResourceInfo_recursiveChangesSet = set
+ResourceInfo_recursiveChangesUnset = unset
+ResourceInfo_recursiveChangesQuestion = Do you want to apply these changes to subfolders and files?
+ResourceInfo_recursiveChangesJobName = Applying recursive changes
+ResourceInfo_recursiveChangesSubTaskName = Applying changes for: ''{0}''
+ResourceInfo_recursiveChangesError = Error applying recursive changes
# --- Project References ---
ProjectReferencesPage_label = Projects may refer to other projects in the workspace.\nUse this page to specify what other projects are referenced by the project.\n\n&Project references for ''{0}'':