diff options
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; + } + } |