Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2015-02-18 23:29:39 +0000
committerAndrey Loskutov2015-02-18 23:37:26 +0000
commit4e219194b8accd6f713e48571a73920cffb35144 (patch)
tree91fa90aaae6bb7fa595bb3930bc7881fb7b47895
parentf1c39d34d89ef0ee0fe54ee3ee02d45ffba9af03 (diff)
downloadegit-4e219194b8accd6f713e48571a73920cffb35144.tar.gz
egit-4e219194b8accd6f713e48571a73920cffb35144.tar.xz
egit-4e219194b8accd6f713e48571a73920cffb35144.zip
Refactoring the way how StagingView reacts on selection.
StagingView will ignore all *text* selection changes now. We do not need to do extra work if user just types in the editor. Added PartListener which tracks the part activation/deactivation and so allows to get the selection from the last activated part. As a nice side effect the view tracks now information if it is visible or not and in case the view is not visible, *all* selection changes are ignored (but last one remembered). The calculation of the repository for selected resource is now done in background job. The reload() of the repository is not blocking the caller thread anymore and is done asynhronously (but still in UI thread). Bug: 460243 Change-Id: Ie98d3d796e74f00d754e7e4de9716c7bd0990040 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java5
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java25
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java210
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties1
5 files changed, 205 insertions, 39 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
index 6f5210c046..d970d95d8f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
@@ -110,6 +110,11 @@ public class JobFamilies {
public static final Object REMOVE_FROM_INDEX = new Object();
/**
+ * Updates staging view repository on selection change
+ */
+ public static final Object UPDATE_SELECTION = new Object();
+
+ /**
* Cherry pick commit job
*/
public static final Object CHERRY_PICK = new Object();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
index a4e5650206..22468523d7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
@@ -21,6 +21,8 @@ import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.CommandException;
import org.eclipse.core.expressions.EvaluationContext;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jgit.lib.Ref;
@@ -169,6 +171,29 @@ public class CommonUtils {
return (T) service;
}
+ /**
+ * @param element
+ * @param adapterType
+ * @return the adapted element, or null
+ */
+ public static <T> T getAdapter(Object element, Class<T> adapterType) {
+ if (adapterType.isInstance(element)) {
+ return adapterType.cast(element);
+ }
+ if (element instanceof IAdaptable) {
+ Object adapted = ((IAdaptable) element).getAdapter(adapterType);
+ if (adapterType.isInstance(adapted)) {
+ return adapterType.cast(adapted);
+ }
+ }
+ Object adapted = Platform.getAdapterManager().getAdapter(element,
+ adapterType);
+ if (adapterType.isInstance(adapted)) {
+ return adapterType.cast(adapted);
+ }
+ return null;
+ }
+
private static LinkedList<String> splitIntoDigitAndNonDigitParts(
String input) {
LinkedList<String> parts = new LinkedList<String>();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index ccf8894a02..a715ba3583 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -5045,6 +5045,9 @@ public class UIText extends NLS {
public static String StagingView_Refresh;
/** */
+ public static String StagingView_GetRepo;
+
+ /** */
public static String StagingView_ReplaceWith;
/** */
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 1eb4acdd92..130af1a4e2 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
@@ -28,7 +28,6 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -167,10 +166,13 @@ import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPartService;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
@@ -227,8 +229,12 @@ public class StagingView extends ViewPart implements IShowInSource {
private boolean reactOnSelection = true;
+ private boolean isViewHidden;
+
private ISelectionListener selectionChangedListener;
+ private IPartListener2 partListener;
+
private ToolBarManager unstagedToolBarManager;
private ToolBarManager stagedToolBarManager;
@@ -332,6 +338,94 @@ public class StagingView extends ViewPart implements IShowInSource {
}
}
+ private final class PartListener implements IPartListener2 {
+ StructuredSelection lastSelection;
+
+ public void partVisible(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, false);
+ }
+
+ public void partOpened(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, false);
+ }
+
+ public void partHidden(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, true);
+ }
+
+ public void partClosed(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, true);
+ }
+
+ public void partActivated(IWorkbenchPartReference partRef) {
+ if (isMe(partRef)) {
+ if (lastSelection != null) {
+ // view activated: synchronize with last active part
+ // selection
+ reactOnSelection(lastSelection);
+ lastSelection = null;
+ }
+ return;
+ }
+ IWorkbenchPart part = partRef.getPart(false);
+ StructuredSelection sel = null;
+ if (part instanceof IEditorPart) {
+ IResource resource = getResource((IEditorPart) part);
+ if (resource != null) {
+ sel = new StructuredSelection(resource);
+ }
+ } else {
+ ISelection selection = partRef.getPage().getSelection();
+ if (selection instanceof StructuredSelection) {
+ sel = (StructuredSelection) selection;
+ }
+ }
+ if (isViewHidden) {
+ // remember last selection in the part so that we can
+ // synchronize on it as soon as we will be visible
+ lastSelection = sel;
+ } else {
+ lastSelection = null;
+ if (sel != null) {
+ reactOnSelection(sel);
+ }
+ }
+
+ }
+
+ private IResource getResource(IEditorPart part) {
+ IEditorInput input = part.getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ return ((IFileEditorInput) input).getFile();
+ } else {
+ return CommonUtils.getAdapter(input, IResource.class);
+ }
+ }
+
+ private void updateHiddenState(IWorkbenchPartReference partRef,
+ boolean hidden) {
+ if (isMe(partRef)) {
+ isViewHidden = hidden;
+ }
+ }
+
+ private boolean isMe(IWorkbenchPartReference partRef) {
+ return partRef.getPart(false) == StagingView.this;
+ }
+
+ public void partDeactivated(IWorkbenchPartReference partRef) {
+ //
+ }
+
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ //
+ }
+
+ public void partInputChanged(IWorkbenchPartReference partRef) {
+ //
+ }
+ }
+
static class TreeDecoratingLabelProvider extends DecoratingLabelProvider {
ILabelProvider provider;
@@ -807,20 +901,18 @@ public class StagingView extends ViewPart implements IShowInSource {
selectionChangedListener = new ISelectionListener() {
public void selectionChanged(IWorkbenchPart part,
ISelection selection) {
- if (!reactOnSelection || part == getSite().getPart())
+ if (part == getSite().getPart()) {
return;
-
- // this may happen if we switch between editors
- if (part instanceof IEditorPart) {
- IEditorInput input = ((IEditorPart) part).getEditorInput();
- if (input instanceof IFileEditorInput)
- reactOnSelection(new StructuredSelection(
- ((IFileEditorInput) input).getFile()));
- } else
- reactOnSelection(selection);
+ }
+ // don't accept text selection, only structural one
+ if (selection instanceof StructuredSelection) {
+ reactOnSelection((StructuredSelection) selection);
+ }
}
};
+ partListener = new PartListener();
+
IPreferenceStore preferenceStore = getPreferenceStore();
if (preferenceStore.contains(UIPreferences.STAGING_VIEW_SYNC_SELECTION))
reactOnSelection = preferenceStore.getBoolean(
@@ -886,6 +978,8 @@ public class StagingView extends ViewPart implements IShowInSource {
IWorkbenchPartSite site = getSite();
ISelectionService srv = CommonUtils.getService(site, ISelectionService.class);
srv.addPostSelectionListener(selectionChangedListener);
+ CommonUtils.getService(site, IPartService.class).addPartListener(
+ partListener);
// Use current selection to populate staging view
UIUtils.notifySelectionChangedWithCurrentSelection(
@@ -1863,30 +1957,60 @@ public class StagingView extends ViewPart implements IShowInSource {
};
}
- private void reactOnSelection(ISelection selection) {
- if (selection instanceof StructuredSelection) {
- StructuredSelection ssel = (StructuredSelection) selection;
- if (ssel.size() != 1)
- return;
- Object firstElement = ssel.getFirstElement();
- if (firstElement instanceof IResource)
- showResource((IResource) firstElement);
- else if (firstElement instanceof RepositoryTreeNode) {
- RepositoryTreeNode repoNode = (RepositoryTreeNode) firstElement;
- if (currentRepository != repoNode.getRepository())
- reload(repoNode.getRepository());
- } else if (firstElement instanceof IAdaptable) {
- IResource adapted = (IResource) ((IAdaptable) firstElement).getAdapter(IResource.class);
- if (adapted != null)
- showResource(adapted);
+ private boolean shouldUpdateSelection() {
+ return !isDisposed() && !isViewHidden && reactOnSelection;
+ }
+
+ private void reactOnSelection(StructuredSelection selection) {
+ if (selection.size() != 1 || !shouldUpdateSelection()) {
+ return;
+ }
+ Object firstElement = selection.getFirstElement();
+ if (firstElement instanceof RepositoryTreeNode) {
+ RepositoryTreeNode repoNode = (RepositoryTreeNode) firstElement;
+ if (currentRepository != repoNode.getRepository()) {
+ reload(repoNode.getRepository());
}
+ } else {
+ IResource resource = CommonUtils.getAdapter(firstElement,
+ IResource.class);
+ showResource(resource);
}
}
private void showResource(final IResource resource) {
- Repository newRep = getRepositoryOrNestedSubmoduleRepository(resource);
- if (newRep != null && newRep != currentRepository)
- reload(newRep);
+ if (resource == null || !resource.isAccessible()) {
+ return;
+ }
+ Job.getJobManager().cancel(JobFamilies.UPDATE_SELECTION);
+ Job job = new Job(UIText.StagingView_GetRepo) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ Repository newRep = getRepositoryOrNestedSubmoduleRepository(resource);
+ if (newRep != null && newRep != currentRepository) {
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ reload(newRep);
+ }
+ return Status.OK_STATUS;
+ }
+
+ @Override
+ public boolean belongsTo(Object family) {
+ return JobFamilies.UPDATE_SELECTION == family;
+ }
+
+ @Override
+ public boolean shouldRun() {
+ return shouldUpdateSelection();
+ }
+ };
+ job.setSystem(true);
+ schedule(job, false);
}
private static Repository getRepositoryOrNestedSubmoduleRepository(
@@ -2181,15 +2305,16 @@ public class StagingView extends ViewPart implements IShowInSource {
}
/**
- * Reload the staging view
+ * Reload the staging view asynchronously
*
* @param repository
*/
public void reload(final Repository repository) {
- if (form.isDisposed())
+ if (isDisposed()) {
return;
+ }
if (repository == null) {
- syncExec(new Runnable() {
+ asyncExec(new Runnable() {
public void run() {
clearRepository();
}
@@ -2197,16 +2322,18 @@ public class StagingView extends ViewPart implements IShowInSource {
return;
}
- if (!isValidRepo(repository))
+ if (!isValidRepo(repository)) {
return;
+ }
final boolean repositoryChanged = currentRepository != repository;
- syncExec(new Runnable() {
+ asyncExec(new Runnable() {
public void run() {
- if (form.isDisposed())
+ if (isDisposed()) {
return;
+ }
final IndexDiffData indexDiff = doReload(repository);
boolean indexDiffAvailable;
@@ -2584,18 +2711,23 @@ public class StagingView extends ViewPart implements IShowInSource {
ISelectionService srv = CommonUtils.getService(getSite(), ISelectionService.class);
srv.removePostSelectionListener(selectionChangedListener);
+ CommonUtils.getService(getSite(), IPartService.class)
+ .removePartListener(partListener);
- if(cacheEntry != null)
+ if (cacheEntry != null) {
cacheEntry.removeIndexDiffChangedListener(myIndexDiffListener);
+ }
- if (undoRedoActionGroup != null)
+ if (undoRedoActionGroup != null) {
undoRedoActionGroup.dispose();
+ }
InstanceScope.INSTANCE.getNode(
org.eclipse.egit.core.Activator.getPluginId())
.removePreferenceChangeListener(prefListener);
- if (refsChangedListener != null)
+ if (refsChangedListener != null) {
refsChangedListener.remove();
+ }
disposed = true;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index e2697bd212..c35f387676 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -1758,6 +1758,7 @@ StagingView_RebaseContinue=Continue
StagingView_RebaseLabel=Rebase
StagingView_RebaseSkip=Skip Commit
StagingView_Refresh=Refresh
+StagingView_GetRepo=Updating Repository Information
StagingView_ReplaceWith=Rep&lace With
StagingView_LinkSelection=Link with Editor and Selection
StagingView_replaceWithFileInGitIndex=Replace with &Index

Back to the top