/******************************* Copyright notice ******************************* Copyright (C)2002 by Andrei Loskutov <loskutov@gmx.de>. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************************/ package adiag.view; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import adiag.model.Const; import adiag.model.Version; /** * Graphical representation of P4 revision as a rectangle * @author Andrei Loskutov */ public class VersionView extends Rectangle2D.Float { /** corresponding version */ protected Version version; /** is selected on view? */ private boolean selected; /** is collapsed on view? */ private boolean collapsed; /** custom user change on x coordinate in layout */ public float dx; /** custom user change on y coordinate in layout */ public float dy; /** arrowhead */ private static final GeneralPath ARROW = new GeneralPath(GeneralPath.WIND_EVEN_ODD); /** fill color for deleted version */ private static final Color COLOR_FILL_DELETED = new Color(16777215); // white:16777215 /** border color for deleted version */ private static final Color COLOR_DRAW_DELETED = Color.red; /** fill color for normal version */ private static final Color COLOR_FILL_VIEW = new Color(15329769); // leicht grau 15329769 /** line color for deleted version */ private static final Color COLOR_LINE_SAME_BRANCH = Color.lightGray; /** border color for not direct received version */ private static final Color COLOR_NOT_RECEIVED = Color.orange.darker(); /** border color for unknown version */ private static final Color COLOR_CHANGE_NOT_KNOWN = Color.red; /** border color for selected version */ private static final Color COLOR_SELECTED = Color.red; /** border color for normal version */ private static final Color COLOR_LINE_DEFAULT = Color.black; /** text color for "branch" - changes */ private static final Color COLOR_TEXT_BRANCH = Color.blue; /** text color for the "edit" - changes */ private static final Color COLOR_TEXT_SAME = new Color(32768); // grn, etwas dunkler /** line color for normal arrow within the branch */ private static final Color COLOR_LINE_ARROW = Color.gray; /** line color for die ignored version */ private static final Color COLOR_LINE_IGNORED = Color.red.darker(); /** the start angle for calculations */ private static final double START_ANGLE = (Math.PI * 3 / 4); /** usual thin line */ private static final BasicStroke STROKE_THIN = new BasicStroke(1); /** usual normal line */ private static final BasicStroke STROKE_DEFAULT = new BasicStroke(2); /** border line for "not received" versions */ private static final BasicStroke STROKE_NOT_RECEIVED = new BasicStroke( 2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 2.0f }, 0.0f); /** border line for "selected" versions */ private static final BasicStroke STROKE_SELECTED = new BasicStroke( 4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 2.0f }, 0.0f); /** border line for "unknown" versions */ private static final BasicStroke STROKE_CHANGE_NOT_KNOWN = new BasicStroke( 1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 3.0f }, 0.0f); /** Make the Arrow head */ static { ARROW.moveTo(4, 8); ARROW.lineTo(0, 0); ARROW.lineTo(8, 4); ARROW.closePath(); } /** the matrix - instance for calculations of arrow rotation */ private final AffineTransform TRANSFORM = new AffineTransform(); /** the text buffer for version info */ private final StringBuffer STRING_BUFFER = new StringBuffer(); /** the x space from text to edge */ public static final int PADDING_X = 1; /** the x space from text to edge */ public static final int PADDING_Y = 1; /** * VersionView Constructor * @param v die corresponded version */ public VersionView(Version v) { this.version = v; } /** * See return description * @return Version the corresponded version */ public Version getVersion() { return version; } /** * See return description * @return true, if VersionView is selected on view */ public boolean isSelected() { return selected; } /** * See return description * @return true, if VersionView is 'collapsed' on view */ public boolean isCollapsed() { return collapsed; } /** * Set collapsed state on/off * @param true, to set VersionView 'collapsed' on view */ public void setCollapsed(boolean collapsed) { this.collapsed = collapsed; } /** * Paint this versionView in given context * @param gr current context */ public void repaint(Graphics2D gr) { // info STRING_BUFFER.setLength(0); STRING_BUFFER.append(version.getVersionAndChangeText()); int x = (int) getX(); int y = (int) getY(); int width = (int) (this.width); int half_width = width / 2; int height = (int) (this.height); int half_height = height / 2; if (isSelected()) { gr.setColor(COLOR_SELECTED); gr.setStroke(STROKE_SELECTED); } gr.draw(this); // border / line color if (!version.isChangeNumOk()) { gr.setColor(COLOR_CHANGE_NOT_KNOWN); gr.setStroke(STROKE_DEFAULT); } else if(!version.isReceived()){ gr.setColor(COLOR_NOT_RECEIVED); gr.setStroke(STROKE_NOT_RECEIVED); } else { gr.setColor(COLOR_LINE_DEFAULT); gr.setStroke(STROKE_DEFAULT); } gr.draw(this); gr.setStroke(STROKE_THIN); boolean deleted = Const.TYPE_DELETE.equals(version.getChangeType()); if (!deleted) { gr.setColor(COLOR_FILL_VIEW); } else { gr.setColor(COLOR_FILL_DELETED); } gr.fill(this); // make a cross ;) if (deleted) { gr.setColor(COLOR_DRAW_DELETED); gr.drawLine(x, y, x + width, y + height); gr.drawLine(x, y + height, x + width, y); } gr.setColor(COLOR_LINE_DEFAULT); // draw text in a box gr.drawString(STRING_BUFFER.toString(), x + PADDING_X, y + height - PADDING_Y*2); Shape arr = null; // is somewhhere in the same branch ? Version n = version.getNext(); Layout layout = LayoutManager.getLayout(version); if (n != null) { VersionView nv = layout.getView(n); String ctype = n.getChangeType(); // good type is: edit/delete and integrate, if next version was ignored by last integrate boolean good_ctype = ctype != null && (Const.TYPE_EDIT.equals(ctype) || Const.TYPE_DELETE.equals(ctype) || n.isIgnored()); Stroke s = gr.getStroke(); if (!good_ctype) { gr.setColor(COLOR_LINE_SAME_BRANCH); gr.setStroke(STROKE_CHANGE_NOT_KNOWN); } int displace_y, displace_y_b; float ny = (float)nv.getY(); float nx = (float)nv.getX(); if (ny > y) { displace_y = height + 1; displace_y_b = 0; } else { displace_y = 0; displace_y_b = height + 1; } gr.drawLine( x + half_width, y + displace_y, (int) (nx + half_width), (int) (ny + displace_y_b)); gr.setStroke(s); if (good_ctype && (!nv.isCollapsed() || ( this.height + this.getY() != ny ))) { // String with action type in the branch gr.setColor(COLOR_TEXT_SAME); gr.drawString( n.getChangeType(), (int) (x + width + (nx - x - width - Const.getFontWidth(gr, n.getChangeType())) / 2), (int) (y + height + (ny - y - height + Const.getFontHeight(gr) / 2) / 2)); arr = getArrow( x + half_width, y + displace_y, nx + half_width, displace_y_b + ny); gr.setColor(COLOR_TEXT_SAME); gr.fill(arr); gr.setColor(COLOR_LINE_ARROW); gr.draw(arr); } gr.setColor(COLOR_LINE_DEFAULT); } // now we paint next branches, if available Version[] next = version.getNextBranch(); if(next == null){ return; } Version nb = null; int displace_x, displace_x_b; float nx, ny, nwidth; String change_type; VersionView nbv; for (int i = 0; i < next.length; i++) { nb = next[i]; if (nb != null) { nbv = layout.getView(nb); nx = (float) nbv.getX(); ny = (float) nbv.getY(); nwidth = getNodeWidth(nb, gr); if (nx > x) { displace_x = width; displace_x_b = 0; } else { displace_x = 0; displace_x_b = (int) nwidth; } if (nb.isIgnored(version)) { gr.setColor(COLOR_LINE_IGNORED); } gr.drawLine( (x + displace_x), (y + half_height), (int) (nx + displace_x_b), (int) (ny + half_height)); arr = getArrow( x + displace_x, y + half_height, (nx + displace_x_b), (ny + half_height)); if (!nb.isIgnored(version)) { gr.setColor(COLOR_TEXT_BRANCH); } // write string with action type outside of the branch change_type = nb.getChangeTypeFrom(version); gr.drawString( change_type, (int) (x + width + (nx - x - width - Const.getFontWidth(gr, change_type)) / 2), (int) ((y + ny + height + i * Const.getFontHeight(gr)) / 2)); if (!nb.isIgnored(version)) { gr.setColor(COLOR_TEXT_BRANCH); gr.fill(arr); gr.setColor(COLOR_LINE_ARROW); } else { gr.fill(arr); } gr.draw(arr); gr.setColor(COLOR_LINE_DEFAULT); } } } /** * See return description * @return the "box" width in a given context, or width of six "4" characters, * if node is null */ private float getNodeWidth(Version v, Graphics gr) { if (v != null) { return VersionView.PADDING_X * 2 + Const.getFontWidth(gr, v.getVersionAndChangeText()); } else { return Const.getFontWidth(gr, "444444"); } } /** * Rotate the arrowhead * @param x the start coordinate of the line * @param y the start coordinate of the line * @param nx the end coordinate of the line * @param ny the end coordinate of the line * @return Shape arrowhead, rotated to right angle and moved to the right point */ private Shape getArrow(float x, float y, float nx, float ny) { TRANSFORM.setToIdentity(); TRANSFORM.translate(nx, ny); TRANSFORM.rotate(START_ANGLE + Math.atan2(ny - y, nx - x)); GeneralPath arrow = (GeneralPath) ARROW.clone(); arrow.transform(TRANSFORM); return arrow; } /** * Set state of this VersionView to selected * @param newSelected true for select state */ public void setSelected(boolean newSelected) { selected = newSelected; } /** * See return description * @return die x - coordinate of the VersionView * @see RectangularShape#getX() */ public double getX() { return x + dx; } /** * See return description * @return die y - coordinate of the VersionView * @see RectangularShape#getY() */ public double getY() { return y + dy; } /** Overriden * @see java.lang.Object#equals(Object) */ public boolean equals(Object object) { // high performance fast path if (this == object){ return true; } // test object not null or other type else if (object == null || getClass() != object.getClass()){ return false; } // real value check is required VersionView theOther = (VersionView) object; return this.getVersion().equals(theOther.getVersion()); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#5 | 2735 | andrei_loskutov | sources are now included to binary distribution at http://andrei.gmxhome.de/perforce/index.html | ||
#4 | 2554 | andrei_loskutov |
#25.12.2002 23:29 Revision 1.3.0.4 beta 1) Some small refactoring 2) First integration with P4eclipse: properties etc, thanks Boris Pr�ssmann 5) Better integration to Eclipse: use Eclipse internal compare tool for diff. 6) Fix some minor bugs. #14.12.2002 23:15 Revision 1.3.0.3 beta 1) Fix endless loop bug if p4 path was not set. 2) Fix never getting focus bug after error message shown 3) Fix painting bug on JDK 1.4.1 (must be verified!!!) 4) Some small refactoring 5) Fix error handling. 6) Fix some minor bugs. |
||
#3 | 2552 | andrei_loskutov | 1.3.0.4 changes | ||
#2 | 2460 | andrei_loskutov |
1) Change configuration: always reed properties 2) Change password store to hex format/password field 3) Create standalone/not standalone state for new branchview eclipse wrapper 4) Refactor all main classes to remove cyclic package dependency 5) Add workaround to fix new JDK 1.4.1 Swing bugs on JScrollPane/JViewPort 6) Add dispose methods to panel/connector 7) Minor internal GUI fixes/refactorings |
||
#1 | 2222 | andrei_loskutov |
#13.10.2002 22:16 Revision 1.2.1 1) Documentation task is finished... Yes!!! 2) New feature: copy P4 depot path 3) Some small fixes to menu shortkeys belongs ctrl + c and ctrl + d 4) Clipboard fix because of JDK 1.2 - 1.3 bug 5) Smallest refactoring on some methods. 6) Html help updated |