Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Michel-Lemieux2003-09-10 19:24:01 +0000
committerJean Michel-Lemieux2003-09-10 19:24:01 +0000
commitf86bcedb2d5348338f237c7ba8b0cd77e4eeb8c7 (patch)
treee461b89842179de336eaa381827400afbfdc1948 /bundles/org.eclipse.team.ui/src
parentba7e4312188694331aed1085e3a91433f5467361 (diff)
downloadeclipse.platform.team-f86bcedb2d5348338f237c7ba8b0cd77e4eeb8c7.tar.gz
eclipse.platform.team-f86bcedb2d5348338f237c7ba8b0cd77e4eeb8c7.tar.xz
eclipse.platform.team-f86bcedb2d5348338f237c7ba8b0cd77e4eeb8c7.zip
*** empty log message ***
Diffstat (limited to 'bundles/org.eclipse.team.ui/src')
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java1
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties12
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncInfoStatistics.java4
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java6
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsCounterBar.java240
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsPanel.java145
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetContentProvider.java38
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetTreeContentProvider.java7
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncViewerLabelProvider.java109
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeView.java83
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeViewNode.java4
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/ViewStatusInformation.java6
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java1
13 files changed, 573 insertions, 83 deletions
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java
index 9f18abc07..1ff8f2e97 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java
@@ -296,6 +296,7 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis
// View decoration overlays
createImageDescriptor(ISharedImages.IMG_DIRTY_OVR, baseURL);
+ createImageDescriptor(ISharedImages.IMG_CONFLICT_OVR, baseURL);
createImageDescriptor(ISharedImages.IMG_CHECKEDIN_OVR, baseURL);
createImageDescriptor(ISharedImages.IMG_CHECKEDOUT_OVR, baseURL);
createImageDescriptor(ISharedImages.IMG_SYNC_VIEW, baseURL);
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties
index 5018560c6..a5ac03c51 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties
@@ -96,11 +96,9 @@ SyncView.errorSaving=Error while saving modified resources
SyncView.cantSaveError=Can't save changes: {0}
SyncView.dirtyIndicatorInTitle=*{0}
+LiveSyncView.titleTooltip=Working Set: {0}
LiveSyncView.title=Synchronize
-LiveSyncView.titleTooltip={0}\nWorking Set: {1}\n
-LiveSyncView.titleChangeNumbers=mode matched {0} of {1} changes: {2} hidden by working set
-LiveSyncView.titleChangeNumbersNoWorkingSet=mode matched {0} of {1} changes
-LiveSyncView.titleWithSubscriber={0} ({1}) - {2}
+LiveSyncView.titleSubscriber=Synchronize - {0}
SubscriberEventHandler.jobName=Updating synchronization state
SubscriberEventHandler.errors=Errors have occured while calculating the synchronization state. The Synchronize View may be out-of-date. Refresh the view or fix the errors and re-run the Synchronize command.
@@ -403,6 +401,12 @@ SynchronizeView.12=One item selected
SynchronizeView.13=\ items selected
SynchronizeView.14=Error opening perspective
SynchronizeView.16=Error opening view
+
+StatisticsPanel.outgoing=Outgoing
+StatisticsPanel.incoming=Incoming
+StatisticsPanel.conflicting=Conflicting
+StatisticsPanel.changeNumbers={0}/{1}
+
SyncViewerPreferencePage.6=Synchronize view preferences
SyncViewerPreferencePage.7=Team Synchronize View settings:
SyncViewerPreferencePage.8=Display
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncInfoStatistics.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncInfoStatistics.java
index 2b9e16ce4..5e08f13ea 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncInfoStatistics.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncInfoStatistics.java
@@ -76,8 +76,8 @@ public class SyncInfoStatistics {
long count = 0;
while (it.hasNext()) {
Integer key = (Integer) it.next();
- if((key.intValue() & mask) != 0) {
- count += ((Integer)stats.get(key)).intValue();
+ if((key.intValue() & mask) == kind) {
+ count += ((Long)stats.get(key)).intValue();
}
}
return count;
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
index 11a62161c..9dc897185 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
@@ -106,7 +106,11 @@ public class SyncSet {
private void internalAddSyncInfo(SyncInfo info) {
IResource local = info.getLocal();
IPath path = local.getFullPath();
- if(resources.put(path, info) == null) {
+ SyncInfo oldSyncInfo = (SyncInfo)resources.put(path, info);
+ if(oldSyncInfo == null) {
+ statistics.add(info);
+ } else {
+ statistics.remove(oldSyncInfo);
statistics.add(info);
}
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsCounterBar.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsCounterBar.java
new file mode 100644
index 000000000..ca42c58b2
--- /dev/null
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsCounterBar.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ui.sync.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.team.core.subscribers.SyncInfo;
+
+/**
+ * A progress bar with a red/green indication for success or failure.
+ */
+public class StatisticsCounterBar extends Canvas {
+ private static final int DEFAULT_WIDTH = 160;
+ private static final int DEFAULT_HEIGHT = 20;
+
+ private int outgoingCount = 0;
+ private int incomingCount = 0;
+ private int conflicCount = 0;
+
+ private int totalCount = 0;
+
+ private int fColorBarWidth = 0;
+
+ private Color outgoingColor;
+ private Color incomingColor;
+ private Color conflictColor;
+
+ private int activeMode = SyncInfo.IN_SYNC;
+
+ private final Cursor counterBarCursor = new Cursor(getDisplay(), SWT.CURSOR_HAND);
+
+ public StatisticsCounterBar(Composite parent, int cSpan) {
+ super(parent, SWT.NONE);
+
+ addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ redraw();
+ }
+ });
+ addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paint(e);
+ }
+ });
+
+ addMouseMoveListener(
+ new MouseMoveListener() {
+ private Cursor fLastCursor;
+ public void mouseMove(MouseEvent e) {
+ Cursor cursor= null;
+ int mode = handlemouseInCounterBar(e.x, e.y);
+ if (mode != SyncInfo.IN_SYNC)
+ cursor= counterBarCursor;
+ if (fLastCursor != cursor) {
+ setCursor(cursor);
+ fLastCursor= cursor;
+ }
+ }
+ }
+ );
+
+ addMouseListener(
+ new MouseAdapter() {
+ public void mouseDown(MouseEvent e) {
+ int mode = handlemouseInCounterBar(e.x, e.y);
+ if(mode != activeMode) {
+ activeMode = mode;
+ redraw();
+ }
+ }
+ }
+ );
+
+ Display display= parent.getDisplay();
+ conflictColor = new Color(display, 204, 51, 51);
+ incomingColor = new Color(display, 51, 102, 204);
+ outgoingColor = new Color(display, 102, 102, 102);
+
+ GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL);
+ data.horizontalSpan = cSpan;
+ setLayoutData(data);
+ }
+
+ protected int handlemouseInCounterBar(int x, int y) {
+ int nextX = 1;
+ int sizeX = 0;
+ if(conflicCount > 0) {
+ sizeX = scale(conflicCount);
+ if(x >= nextX && x <= sizeX) return SyncInfo.CONFLICTING;
+ nextX = (sizeX - 1);
+ }
+ if(incomingCount > 0) {
+ sizeX = scale(incomingCount) + nextX;
+ if(x >= nextX && x <= sizeX) return SyncInfo.INCOMING;
+ nextX = (sizeX - 1);
+ }
+ if(outgoingCount > 0) {
+ sizeX = scale(outgoingCount) + nextX;
+ if(x >= nextX && x <= sizeX) return SyncInfo.OUTGOING;
+ }
+ return SyncInfo.IN_SYNC;
+ }
+
+ public void reset() {
+ conflicCount = 0;
+ incomingCount = 0;
+ outgoingCount = 0;
+ fColorBarWidth = 0;
+ redraw();
+ }
+
+ private void paintStep(int startX, int endX, int direction) {
+ GC gc = new GC(this);
+ setStatusColor(gc, direction);
+ Rectangle rect= getClientArea();
+ startX= Math.max(1, startX);
+ gc.fillRectangle(startX, 1, endX, rect.height-2);
+ gc.dispose();
+ }
+
+ public void dispose() {
+ super.dispose();
+ conflictColor.dispose();
+ outgoingColor.dispose();
+ incomingColor.dispose();
+ }
+
+ private void setStatusColor(GC gc, int direction) {
+ switch(direction) {
+ case SyncInfo.OUTGOING:
+ gc.setBackground(outgoingColor); break;
+ case SyncInfo.INCOMING:
+ gc.setBackground(incomingColor); break;
+ case SyncInfo.CONFLICTING:
+ gc.setBackground(conflictColor); break;
+ }
+ }
+
+ private int scale(int value) {
+ if (totalCount > 0) {
+ Rectangle r= getClientArea();
+ if (r.width != 0)
+ return Math.max(0, value*(r.width-2)/totalCount);
+ }
+ return value;
+ }
+
+ private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
+ gc.setForeground(topleft);
+ gc.drawLine(x, y, x+w-1, y);
+ gc.drawLine(x, y, x, y+h-1);
+
+ gc.setForeground(bottomright);
+ gc.drawLine(x+w, y, x+w, y+h);
+ gc.drawLine(x, y+h, x+w, y+h);
+ }
+
+ private void paint(PaintEvent event) {
+ GC gc = event.gc;
+ Display disp= getDisplay();
+
+ Rectangle rect= getClientArea();
+ gc.fillRectangle(rect);
+ drawBevelRect(gc, rect.x, rect.y, rect.width-1, rect.height-1,
+ disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW),
+ disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+
+ int nextX = 1;
+ int sizeX = 0;
+ if(conflicCount > 0) {
+ sizeX = scale(conflicCount);
+ paintStep(nextX, sizeX, SyncInfo.CONFLICTING);
+ if(activeMode == SyncInfo.CONFLICTING) {
+ drawBorder(gc, rect, nextX, sizeX);
+ }
+ nextX = (sizeX - 1);
+ }
+ if(incomingCount > 0) {
+ sizeX = scale(incomingCount) + nextX;
+ paintStep(nextX, sizeX, SyncInfo.INCOMING);
+ if(activeMode == SyncInfo.INCOMING) {
+ drawBorder(gc, rect, nextX, sizeX);
+ }
+ nextX = (sizeX - 1);
+ }
+ if(outgoingCount > 0) {
+ sizeX = scale(outgoingCount) + nextX;
+ paintStep(nextX, sizeX, SyncInfo.OUTGOING);
+ if(activeMode == SyncInfo.OUTGOING) {
+ drawBorder(gc, rect, nextX, sizeX);
+ }
+ }
+ }
+
+ private void drawBorder(GC gc, Rectangle rect, int nextX, int sizeX) {
+ int lineWidth = 3;
+ gc.setLineWidth(lineWidth);
+ gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_YELLOW));
+ gc.drawRectangle(nextX, 0, (sizeX - lineWidth) + 1, rect.height - lineWidth);
+ }
+
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ Point size= new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ if (wHint != SWT.DEFAULT) size.x= wHint;
+ if (hHint != SWT.DEFAULT) size.y= hHint;
+ return size;
+ }
+
+ public void update(int conflicts, int outgoing, int incoming) {
+ totalCount = conflicts + outgoing + incoming;
+ conflicCount = conflicts;
+ incomingCount = incoming;
+ outgoingCount = outgoing;
+ redraw();
+ }
+}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsPanel.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsPanel.java
new file mode 100644
index 000000000..815413113
--- /dev/null
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/StatisticsPanel.java
@@ -0,0 +1,145 @@
+/*************.******************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ui.sync.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.team.core.subscribers.SyncInfo;
+import org.eclipse.team.internal.ui.Policy;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
+import org.eclipse.team.internal.ui.sync.sets.SyncInfoStatistics;
+import org.eclipse.team.ui.ISharedImages;
+
+/**
+ * Composite that displays statistics relating to Synchronization information.
+ *
+ * @since 3.0
+ */
+public class StatisticsPanel extends Composite {
+
+ private ViewStatusInformation stats;
+
+ private Label nOutgoing;
+ private Label nIncoming;
+ private Label nConflicting;
+
+ private final Image iOutgoing = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_OUTGOING).createImage();
+ private final Image iIncoming = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_INCOMING).createImage();
+ private final Image iConflicting = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_CONFLICTING).createImage();
+
+ private boolean showDirectionText = true;
+
+ public StatisticsPanel(Composite parent) {
+ super(parent, SWT.WRAP);
+
+ GridLayout gridLayout= new GridLayout();
+ gridLayout.numColumns= 9;
+ gridLayout.makeColumnsEqualWidth= false;
+ gridLayout.marginWidth= 3;
+ gridLayout.marginHeight= 0;
+ setLayout(gridLayout);
+
+ nConflicting = createLabel(Policy.bind("StatisticsPanel.conflicting"), iConflicting, "0/0"); //$NON-NLS-1$ //$NON-NLS-2$
+ nIncoming = createLabel(Policy.bind("StatisticsPanel.incoming"), iIncoming, "0/0"); //$NON-NLS-1$ //$NON-NLS-2$
+ nOutgoing = createLabel(Policy.bind("StatisticsPanel.outgoing"), iOutgoing, "0/0"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ disposeIcons();
+ }
+ });
+
+ addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ }
+ });
+ addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paint(e);
+ }
+ });
+
+ setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
+ }
+
+ protected void disposeIcons() {
+ iOutgoing.dispose();
+ iIncoming.dispose();
+ iConflicting.dispose();
+ }
+
+ private Label createLabel(String name, Image image, String init) {
+ Label label= new Label(this, SWT.NONE);
+ if (image != null) {
+ image.setBackground(label.getBackground());
+ label.setImage(image);
+ }
+ label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+
+ label= new Label(this, SWT.NONE);
+ label.setText(name);
+ label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+
+ Label value= new Label(this, SWT.NONE);
+ value.setText(init);
+
+ value.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ value.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING));
+ return value;
+ }
+
+ private void paint(PaintEvent e) {
+ }
+
+ public void update(ViewStatusInformation stats) {
+ this.stats = stats;
+ updateStats();
+ }
+
+ private void updateStats() {
+ if(stats != null) {
+
+ SyncInfoStatistics workspaceSetStats = stats.getSubscriberInput().getSubscriberSyncSet().getStatistics();
+ SyncInfoStatistics workingSetSetStats = stats.getSubscriberInput().getWorkingSetSyncSet().getStatistics();
+
+ int workspaceConflicting = (int)workspaceSetStats.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK);
+ int workspaceOutgoing = (int)workspaceSetStats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK);
+ int workspaceIncoming = (int)workspaceSetStats.countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK);
+ int workingSetConflicting = (int)workingSetSetStats.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK);
+ int workingSetOutgoing = (int)workingSetSetStats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK);
+ int workingSetIncoming = (int)workingSetSetStats.countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK);
+
+ nConflicting.setText(Policy.bind("StatisticsPanel.changeNumbers", new Integer(workingSetConflicting).toString(), new Integer(workspaceConflicting).toString())); //$NON-NLS-1$
+ nIncoming.setText(Policy.bind("StatisticsPanel.changeNumbers", new Integer(workingSetIncoming).toString(), new Integer(workspaceIncoming).toString())); //$NON-NLS-1$
+ nOutgoing.setText(Policy.bind("StatisticsPanel.changeNumbers", new Integer(workingSetOutgoing).toString(), new Integer(workspaceOutgoing).toString())); //$NON-NLS-1$
+
+ redraw();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ public void dispose() {
+ super.dispose();
+ disposeIcons();
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetContentProvider.java
index ddea777a8..0d1c9ad09 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetContentProvider.java
@@ -10,10 +10,12 @@
*******************************************************************************/
package org.eclipse.team.internal.ui.sync.views;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control;
@@ -129,8 +131,10 @@ public abstract class SyncSetContentProvider implements IStructuredContentProvid
protected void handleResourceChanges(SyncSetChangedEvent event) {
// Refresh the viewer for each changed resource
SyncInfo[] infos = event.getChangedResources();
- for (int i = 0; i < infos.length; i++) {
- ((StructuredViewer) viewer).refresh(getModelObject(infos[i].getLocal()), true);
+ for (int i = 0; i < infos.length; i++) {
+ IResource local = infos[i].getLocal();
+ ((StructuredViewer) viewer).refresh(getModelObject(local), true);
+ updateParentLabels(local);
}
}
@@ -146,6 +150,7 @@ public abstract class SyncSetContentProvider implements IStructuredContentProvid
for (int i = 0; i < removed.length; i++) {
IResource resource = removed[i];
((StructuredViewer) viewer).refresh(getModelObject(resource));
+ updateParentLabels(resource);
}
}
@@ -161,12 +166,7 @@ public abstract class SyncSetContentProvider implements IStructuredContentProvid
for (int i = 0; i < added.length; i++) {
IResource resource = added[i];
((StructuredViewer) viewer).refresh(getModelObject(resource.getParent()));
- }
- IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
- if(selection.size() == 0) {
- if(viewer instanceof INavigableControl) {
- ((INavigableControl)viewer).gotoDifference(INavigableControl.NEXT);
- }
+ updateParentLabels(resource);
}
}
@@ -268,4 +268,22 @@ public abstract class SyncSetContentProvider implements IStructuredContentProvid
}
return result;
}
-}
+
+ /**
+ * Forces the viewer to update the labels for parents of this element. This
+ * can be useful when parents labels include information about their children
+ * that needs updating when a child changes.
+ */
+ protected void updateParentLabels(IResource resource) {
+ List parents = new ArrayList(3);
+ IResource parent = resource.getParent();
+ while(parent.getType() != IResource.ROOT) {
+ parents.add(getModelObject(parent));
+ parent = parent.getParent();
+ }
+ getViewer().update(
+ (SynchronizeViewNode[])parents.toArray(new SynchronizeViewNode[parents.size()]),
+ null
+ );
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetTreeContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetTreeContentProvider.java
index 15278c5cd..e7b94e6c3 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetTreeContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncSetTreeContentProvider.java
@@ -15,7 +15,8 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.team.internal.ui.sync.sets.*;
+import org.eclipse.team.internal.ui.sync.sets.SubscriberInput;
+import org.eclipse.team.internal.ui.sync.sets.SyncSetChangedEvent;
/**
* This class provides the contents for a AbstractTreeViewer using a SyncSet as the model
@@ -83,7 +84,8 @@ public class SyncSetTreeContentProvider extends SyncSetContentProvider implement
parent = getModelParent(resource);
}
Object element = getModelObject(resource);
- tree.add(parent, element);
+ tree.add(parent, element);
+ updateParentLabels(resource);
}
} else {
super.handleResourceAdditions(event);
@@ -101,6 +103,7 @@ public class SyncSetTreeContentProvider extends SyncSetContentProvider implement
Object[] modelRoots = new Object[roots.length];
for (int i = 0; i < modelRoots.length; i++) {
modelRoots[i] = getModelObject(roots[i]);
+ updateParentLabels(roots[i]);
}
tree.remove(modelRoots);
} else {
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncViewerLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncViewerLabelProvider.java
index 546c3c61e..564fc63a3 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncViewerLabelProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SyncViewerLabelProvider.java
@@ -1,16 +1,26 @@
package org.eclipse.team.internal.ui.sync.views;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.team.core.subscribers.SyncInfo;
import org.eclipse.team.core.sync.IRemoteSyncElement;
+import org.eclipse.team.internal.ui.OverlayIcon;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.actions.TeamAction;
+import org.eclipse.team.internal.ui.sync.sets.SubscriberInput;
+import org.eclipse.team.internal.ui.sync.sets.SyncInfoStatistics;
+import org.eclipse.team.internal.ui.sync.sets.SyncSet;
import org.eclipse.team.ui.ISharedImages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.model.WorkbenchLabelProvider;
@@ -26,14 +36,14 @@ public class SyncViewerLabelProvider extends LabelProvider implements ITableLabe
private Image compressedFolderImage;
+ // cache for folder images that have been overlayed with conflict icon
+ private Map fgImageCache;
+
// Keep track of the compare and workbench image providers
// so they can be properly disposed
CompareConfiguration compareConfig = new CompareConfiguration();
WorkbenchLabelProvider workbenchLabelProvider = new WorkbenchLabelProvider();
- /**
- * @return
- */
public Image getCompressedFolderImage() {
if (compressedFolderImage == null) {
compressedFolderImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER).createImage();
@@ -62,32 +72,79 @@ public class SyncViewerLabelProvider extends LabelProvider implements ITableLabe
}
public String getText(Object element) {
- if (element instanceof CompressedFolder) {
- IResource resource = getResource(element);
- return resource.getProjectRelativePath().toString();
- }
+ String name;
IResource resource = getResource(element);
- return workbenchLabelProvider.getText(resource);
+ if (element instanceof CompressedFolder) {
+ name = resource.getProjectRelativePath().toString();
+ } else {
+ name = workbenchLabelProvider.getText(resource);
+ }
+ return name;
}
+ /**
+ * An image is decorated by at most 3 different plugins.
+ * 1. ask the workbench for the default icon for the resource
+ * 2. ask the compare plugin for the sync kind overlay
+ * 3. overlay the conflicting image on folders/projects containing conflicts
+ */
public Image getImage(Object element) {
+ Image decoratedImage = null;
+ IResource resource = getResource(element);
+
if (element instanceof CompressedFolder) {
- return compareConfig.getImage(getCompressedFolderImage(), 0);
+ decoratedImage = compareConfig.getImage(getCompressedFolderImage(), IRemoteSyncElement.IN_SYNC);
+ } else {
+ int kind = getSyncKind(element);
+ switch (kind & IRemoteSyncElement.DIRECTION_MASK) {
+ case IRemoteSyncElement.OUTGOING:
+ kind = (kind &~ IRemoteSyncElement.OUTGOING) | IRemoteSyncElement.INCOMING;
+ break;
+ case IRemoteSyncElement.INCOMING:
+ kind = (kind &~ IRemoteSyncElement.INCOMING) | IRemoteSyncElement.OUTGOING;
+ break;
+ }
+ Image image = workbenchLabelProvider.getImage(resource);
+ decoratedImage = compareConfig.getImage(image, kind);
}
- IResource resource = getResource(element);
- int kind = getSyncKind(element);
- switch (kind & IRemoteSyncElement.DIRECTION_MASK) {
- case IRemoteSyncElement.OUTGOING:
- kind = (kind &~ IRemoteSyncElement.OUTGOING) | IRemoteSyncElement.INCOMING;
- break;
- case IRemoteSyncElement.INCOMING:
- kind = (kind &~ IRemoteSyncElement.INCOMING) | IRemoteSyncElement.OUTGOING;
- break;
- }
- Image image = workbenchLabelProvider.getImage(resource);
- return compareConfig.getImage(image, kind);
+
+ return propagateConflicts(decoratedImage, element, resource);
}
+ private Image propagateConflicts(Image base, Object element, IResource resource) {
+ if(element instanceof SynchronizeViewNode && resource.getType() != IResource.FILE) {
+ // if the folder is already conflicting then don't bother propagating the conflict
+ if((getSyncKind(element) & SyncInfo.DIRECTION_MASK) != SyncInfo.CONFLICTING) {
+ SubscriberInput input = ((SynchronizeViewNode)element).getSubscriberInput();
+ SyncSet set = new SyncSet();
+ SyncInfo[] infos = input.getWorkingSetSyncSet().getOutOfSyncDescendants(resource);
+ for (int i = 0; i < infos.length; i++) {
+ set.add(infos[i]);
+ }
+ SyncInfoStatistics stats = set.getStatistics();
+ long count = stats.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK);
+ if(count > 0) {
+ ImageDescriptor overlay = new OverlayIcon(
+ base,
+ new ImageDescriptor[] { TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR)},
+ new int[] {OverlayIcon.BOTTOM_LEFT},
+ 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;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
@@ -95,8 +152,16 @@ public class SyncViewerLabelProvider extends LabelProvider implements ITableLabe
super.dispose();
workbenchLabelProvider.dispose();
compareConfig.dispose();
- if (compressedFolderImage != null)
+ if (compressedFolderImage != null) {
compressedFolderImage.dispose();
+ }
+ if(fgImageCache != null) {
+ Iterator it = fgImageCache.values().iterator();
+ while (it.hasNext()) {
+ Image element = (Image) it.next();
+ element.dispose();
+ }
+ }
}
/* (non-Javadoc)
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeView.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeView.java
index cac599459..4f2c39eec 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeView.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeView.java
@@ -47,6 +47,7 @@ import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
@@ -114,6 +115,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
// Parent composite of this view. It is remembered so that we can dispose of its children when
// the viewer type is switched.
private Composite composite = null;
+ private StatisticsPanel statsPanel;
private IMemento memento;
// Viewer type constants
@@ -125,9 +127,6 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
// Remembering the current input and the previous.
private SubscriberInput input = null;
- // Stats about the current subscriber. This is used for status line and/or title updating
- private ViewStatusInformation statusInformation;
-
// A set of common actions. They are hooked to the active SubscriberInput and must
// be reset when the input changes.
private SyncViewerActions actions;
@@ -156,7 +155,13 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
- public void createPartControl(Composite parent) {
+ public void createPartControl(Composite parent) {
+ GridLayout gridLayout= new GridLayout();
+ gridLayout.makeColumnsEqualWidth= false;
+ gridLayout.marginWidth= 0;
+ gridLayout.marginHeight = 0;
+ parent.setLayout(gridLayout);
+
createViewer(parent);
this.composite = parent;
@@ -178,7 +183,8 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
TeamUIPlugin.disposeOnShutdown(refreshingImg);
setViewImage(initialImg);
- updateTitle();
+ updateStatusPanel();
+ updateTooltip();
initializeJobListener();
actions.setContext(null);
@@ -222,9 +228,10 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
RefreshSubscriberInputJob refreshJob = TeamUIPlugin.getPlugin().getRefreshJob();
refreshJob.setSubscriberInput(input);
+ updateStatusPanel();
+ setTitle(Policy.bind("LiveSyncView.titleSubscriber", input.getSubscriber().getName())); //$NON-NLS-1$
}
- });
- updateTitle();
+ });
}
private void disconnectSubscriberInput() {
@@ -254,6 +261,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
viewer.setSelection(oldSelection, true);
}
fireSafePropertyChange(PROP_VIEWTYPE);
+ updateStatusPanel();
}
}
/**
@@ -343,6 +351,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
Label label = new Label(parent, SWT.WRAP);
label.setText(Policy.bind("SynchronizeView.noSubscribersMessage")); //$NON-NLS-1$
} else {
+ statsPanel = new StatisticsPanel(parent);
switch(currentViewType) {
case TREE_VIEW:
createTreeViewerPartControl(parent);
@@ -359,9 +368,11 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
}
protected void createTreeViewerPartControl(Composite parent) {
+ GridData data = new GridData(GridData.FILL_BOTH);
viewer = new SyncTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setLabelProvider(SyncViewerLabelProvider.getDecoratingLabelProvider());
viewer.setSorter(new SyncViewerSorter(ResourceSorter.NAME));
+ ((TreeViewer)viewer).getTree().setLayoutData(data);
}
protected void createTableViewerPartControl(Composite parent) {
@@ -470,46 +481,33 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
initializeSubscriberInput(newInput);
}
}
- /*
- * Synchronize - (showing N of M changes) - {Subscriber name}
- */
- protected void updateTitle() {
+
+ protected void updateStatusPanel() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
SubscriberInput input = getInput();
- if(input != null) {
- ViewStatusInformation newStatus = new ViewStatusInformation(input);
- if(statusInformation == null || ! statusInformation.equals(newStatus)) {
- statusInformation = newStatus;
-
- TeamSubscriber subscriber = input.getSubscriber();
- String changesText;
- if(input.getWorkingSet() != null) {
- changesText = Policy.bind("LiveSyncView.titleChangeNumbers", //$NON-NLS-1$
- new Long(statusInformation.getNumShowing()).toString(),
- new Long(statusInformation.getNumInWorkingSet()).toString(),
- new Long(statusInformation.getNumInWorkspace() - statusInformation.getNumInWorkingSet()).toString());
- } else {
- changesText = Policy.bind("LiveSyncView.titleChangeNumbersNoWorkingSet", //$NON-NLS-1$
- new Long(statusInformation.getNumShowing()).toString(),
- new Long(statusInformation.getNumInWorkingSet()).toString());
- }
- String title = Policy.bind("LiveSyncView.titleWithSubscriber", new String[] {Policy.bind("LiveSyncView.title"), changesText, subscriber.getName()}); //$NON-NLS-1$ //$NON-NLS-2$
- setTitle(title);
- StringBuffer b = new StringBuffer(title + "\n"); //$NON-NLS-1$
- b.append(input.getSubscriberSyncSet().getStatistics().toString());
- setTitleToolTip(b.toString());
+ if(input != null && statsPanel != null) {
+ statsPanel.update(new ViewStatusInformation(input));
+ }
+ }
+ });
+ }
+
+ protected void updateTooltip() {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ SubscriberInput input = getInput();
+ if(input != null) {
+ if(input.getWorkingSet() != null) {
+ String tooltip = Policy.bind("LiveSyncView.titleTooltip", input.getWorkingSet().getName()); //$NON-NLS-1$
+ setTitleToolTip(tooltip);
+ } else {
+ setTitleToolTip(""); //$NON-NLS-1$
}
- } else {
- setTitle(Policy.bind("LiveSyncView.title")); //$NON-NLS-1$
- setTitleToolTip(""); //$NON-NLS-1$
}
- }
+ }
});
}
-
-
-
/**
* Passing the focus request to the viewer's control.
*/
@@ -632,6 +630,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
context.setInput(null);
actions.setContext(context);
viewer.setInput(null);
+ setTitle(Policy.bind("LiveSyncView.titleSubscriber")); //$NON-NLS-1$
}
});
}
@@ -757,7 +756,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
* Update the title when either the subscriber or filter sync set changes.
*/
public void syncSetChanged(SyncSetChangedEvent event) {
- updateTitle();
+ updateStatusPanel();
// remove opened compare editors if file was removed from sync view and update if changed
IResource[] resources =event.getRemovedResources();
@@ -844,7 +843,7 @@ public class SynchronizeView extends ViewPart implements ITeamResourceChangeList
public void workingSetChanged(IWorkingSet set) {
input.setWorkingSet(set);
- updateTitle();
+ updateTooltip();
}
/**
* Updates the filter applied to the active subscriber input and ensures that selection and expansions
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeViewNode.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeViewNode.java
index d91150d33..5269efc77 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeViewNode.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/SynchronizeViewNode.java
@@ -45,6 +45,10 @@ public class SynchronizeViewNode implements IAdaptable, IActionFilter, ISynchron
return input.getFilteredSyncSet();
}
+ public SubscriberInput getSubscriberInput() {
+ return input;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.team.ui.sync.ISynchronizeViewNode#getTeamSubscriber()
*/
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/ViewStatusInformation.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/ViewStatusInformation.java
index e09f6d150..02e6603c6 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/ViewStatusInformation.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/views/ViewStatusInformation.java
@@ -20,9 +20,11 @@ class ViewStatusInformation {
private long numShowing = 0;
private long numInWorkingSet = 0;
private long numInWorkspace = 0;
+ private SubscriberInput input;
ViewStatusInformation(SubscriberInput input) {
this.subscriberName = input.getSubscriber().getName();
+ this.input = input;
IWorkingSet set = input.getWorkingSet();
if(set != null) {
this.workingSetName = set.getName();
@@ -54,6 +56,10 @@ class ViewStatusInformation {
return workingSetName;
}
+ public SubscriberInput getSubscriberInput() {
+ return input;
+ }
+
public boolean equals(Object other) {
if(other == this) return true;
if(other instanceof ViewStatusInformation) {
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java
index 8838e6016..097f7a723 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java
@@ -23,6 +23,7 @@ public interface ISharedImages {
public final String IMG_DIRTY_OVR = "ovr/dirty_ov.gif"; //$NON-NLS-1$
public final String IMG_CHECKEDIN_OVR = "ovr/version_controlled.gif"; //$NON-NLS-1$
public final String IMG_CHECKEDOUT_OVR = "ovr/checkedout_ov.gif"; //$NON-NLS-1$
+ public final String IMG_CONFLICT_OVR = "ovr/confchg_ov.gif"; //$NON-NLS-1$
public final String IMG_COLLAPSE_ALL = "clcl16/collapseall.gif"; //$NON-NLS-1$
public final String IMG_COLLAPSE_ALL_ENABLED = "elcl16/collapseall.gif"; //$NON-NLS-1$

Back to the top