1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.atlassian.theplugin.idea.ui.tree.file;
17
18 import com.atlassian.theplugin.commons.crucible.ValueNotYetInitialized;
19 import com.atlassian.theplugin.commons.crucible.api.model.CommitType;
20 import com.atlassian.theplugin.commons.crucible.api.model.CrucibleFileInfo;
21 import com.atlassian.theplugin.commons.crucible.api.model.ReviewAdapter;
22 import com.atlassian.theplugin.idea.ui.tree.AtlassianClickAction;
23 import com.atlassian.theplugin.idea.ui.tree.AtlassianTreeNode;
24 import com.atlassian.theplugin.util.PluginUtil;
25 import com.intellij.openapi.fileTypes.FileType;
26 import com.intellij.openapi.fileTypes.FileTypeManager;
27 import com.intellij.openapi.vcs.FileStatus;
28 import com.intellij.ui.ColoredTreeCellRenderer;
29 import com.intellij.ui.SimpleTextAttributes;
30 import com.intellij.util.Icons;
31 import com.intellij.util.ui.UIUtil;
32 import org.apache.commons.io.FilenameUtils;
33 import org.apache.commons.lang.StringUtils;
34
35 import javax.swing.*;
36 import javax.swing.tree.TreeCellRenderer;
37 import java.awt.*;
38
39 public class CrucibleFileNode extends FileNode {
40
41 private CrucibleFileInfo file;
42 private static final ColoredTreeCellRenderer MY_RENDERER = new CrucibleFileNodeRenderer();
43 private ReviewAdapter review;
44
45 public CrucibleFileNode(final ReviewAdapter review, final CrucibleFileInfo file) {
46 this(review, file, AtlassianClickAction.EMPTY_ACTION);
47 }
48
49 public CrucibleFileNode(final ReviewAdapter review, final CrucibleFileInfo file,
50 final AtlassianClickAction action) {
51 super(FilenameUtils.getName(file.getFileDescriptor().getUrl()), action);
52 this.review = review;
53 this.file = file;
54 }
55
56 public CrucibleFileNode(final CrucibleFileNode node) {
57 this(node.getReview(), node.getFile(), node.getAtlassianClickAction());
58 }
59
60 @Override
61 public TreeCellRenderer getTreeCellRenderer() {
62 return MY_RENDERER;
63 }
64
65 public CrucibleFileInfo getFile() {
66 return file;
67 }
68
69 public ReviewAdapter getReview() {
70 return review;
71 }
72
73 public void setReview(ReviewAdapter review) {
74 this.review = review;
75 try {
76 for (CrucibleFileInfo info : review.getFiles()) {
77 if (info.getPermId().equals(file.getPermId())) {
78 file.setVersionedComments(info.getVersionedComments());
79 break;
80 }
81 }
82 } catch (ValueNotYetInitialized e) {
83 PluginUtil.getLogger().warn(e);
84 }
85 }
86
87 private static class CrucibleFileNodeRenderer extends ColoredTreeCellRenderer {
88 private static final SimpleTextAttributes TEXT_ITALIC =
89 new SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, null);
90 private static final SimpleTextAttributes RED_ITALIC =
91 new SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, Color.red);
92
93 @Override
94 public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded,
95 boolean leaf, int row, boolean hasFocus) {
96 CrucibleFileNode node = (CrucibleFileNode) value;
97 append(node.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
98
99 StringBuilder txt = new StringBuilder();
100 final CommitType commitType = node.getFile().getCommitType();
101 switch (commitType) {
102 case Moved:
103 txt.append(" moved, ");
104 break;
105 default:
106 break;
107 }
108 txt.append(" (rev: ");
109 switch (commitType) {
110 case Added:
111 txt.append(node.getFile().getFileDescriptor().getRevision());
112 break;
113 case Deleted:
114 txt.append(node.getFile().getOldFileDescriptor().getRevision());
115 break;
116 case Modified:
117 case Copied:
118 case Moved:
119 case Unknown:
120 default:
121 String oldRev = node.getFile().getOldFileDescriptor().getRevision();
122 if (!StringUtils.isEmpty(oldRev)) {
123 txt.append(oldRev);
124 } else {
125 txt.append("Unknown");
126 }
127 txt.append("-");
128 String newRev = node.getFile().getFileDescriptor().getRevision();
129 if (!StringUtils.isEmpty(newRev)) {
130 txt.append(newRev);
131 } else {
132 txt.append("Unknown");
133 }
134 break;
135 }
136 txt.append(")");
137
138 if (selected) {
139 append(txt.toString(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, null));
140 } else {
141 append(txt.toString(), SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
142 }
143
144 int noOfComments = node.getFile().getNumberOfComments();
145 if (noOfComments > 0) {
146 int noOfDefects = node.getFile().getNumberOfCommentsDefects();
147 append(" ",
148 TEXT_ITALIC);
149 append(String.valueOf(noOfComments),
150 TEXT_ITALIC);
151 append(" comment", TEXT_ITALIC);
152 if (noOfComments != 1) {
153 append("s", TEXT_ITALIC);
154 }
155
156 if (noOfDefects > 0) {
157 append(" (", TEXT_ITALIC);
158 append(String.valueOf(noOfDefects),
159 RED_ITALIC);
160 append(" defect",
161 RED_ITALIC);
162 if (noOfDefects != 1) {
163 append("s",
164 RED_ITALIC);
165 }
166 append(")", TEXT_ITALIC);
167 }
168 }
169
170 if (node.getFile().getFileType() == com.atlassian.theplugin.commons.crucible.api.model.FileType.Directory) {
171 setIcon(Icons.DIRECTORY_OPEN_ICON);
172 } else {
173 FileTypeManager mgr = FileTypeManager.getInstance();
174 FileType type = mgr.getFileTypeByFileName(node.getName());
175 setIcon(type.getIcon());
176 }
177 switch (node.getFile().getCommitType()) {
178 case Added:
179 setForeground(FileStatus.COLOR_ADDED);
180 break;
181 case Deleted:
182 setForeground(FileStatus.COLOR_MISSING);
183 break;
184 case Modified:
185 case Moved:
186 case Copied:
187 setForeground(FileStatus.COLOR_MODIFIED);
188 break;
189 case Unknown:
190 default:
191 setForeground(FileStatus.COLOR_UNKNOWN);
192 break;
193 }
194
195 if (selected) {
196
197 setBackground(UIUtil.getTreeSelectionBackground());
198 setForeground(UIUtil.getTreeSelectionForeground());
199 }
200
201 }
202 }
203
204 @Override
205 public AtlassianTreeNode getClone() {
206 return new CrucibleFileNode(this);
207 }
208
209 @Override
210 public boolean isCompactable() {
211 return false;
212 }
213 }