Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2018-08-24 10:29:59 -0400
committerThomas Wolf2019-06-14 14:40:43 -0400
commit5e1ab83c744b633371b0ce3328f7a5fb06d552dd (patch)
tree5142b47c910086a9379e5b94e8dde0bbd06e9deb /org.eclipse.egit.ui/src/org/eclipse
parent347fd6ae9b9b2e2ae5193e1c62164537d24f6334 (diff)
downloadegit-5e1ab83c744b633371b0ce3328f7a5fb06d552dd.tar.gz
egit-5e1ab83c744b633371b0ce3328f7a5fb06d552dd.tar.xz
egit-5e1ab83c744b633371b0ce3328f7a5fb06d552dd.zip
Improve reflog view updates
Update the view only when it is visible, otherwise remember the new input and set it when the view becomes visible. This is the same mechanism as used in StagingView, which has been factored out now into a new class PartVisibilityListener. Make sure the view reacts correctly when the branch of which the reflog is shown is deleted, or when the whole repository is deleted. Bug: 548079 Change-Id: Id429a1e02684298a91747fa99889d4e9ebcdae9a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.ui/src/org/eclipse')
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/PartVisibilityListener.java104
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java155
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java60
3 files changed, 240 insertions, 79 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/PartVisibilityListener.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/PartVisibilityListener.java
new file mode 100644
index 000000000..47f188f2c
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/PartVisibilityListener.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.components;
+
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+
+/**
+ * Maintains a simple boolean flag telling whether the view is currently hidden
+ * or visible. Needs to be registered and unregistered in
+ * {@link org.eclipse.ui.IPartService}. Assumes the view is visible initially.
+ */
+public abstract class PartVisibilityListener implements IPartListener2 {
+
+ private final IWorkbenchPart myself;
+
+ private boolean viewVisible = true;
+
+ /**
+ * Creates a new {@link PartVisibilityListener} with an initial state of
+ * "visible"
+ *
+ * @param part
+ */
+ public PartVisibilityListener(IWorkbenchPart part) {
+ myself = part;
+ }
+
+ /**
+ * Whether the the part this {@link PartVisibilityListener} was instantiated
+ * with is currently visible.
+ *
+ * @return {@code true} if the part is visible, {@cod false} otherwise.
+ */
+ public boolean isVisible() {
+ return viewVisible;
+ }
+
+ private void updateHiddenState(IWorkbenchPartReference partRef,
+ boolean visible) {
+ if (isMe(partRef)) {
+ viewVisible = visible;
+ }
+ }
+
+ /**
+ * Determines whether the {@code partRef} is for the part this
+ * {@link PartVisibilityListener} was instantiated with.
+ *
+ * @param partRef
+ * to check
+ * @return {@code true} if the {@code partRef} is for the part this
+ * {@link PartVisibilityListener} was instantiated with,
+ * {@code false} otherwise
+ */
+ protected final boolean isMe(IWorkbenchPartReference partRef) {
+ return partRef.getPart(false) == myself;
+ }
+
+ @Override
+ public void partClosed(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, false);
+ }
+
+ @Override
+ public void partHidden(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, false);
+ }
+
+ @Override
+ public void partOpened(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, true);
+ }
+
+ @Override
+ public void partVisible(IWorkbenchPartReference partRef) {
+ updateHiddenState(partRef, true);
+ }
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ // Nothing to do
+ }
+
+ @Override
+ public void partDeactivated(IWorkbenchPartReference partRef) {
+ // Nothing to do
+ }
+
+ @Override
+ public void partInputChanged(IWorkbenchPartReference partRef) {
+ // Nothing to do
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
index 2abf2fb62..b8188eeda 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2017 Chris Aniszczyk <caniszczyk@gmail.com> and others.
+ * Copyright (c) 2011, 2019 Chris Aniszczyk <caniszczyk@gmail.com> and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -20,7 +20,10 @@ import java.io.IOException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Adapters;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.egit.core.AdapterUtils;
+import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.egit.core.internal.Utils;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
@@ -34,6 +37,7 @@ import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.actions.ResetMenu;
import org.eclipse.egit.ui.internal.commit.CommitEditor;
import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
+import org.eclipse.egit.ui.internal.components.PartVisibilityListener;
import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.reflog.ReflogViewContentProvider.ReflogInput;
import org.eclipse.egit.ui.internal.repository.tree.RefNode;
@@ -84,13 +88,14 @@ import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartService;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.OpenAndLinkWithEditorHelper;
-import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.FilteredTree;
@@ -131,12 +136,34 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
private ListenerHandle addRefsChangedListener;
+ private final IPreferenceChangeListener prefListener = event -> {
+ if (!RepositoryUtil.PREFS_DIRECTORIES_REL.equals(event.getKey())) {
+ return;
+ }
+ Repository repo = getRepository();
+ if (repo == null
+ || !Activator.getDefault().getRepositoryUtil().contains(repo)) {
+ Control control = refLogTreeViewer.getControl();
+ if (!control.isDisposed()) {
+ control.getDisplay().asyncExec(() -> {
+ if (!control.isDisposed()) {
+ updateView(null);
+ }
+ });
+ }
+ }
+ };
+
private IPropertyChangeListener uiPrefsListener;
private PreferenceBasedDateFormatter dateFormatter;
private IWorkbenchAction switchRepositoriesAction;
+ private VisibilityListener partListener;
+
+ private ReflogInput pendingInput;
+
@SuppressWarnings("unused")
@Override
public void createPartControl(Composite parent) {
@@ -361,6 +388,10 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
};
Activator.getDefault().getPreferenceStore()
.addPropertyChangeListener(uiPrefsListener);
+ InstanceScope.INSTANCE
+ .getNode(org.eclipse.egit.core.Activator.getPluginId())
+ .addPreferenceChangeListener(prefListener);
+
selectionChangedListener = new ISelectionListener() {
@Override
public void selectionChanged(IWorkbenchPart part,
@@ -381,7 +412,10 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
}
};
+ partListener = new VisibilityListener();
IWorkbenchPartSite site = getSite();
+ CommonUtils.getService(site, IPartService.class)
+ .addPartListener(partListener);
ISelectionService service = CommonUtils.getService(site, ISelectionService.class);
service.addPostSelectionListener(selectionChangedListener);
@@ -430,7 +464,11 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
@Override
public void dispose() {
- super.dispose();
+ InstanceScope.INSTANCE
+ .getNode(org.eclipse.egit.core.Activator.getPluginId())
+ .removePreferenceChangeListener(prefListener);
+ CommonUtils.getService(getSite(), IPartService.class)
+ .removePartListener(partListener);
ISelectionService service = CommonUtils.getService(getSite(), ISelectionService.class);
service.removePostSelectionListener(selectionChangedListener);
if (addRefsChangedListener != null) {
@@ -438,6 +476,8 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
}
Activator.getDefault().getPreferenceStore()
.removePropertyChangeListener(uiPrefsListener);
+ pendingInput = null;
+ super.dispose();
if (switchRepositoriesAction != null) {
switchRepositoriesAction.dispose();
switchRepositoriesAction = null;
@@ -468,9 +508,10 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
return;
}
- // Only update when different repository is selected
+ // Only update when different repository is selected, unless we're not
+ // visible
Repository currentRepo = getRepository();
- if (currentRepo == null
+ if (currentRepo == null || !partListener.isVisible()
|| !selectedRepo.getDirectory().equals(
currentRepo.getDirectory())) {
showReflogFor(selectedRepo);
@@ -567,9 +608,53 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
*/
private void showReflogFor(Repository repository, String ref) {
if (repository != null && ref != null) {
- refLogTreeViewer.setInput(new ReflogInput(repository, ref));
- updateRefLink(ref);
- form.setText(getRepositoryName(repository));
+ updateView(new ReflogInput(repository, ref));
+ }
+ }
+
+ private void updateView(ReflogInput input) {
+ if (input != null) {
+ if (!partListener.isVisible()) {
+ pendingInput = input;
+ return;
+ }
+ pendingInput = null;
+ Object currentInput = refLogTreeViewer.getInput();
+ boolean repoChanged = true;
+ boolean needRefUpdate = true;
+ if (currentInput instanceof ReflogInput) {
+ ReflogInput oldInput = (ReflogInput) currentInput;
+ repoChanged = oldInput.getRepository() != input.getRepository();
+ needRefUpdate = repoChanged
+ || !oldInput.getRef().equals(input.getRef());
+ }
+ // Check that the ref exists; fall back to HEAD if not
+ if (!hasRef(input)) {
+ input = new ReflogInput(input.getRepository(), Constants.HEAD);
+ needRefUpdate = true;
+ }
+ refLogTreeViewer.setInput(input);
+ if (needRefUpdate) {
+ updateRefLink(input.getRef());
+ }
+ if (repoChanged) {
+ form.setText(getRepositoryName(input.getRepository()));
+ }
+ } else {
+ // Repository gone?
+ refLogTreeViewer.setInput(null);
+ form.setText(UIText.StagingView_NoSelectionTitle);
+ IToolBarManager toolbar = form.getToolBarManager();
+ toolbar.removeAll();
+ toolbar.update(true);
+ }
+ }
+
+ private static boolean hasRef(ReflogInput input) {
+ try {
+ return input.getRepository().findRef(input.getRef()) != null;
+ } catch (IOException e) {
+ return false;
}
}
@@ -596,27 +681,43 @@ public class ReflogView extends ViewPart implements RefsChangedListener, IShowIn
@Override
public void onRefsChanged(RefsChangedEvent event) {
- PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
- Object currentInput = refLogTreeViewer.getInput();
- if (currentInput instanceof ReflogInput) {
- ReflogInput oldInput = (ReflogInput) currentInput;
- Repository repo = oldInput.getRepository();
- if (repo.getDirectory()
- .equals(event.getRepository().getDirectory())) {
- try {
- if (repo.findRef(oldInput.getRef()) != null) {
- refLogTreeViewer.setInput(
- new ReflogInput(oldInput.getRepository(),
- oldInput.getRef()));
- return;
- }
- } catch (IOException e) {
- // Ignore here
+ Control control = refLogTreeViewer.getControl();
+ if (control != null && !control.isDisposed()) {
+ control.getDisplay().asyncExec(() -> {
+ if (control.isDisposed()) {
+ return;
+ }
+ Object currentInput = refLogTreeViewer.getInput();
+ if (currentInput instanceof ReflogInput) {
+ ReflogInput oldInput = (ReflogInput) currentInput;
+ Repository repo = oldInput.getRepository();
+ if (repo.getDirectory()
+ .equals(event.getRepository().getDirectory())) {
+ updateView(new ReflogInput(oldInput.getRepository(),
+ oldInput.getRef()));
}
- // Fall back to HEAD
- showReflogFor(repo);
}
+ });
+ }
+ }
+
+ private final class VisibilityListener extends PartVisibilityListener {
+
+ public VisibilityListener() {
+ super(ReflogView.this);
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPartReference partRef) {
+ if (isMe(partRef) && pendingInput != null) {
+ ReflogInput input = pendingInput;
+ pendingInput = null;
+ // Verify that the repository still exists
+ if (!input.getRepository().getDirectory().exists()) {
+ input = null;
+ }
+ updateView(input);
}
- });
+ }
}
}
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 b9cc24904..68de0f9a6 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2011, 2018 Bernard Leach <leachbj@bouncycastle.org> and others.
+ * Copyright (C) 2011, 2019 Bernard Leach <leachbj@bouncycastle.org> and others.
* Copyright (C) 2015 SAP SE (Christian Georgi <christian.georgi@sap.com>)
* Copyright (C) 2015 Denis Zygann <d.zygann@web.de>
* Copyright (C) 2016 IBM (Daniel Megert <daniel_megert@ch.ibm.com>)
@@ -90,6 +90,7 @@ import org.eclipse.egit.ui.internal.commit.CommitJob;
import org.eclipse.egit.ui.internal.commit.CommitMessageHistory;
import org.eclipse.egit.ui.internal.commit.CommitProposalProcessor;
import org.eclipse.egit.ui.internal.commit.DiffViewer;
+import org.eclipse.egit.ui.internal.components.PartVisibilityListener;
import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction;
import org.eclipse.egit.ui.internal.decorators.ProblemLabelDecorator;
import org.eclipse.egit.ui.internal.dialogs.CommandConfirmation;
@@ -207,7 +208,6 @@ 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;
@@ -295,14 +295,12 @@ public class StagingView extends ViewPart
private boolean reactOnSelection = true;
- private boolean isViewHidden;
-
/** Tracks the last selection while the view is not active. */
private StructuredSelection lastSelection;
private ISelectionListener selectionChangedListener;
- private IPartListener2 partListener;
+ private PartVisibilityListener partListener;
private ToolBarManager unstagedToolBarManager;
@@ -509,26 +507,10 @@ public class StagingView extends ViewPart
}
}
- private final class PartListener implements IPartListener2 {
+ private final class PartListener extends PartVisibilityListener {
- @Override
- public void partVisible(IWorkbenchPartReference partRef) {
- updateHiddenState(partRef, false);
- }
-
- @Override
- public void partOpened(IWorkbenchPartReference partRef) {
- updateHiddenState(partRef, false);
- }
-
- @Override
- public void partHidden(IWorkbenchPartReference partRef) {
- updateHiddenState(partRef, true);
- }
-
- @Override
- public void partClosed(IWorkbenchPartReference partRef) {
- updateHiddenState(partRef, true);
+ public PartListener() {
+ super(StagingView.this);
}
@Override
@@ -544,7 +526,7 @@ public class StagingView extends ViewPart
}
IWorkbenchPart part = partRef.getPart(false);
StructuredSelection sel = getSelectionOfPart(part);
- if (isViewHidden) {
+ if (!isVisible()) {
// remember last selection in the part so that we can
// synchronize on it as soon as we will be visible
lastSelection = sel;
@@ -556,32 +538,6 @@ public class StagingView extends ViewPart
}
}
-
- private void updateHiddenState(IWorkbenchPartReference partRef,
- boolean hidden) {
- if (isMe(partRef)) {
- isViewHidden = hidden;
- }
- }
-
- private boolean isMe(IWorkbenchPartReference partRef) {
- return partRef.getPart(false) == StagingView.this;
- }
-
- @Override
- public void partDeactivated(IWorkbenchPartReference partRef) {
- //
- }
-
- @Override
- public void partBroughtToTop(IWorkbenchPartReference partRef) {
- //
- }
-
- @Override
- public void partInputChanged(IWorkbenchPartReference partRef) {
- //
- }
}
/**
@@ -3292,7 +3248,7 @@ public class StagingView extends ViewPart
}
private boolean shouldUpdateSelection() {
- return !isDisposed() && !isViewHidden && reactOnSelection;
+ return !isDisposed() && partListener.isVisible() && reactOnSelection;
}
private void reactOnSelection(ISelection sel) {

Back to the top