1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.theplugin.util;
18
19 import com.atlassian.theplugin.commons.crucible.api.model.*;
20 import com.atlassian.theplugin.idea.crucible.ReviewData;
21 import com.intellij.ui.components.labels.BoldLabel;
22 import com.jgoodies.forms.layout.CellConstraints;
23 import com.jgoodies.forms.layout.FormLayout;
24
25 import javax.swing.*;
26 import java.awt.*;
27 import java.util.Map;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31
32
33 public final class CommentPanelBuilder {
34 private static final Color NOT_MINE_GENERAL_COMMENT_HEADER_COLOR = new Color(239, 224, 255);
35 private static final Color NOT_MINE_GENERAL_COMMENT_BODY_COLOR = new Color(234, 255, 255);
36 private static final Color NOT_MINE_FILE_COMMENT_HEADER_COLOR = new Color(255, 224, 224);
37 private static final Color NOT_MINE_FILE_COMMENT_BODY_COLOR = new Color(234, 255, 255);
38
39 private static final Color MINE_GENERAL_COMMENT_HEADER_COLOR = new Color(0xE0, 0xFE, 0xFF);
40 private static final Color MINE_GENERAL_COMMENT_BODY_COLOR = new Color(0xEA, 0xFF, 0xFF);
41 private static final Color MINE_FILE_COMMENT_HEADER_COLOR = new Color(0xE0, 0xFE, 0xFF);
42 private static final Color MINE_FILE_COMMENT_BODY_COLOR = new Color(0xEA, 0xFF, 0xFF);
43
44 private CommentPanelBuilder() {
45
46 }
47
48 public static JPanel createEditPanelOfGeneralComment(ReviewData review, GeneralComment comment) {
49 return createViewPanelOfGeneralComment(review, comment);
50 }
51
52 public static JPanel createViewPanelOfGeneralComment(final ReviewData review, final GeneralComment comment) {
53 return new CommentPanel(review, comment) {
54 @Override
55 public Color getHeaderBackground() {
56 if (comment.getAuthor().getUserName().equals(review.getServer().getUsername())) {
57 return MINE_GENERAL_COMMENT_HEADER_COLOR;
58 }
59 return NOT_MINE_GENERAL_COMMENT_HEADER_COLOR;
60
61 }
62
63 @Override
64 public Color getBodyBackground() {
65 if (comment.getAuthor().getUserName().equals(review.getServer().getUsername())) {
66 return MINE_GENERAL_COMMENT_BODY_COLOR;
67 }
68 return NOT_MINE_GENERAL_COMMENT_BODY_COLOR;
69 }
70
71 };
72 }
73
74 public static JPanel createEditPanelOfVersionedComment(ReviewData review, CrucibleFileInfo file,
75 VersionedComment comment) {
76 return createViewPanelOfVersionedComment(review, file, comment);
77 }
78
79 public static JPanel createViewPanelOfVersionedComment(final ReviewData review, CrucibleFileInfo file,
80 final VersionedComment comment) {
81 return new CommentPanel(review, comment) {
82 @Override
83 public Color getHeaderBackground() {
84 if (comment.getAuthor().getUserName().equals(review.getServer().getUsername())) {
85 return MINE_FILE_COMMENT_HEADER_COLOR;
86 }
87 return NOT_MINE_FILE_COMMENT_HEADER_COLOR;
88 }
89
90 @Override
91 public Color getBodyBackground() {
92 if (comment.getAuthor().getUserName().equals(review.getServer().getUsername())) {
93 return MINE_FILE_COMMENT_BODY_COLOR;
94 }
95 return NOT_MINE_FILE_COMMENT_BODY_COLOR;
96 }
97 };
98 }
99
100 private abstract static class CommentPanel extends JPanel {
101 private ReviewData review;
102 private Comment comment;
103 private static final CellConstraints AUTHOR_POS = new CellConstraints(2, 2);
104 private static final CellConstraints DATE_POS = new CellConstraints(4, 2);
105 private static final CellConstraints LINE_POS = new CellConstraints(6, 2);
106 private static final CellConstraints RANKING_POS = new CellConstraints(8, 2);
107 private static final CellConstraints DRAF_STATE_POS = new CellConstraints(10, 2);
108 private static final CellConstraints DEFECT_STATE_POS = new CellConstraints(12, 2);
109 private static final CellConstraints TOOLBAR_POS = new CellConstraints(14, 2);
110 private static final Color BORDER_COLOR = new Color(0xCC, 0xCC, 0xCC);
111
112 private static final float MINIMUM_FONT_SIZE = 3;
113 private static final float DATE_FONT_DIFFERENCE = -3;
114 private static final float AUTHOR_FONT_DIFFERENCE = -3;
115 private static final float LINE_NUMBER_FONT_DIFFERENCE = -3;
116 private static final float RANKING_FONT_DIFFERENCE = -3;
117 private static final float STATE_FONT_DIFFERENCE = -3;
118 private static final Color STATE_DRAFT_LABEL_COLOR = new Color(0xFF, 0xD4, 0x15);
119
120 private CommentPanel(ReviewData review, Comment comment) {
121 super(new FormLayout("pref:grow",
122 "pref, pref:grow"));
123
124 this.review = review;
125 this.comment = comment;
126 setBackground(getBodyBackground());
127 CellConstraints cc = new CellConstraints();
128 JPanel header = new JPanel(
129 new FormLayout(
130 "4dlu, left:pref, 10dlu, left:pref, 10dlu, left:pref, 10dlu, pref:grow, 10dlu, right:pref, "
131 + "10dlu, right:pref, 10dlu, pref, 4dlu",
132 "2dlu, pref:grow, 2dlu"));
133 header.add(getAuthorLabel(), AUTHOR_POS);
134 header.add(getDateLabel(), DATE_POS);
135 header.add(getLineInfoLabel(), LINE_POS);
136 if (comment.isDefectRaised()) {
137 header.add(getRankingLabel(getHeaderBackground()), RANKING_POS);
138 }
139 header.add(getStateLabel("DRAFT", comment.isDraft(), STATE_DRAFT_LABEL_COLOR), DRAF_STATE_POS);
140 header.add(getStateLabel("DEFECT", comment.isDefectRaised(), Color.RED), DEFECT_STATE_POS);
141 header.add(getToolBar(), TOOLBAR_POS);
142 header.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, 1));
143 header.setBackground(getHeaderBackground());
144
145
146
147 JPanel body = new JPanel(new FormLayout("4dlu, pref:grow, 4dlu", "2dlu, pref:grow, 2dlu"));
148 body.add(getMessageBody(), cc.xy(2, 2));
149 body.setBackground(getBodyBackground());
150 add(header, cc.xy(1, 1));
151 add(body, cc.xy(1, 2));
152 }
153
154 private Component getDateLabel() {
155 StringBuilder sb = new StringBuilder();
156 JLabel label;
157 sb.append("[ ");
158 sb.append(comment.getCreateDate().toString());
159 sb.append(" ]");
160 label = new JLabel(sb.toString());
161 label.setFont(getSmallerFont(label.getFont(), DATE_FONT_DIFFERENCE));
162 label.setForeground(Color.GRAY);
163 return label;
164 }
165
166 private Font getSmallerFont(final Font font, final float dateFontSizeDifference) {
167 if (font != null) {
168 float newFontSize = font.getSize() + dateFontSizeDifference;
169 return font.deriveFont(font.getStyle(), (newFontSize > 0 ? newFontSize : MINIMUM_FONT_SIZE));
170 }
171 return null;
172 }
173
174 protected Component getAuthorLabel() {
175 BoldLabel label =
176 new BoldLabel("".equals(comment.getAuthor().getDisplayName()) ? comment.getAuthor().getUserName() : comment
177 .getAuthor().getDisplayName());
178 label.setFont(getSmallerFont(label.getFont(), AUTHOR_FONT_DIFFERENCE));
179 return label;
180 }
181
182 protected Component getLineInfoLabel() {
183 if (comment instanceof VersionedComment) {
184 VersionedComment vc = (VersionedComment) comment;
185 if (vc.getToStartLine() > 0 && vc.getToEndLine() > 0) {
186 JLabel label = new JLabel("Lines: [" + vc.getToStartLine() + " - " + vc.getToEndLine() + "]");
187 label.setFont(getSmallerFont(label.getFont(), LINE_NUMBER_FONT_DIFFERENCE));
188 label.setForeground(Color.GRAY);
189 return label;
190 }
191 }
192 return new JLabel("");
193 }
194
195
196 protected Component getStateLabel(String text, boolean isInState, Color color) {
197 JLabel label = new JLabel("");
198
199 if (isInState) {
200 label.setText(text);
201 label.setFont(getSmallerFont(label.getFont(), STATE_FONT_DIFFERENCE));
202 label.setFont(label.getFont().deriveFont(Font.BOLD));
203 label.setForeground(color);
204 }
205 return label;
206 }
207
208
209 protected Component getRankingLabel(Color backgroundColor) {
210 JPanel panel = new JPanel(new FlowLayout());
211 panel.setBackground(backgroundColor);
212
213
214 for (Map.Entry<String, CustomField> elem : comment.getCustomFields().entrySet()) {
215
216
217 JLabel keyLabel = new JLabel(" " + firstLetterUpperCase(elem.getKey()) + ": ");
218 keyLabel.setFont(getSmallerFont(keyLabel.getFont(), RANKING_FONT_DIFFERENCE));
219 keyLabel.setForeground(Color.GRAY);
220 keyLabel.setBackground(backgroundColor);
221
222 JLabel valueLabel = new JLabel(elem.getValue().getValue());
223 valueLabel.setFont(getSmallerFont(valueLabel.getFont(), RANKING_FONT_DIFFERENCE));
224 valueLabel.setFont(valueLabel.getFont().deriveFont(Font.BOLD));
225 valueLabel.setForeground(Color.GRAY);
226 valueLabel.setBackground(backgroundColor);
227
228 panel.add(keyLabel);
229 panel.add(valueLabel);
230
231
232 }
233
234 return panel;
235 }
236
237 private static final Pattern FIRST_LETTER = Pattern.compile("([a-z])");
238
239 protected String firstLetterUpperCase(String key) {
240 StringBuffer sb = new StringBuffer();
241 Matcher matcher = FIRST_LETTER.matcher(key);
242 if (matcher.find(0)) {
243 matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
244 }
245 key = matcher.appendTail(sb).toString();
246 return key;
247 }
248
249 protected Component getMessageBody() {
250 JTextArea result = new JTextArea();
251 result.setText(comment.getMessage());
252 result.setLineWrap(true);
253 result.setWrapStyleWord(true);
254 result.setBackground(getBodyBackground());
255 return result;
256 }
257
258 public abstract Color getHeaderBackground();
259
260 public abstract Color getBodyBackground();
261
262 public Component getToolBar() {
263 return new JLabel();
264 }
265 }
266 }