Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Mayer2016-06-08 15:53:43 -0400
committerLaurent Delaigue2016-06-14 11:09:20 -0400
commit5722fba2307aeda65d7367dd302bcd9b20f02a7a (patch)
treee3a05a8e6b8b942df7aacec421820bbd56ed9c7b
parentc8c94bc43d1b4c479914475566a2690bce73c785 (diff)
downloadorg.eclipse.emf.compare-5722fba2307aeda65d7367dd302bcd9b20f02a7a.tar.gz
org.eclipse.emf.compare-5722fba2307aeda65d7367dd302bcd9b20f02a7a.tar.xz
org.eclipse.emf.compare-5722fba2307aeda65d7367dd302bcd9b20f02a7a.zip
Bug 495741 - Fix computation of visible and filtered diffs
If a node has been filtered out, then refreshTitle() now also considers all the descendants of that node as hidden. So the number of filtered diffs in the title should match the actual number of diffs filtered from the viewer -- except a diff is shown in two different sub-trees and only filtered in one of them. Change-Id: I171552743a4d8c3d702f7830d03098755e688b4d Signed-off-by: Andreas Mayer <anma-e@gmx.de>
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java82
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/FilteredIterator.java58
2 files changed, 109 insertions, 31 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
index e4bd93bf0..a534fc66b 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
@@ -15,15 +15,14 @@ package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
import static com.google.common.base.Predicates.instanceOf;
import static com.google.common.collect.Iterables.any;
-import static com.google.common.collect.Iterables.size;
import static org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.EMFCompareStructureMergeViewerContentProvider.CallbackType.IN_UI_ASYNC;
import static org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.EMFCompareStructureMergeViewerContentProvider.CallbackType.IN_UI_SYNC;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
@@ -36,7 +35,6 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.EventObject;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -104,6 +102,7 @@ import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.Merg
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.TreeCompareInputAdapterFactory;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.TreeNodeCompareInput;
import org.eclipse.emf.compare.ide.ui.internal.util.CompareHandlerService;
+import org.eclipse.emf.compare.ide.ui.internal.util.FilteredIterator;
import org.eclipse.emf.compare.ide.ui.internal.util.JFaceUtil;
import org.eclipse.emf.compare.ide.ui.internal.util.PlatformElementUtil;
import org.eclipse.emf.compare.internal.merge.MergeMode;
@@ -122,6 +121,7 @@ import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.Struc
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.provider.TreeItemProviderAdapterFactorySpec;
import org.eclipse.emf.compare.rcp.ui.internal.util.SWTUtil;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProviderChange;
import org.eclipse.emf.compare.scope.IComparisonScope;
@@ -177,7 +177,7 @@ import org.eclipse.ui.themes.ITheme;
import org.eclipse.ui.themes.IThemeManager;
/**
- * Implementation of {@link AbstractViewerWrapper}.
+ * Implementation of {@link AbstractStructuredViewerWrapper}.
*
* @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
*/
@@ -679,37 +679,57 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
private void refreshTitle() {
// TODO Make sure this is called as little as possible
// Or make this asynchronous?
- if (!getControl().isDisposed()) {
- Composite parent = getControl().getParent();
- Comparison comparison = getCompareConfiguration().getComparison();
- if (parent instanceof CompareViewerSwitchingPane && comparison != null) {
- final Predicate<? super TreeNode> unfilteredNode = new Predicate<TreeNode>() {
- public boolean apply(TreeNode input) {
- return input != null && !JFaceUtil.isFiltered(getViewer(), input, null);
+ if (getControl().isDisposed() || !(getControl().getParent() instanceof CompareViewerSwitchingPane)) {
+ return;
+ }
+
+ if (getCompareConfiguration().getComparison() == null) {
+ return;
+ }
+
+ Set<Diff> allDiffs = getAllDiffs();
+ Set<Diff> visibleDiffs = getVisibleDiffs();
+
+ int visibleDiffCount = visibleDiffs.size();
+ int filteredDiffCount = Sets.difference(allDiffs, visibleDiffs).size();
+ int diffsToMergeCount = Iterables.size(Iterables.filter(visibleDiffs, hasState(
+ DifferenceState.UNRESOLVED)));
+ String titleArgument = EMFCompareIDEUIMessages.getString("EMFCompareStructureMergeViewer.titleDesc", //$NON-NLS-1$
+ diffsToMergeCount, visibleDiffCount, filteredDiffCount);
+
+ ((CompareViewerSwitchingPane)getControl().getParent()).setTitleArgument(titleArgument);
+ }
+
+ private Set<Diff> getAllDiffs() {
+ Comparison comparison = getCompareConfiguration().getComparison();
+ return Sets.newHashSet(comparison.getDifferences());
+ }
+
+ private Set<Diff> getVisibleDiffs() {
+ Set<Diff> visibleDiffs = Sets.newHashSet();
+
+ EMFCompareConfiguration configuration = getCompareConfiguration();
+ Comparison comparison = configuration.getComparison();
+ IDifferenceGroupProvider groupProvider = configuration.getStructureMergeViewerGrouper().getProvider();
+ Predicate<? super EObject> filterPredicate = configuration.getStructureMergeViewerFilter()
+ .getAggregatedPredicate();
+ for (IDifferenceGroup group : groupProvider.getGroups(comparison)) {
+ for (TreeNode node : group.getChildren()) {
+ if (filterPredicate.apply(node)) {
+ if (node.getData() instanceof Diff) {
+ visibleDiffs.add((Diff)node.getData());
}
- };
- final IDifferenceGroupProvider groupProvider = getCompareConfiguration()
- .getStructureMergeViewerGrouper().getProvider();
- final Set<Diff> differences = new LinkedHashSet<Diff>();
- final List<Iterable<TreeNode>> allTreeNodes = new ArrayList<Iterable<TreeNode>>();
- for (Diff diff : comparison.getDifferences()) {
- differences.add(diff);
- allTreeNodes.add(groupProvider.getTreeNodes(diff));
+
+ Iterator<TreeNode> nodes = Iterators.filter(new FilteredIterator<EObject>(node
+ .eAllContents(), filterPredicate), TreeNode.class);
+ Iterator<Diff> diffs = Iterators.filter(Iterators.transform(nodes, TREE_NODE_AS_DIFF),
+ Predicates.notNull());
+ Iterators.addAll(visibleDiffs, diffs);
}
- final Iterable<TreeNode> treeNodes = Iterables.concat(allTreeNodes);
- final Set<TreeNode> visibleNodes = ImmutableSet.copyOf(Iterables.filter(treeNodes,
- unfilteredNode));
- final Set<Diff> visibleDiffs = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(
- visibleNodes, TREE_NODE_AS_DIFF), Diff.class));
-
- final int filteredDiff = Sets.difference(differences, visibleDiffs).size();
- final int differencesToMerge = size(Iterables.filter(visibleDiffs,
- hasState(DifferenceState.UNRESOLVED)));
- ((CompareViewerSwitchingPane)parent).setTitleArgument(EMFCompareIDEUIMessages.getString(
- "EMFCompareStructureMergeViewer.titleDesc", differencesToMerge, visibleNodes.size(), //$NON-NLS-1$
- filteredDiff));
}
}
+
+ return visibleDiffs;
}
static EObject getDataOfTreeNodeOfAdapter(Object object) {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/FilteredIterator.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/FilteredIterator.java
new file mode 100644
index 000000000..71f206ca2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/FilteredIterator.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andreas Mayer - initial implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.internal.util;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.AbstractIterator;
+
+import org.eclipse.emf.common.util.TreeIterator;
+
+/**
+ * A wrapper for a {@link TreeIterator} that only returns nodes that satisfy a predicate and skips all others
+ * and their descendants.
+ *
+ * @param <E>
+ * the type of elements returned by this iterator
+ */
+public class FilteredIterator<E> extends AbstractIterator<E> {
+ private TreeIterator<E> delegate;
+
+ private Predicate<? super E> predicate;
+
+ /**
+ * Constructs a new iterator.
+ *
+ * @param delegate
+ * a tree iterator
+ * @param predicate
+ * the predicate to satisfy; all nodes (including their descendants) for which the predicate
+ * yields {@code false} are skipped
+ */
+ public FilteredIterator(TreeIterator<E> delegate, Predicate<? super E> predicate) {
+ this.delegate = delegate;
+ this.predicate = predicate;
+ }
+
+ @Override
+ protected E computeNext() {
+ while (delegate.hasNext()) {
+ E next = delegate.next();
+ if (predicate.apply(next)) {
+ return next;
+ }
+
+ delegate.prune();
+ }
+
+ endOfData();
+ return null;
+ }
+}

Back to the top