diff options
author | james | 2002-04-16 20:34:06 +0000 |
---|---|---|
committer | james | 2002-04-16 20:34:06 +0000 |
commit | f74c0e08d576a9312b26da955669614f250a8268 (patch) | |
tree | 412bb1be8ff519cd9bd6013d306e1aef8b5488dc | |
parent | e6638703f434c8d83c064301c723c4c12b3c830a (diff) | |
download | eclipse.platform.team-f74c0e08d576a9312b26da955669614f250a8268.tar.gz eclipse.platform.team-f74c0e08d576a9312b26da955669614f250a8268.tar.xz eclipse.platform.team-f74c0e08d576a9312b26da955669614f250a8268.zip |
12233: CVS catchup-release viewer is leaking imagesroot_getRevisionBranchRoot_SerializedReferencing
4 files changed, 133 insertions, 176 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecorator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecorator.java index 08ca6a425..87c974b40 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecorator.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecorator.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,6 +29,7 @@ import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.RepositoryProvider; @@ -68,11 +68,25 @@ public class CVSDecorator extends LabelProvider implements ILabelDecorator, IRes private boolean shutdown = false; - private Hashtable imageCache = new Hashtable(); + private OverlayIconCache iconCache = new OverlayIconCache();
// Keep track of deconfigured projects private Set deconfiguredProjects = new HashSet(); + private static class DecoratorOverlayIcon extends OverlayIcon {
+ private static final int HEIGHT = 16;
+ private static final int WIDTH = 16;
+ public DecoratorOverlayIcon(Image base, ImageDescriptor[] overlays) {
+ super(base, overlays, new Point(WIDTH, HEIGHT));
+ }
+ protected void drawOverlays(ImageDescriptor[] overlays) {
+ for (int i = overlays.length - 1; i >= 0; --i) {
+ ImageData imageData = overlays[i].getImageData();
+ drawImage(imageData, 0, 0);
+ }
+ }
+ }
+
public CVSDecorator() { // thread that calculates the decoration for a resource decoratorUpdateThread = new Thread(new CVSDecorationRunnable(this), "CVS"); //$NON-NLS-1$ @@ -118,30 +132,16 @@ public class CVSDecorator extends LabelProvider implements ILabelDecorator, IRes if (decoration != null) { List overlays = decoration.getOverlays(); - return overlays == null ? image : getCachedImage(image, overlays); + if (overlays != null) {
+ return iconCache.getImageFor(new DecoratorOverlayIcon(image,
+ (ImageDescriptor[]) overlays.toArray(new ImageDescriptor[overlays.size()])));
+ }
} else { addResourcesToBeDecorated(new IResource[] { resource }); - return image; } + return image;
} - /** - * Get the composite image for the given image and overlays. Return one from the cache if - * it exists. If not, create it, cache it, and return it. - */ - private Image getCachedImage(Image image, List overlays) { - Hashtable overlayTable = (Hashtable)imageCache.get(image); - if (overlayTable == null) { - overlayTable = new Hashtable(); - imageCache.put(image, overlayTable); - } - Image cachedImage = (Image)overlayTable.get(overlays); - if (cachedImage == null) { - cachedImage = new OverlayIcon(image.getImageData(), new ImageDescriptor[][] {(ImageDescriptor[])overlays.toArray(new ImageDescriptor[overlays.size()])}, new Point(16, 16)).createImage(); - overlayTable.put(overlays, cachedImage); - } - return cachedImage; - } /* * @see IDecorationNotifier#next() @@ -422,15 +422,7 @@ public class CVSDecorator extends LabelProvider implements ILabelDecorator, IRes // dispose of images created as overlays decoratorNeedsUpdating.clear(); clearCache(); - Iterator it = imageCache.values().iterator(); - while (it.hasNext()) { - Hashtable overlayTable = (Hashtable)it.next(); - Iterator it2 = overlayTable.values().iterator(); - while (it2.hasNext()) { - ((Image)it2.next()).dispose(); - } - } - imageCache = new Hashtable(); + iconCache.disposeAll();
} /** * @see IResourceStateChangeListener#projectConfigured(IProject) diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java index ebb9dbc12..95fcbeaa4 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java @@ -1,144 +1,70 @@ +/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
package org.eclipse.team.internal.ccvs.ui; -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ - +import java.util.Arrays;
+
import org.eclipse.jface.resource.CompositeImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point; -import org.eclipse.team.internal.ui.*; /** * An OverlayIcon consists of a main icon and several adornments. */ -public class OverlayIcon extends CompositeImageDescriptor { - // Constants for default size - static final int DEFAULT_WIDTH = 22; - static final int DEFAULT_HEIGHT = 16; - - // The size of this icon - private Point size = null; - - // The base image - private ImageData base; - // All overlay images - private ImageDescriptor overlays[][]; +public abstract class OverlayIcon extends CompositeImageDescriptor {
+ // the base image
+ private Image base;
+ // the overlay images
+ private ImageDescriptor[] overlays;
+ // the size
+ private Point size;
/** - * OverlayIcon constructor + * OverlayIcon constructor.
* - * @param base the base image - * @param overlays the overlay images - * @param size the size of the icon + * @param base the base image
+ * @param overlays the overlay images
+ * @param size the size
*/ - public OverlayIcon(ImageData base, ImageDescriptor[][] overlays, Point size) { + public OverlayIcon(Image base, ImageDescriptor[] overlays, Point size) {
this.base = base; this.overlays = overlays; this.size = size; } /** - * Draws the overlays in the bottom left - * - * @param overlays the overlay images + * Superclasses override to draw the overlays.
*/ - protected void drawBottomLeft(ImageDescriptor[] overlays) { - if (overlays == null) return; - int length = overlays.length; - int x = 0; - for (int i= 0; i < 3; i++) { - if (i < length && overlays[i] != null) { - ImageData id = overlays[i].getImageData(); - drawImage(id, x, getSize().y - id.height); - //x += id.width; - } - } + protected abstract void drawOverlays(ImageDescriptor[] overlays);
+
+ public boolean equals(Object o) {
+ if (! (o instanceof OverlayIcon)) return false;
+ OverlayIcon other = (OverlayIcon) o;
+ return base.equals(other.base) && Arrays.equals(overlays, other.overlays);
} - /** - * Draws the overlays in the bottom right - * - * @param overlays the overlay images - */ - protected void drawBottomRight(ImageDescriptor[] overlays) { - if (overlays == null) return; - int length = overlays.length; - int x = getSize().x; - for (int i= 2; i >= 0; i--) { - if (i < length && overlays[i] != null) { - ImageData id = overlays[i].getImageData(); - //x -= id.width; - drawImage(id, x, getSize().y - id.height); - } +
+ public int hashCode() {
+ int code = base.hashCode();
+ for (int i = 0; i < overlays.length; i++) {
+ code ^= overlays[i].hashCode();
} + return code;
} - /* - * @see CompositeImage#fill - */ +
+
protected void drawCompositeImage(int width, int height) { - ImageData bg = base; - if (bg == null) { - bg = DEFAULT_IMAGE_DATA; - } - drawImage(bg, 0, 0); - - if (overlays != null) { - if (overlays.length > 0) { - drawTopRight(overlays[0]); - } - - if (overlays.length > 1) { - drawBottomRight(overlays[1]); - } - - if (overlays.length > 2) { - drawBottomLeft(overlays[2]); - } - - if (overlays.length > 3) { - drawTopLeft(overlays[3]); - } - } + drawImage(base.getImageData(), 0, 0);
+ drawOverlays(overlays);
} - /** - * Draws the overlays in the top left - * - * @param overlays the overlay images - */ - protected void drawTopLeft(ImageDescriptor[] overlays) { - if (overlays == null) return; - int length = overlays.length; - int x = 0; - for (int i= 0; i < 3; i++) { - if (i < length && overlays[i] != null) { - ImageData id = overlays[i].getImageData(); - drawImage(id, x, 0); - //x += id.width; - } - } - } - /** - * Draws the overlays in the top right - * - * @param overlays the overlay images - */ - protected void drawTopRight(ImageDescriptor[] overlays) { - if (overlays == null) return; - int length = overlays.length; - //int x = getSize().x; - int x = 0; - for (int i = 8; i >= 0; i--) { - if (i < length && overlays[i] != null) { - ImageData id = overlays[i].getImageData(); - //x -= id.width; - drawImage(id, x, 0); - } - } - } - /* - * @see CompositeImage#getSize - */ +
protected Point getSize() { return size; } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java new file mode 100644 index 000000000..eed81dad7 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java @@ -0,0 +1,49 @@ +/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Maintains a cache of OverlayIcons.
+ */
+public class OverlayIconCache {
+ private Map /*from OverlayIcon to Image*/ cache = new HashMap();
+
+ /**
+ * Returns and caches an image corresponding to the specified icon.
+ * @param icon the icon
+ * @return the image
+ */
+ public Image getImageFor(OverlayIcon icon) {
+ Image image = (Image) cache.get(icon);
+ if (image == null) {
+ image = icon.createImage();
+ cache.put(icon, image);
+ }
+ return image;
+ }
+
+ /**
+ * Disposes of all images in the cache.
+ */
+ public void disposeAll() {
+ for (Iterator it = cache.values().iterator(); it.hasNext();) {
+ Image image = (Image) it.next();
+ image.dispose();
+ }
+ cache.clear();
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java index ec779ba92..c42e9a164 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java @@ -14,7 +14,6 @@ import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.resource.CompositeImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -42,6 +41,8 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.HistoryView; import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; +import org.eclipse.team.internal.ccvs.ui.OverlayIcon;
+import org.eclipse.team.internal.ccvs.ui.OverlayIconCache;
import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.merge.OverrideUpdateMergeAction; import org.eclipse.team.internal.ccvs.ui.merge.UpdateMergeAction; @@ -64,35 +65,20 @@ public class CVSCatchupReleaseViewer extends CatchupReleaseViewer { private HistoryAction showInHistory; private OverrideUpdateMergeAction forceUpdateMergeAction; - class DiffImage extends CompositeImageDescriptor { - private static final int HEIGHT= 16; - private static final int WIDTH= 22; - - Image baseImage; - ImageDescriptor overlay; - - public DiffImage(Image baseImage, ImageDescriptor overlay) { - this.baseImage = baseImage; - this.overlay = overlay; + private static class DiffOverlayIcon extends OverlayIcon {
+ private static final int HEIGHT = 16;
+ private static final int WIDTH = 22;
+ public DiffOverlayIcon(Image baseImage, ImageDescriptor overlay) {
+ super(baseImage, new ImageDescriptor[] { overlay }, new Point(WIDTH, HEIGHT));
} - - /* - * @see CompositeImageDescriptor#drawCompositeImage(int, int) - */ - protected void drawCompositeImage(int width, int height) { - drawImage(baseImage.getImageData(), 0, 0); + protected void drawOverlays(ImageDescriptor[] overlays) {
+ ImageDescriptor overlay = overlays[0];
ImageData overlayData = overlay.getImageData(); drawImage(overlayData, WIDTH - overlayData.width, (HEIGHT - overlayData.height) / 2); } - - /* - * @see CompositeImageDescriptor#getSize() - */ - protected Point getSize() { - return new Point(WIDTH, HEIGHT); - } } - class HistoryAction extends Action implements ISelectionChangedListener { +
+ private static class HistoryAction extends Action implements ISelectionChangedListener {
IStructuredSelection selection; public HistoryAction(String label) { super(label); @@ -157,14 +143,19 @@ public class CVSCatchupReleaseViewer extends CatchupReleaseViewer { final ImageDescriptor questionableDescriptor = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_QUESTIONABLE); final LabelProvider oldProvider = (LabelProvider)getLabelProvider(); setLabelProvider(new LabelProvider() { + private OverlayIconCache iconCache = new OverlayIconCache();
+
+ public void dispose() {
+ iconCache.disposeAll();
+ oldProvider.dispose();
+ }
public Image getImage(Object element) { Image image = oldProvider.getImage(element); if (element instanceof ITeamNode) { ITeamNode node = (ITeamNode)element; int kind = node.getKind(); if ((kind & IRemoteSyncElement.AUTOMERGE_CONFLICT) != 0) { - DiffImage diffImage = new DiffImage(image, conflictDescriptor); - return diffImage.createImage(); + return iconCache.getImageFor(new DiffOverlayIcon(image, conflictDescriptor));
} if (kind == (IRemoteSyncElement.OUTGOING | IRemoteSyncElement.ADDITION)) { IResource resource = node.getResource(); @@ -172,8 +163,7 @@ public class CVSCatchupReleaseViewer extends CatchupReleaseViewer { try { ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile) resource); if (cvsFile.getSyncInfo() == null) { - DiffImage diffImage = new DiffImage(image, questionableDescriptor); - return diffImage.createImage(); + return iconCache.getImageFor(new DiffOverlayIcon(image, questionableDescriptor));
} } catch (TeamException e) { ErrorDialog.openError(getControl().getShell(), null, null, e.getStatus()); |