Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffChangeListener.java3
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java38
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/provider/DiffTree.java105
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/mapping/PathTree.java201
-rw-r--r--bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceCommitAction.java8
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java15
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/MergeIncomingChangesAction.java4
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMarkAsMergedHandler.java2
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMergeHandler.java2
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelLabelProvider.java38
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelProviderOperation.java9
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceTeamAwareContentProvider.java68
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffTreeChangesSection.java8
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshModelParticipantJob.java4
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/DiffTreeStatusLineContributionGroup.java8
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java10
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java11
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationOperation.java71
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeLabelProvider.java189
19 files changed, 697 insertions, 97 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffChangeListener.java
index 52a0b8953..21d6bc588 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffChangeListener.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffChangeListener.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.team.core.diff;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
@@ -33,5 +34,7 @@ public interface IDiffChangeListener {
* @param monitor a progress monitor
*/
void diffChanged(IDiffChangeEvent event, IProgressMonitor monitor);
+
+ void propertyChanged(int property, IPath[] paths);
}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java
index 6e21dc854..10d5c5bca 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java
@@ -10,8 +10,7 @@
*******************************************************************************/
package org.eclipse.team.core.diff;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.*;
/**
* A diff tree provides access to a tree of {@link IDiffNode} instances.
@@ -32,6 +31,16 @@ import org.eclipse.core.runtime.IPath;
* @since 3.2
*/
public interface IDiffTree {
+
+ /**
+ * Property constant used to indicate that a particular path may be involved in an operation.
+ */
+ public static final int P_BUSY_HINT = 1;
+
+ /**
+ * Property constant used to indicate that a particular path has descendants that are conflicts.
+ */
+ public static final int P_HAS_DESCENDANT_CONFLICTS = 2;
/**
* Add a listener to the tree. The listener will be informed of any changes
@@ -105,7 +114,6 @@ public interface IDiffTree {
*/
public boolean isEmpty();
-
/**
* Return the number of out-of-sync elements in the given set whose synchronization
* state matches the given mask. A mask of 0 assumes a direct match of the given state.
@@ -120,5 +128,29 @@ public interface IDiffTree {
* @return the number of matching resources in the set.
*/
public long countFor(int state, int mask);
+
+ /**
+ * Set the given diff nodes and all their parents to busy
+ * @param diffs the busy diffs
+ * @param monitor a progress monitor or <code>null</code> if progress indication
+ * is not required
+ */
+ public void setBusy(IDiffNode[] diffs, IProgressMonitor monitor);
+
+ /**
+ * Return the value of the property for the given path.
+ * @param path the path
+ * @param property the property
+ * @return the value of the property
+ */
+ public boolean getProperty(IPath path, int property);
+
+
+ /**
+ * Clear all busy properties in this tree.
+ * @param monitor a progress monitor or <code>null</code> if progress indication
+ * is not required
+ */
+ public void clearBusy(IProgressMonitor monitor);
}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/provider/DiffTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/provider/DiffTree.java
index 829ecee65..ed411b966 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/provider/DiffTree.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/diff/provider/DiffTree.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.team.core.diff.provider;
+import java.util.*;
+
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ILock;
@@ -34,6 +36,12 @@ import org.eclipse.team.internal.core.subscribers.DiffTreeStatistics;
*/
public class DiffTree implements IDiffTree {
+ /**
+ * Constant that indicates the start of the property value
+ * range that clients can use when storing properties in this tree.
+ */
+ public static final int START_CLIENT_PROPERTY_RANGE = 1024;
+
private ListenerList listeners = new ListenerList();
private PathTree pathTree = new PathTree();
@@ -46,6 +54,8 @@ public class DiffTree implements IDiffTree {
private boolean lockedForModification;
+ private Map propertyChanges = new HashMap();
+
/**
* Create an empty diff tree.
*/
@@ -123,9 +133,9 @@ public class DiffTree implements IDiffTree {
public void add(IDiffNode delta) {
try {
beginInput();
- boolean alreadyExists = getDiff(delta.getPath()) != null;
+ IDiffNode oldDiff = getDiff(delta.getPath());
internalAdd(delta);
- if (alreadyExists) {
+ if (oldDiff != null) {
internalChanged(delta);
} else {
internalAdded(delta);
@@ -223,11 +233,15 @@ public class DiffTree implements IDiffTree {
private void fireChanges(final IProgressMonitor monitor) {
// Use a synchronized block to ensure that the event we send is static
final DiffChangeEvent event;
+ final Map propertyChanges;
+
synchronized(this) {
event = getChangeEvent();
resetChanges();
+ propertyChanges = this.propertyChanges;
+ this.propertyChanges = new HashMap();
}
- if(event.isEmpty() && ! event.isReset()) return;
+ if(event.isEmpty() && ! event.isReset() && propertyChanges.isEmpty()) return;
Object[] listeners = this.listeners.getListeners();
for (int i = 0; i < listeners.length; i++) {
final IDiffChangeListener listener = (IDiffChangeListener)listeners[i];
@@ -238,7 +252,15 @@ public class DiffTree implements IDiffTree {
public void run() throws Exception {
try {
lockedForModification = true;
- listener.diffChanged(event, Policy.subMonitorFor(monitor, 100));
+ if (!event.isEmpty() || event.isReset())
+ listener.diffChanged(event, Policy.subMonitorFor(monitor, 100));
+ for (Iterator iter = propertyChanges.keySet().iterator(); iter.hasNext();) {
+ Integer key = (Integer) iter.next();
+ Set paths = (Set)propertyChanges.get(key);
+ listener.propertyChanged(key.intValue(), (IPath[]) paths.toArray(new IPath[paths
+ .size()]));
+ }
+
} finally {
lockedForModification = false;
}
@@ -270,14 +292,19 @@ public class DiffTree implements IDiffTree {
statistics.remove(oldDiff);
statistics.add(delta);
}
+ boolean isConflict = false;
+ if (delta instanceof IThreeWayDiff) {
+ IThreeWayDiff twd = (IThreeWayDiff) delta;
+ isConflict = twd.getDirection() == IThreeWayDiff.CONFLICTING;
+ }
+ setPropertyToRoot(delta, P_HAS_DESCENDANT_CONFLICTS, isConflict);
}
private void internalRemove(IDiffNode delta) {
Assert.isTrue(!lockedForModification);
- IDiffNode oldDiff = (IDiffNode)pathTree.get(delta.getPath());
- if(oldDiff != null) {
- statistics.remove(oldDiff);
- }
+ statistics.remove(delta);
+ setPropertyToRoot(delta, P_HAS_DESCENDANT_CONFLICTS, false);
+ setPropertyToRoot(delta, P_BUSY_HINT, false);
pathTree.remove(delta.getPath());
}
@@ -326,4 +353,66 @@ public class DiffTree implements IDiffTree {
return pathTree.size();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffTree#setPropertyToRoot(org.eclipse.core.runtime.IPath, int, boolean)
+ */
+ public void setPropertyToRoot(IDiffNode node, int property, boolean value) {
+ try {
+ beginInput();
+ IPath[] paths = pathTree.setPropogatedProperty(node.getPath(), property, value);
+ accumulatePropertyChanges(property, paths);
+ } finally {
+ endInput(null);
+ }
+ }
+
+ private void accumulatePropertyChanges(int property, IPath[] paths) {
+ Integer key = new Integer(property);
+ Set changes = (Set)propertyChanges.get(key);
+ if (changes == null) {
+ changes = new HashSet();
+ propertyChanges.put(key, changes);
+ }
+ for (int i = 0; i < paths.length; i++) {
+ IPath path = paths[i];
+ changes.add(path);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffTree#getProperty(org.eclipse.core.runtime.IPath, int)
+ */
+ public boolean getProperty(IPath path, int property) {
+ return pathTree.getProperty(path, property);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffTree#setBusy(org.eclipse.team.core.diff.IDiffNode[], org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void setBusy(IDiffNode[] diffs, IProgressMonitor monitor) {
+ try {
+ beginInput();
+ for (int i = 0; i < diffs.length; i++) {
+ IDiffNode node = diffs[i];
+ setPropertyToRoot(node, P_BUSY_HINT, true);
+ }
+ } finally {
+ endInput(monitor);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffTree#clearBusy(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void clearBusy(IProgressMonitor monitor) {
+ try {
+ IPath[] paths = pathTree.getPaths();
+ for (int i = 0; i < paths.length; i++) {
+ IPath path = paths[i];
+ pathTree.setPropogatedProperty(path, P_BUSY_HINT, false);
+ }
+ } finally {
+ endInput(monitor);
+ }
+ }
}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/mapping/PathTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/mapping/PathTree.java
index dd2be75f0..aefa8bad8 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/mapping/PathTree.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/mapping/PathTree.java
@@ -19,9 +19,46 @@ import org.eclipse.core.runtime.IPath;
*/
public class PathTree {
- private Map objects = new HashMap();
+ class Node {
+ Object payload;
+ Set descendantsWithPayload;
+ int flags;
+ public boolean isEmpty() {
+ return payload == null && (descendantsWithPayload == null || descendantsWithPayload.isEmpty());
+ }
+ public Object getPayload() {
+ return payload;
+ }
+ public void setPayload(Object payload) {
+ this.payload = payload;
+ }
+ public boolean hasDescendants() {
+ return descendantsWithPayload != null && !descendantsWithPayload.isEmpty();
+ }
+ public boolean hasFlag(int propertyBit) {
+ return (flags & propertyBit) != 0;
+ }
+ public void setProperty(int propertyBit, boolean value) {
+ if (value)
+ flags |= propertyBit;
+ else
+ flags ^= propertyBit;
+ }
+ public boolean descendantHasFlag(int property) {
+ if (hasDescendants()) {
+ for (Iterator iter = descendantsWithPayload.iterator(); iter.hasNext();) {
+ IPath path = (IPath) iter.next();
+ Node child = getNode(path);
+ if (child.hasFlag(property)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
- private Map parents = new HashMap();
+ private Map objects = new HashMap();
/**
* Return the object at the given path or <code>null</code>
@@ -30,7 +67,10 @@ public class PathTree {
* @return the object at the given path or <code>null</code>
*/
public synchronized Object get(IPath path) {
- return objects.get(path);
+ Node node = getNode(path);
+ if (node == null)
+ return null;
+ return node.getPayload();
}
/**
@@ -42,8 +82,12 @@ public class PathTree {
* @return the previous object at that path or <code>null</code>
*/
public synchronized Object put(IPath path, Object object) {
- Object previous = get(path);
- objects.put(path, object);
+ Node node = getNode(path);
+ if (node == null) {
+ node = addNode(path);
+ }
+ Object previous = node.getPayload();
+ node.setPayload(object);
if(previous == null) {
addToParents(path, path);
}
@@ -51,7 +95,7 @@ public class PathTree {
}
/**
- * Remove the removed object at the given path and return
+ * Remove the object at the given path and return
* the removed object or <code>null</code> if no
* object was removed.
* @param path the path to remove
@@ -59,9 +103,16 @@ public class PathTree {
* the removed object or <code>null</code>
*/
public synchronized Object remove(IPath path) {
- Object previous = objects.remove(path);
- if(previous == null) {
+ Node node = getNode(path);
+ if (node == null)
+ return null;
+ Object previous = node.getPayload();
+ node.setPayload(null);
+ if(previous != null) {
removeFromParents(path, path);
+ if (node.isEmpty()) {
+ removeNode(path);
+ }
}
return previous;
@@ -74,8 +125,10 @@ public class PathTree {
*/
public synchronized boolean hasChildren(IPath path) {
if (path.isEmpty()) return !objects.isEmpty();
- Set allDescendants = (Set)parents.get(path);
- return (allDescendants != null && !allDescendants.isEmpty());
+ Node node = getNode(path);
+ if (node == null)
+ return false;
+ return node.hasDescendants();
}
/**
@@ -87,19 +140,22 @@ public class PathTree {
// OPTIMIZE: could be optimized so that we don't traverse all the deep
// children to find the immediate ones.
Set children = new HashSet();
- Set possibleChildren = (Set)parents.get(path);
- if(possibleChildren != null) {
- for (Iterator it = possibleChildren.iterator(); it.hasNext();) {
- Object next = it.next();
- IPath descendantPath = (IPath)next;
- IPath childPath = null;
- if(descendantPath.segmentCount() == (path.segmentCount() + 1)) {
- childPath = descendantPath;
- } else if (descendantPath.segmentCount() > path.segmentCount()) {
- childPath = path.append(descendantPath.segment(path.segmentCount()));
- }
- if (childPath != null) {
- children.add(childPath);
+ Node node = getNode(path);
+ if (node != null) {
+ Set possibleChildren = node.descendantsWithPayload;
+ if(possibleChildren != null) {
+ for (Iterator it = possibleChildren.iterator(); it.hasNext();) {
+ Object next = it.next();
+ IPath descendantPath = (IPath)next;
+ IPath childPath = null;
+ if(descendantPath.segmentCount() == (path.segmentCount() + 1)) {
+ childPath = descendantPath;
+ } else if (descendantPath.segmentCount() > path.segmentCount()) {
+ childPath = path.append(descendantPath.segment(path.segmentCount()));
+ }
+ if (childPath != null) {
+ children.add(childPath);
+ }
}
}
}
@@ -113,10 +169,13 @@ public class PathTree {
// this is the leaf that was just added
addedParent = true;
} else {
- Set children = (Set)parents.get(parent);
+ Node node = getNode(parent);
+ if (node == null)
+ node = addNode(parent);
+ Set children = node.descendantsWithPayload;
if (children == null) {
children = new HashSet();
- parents.put(parent, children);
+ node.descendantsWithPayload = children;
// this is a new folder in the sync set
addedParent = true;
}
@@ -133,19 +192,27 @@ public class PathTree {
private boolean removeFromParents(IPath path, IPath parent) {
// this flag is used to indicate if the parent was removed from the set
boolean removedParent = false;
- Set children = (Set)parents.get(parent);
- if (children == null) {
+ Node node = getNode(parent);
+ if (node == null) {
// this is the leaf
removedParent = true;
} else {
- children.remove(path);
- if (children.isEmpty()) {
- parents.remove(parent);
+ Set children = node.descendantsWithPayload;
+ if (children == null) {
+ // this is the leaf
removedParent = true;
+ } else {
+ children.remove(path);
+ if (children.isEmpty()) {
+ node.descendantsWithPayload = null;
+ if (node.isEmpty())
+ removeNode(parent);
+ removedParent = true;
+ }
}
}
// if the parent wasn't removed and the resource was, record it
- if ((parent .isEmpty() || !removeFromParents(path, parent.removeLastSegments(1))) && removedParent) {
+ if ((parent.segmentCount() == 0 || !removeFromParents(path, parent.removeLastSegments(1))) && removedParent) {
// TODO: may not need to record this
//internalRemovedSubtreeRoot(parent);
}
@@ -157,7 +224,6 @@ public class PathTree {
*/
public void clear() {
objects.clear();
- parents.clear();
}
/**
@@ -176,7 +242,9 @@ public class PathTree {
List result = new ArrayList();
for (Iterator iter = objects.keySet().iterator(); iter.hasNext();) {
IPath path = (IPath) iter.next();
- result.add(path);
+ Node node = getNode(path);
+ if (node.getPayload() != null)
+ result.add(path);
}
return (IPath[]) result.toArray(new IPath[result.size()]);
}
@@ -185,7 +253,14 @@ public class PathTree {
* Return all the values contained in this path tree.
*/
public Collection values() {
- return objects.values();
+ List result = new ArrayList();
+ for (Iterator iter = objects.keySet().iterator(); iter.hasNext();) {
+ IPath path = (IPath) iter.next();
+ Node node = getNode(path);
+ if (node.getPayload() != null)
+ result.add(node.getPayload());
+ }
+ return result;
}
/**
@@ -193,7 +268,63 @@ public class PathTree {
* @return the number of nodes contained in this path tree
*/
public int size() {
- return objects.size();
+ return values().size();
+ }
+
+ private Node getNode(IPath path) {
+ return (Node)objects.get(path);
+ }
+
+ private Node addNode(IPath path) {
+ Node node;
+ node = new Node();
+ objects.put(path, node);
+ return node;
+ }
+
+ private Object removeNode(IPath path) {
+ return objects.remove(path);
+ }
+
+ /**
+ * Set the property for the given path and propogate the
+ * bit to the root. The property is only set if the given path
+ * already exists in the tree.
+ * @param path the path
+ * @param property the property bit to set
+ * @param whether the bit should be on or off
+ * @return the paths whose bit changed
+ */
+ public synchronized IPath[] setPropogatedProperty(IPath path, int property, boolean value) {
+ Set changed = new HashSet();
+ internalSetPropertyBit(path, property, value, changed);
+ return (IPath[]) changed.toArray(new IPath[changed.size()]);
+ }
+
+ private void internalSetPropertyBit(IPath path, int property, boolean value, Set changed) {
+ if (path.segmentCount() == 0)
+ return;
+ Node node = getNode(path);
+ if (node == null)
+ return;
+ // No need to set it if the value hans't changed
+ if (value == node.hasFlag(property))
+ return;
+ // Only unset the property if no descendants have the flag set
+ if (!value && node.descendantHasFlag(property))
+ return;
+ node.setProperty(property, value);
+ changed.add(path);
+ internalSetPropertyBit(path.removeLastSegments(1), property, value, changed);
+ }
+
+ public synchronized boolean getProperty(IPath path, int property) {
+ if (path.segmentCount() == 0)
+ return false;
+ Node node = getNode(path);
+ if (node == null)
+ return false;
+ return (node.hasFlag(property));
}
}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceCommitAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceCommitAction.java
index 2dd92a5a2..a5065c060 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceCommitAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceCommitAction.java
@@ -11,6 +11,7 @@
package org.eclipse.team.internal.ccvs.ui.mappings;
import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
@@ -67,6 +68,13 @@ public class WorkspaceCommitAction extends ModelProviderAction implements IDiffC
updateEnablement();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffChangeListener#propertyChanged(int, org.eclipse.core.runtime.IPath[])
+ */
+ public void propertyChanged(int property, IPath[] paths) {
+ // Do nothing
+ }
+
private void updateEnablement() {
boolean enabled = (getDiffTree().countFor(IThreeWayDiff.OUTGOING, IThreeWayDiff.DIRECTION_MASK) > 0)
&& (getDiffTree().countFor(IThreeWayDiff.CONFLICTING, IThreeWayDiff.DIRECTION_MASK) == 0);
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java
index 715591351..6802a9707 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java
@@ -36,6 +36,7 @@ import org.eclipse.team.core.mapping.IResourceMappingScope;
import org.eclipse.team.core.synchronize.FastSyncInfoFilter;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.internal.core.mapping.CompoundResourceTraversal;
import org.eclipse.team.internal.ui.synchronize.SyncInfoModelElement;
import org.eclipse.team.ui.TeamImages;
import org.eclipse.team.ui.TeamUI;
@@ -792,7 +793,19 @@ public class Utils {
}
}
if (buffer.length() == 0)
- return new Date().toString(); //$NON-NLS-1$
+ return new Date().toString();
return buffer.toString();
}
+
+ public static ResourceTraversal[] getTraversals(Object[] elements) throws CoreException {
+ CompoundResourceTraversal traversal = new CompoundResourceTraversal();
+ for (int i = 0; i < elements.length; i++) {
+ Object object = elements[i];
+ ResourceMapping mapping = getResourceMapping(object);
+ if (mapping != null) {
+ traversal.addTraversals(mapping.getTraversals(ResourceMappingContext.LOCAL_CONTEXT, null));
+ }
+ }
+ return traversal.asTraversals();
+ }
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/MergeIncomingChangesAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/MergeIncomingChangesAction.java
index df7cc319f..f1c89464f 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/MergeIncomingChangesAction.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/MergeIncomingChangesAction.java
@@ -52,8 +52,8 @@ public class MergeIncomingChangesAction extends ModelProviderAction {
}
final IMergeContext context = (IMergeContext)((ModelSynchronizeParticipant)getConfiguration().getParticipant()).getContext();
try {
- new SynchronizationOperation(getConfiguration()) {
- public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ new SynchronizationOperation(getConfiguration(), getContext().getScope().getMappings()) {
+ public void execute(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
try {
// TODO: Should validate before merging
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMarkAsMergedHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMarkAsMergedHandler.java
index f042fa116..3922d86da 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMarkAsMergedHandler.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMarkAsMergedHandler.java
@@ -44,7 +44,7 @@ public class ResourceMarkAsMergedHandler extends MergeActionHandler {
/* (non-Javadoc)
* @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
*/
- public void run(IProgressMonitor monitor)
+ public void execute(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
try {
final IMergeContext context = (IMergeContext) getContext();
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMergeHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMergeHandler.java
index fb560b931..33ffaf370 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMergeHandler.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceMergeHandler.java
@@ -39,7 +39,7 @@ public class ResourceMergeHandler extends MergeActionHandler {
/* (non-Javadoc)
* @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
*/
- public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ public void execute(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
try {
IMergeContext context = (IMergeContext)getContext();
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelLabelProvider.java
index e6f765c96..62a1a4091 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelLabelProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelLabelProvider.java
@@ -11,18 +11,18 @@
package org.eclipse.team.internal.ui.mapping;
import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.team.core.diff.IDiffNode;
+import org.eclipse.team.core.diff.IDiffTree;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.ui.mapping.SynchronizationLabelProvider;
-import org.eclipse.ui.navigator.IExtensionStateModel;
/**
* Resource label provider that can decorate using sync state.
*/
public class ResourceModelLabelProvider extends
- SynchronizationLabelProvider {
+ SynchronizationLabelProvider implements IFontProvider {
private ILabelProvider provider = new ResourceMappingLabelProvider();
@@ -55,20 +55,24 @@ public class ResourceModelLabelProvider extends
}
return null;
}
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.navigator.IDescriptionProvider#getDescription(java.lang.Object)
- */
- public String getDescription(Object anElement) {
- // TODO Auto-generated method stub
- return null;
+
+ protected boolean isBusy(Object element) {
+ if (element instanceof IResource) {
+ IResource resource = (IResource) element;
+ ISynchronizationContext context = getContext();
+ if (context != null)
+ return context.getDiffTree().getProperty(resource.getFullPath(), IDiffTree.P_BUSY_HINT);
+ }
+ return super.isBusy(element);
}
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.ui.mapping.SynchronizationOperationLabelProvider#init(org.eclipse.ui.navigator.IExtensionStateModel, org.eclipse.jface.viewers.ITreeContentProvider)
- */
- public void init(IExtensionStateModel aStateModel, ITreeContentProvider aContentProvider) {
- // TODO Auto-generated method stub
- super.init(aStateModel, aContentProvider);
+
+ protected boolean hasDecendantConflicts(Object element) {
+ if (element instanceof IResource) {
+ IResource resource = (IResource) element;
+ ISynchronizationContext context = getContext();
+ if (context != null)
+ return context.getDiffTree().getProperty(resource.getFullPath(), IDiffTree.P_HAS_DESCENDANT_CONFLICTS);
+ }
+ return super.hasDecendantConflicts(element);
}
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelProviderOperation.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelProviderOperation.java
index 6a08794b1..cfdb73e58 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelProviderOperation.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceModelProviderOperation.java
@@ -26,11 +26,8 @@ import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
public abstract class ResourceModelProviderOperation extends SynchronizationOperation {
- private final Object[] elements;
-
protected ResourceModelProviderOperation(ISynchronizePageConfiguration configuration, Object[] elements) {
- super(configuration);
- this.elements = elements;
+ super(configuration, elements);
}
/**
@@ -137,10 +134,6 @@ public abstract class ResourceModelProviderOperation extends SynchronizationOper
* @return the filter used to match diffs to which this action applies
*/
protected abstract FastDiffFilter getDiffFilter();
-
- public Object[] getElements() {
- return elements;
- }
/* (non-Javadoc)
* @see org.eclipse.team.ui.mapping.ModelProviderOperation#shouldRun()
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceTeamAwareContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceTeamAwareContentProvider.java
index c8f268a0c..9386d839a 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceTeamAwareContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/ResourceTeamAwareContentProvider.java
@@ -16,11 +16,11 @@ import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.*;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
-import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.*;
import org.eclipse.team.core.diff.IDiffNode;
import org.eclipse.team.core.diff.IDiffTree;
-import org.eclipse.team.core.mapping.IResourceMappingScope;
-import org.eclipse.team.core.mapping.ISynchronizationContext;
+import org.eclipse.team.core.mapping.*;
+import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.ui.mapping.SynchronizationContentProvider;
import org.eclipse.ui.model.WorkbenchContentProvider;
@@ -212,11 +212,67 @@ public class ResourceTeamAwareContentProvider extends SynchronizationContentProv
IFolder folder = (IFolder) element;
// For folders check to see if the delta contains any children
ISynchronizationContext context = getContext();
- IDiffTree tree = context.getDiffTree();
- if (tree.getChildren(folder.getFullPath()).length > 0) {
- return true;
+ if (context != null) {
+ IDiffTree tree = context.getDiffTree();
+ if (tree.getChildren(folder.getFullPath()).length > 0) {
+ return true;
+ }
}
}
return false;
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#propertyChanged(int, org.eclipse.core.runtime.IPath[])
+ */
+ public void propertyChanged(final int property, final IPath[] paths) {
+ Utils.syncExec(new Runnable() {
+ public void run() {
+ ISynchronizationContext context = getContext();
+ if (context != null) {
+ IResource[] resources = getResources(paths);
+ if (resources.length > 0)
+ ((AbstractTreeViewer)getViewer()).update(resources, null);
+ }
+ }
+ }, (StructuredViewer)getViewer());
+ }
+
+ private IResource[] getResources(IPath[] paths) {
+ List resources = new ArrayList();
+ for (int i = 0; i < paths.length; i++) {
+ IPath path = paths[i];
+ IResource resource = getResource(path);
+ if (resource != null)
+ resources.add(resource);
+ }
+ return (IResource[]) resources.toArray(new IResource[resources.size()]);
+ }
+
+ private IResource getResource(IPath path) {
+ // Does the resource exist locally
+ IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+ if (resource != null) {
+ return resource;
+ }
+ // Look in the diff tree for a phantom
+ ISynchronizationContext context = getContext();
+ if (context != null) {
+ IResourceDiffTree diffTree = context.getDiffTree();
+ // Is there a diff for the path
+ IDiffNode node = diffTree.getDiff(path);
+ if (node != null) {
+ return diffTree.getResource(node);
+ }
+ // Is there any descendants of the path
+ if (diffTree.getChildren(path).length > 0) {
+ if (path.segmentCount() == 1) {
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
+ } else if (path.segmentCount() > 1) {
+ return ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
+ }
+ }
+ }
+ return null;
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffTreeChangesSection.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffTreeChangesSection.java
index 56728274c..41846c14d 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffTreeChangesSection.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffTreeChangesSection.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
@@ -96,6 +97,13 @@ public class DiffTreeChangesSection extends ForwardingChangesSection implements
calculateDescription();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffChangeListener#propertyChanged(int, org.eclipse.core.runtime.IPath[])
+ */
+ public void propertyChanged(int property, IPath[] paths) {
+ // Do nothing
+ }
+
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(ISynchronizePageConfiguration.P_MODE)) {
calculateDescription();
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshModelParticipantJob.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshModelParticipantJob.java
index 3502eb026..f0fb00d2a 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshModelParticipantJob.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshModelParticipantJob.java
@@ -43,6 +43,10 @@ public class RefreshModelParticipantJob extends RefreshParticipantJob {
changes.put(node.getPath(), node);
}
}
+
+ public void propertyChanged(int property, IPath[] paths) {
+ // Do nothing
+ }
}
public RefreshModelParticipantJob(ISynchronizeParticipant participant, String jobName, String taskName, ResourceMapping[] mappings, IRefreshSubscriberListener listener) {
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/DiffTreeStatusLineContributionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/DiffTreeStatusLineContributionGroup.java
index 08022461c..9881ef366 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/DiffTreeStatusLineContributionGroup.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/DiffTreeStatusLineContributionGroup.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.team.internal.ui.synchronize.actions;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.diff.*;
@@ -57,5 +58,12 @@ public class DiffTreeStatusLineContributionGroup extends
public void diffChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
updateCounts();
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffChangeListener#propertyChanged(int, org.eclipse.core.runtime.IPath[])
+ */
+ public void propertyChanged(int property, IPath[] paths) {
+ // Do nothing
+ }
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java
index 4945308ca..4d84305e3 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java
@@ -15,8 +15,7 @@ import java.util.List;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.ResourceTraversal;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.*;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.*;
@@ -284,6 +283,13 @@ public abstract class SynchronizationContentProvider implements ICommonContentPr
public void diffChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
refresh();
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.diff.IDiffChangeListener#propertyChanged(int, org.eclipse.core.runtime.IPath[])
+ */
+ public void propertyChanged(int property, IPath[] paths) {
+ // Property changes only effect labels
+ }
/**
* Refresh the subtree associated with this model.
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java
index 40f1d99bd..dbf659879 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java
@@ -18,8 +18,7 @@ import org.eclipse.team.core.mapping.IResourceMappingScope;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.ui.synchronize.AbstractSynchronizeLabelProvider;
import org.eclipse.ui.IMemento;
-import org.eclipse.ui.navigator.ICommonLabelProvider;
-import org.eclipse.ui.navigator.IExtensionStateModel;
+import org.eclipse.ui.navigator.*;
/**
* A label provider wrapper that adds synchronization image and/or text decorations
@@ -33,7 +32,7 @@ import org.eclipse.ui.navigator.IExtensionStateModel;
*
* @since 3.2
*/
-public abstract class SynchronizationLabelProvider extends AbstractSynchronizeLabelProvider implements ICommonLabelProvider {
+public abstract class SynchronizationLabelProvider extends AbstractSynchronizeLabelProvider implements ICommonLabelProvider, IFontProvider {
private IResourceMappingScope scope;
private ISynchronizationContext context;
@@ -107,10 +106,10 @@ public abstract class SynchronizationLabelProvider extends AbstractSynchronizeLa
*/
public String getDescription(Object anElement) {
ILabelProvider provider = getDelegateLabelProvider();
- if (provider instanceof ICommonLabelProvider) {
- return ((ICommonLabelProvider) provider).getDescription(anElement);
+ if (provider instanceof IDescriptionProvider) {
+ return ((IDescriptionProvider) provider).getDescription(anElement);
}
- return getDelegateLabelProvider().toString();
+ return null;
}
/* (non-Javadoc)
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationOperation.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationOperation.java
index 518e4662e..b21107cae 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationOperation.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationOperation.java
@@ -10,8 +10,15 @@
*******************************************************************************/
package org.eclipse.team.ui.mapping;
-import org.eclipse.team.core.mapping.IMergeContext;
-import org.eclipse.team.core.mapping.ISynchronizationContext;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.diff.IDiffNode;
+import org.eclipse.team.core.mapping.*;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
+import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.ui.TeamOperation;
import org.eclipse.team.ui.compare.IModelBuffer;
import org.eclipse.team.ui.operations.ModelSynchronizeParticipant;
@@ -40,6 +47,7 @@ import org.eclipse.ui.IWorkbenchPart;
public abstract class SynchronizationOperation extends TeamOperation {
private final ISynchronizePageConfiguration configuration;
+ private final Object[] elements;
/*
* Helper method for extracting the part safely from a configuration
@@ -54,11 +62,23 @@ public abstract class SynchronizationOperation extends TeamOperation {
return null;
}
- protected SynchronizationOperation(ISynchronizePageConfiguration configuration) {
+ /**
+ * Create a synchronize operation that operations on the given elements
+ * @param configuration the configuration for the page the operation is associated with
+ * @param elements the elements to be operated on
+ */
+ protected SynchronizationOperation(ISynchronizePageConfiguration configuration, Object[] elements) {
super(getPart(configuration));
this.configuration = configuration;
+ this.elements = elements;
}
+ /**
+ * Return the configuration for the page from which this
+ * operation was launched.
+ * @return the configuration for the page from which this
+ * operation was launched
+ */
public ISynchronizePageConfiguration getConfiguration() {
return configuration;
}
@@ -72,6 +92,14 @@ public abstract class SynchronizationOperation extends TeamOperation {
}
/**
+ * Return the model elements that are the target of this operation.
+ * @return the model elements that are the target of this operation
+ */
+ public Object[] getElements() {
+ return elements;
+ }
+
+ /**
* Make <code>shouldRun</code> public so the result
* can be used to provide handler enablement
*/
@@ -90,6 +118,43 @@ public abstract class SynchronizationOperation extends TeamOperation {
public IModelBuffer getTargetBuffer() {
return null;
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public final void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ setContextBusy(monitor);
+ execute(monitor);
+ } finally {
+ clearContextBusy(monitor);
+ }
+ }
+
+ private void clearContextBusy(final IProgressMonitor monitor) {
+ final IResourceDiffTree diffTree = getContext().getDiffTree();
+ diffTree.clearBusy(monitor);
+ }
+ private void setContextBusy(final IProgressMonitor monitor) {
+ try {
+ ResourceTraversal[] traversals = Utils.getTraversals(getElements());
+ final IResourceDiffTree diffTree = getContext().getDiffTree();
+ IDiffNode[] diffs = diffTree.getDiffs(traversals);
+ diffTree.setBusy(diffs, monitor);
+ } catch (CoreException e) {
+ TeamUIPlugin.log(e);
+ }
+ }
+
+ /**
+ * Execute the operation. Subclasses should implement the operations behavior in the
+ * execute method. Clients should call either {@link #run()} or {@link #run(IProgressMonitor)}
+ * to invoke the operation.
+ * @param monitor a progress monitor
+ * @throws InvocationTargetException
+ * @throws InterruptedException
+ */
+ protected abstract void execute(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException;
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeLabelProvider.java
index 72c8516a0..b12556973 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeLabelProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeLabelProvider.java
@@ -10,17 +10,25 @@
*******************************************************************************/
package org.eclipse.team.ui.synchronize;
+import java.util.*;
+
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.mapping.ModelProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
import org.eclipse.team.core.diff.IDiffNode;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ui.*;
+import org.eclipse.team.ui.ISharedImages;
/**
* A label provider wrapper that adds synchronization image and/or text decorations
@@ -36,6 +44,12 @@ import org.eclipse.team.internal.ui.*;
*/
public abstract class AbstractSynchronizeLabelProvider implements ILabelProvider {
+ // Cache for images that have been overlayed
+ private Map fgImageCache;
+
+ // Font used to display busy elements
+ private Font busyFont;
+
// Contains direction images
private CompareConfiguration compareConfig = new CompareConfiguration();
@@ -45,7 +59,11 @@ public abstract class AbstractSynchronizeLabelProvider implements ILabelProvider
public Image getImage(Object element) {
Image base = getDelegateImage(element);
if (isDecorationEnabled() && base != null) {
- return decorateImage(base, element);
+ Image decorateImage = decorateImage(base, element);
+ base = decorateImage;
+ }
+ if (isIncludeOverlays() && base != null) {
+ base = addOverlays(base, element);
}
return base;
}
@@ -176,6 +194,16 @@ public abstract class AbstractSynchronizeLabelProvider implements ILabelProvider
*/
public void dispose() {
compareConfig.dispose();
+ if(busyFont != null) {
+ busyFont.dispose();
+ }
+ if (fgImageCache != null) {
+ Iterator it = fgImageCache.values().iterator();
+ while (it.hasNext()) {
+ Image element = (Image) it.next();
+ element.dispose();
+ }
+ }
}
/* (non-Javadoc)
@@ -230,4 +258,157 @@ public abstract class AbstractSynchronizeLabelProvider implements ILabelProvider
return null;
}
+ private Image addOverlays(Image base, Object element) {
+ if (!isIncludeOverlays())
+ return base;
+ // if the folder is already conflicting then don't bother propagating
+ // the conflict
+ List overlays = new ArrayList();
+ List locations = new ArrayList();
+
+ // Decorate with the busy indicator
+ if (isBusy(element)) {
+ overlays.add(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_HOURGLASS_OVR));
+ locations.add(new Integer(OverlayIcon.TOP_LEFT));
+ }
+ // Decorate with propagated conflicts and problem markers
+ if (!isConflicting(element)) {
+ if (hasDecendantConflicts(element)) {
+ overlays.add(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR));
+ locations.add(new Integer(OverlayIcon.BOTTOM_RIGHT));
+ }
+ }
+ int severity = getMarkerSeverity(element);
+ if (severity == IMarker.SEVERITY_ERROR) {
+ overlays.add(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_ERROR_OVR));
+ locations.add(new Integer(OverlayIcon.BOTTOM_LEFT));
+ } else if (severity == IMarker.SEVERITY_WARNING) {
+ overlays.add(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_WARNING_OVR));
+ locations.add(new Integer(OverlayIcon.BOTTOM_LEFT));
+ }
+ if (!overlays.isEmpty()) {
+ ImageDescriptor[] overlayImages = (ImageDescriptor[]) overlays.toArray(new ImageDescriptor[overlays.size()]);
+ int[] locationInts = new int[locations.size()];
+ for (int i = 0; i < locations.size(); i++) {
+ locationInts[i] = ((Integer) locations.get(i)).intValue();
+ }
+ ImageDescriptor overlay = new OverlayIcon(base, overlayImages, locationInts, new Point(base.getBounds().width, base.getBounds().height));
+ if (fgImageCache == null) {
+ fgImageCache = new HashMap(10);
+ }
+ Image conflictDecoratedImage = (Image) fgImageCache.get(overlay);
+ if (conflictDecoratedImage == null) {
+ conflictDecoratedImage = overlay.createImage();
+ fgImageCache.put(overlay, conflictDecoratedImage);
+ }
+ return conflictDecoratedImage;
+ }
+ return base;
+ }
+
+ /**
+ * Indicate whether the overlays provided by this class should be applied.
+ * By default, <code>true</code> is returned. Subclasses may override
+ * and control individual overlays by overriding the appropriate
+ * query methods.
+ * @return hether the overlays provided by this class should be applied
+ */
+ protected boolean isIncludeOverlays() {
+ return true;
+ }
+
+ /**
+ * Return the marker severity (one of IMarker.SEVERITY_ERROR or
+ * IMarker.SEVERITY_WARNING) to be overlayed on the given element or -1 if
+ * there are no markers. By Default, the element is adapted to resource
+ * mapping in order to look for markers.
+ * <p>
+ * Although this class handles providing the label updates, it does not react
+ * to marker changes. Subclasses must issue label updates when the markers on
+ * a logical model element change.
+ *
+ * @param element
+ * the element
+ * @return the marker severity
+ */
+ protected int getMarkerSeverity(Object element) {
+ ResourceMapping mapping = Utils.getResourceMapping(element);
+ int result = -1;
+ if (mapping != null) {
+ try {
+ IMarker[] markers = mapping.findMarkers(IMarker.PROBLEM, true, null);
+ for (int i = 0; i < markers.length; i++) {
+ IMarker marker = markers[i];
+ Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY);
+ if (severity != null) {
+ if (severity.intValue() == IMarker.SEVERITY_ERROR) {
+ return IMarker.SEVERITY_ERROR;
+ } else if (severity.intValue() == IMarker.SEVERITY_WARNING) {
+ result = IMarker.SEVERITY_WARNING;
+ }
+ }
+ }
+ } catch (CoreException e) {
+ // Ignore
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return whether the given element has decendant conflicts.
+ * By defautl, <code>false</code> is returned. Subclasses
+ * may override.
+ * @param element the element
+ * @return whether the given element has decendant conflicts
+ */
+ protected boolean hasDecendantConflicts(Object element) {
+ return false;
+ }
+
+ private boolean isConflicting(Object element) {
+ IDiffNode node = getDiff(element);
+ if (node != null) {
+ if (node instanceof IThreeWayDiff) {
+ IThreeWayDiff twd = (IThreeWayDiff) node;
+ return twd.getDirection() == IThreeWayDiff.CONFLICTING;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the given element is busy (i.e. is involved
+ * in an opertion. By default, <code>false</code> is returned.
+ * Subclasses may override.
+ * @param element the element
+ * @return hether the given element is busy
+ */
+ protected boolean isBusy(Object element) {
+ return false;
+ }
+
+ /**
+ * Method that provides a custom font for elements that are
+ * busy. Although this label provider does not implement
+ * {@link IFontProvider}, subclasses that wish to get
+ * busy indication using a font can do so.
+ * @param element the element
+ * @return the font to indicate tahtthe element is busy
+ */
+ public Font getFont(Object element) {
+ if(isBusy(element)) {
+ if (busyFont == null) {
+ Font defaultFont = JFaceResources.getDefaultFont();
+ FontData[] data = defaultFont.getFontData();
+ for (int i = 0; i < data.length; i++) {
+ data[i].setStyle(SWT.ITALIC);
+ }
+ busyFont = new Font(TeamUIPlugin.getStandardDisplay(), data);
+ }
+ return busyFont;
+ }
+ return null;
+ }
+
}

Back to the top