Java tutorial
/******************************************************************************* * Copyright (c) 2003 Jan Karstens, Andr Langhorst. * 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: * Jan Karstens <jan.karstens@web.de> - initial implementation *******************************************************************************/ package net.sf.versiontree.ui; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.versiontree.VersionTreePlugin; import net.sf.versiontree.data.IRevision; import net.sf.versiontree.data.ITreeElement; import net.sf.versiontree.data.MergePoint; import org.eclipse.jface.preference.IPreferenceStore; 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.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; /** * @author Jan * * Custom made widget that represent a revision in the revision * graph. */ public class Revision extends Canvas { private static final int STRING_OFFSET = 2; private static final int INSET = 3; private int stringXPosition = 0; private IRevision revisionData; private int width; private int height; private Color background; private Image versionImage; private Image lockedImage; private Image requestImage; private Image mergedToImage; private Image mergedFromImage; private Image closedImage; private Image completedImage; /** * Creates a new revision widget. * @param parent * @param style */ public Revision(Composite parent, int style) { super(parent, style); initializeImages(); IPreferenceStore prefs = VersionTreePlugin.getDefault().getPreferenceStore(); height = prefs.getInt(VersionTreePlugin.PREF_ELEMENT_HEIGHT); width = prefs.getInt(VersionTreePlugin.PREF_ELEMENT_WIDTH); // add paint listener addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { Revision.this.paintControl(e); } }); // add dispose listner addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { background.dispose(); versionImage.dispose(); } }); } /** * Initializes the version image. */ private void initializeImages() { CVSUIPlugin plugin = CVSUIPlugin.getPlugin(); versionImage = plugin.getImageDescriptor(ICVSUIConstants.IMG_PROJECT_VERSION).createImage(); lockedImage = VersionTreeImages.getImage(VersionTreeImages.IMG_LOCKED); requestImage = VersionTreeImages.getImage(VersionTreeImages.IMG_REQUEST); mergedToImage = VersionTreeImages.getImage(VersionTreeImages.IMG_MERGE_TO); mergedFromImage = VersionTreeImages.getImage(VersionTreeImages.IMG_MERGE_FROM); closedImage = VersionTreeImages.getImage(VersionTreeImages.IMG_CLOSED); completedImage = VersionTreeImages.getImage(VersionTreeImages.IMG_COMPLETED); stringXPosition = versionImage.getBounds().width + 2 * INSET; } /** * Paints the revision component. * @param e Paint Event */ protected void paintControl(PaintEvent e) { GC gc = e.gc; Rectangle size = getBounds(); // draw version tag icon if revision is tagged if (revisionData.hasVersionTags()) { IPreferenceStore prefs = VersionTreePlugin.getDefault().getPreferenceStore(); boolean isHeadRevision = revisionData.getRevision().matches("\\d*\\.\\d*"); boolean isLocked = false; boolean isMerged = false; boolean isBeingMerged = false; boolean isPropagated = false; boolean isClosed = false; List<String> tags = revisionData.getTags(); for (String tag : tags) { if (tag.matches(prefs.getString(VersionTreePlugin.PREF_REGEX_LOCKED))) { isLocked = true; // "locked" has preference over other icons break; } if (tag.matches(prefs.getString(VersionTreePlugin.PREF_REGEX_REQUEST))) { isBeingMerged = true; } if (tag.matches(prefs.getString(VersionTreePlugin.PREF_REGEX_CLOSED))) { isClosed = true; } if (tag.matches(prefs.getString(VersionTreePlugin.PREF_REGEX_MERGE_TO))) { isMerged = true; } if (tag.matches(prefs.getString(VersionTreePlugin.PREF_REGEX_MERGE_FROM))) { isPropagated = true; } } Image image = versionImage; if (isLocked) { image = lockedImage; } else if (isBeingMerged) { image = requestImage; } else if (isClosed && isMerged && !isHeadRevision) { image = completedImage; } else if (isClosed && !isHeadRevision) { image = closedImage; } else if (isMerged && !isHeadRevision) { image = mergedToImage; } else if (isPropagated && !isHeadRevision) { image = mergedFromImage; } gc.drawImage(image, INSET, INSET); } int yOffset = INSET; Point extent = gc.stringExtent(getRevisionString()); // draw revision string Color rememberColor = gc.getForeground(); if (revisionData.getLogEntry().isDeletion()) { gc.setForeground(new Color(Display.getDefault(), 128, 128, 128)); } gc.drawString(getRevisionString(), stringXPosition, yOffset); yOffset += STRING_OFFSET + extent.y; // draw author string extent = gc.stringExtent(revisionData.getAuthor()); gc.drawString(revisionData.getAuthor(), stringXPosition, yOffset); // draw rectangle (or focus border if selected) if (isSelected()) { gc.drawFocus(0, 0, size.width, size.height); } else { gc.drawRectangle(0, 0, size.width - 1, size.height - 1); } gc.setForeground(rememberColor); } @Override public Point computeSize(int wHint, int hHint, boolean changed) { return new Point(width, height); } /** * Returns the revision number as a String. * @return the revision number. */ public String getRevision() { return revisionData.getRevision(); } /** * Returns the revision as a String. Prepended with a "*" if this * is the current revision in the workingspace. * @return */ private String getRevisionString() { String revisionNumber = revisionData.getRevision(); if ((revisionData.getState() & ITreeElement.STATE_CURRENT) > 0) { revisionNumber = "*" + revisionNumber; //$NON-NLS-1$ } if (revisionData.getLogEntry().isDeletion()) { revisionNumber += " (" + revisionData.getLogEntry().getState() + ")"; } return revisionNumber; } /** * Returns the revision data. This is the data model for this * widget. * @return */ public IRevision getRevisionData() { return revisionData; } /** * Sets the data model for this widget. * @param data */ public void setRevisionData(IRevision data) { revisionData = data; String tooltip = ""; IPreferenceStore prefs = VersionTreePlugin.getDefault().getPreferenceStore(); List<String> tags = revisionData.getTags(); for (String tag : tags) { final Pattern patternLocked = Pattern.compile(prefs.getString(VersionTreePlugin.PREF_REGEX_LOCKED)); Matcher matcherLockedBy = patternLocked.matcher(tag); while (matcherLockedBy.find()) { // "tag_(.*)_LOCKED_.*" String branchLocked = matcherLockedBy.group(1); if (tooltip.length() > 0) { tooltip += "\n"; } tooltip += VersionTreePlugin.getResourceString("VersionTreeView.Locked_By") + ": " + branchLocked; //$NON-NLS-1$ } } for (String tag : tags) { final Pattern patternRequest = Pattern.compile(prefs.getString(VersionTreePlugin.PREF_REGEX_REQUEST)); Matcher matcherRequest = patternRequest.matcher(tag); while (matcherRequest.find()) { // "tag_.*_REQUEST_(.*)" if (tooltip.length() > 0) { tooltip += "\n"; } String request = matcherRequest.groupCount() > 0 ? matcherRequest.group(1) : tag; tooltip += VersionTreePlugin.getResourceString("VersionTreeView.Request") + ": " + request; //$NON-NLS-1$ } } List<MergePoint> mergeFromList = data.getMergeFromRevisions(); List<MergePoint> mergeToList = data.getMergeToRevisions(); for (MergePoint mergeFromPoint : mergeFromList) { String mergeFromMessage = VersionTreePlugin.getResourceString("VersionTreeView.Merge_From_Message"); //$NON-NLS-1$ if (tooltip.length() > 0) { tooltip += "\n"; } tooltip += mergeFromMessage + ": " + mergeFromPoint.getBranchName(); tooltip += " (" + mergeFromPoint.getMergeRevision().getRevision() + ")"; } for (MergePoint mergeToPoint : mergeToList) { String mergeToMessage = VersionTreePlugin.getResourceString("VersionTreeView.Merge_To_Message"); //$NON-NLS-1$ if (tooltip.length() > 0) { tooltip += "\n"; } tooltip += mergeToMessage + ": " + mergeToPoint.getBranchName(); tooltip += " (" + mergeToPoint.getMergeRevision().getRevision() + ")"; } setToolTipText(tooltip); // Parse background color String color = prefs.getString(VersionTreePlugin.PREF_REVISION_BACKGROUNDCOLOR); if (revisionData.getLogEntry().isDeletion()) { color = prefs.getString(VersionTreePlugin.PREF_DEADREVISION_BACKGROUNDCOLOR); } int temp1 = color.indexOf(','); int temp2 = color.indexOf(',', temp1 + 1); background = new Color(null, Integer.valueOf(color.substring(0, temp1)).intValue(), Integer.valueOf(color.substring(temp1 + 1, temp2)).intValue(), Integer.valueOf(color.substring(temp2 + 1, color.length())).intValue()); setBackground(background); redraw(); } /** * Toggles the selection state. * @param b selected if true. */ public void setSelected(boolean b) { revisionData.setSelected(b); redraw(); } /** * Returns true if selected. * @return true if selected. */ public boolean isSelected() { return revisionData.isSelected(); } }