diff options
author | Bernard Leach | 2011-06-01 21:35:41 +0000 |
---|---|---|
committer | Chris Aniszczyk | 2011-06-02 18:41:47 +0000 |
commit | 707b6ee2391b124f781b767da32bec18206a4f73 (patch) | |
tree | c59c5dfb87d028d74242c082172f7ecd403394f9 | |
parent | c8d570da90bcd6352a0f961513f913376f7d3e0a (diff) | |
download | egit-707b6ee2391b124f781b767da32bec18206a4f73.tar.gz egit-707b6ee2391b124f781b767da32bec18206a4f73.tar.xz egit-707b6ee2391b124f781b767da32bec18206a4f73.zip |
Add workspace change listener support to StagingView
Listens for workspace changes to resources in the current repository
so we can refresh the StagingView.
Bug: 346776
Change-Id: Ifeb136f4bcdd596f35ff0d52c29ffffde28bcc3f
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
4 files changed, 134 insertions, 13 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index d4376827d1..47f68df520 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -3788,6 +3788,12 @@ public class UIText extends NLS { public static String StagingView_LinkSelection; /** */ + public static String StagingView_exceptionTitle; + + /** */ + public static String StagingView_exceptionMessage; + + /** */ public static String SynchronizeWithMenu_custom; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java index 1e6a17f133..a9b893bcde 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java @@ -10,7 +10,10 @@ package org.eclipse.egit.ui.internal.staging; import java.io.IOException; import java.text.MessageFormat; +import java.util.Collection; +import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -23,6 +26,10 @@ import org.eclipse.core.commands.common.CommandException; import org.eclipse.core.expressions.EvaluationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -92,6 +99,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.WorkingTreeIterator; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.dnd.DND; @@ -105,6 +113,7 @@ import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; +import org.eclipse.team.core.Team; import org.eclipse.team.core.TeamException; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; @@ -163,8 +172,32 @@ public class StagingView extends ViewPart { private ISelectionListener selectionChangedListener; + private IResourceChangeListener resourceChangeListener; + private Repository currentRepository; + static class StagingViewUpdate { + Repository repository; + IndexDiff indexDiff; + Collection<String> changedResources; + + StagingViewUpdate(Repository theRepository, + IndexDiff theIndexDiff, Collection<String> theChanges) { + this.repository = theRepository; + this.indexDiff = theIndexDiff; + this.changedResources = theChanges; + } + } + + /** + * Bit-mask describing interesting changes for IResourceChangeListener + * events + */ + private static int INTERESTING_CHANGES = IResourceDelta.CONTENT + | IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO + | IResourceDelta.OPEN | IResourceDelta.REPLACED + | IResourceDelta.TYPE; + private final RefsChangedListener myRefsChangedListener = new RefsChangedListener() { public void onRefsChanged(RefsChangedEvent event) { // refs change when files are committed, we naturally want to remove @@ -379,6 +412,77 @@ public class StagingView extends ViewPart { else preferenceStore.setDefault(UIPreferences.STAGING_VIEW_SYNC_SELECTION, true); + resourceChangeListener = new IResourceChangeListener() { + public void resourceChanged(IResourceChangeEvent event) { + final Collection<String> resourcesToUpdate = new HashSet<String>(); + + try { + event.getDelta().accept(new IResourceDeltaVisitor() { + public boolean visit(IResourceDelta delta) throws CoreException { + // If the file has changed but not in a way that we care + // about (e.g. marker changes to files) then ignore + if (delta.getKind() == IResourceDelta.CHANGED + && (delta.getFlags() & INTERESTING_CHANGES) == 0) + return true; + + final IResource resource = delta.getResource(); + + // skip any non-FILE resources + if (resource.getType() != IResource.FILE) + return true; + + // If the resource is not part of a project under Git + // revision control + final RepositoryMapping mapping = RepositoryMapping.getMapping(resource); + if (mapping == null || mapping.getRepository() != currentRepository) + // Ignore the change + return true; + + // Don't include ignored resources + if (Team.isIgnoredHint(resource)) + return false; + + String repoRelativePath = mapping.getRepoRelativePath(resource); + resourcesToUpdate.add(repoRelativePath); + + return true; + } + }); + } catch (CoreException e) { + MessageDialog.openError(getSite().getShell(), + UIText.StagingView_exceptionTitle, + UIText.StagingView_exceptionMessage); + } + + if (!resourcesToUpdate.isEmpty()) { + final IndexDiff indexDiff; + try { + WorkingTreeIterator iterator = IteratorService.createInitialIterator(currentRepository); + indexDiff = new IndexDiff(currentRepository, Constants.HEAD, iterator); + indexDiff.setFilter(PathFilterGroup.createFromStrings(resourcesToUpdate)); + indexDiff.diff(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + final StagingViewUpdate update = new StagingViewUpdate(currentRepository, indexDiff, resourcesToUpdate); + form.getDisplay().asyncExec(new Runnable() { + public void run() { + if (form.isDisposed()) + return; + + unstagedTableViewer.setInput(update); + stagedTableViewer.setInput(update); + + updateSectionText(); + } + }); + } + } + }; + ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, + IResourceChangeEvent.POST_CHANGE); + updateSectionText(); updateToolbar(); @@ -763,10 +867,9 @@ public class StagingView extends ViewPart { return; final IndexDiff indexDiff = results.get(); - unstagedTableViewer.setInput(new Object[] { repository, - indexDiff }); - stagedTableViewer - .setInput(new Object[] { repository, indexDiff }); + final StagingViewUpdate update = new StagingViewUpdate(currentRepository, indexDiff, null); + unstagedTableViewer.setInput(update); + stagedTableViewer.setInput(update); commitAction.setEnabled(repository.getRepositoryState() .canCommit()); form.setText(StagingView.getRepositoryName(repository)); @@ -822,10 +925,9 @@ public class StagingView extends ViewPart { public void run() { if (form.isDisposed()) return; - unstagedTableViewer.setInput(new Object[] { repository, - indexDiff }); - stagedTableViewer - .setInput(new Object[] { repository, indexDiff }); + StagingViewUpdate update = new StagingViewUpdate(repository, indexDiff, Collections.<String> emptyList()); + unstagedTableViewer.setInput(update); + stagedTableViewer.setInput(update); commitAction.setEnabled(repository.getRepositoryState() .canCommit()); form.setText(StagingView.getRepositoryName(repository)); @@ -1042,6 +1144,7 @@ public class StagingView extends ViewPart { ISelectionService srv = (ISelectionService) getSite().getService( ISelectionService.class); srv.removePostSelectionListener(selectionChangedListener); + ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener); removeListeners(); } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java index 9d7311641f..b25f41fae2 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java @@ -8,10 +8,12 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.staging; +import java.util.Arrays; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; +import org.eclipse.egit.ui.internal.staging.StagingView.StagingViewUpdate; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jgit.lib.IndexDiff; @@ -35,12 +37,10 @@ public class StagingViewContentProvider implements public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput != null) { + if (newInput != null && newInput instanceof StagingViewUpdate) { + StagingViewUpdate update = (StagingViewUpdate)newInput; - Repository repository = (Repository)((Object[])newInput)[0]; - IndexDiff indexDiff = (IndexDiff)((Object[])newInput)[1]; - - if (repository == null || indexDiff == null) + if (update.repository == null || update.indexDiff == null) return; Set<StagingEntry> nodes = new TreeSet<StagingEntry>(new Comparator<StagingEntry>() { @@ -49,6 +49,16 @@ public class StagingViewContentProvider implements } }); + if (update.changedResources != null && update.changedResources.size() != 0) { + nodes.addAll(Arrays.asList(content)); + for (String res : update.changedResources) + for (StagingEntry entry : content) + if (entry.getPath().equals(res)) + nodes.remove(entry); + } + + final IndexDiff indexDiff = update.indexDiff; + final Repository repository = update.repository; if (isWorkspace) { for (String file : indexDiff.getMissing()) nodes.add(new StagingEntry(repository, StagingEntry.State.MISSING, file)); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties index 46ca28d8dd..900a9c0228 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties @@ -1315,6 +1315,8 @@ StagingView_OpenNewCommits=Open new commits StagingView_IndexDiffReload=Staging view reindexing repository {0} StagingView_Refresh=Refresh StagingView_LinkSelection=Link with Editor and Selection +StagingView_exceptionTitle=Refresh Error +StagingView_exceptionMessage=Errors occurred while applying processing change notifications. SynchronizeWithMenu_custom=&Custom... SynchronizeFetchJob_JobName=Fetching changes before synchronization launch |