Index: plugin.xml
===================================================================
RCS file: /home/eclipse/org.eclipse.compare/plugin.xml,v
--- plugin.xml 20 Apr 2004 09:23:45 -0000 1.47
+++ plugin.xml 13 May 2004 05:23:56 -0000
@@ -255,14 +255,16 @@
name="replaceWithGroup">
+
+
+
+
+
+
t1 ? -1 : t0 == t1 ? 0 : 1;
+ }
+ };
+
+ Arrays.sort(states, comparator);
+
+ fileStates = Arrays.asList(states);
+
+ // Create a dialog to let the user pick where they want to roll back to
+ ListDialog listDialog = new ListDialog(shell);
+
+ listDialog.setContentProvider(new ListContentProvider());
+ listDialog.setInput(fileStates);
+ listDialog.setLabelProvider(new LabelProvider() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object element) {
+ FileStateWrapper state = ((FileStateWrapper)element);
+ String date = DateFormat.getDateTimeInstance().format(new Date(state.timestamp));
+
+ return MessageFormat.format( bundle.getString("historyFormat"), new String[]{date, state.file.getName()});
+ }
+
+ });
+
+ listDialog.setTitle(bundle.getString("selectEarliest"));
+
+ listDialog.setAddCancelButton(true);
+ listDialog.open();
+
+ Object[] selections = listDialog.getResult();
+
+ // Just exit if the user cancelled or didn't pick anything
+ if (selections != null && selections.length == 1) {
+ final FileStateWrapper earliestChange = (FileStateWrapper)selections[0];
+
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ final IWorkspaceRoot root = workspace.getRoot();
+
+ final List finalFileStates = fileStates;
+ final Object[] finalStates = states;
+
+ final String restoringFromHistoryName = bundle.getString("restoringFromHistory");
+
+ WorkspaceJob workspaceJob = new WorkspaceJob(restoringFromHistoryName) {
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+ monitor.beginTask(restoringFromHistoryName, finalStates.length * 100);
+
+ Set alreadyProcessed = new HashSet();
+
+ for (int idx = finalFileStates.indexOf(earliestChange); idx >= 0; idx--) {
+ FileStateWrapper next = (FileStateWrapper)finalStates[idx];
+ IPath path = next.file.getFullPath();
+
+ if (!alreadyProcessed.contains(path)) {
+ IFile file = next.file;
+
+ SubProgressMonitor subMon = new SubProgressMonitor(monitor, 100);
+
+ rollback(file, earliestChange.timestamp, subMon);
+
+ alreadyProcessed.add(path);
+ } else {
+ monitor.worked(100);
+ }
+ }
+
+ monitor.done();
+
+ return Status.OK_STATUS;
+ }
+
+ };
+
+ workspaceJob.setRule(root);
+ workspaceJob.setUser(true);
+ workspaceJob.schedule();
+ };
+
+ } catch (CoreException e) {
+ MessageDialog.openError(shell, bundle.getString("error"), e.toString());
+ }
+ }
+
+ /**
+ * Rolls back the given file to the given time (if possible).
+ *
+ * @param file
+ * @param timestamp
+ * @param mon
+ * @throws CoreException
+ */
+ public static void rollback(IFile file, long timestamp, IProgressMonitor mon) throws CoreException {
+ if (file.getLocalTimeStamp() >= timestamp) {
+
+ IFileState[] states = file.getHistory(null);
+
+ IFileState mostRecent = null;
+ long mostRecentTimestamp = 0;
+
+ for (int stateIdx = 0; stateIdx < states.length; stateIdx++) {
+ IFileState state = states[stateIdx];
+
+ if (state.exists()) {
+ long modTime = state.getModificationTime();
+ if (modTime > mostRecentTimestamp && modTime < timestamp) {
+ mostRecent = state;
+ mostRecentTimestamp = modTime;
+ }
+ }
+ }
+
+ if (mostRecent != null) {
+ file.setContents(mostRecent, true, true, mon);
+ }
+
+ }
+ }
+
+ /**
+ *
+ *
+ * @param files
+ * @return a List of FileStateWrappers representing all known times when the files in the given
+ * list were modified. This includes the current file timestamp plus everything found in the
+ * resource history.
+ */
+ protected static List getAllFileStates(IFile[] files) throws CoreException {
+ List result = new ArrayList(files.length);
+
+ for (int idx = 0; idx < files.length; idx++) {
+ IFile file = files[idx];
+ if (!file.isAccessible()) {
+ continue;
+ }
+
+ result.add(new FileStateWrapper(file, file.getLocalTimeStamp()));
+
+ IFileState[] states = files[idx].getHistory(null);
+ for (int stateIdx = 0; stateIdx < states.length; stateIdx++) {
+ IFileState state = states[stateIdx];
+
+ if (state.exists()) {
+ result.add(new FileStateWrapper(file, state.getModificationTime()));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected static IFile[] getFilesRecursive(ISelection selection) throws CoreException {
+ List result = getFilesRecursive(Utilities.getResources(selection));
+ return (IFile[]) result.toArray(new IFile[result.size()]);
+ }
+
+ private static List getFilesRecursive(IResource[] input) throws CoreException {
+ List result = new ArrayList(input.length);
+
+ for (int idx = 0; idx < input.length; idx++) {
+
+ IResource resource = input[idx];
+
+ if (!resource.isAccessible()) {
+ continue;
+ }
+
+ if (resource instanceof IContainer) {
+ IContainer container = (IContainer)resource;
+
+ result.addAll(getFilesRecursive(container.members()));
+ }
+
+ if (resource instanceof IFile) {
+ result.add(resource);
+ }
+ }
+
+ return result;
}
}
Index: compare/org/eclipse/compare/internal/ReplaceWithEditionAction.properties
===================================================================
RCS file: /home/eclipse/org.eclipse.compare/compare/org/eclipse/compare/internal/ReplaceWithEditionAction.properties,v
--- compare/org/eclipse/compare/internal/ReplaceWithEditionAction.properties 28 Apr 2004 10:47:12 -0000 1.22
+++ compare/org/eclipse/compare/internal/ReplaceWithEditionAction.properties 13 May 2004 05:23:57 -0000
@@ -37,4 +37,10 @@
noLocalHistoryError= No local history available for selected resource.
replaceError=Cannot replace resource (reason: {0}).
-taskName=Replacing
+taskName=Replacing
+
+
+historyFormat={0} : {1}
+selectEarliest=Select earliest change to undo
+restoringFromHistory=Restoring from history
+error=Error