1 package com.atlassian.theplugin.idea;
2
3 import com.atlassian.theplugin.commons.crucible.*;
4 import com.atlassian.theplugin.commons.crucible.api.model.ReviewItem;
5 import com.atlassian.theplugin.commons.crucible.api.model.GeneralComment;
6 import com.atlassian.theplugin.commons.crucible.api.model.VersionedComment;
7 import com.atlassian.theplugin.commons.configuration.PluginConfiguration;
8 import com.atlassian.theplugin.commons.bamboo.HtmlBambooStatusListenerNotUsed;
9 import com.atlassian.theplugin.commons.remoteapi.RemoteApiException;
10 import com.atlassian.theplugin.commons.exception.ServerPasswordNotProvidedException;
11 import com.atlassian.theplugin.commons.util.Logger;
12 import com.atlassian.theplugin.configuration.ProjectConfigurationBean;
13 import com.atlassian.theplugin.idea.ProgressAnimationProvider;
14 import com.atlassian.theplugin.idea.crucible.tree.ReviewItemTreePanel;
15 import com.atlassian.theplugin.idea.crucible.comments.ReviewCommentsPanel;
16 import com.atlassian.theplugin.idea.crucible.comments.CrucibleReviewActionListener;
17 import com.atlassian.theplugin.idea.crucible.ReviewDataInfoAdapter;
18 import com.atlassian.theplugin.idea.crucible.ReviewDetailsPanel;
19 import com.atlassian.theplugin.idea.crucible.CrucibleHelper;
20 import com.atlassian.theplugin.idea.config.ContentPanel;
21 import com.atlassian.theplugin.util.PluginUtil;
22 import com.intellij.util.ui.UIUtil;
23 import com.intellij.openapi.ui.Splitter;
24 import com.intellij.openapi.wm.ToolWindow;
25 import com.intellij.openapi.util.IconLoader;
26 import com.intellij.openapi.util.Key;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.ui.content.Content;
29 import com.intellij.ui.content.ContentManager;
30 import com.intellij.peer.PeerFactory;
31 import com.intellij.ide.DataManager;
32
33 import javax.swing.*;
34 import java.awt.*;
35 import java.util.Collection;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class CrucibleBottomToolWindowPanel extends JPanel implements ContentPanel {
55 private static final Key<CrucibleBottomToolWindowPanel> WINDOW_PROJECT_KEY = Key.create(CrucibleBottomToolWindowPanel.class.getName());
56 private Project project;
57 private static final float SPLIT_RATIO = 0.3f;
58 private ProjectConfigurationBean projectConfiguration;
59 protected static final Dimension ED_PANE_MINE_SIZE = new Dimension(200, 200);
60 protected ProgressAnimationProvider progressAnimation = new ProgressAnimationProvider();
61 private static CrucibleServerFacade serverFacade;
62 private CrucibleVersion crucibleVersion = CrucibleVersion.UNKNOWN;
63 static CrucibleBottomToolWindowPanel instance;
64 private static ReviewItemTreePanel reviewItemTreePanel;
65 private static Splitter splitter;
66 private ReviewCommentsPanel reviewComentsPanel;
67 private static CrucibleReviewActionListener tabManager;
68 private static final int LEFT_WIDTH = 150;
69 private static final int LEFT_HEIGHT = 250;
70
71
72 protected String getInitialMessage() {
73
74 return "Waiting for Crucible review info.";
75 }
76
77 public ReviewCommentsPanel getReviewComentsPanel() {
78 return reviewComentsPanel;
79 }
80
81
82
83 public static CrucibleBottomToolWindowPanel getInstance(Project project, ProjectConfigurationBean projectConfigurationBean) {
84
85 CrucibleBottomToolWindowPanel window = project.getUserData(WINDOW_PROJECT_KEY);
86
87 if (window == null) {
88 window = new CrucibleBottomToolWindowPanel(project, projectConfigurationBean);
89 project.putUserData(WINDOW_PROJECT_KEY, window);
90 }
91 return window;
92 }
93
94 private CrucibleBottomToolWindowPanel(Project project, ProjectConfigurationBean projectConfigurationBean) {
95 super(new BorderLayout());
96
97 this.project = project;
98 this.projectConfiguration = projectConfigurationBean;
99
100 serverFacade = CrucibleServerFacadeImpl.getInstance();
101
102 setBackground(UIUtil.getTreeTextBackground());
103 splitter = new Splitter();
104 reviewItemTreePanel = ReviewItemTreePanel.getInstance(projectConfigurationBean);
105 Splitter splitter = new Splitter(false, SPLIT_RATIO);
106 splitter.setShowDividerControls(true);
107 JPanel leftPanel = new JPanel();
108 leftPanel.setBackground(UIUtil.getTreeTextBackground());
109 leftPanel.setLayout(new BorderLayout());
110 leftPanel.setMinimumSize(new Dimension(LEFT_WIDTH, LEFT_HEIGHT));
111 leftPanel.add(reviewItemTreePanel);
112 reviewItemTreePanel.getProgressAnimation().configure(leftPanel, reviewItemTreePanel, BorderLayout.CENTER);
113 splitter.setFirstComponent(leftPanel);
114 splitter.setHonorComponentsMinimumSize(true);
115 tabManager = new ReviewTabManager();
116 reviewComentsPanel = ReviewCommentsPanel.getInstance();
117 splitter.setSecondComponent(reviewComentsPanel);
118 add(splitter, BorderLayout.CENTER);
119
120 progressAnimation.configure(this, reviewItemTreePanel, BorderLayout.CENTER);
121
122 }
123
124
125 protected JScrollPane setupPane(JEditorPane pane, String initialText) {
126 pane.setText(initialText);
127 JScrollPane scrollPane = new JScrollPane(pane,
128 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
129 scrollPane.setWheelScrollingEnabled(true);
130 return scrollPane;
131 }
132
133 protected String wrapBody(String s) {
134 return "<html>" + HtmlBambooStatusListenerNotUsed.BODY_WITH_STYLE + s + "</body></html>";
135
136 }
137
138 protected void setStatusMessage(String msg) {
139 setStatusMessage(msg, false);
140 }
141
142 protected void setStatusMessage(String msg, boolean isError) {
143
144
145 }
146
147
148 public ProgressAnimationProvider getProgressAnimation() {
149 return progressAnimation;
150 }
151
152 public CrucibleVersion getCrucibleVersion() {
153 return crucibleVersion;
154 }
155
156
157 public void resetState() {
158 }
159
160 public ProjectConfigurationBean getProjectConfiguration() {
161 return projectConfiguration;
162 }
163
164 public boolean isModified() {
165 return false;
166 }
167
168 public String getTitle() {
169 return null;
170 }
171
172 public void getData() {
173
174 }
175
176 public void setData(PluginConfiguration config) {
177
178 }
179
180 private static class ReviewTabManager implements CrucibleReviewActionListener {
181 private CrucibleServerFacade crucibleServerFacade;
182 private static final Logger LOGGER = PluginUtil.getLogger();
183
184 public ReviewTabManager() {
185 super();
186 IdeaHelper.getReviewActionEventBroker().registerListener(this);
187 crucibleServerFacade = CrucibleServerFacadeImpl.getInstance();
188 }
189
190 public static Content findOrCreatePanel(String panelName, JPanel panel, Boolean requestFocus) {
191 Content content = null;
192 PeerFactory peerFactory = PeerFactory.getInstance();
193 ToolWindow tw = IdeaHelper.getCurrentBottomIdeaToolWindow(DataManager.getInstance().getDataContext(panel));
194 if (tw != null) {
195 ContentManager contentManager = tw.getContentManager();
196 content = contentManager.findContent(panelName);
197 if (content == null && panel != null) {
198 content = peerFactory.getContentFactory().createContent(
199 panel, panelName, false);
200 content.setIcon(IconLoader.getIcon("/icons/tab_jira.png"));
201 content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
202 contentManager.addContent(content);
203 }
204 if (requestFocus) {
205 contentManager.setSelectedContent(content);
206 }
207 }
208 return content;
209 }
210
211
212 public void focusOnReview(ReviewDataInfoAdapter reviewDataInfoAdapter) {
213
214 }
215
216 public void focusOnFile(ReviewDataInfoAdapter reviewDataInfoAdapter, ReviewItem reviewItem) {
217
218 }
219
220 public void focusOnGeneralComment(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
221
222 }
223
224 public void focusOnGeneralCommentReply(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
225
226 }
227
228 public void focusOnVersionedComment(ReviewDataInfoAdapter reviewDataInfoAdapter, ReviewItem reviewItem, Collection<VersionedComment> versionedComments, VersionedComment versionedComment) {
229
230 }
231
232 public void focusOnVersionedCommentReply(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
233
234 }
235
236 public void showReview(ReviewDataInfoAdapter reviewItem) {
237 EventQueue.invokeLater(new Runnable() {
238 public void run() {
239 ToolWindow tw = IdeaHelper.getCurrentBottomIdeaToolWindow(DataManager.getInstance().getDataContext(CrucibleBottomToolWindowPanel.instance));
240 if (tw != null) {
241 ContentManager contentManager = tw.getContentManager();
242 for (Content content : contentManager.getContents()) {
243 if (content.getComponent() instanceof ReviewDetailsPanel) {
244 contentManager.removeContent(content, true);
245 }
246 }
247 }
248 }
249 });
250 }
251
252 public void showReviewedFileItem(final ReviewDataInfoAdapter reviewDataInfoAdapter, final ReviewItem reviewItem) {
253 try {
254
255 final Collection<VersionedComment> versionedComments = crucibleServerFacade.getVersionedComments(
256 reviewDataInfoAdapter.getServer(), reviewDataInfoAdapter.getPermaId(), reviewItem.getPermId());
257 EventQueue.invokeLater(new Runnable() {
258 public void run() {
259 Project project = IdeaHelper.getCurrentProject();
260
261 Content content = findOrCreatePanel(reviewItem.toString(),
262 new ReviewDetailsPanel(reviewDataInfoAdapter, reviewItem, versionedComments), true);
263 CrucibleHelper.showVirtualFileWithComments(project, reviewItem, versionedComments);
264
265 }
266 });
267 } catch (RemoteApiException e) {
268 LOGGER.warn(e);
269 } catch (ServerPasswordNotProvidedException e) {
270 LOGGER.warn(e);
271 }
272 }
273
274 public void showGeneralComment(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
275
276 }
277
278 public void showGeneralCommentReply(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
279
280 }
281
282 public void showVersionedComment(ReviewDataInfoAdapter reviewDataInfoAdapter, ReviewItem reviewItem, Collection<VersionedComment> versionedComments, VersionedComment versionedComment) {
283
284 }
285
286 public void focusOnVersionedComment(ReviewDataInfoAdapter reviewDataInfoAdapter, VersionedComment versionedComment) {
287
288 }
289
290 public void showVersionedCommentReply(ReviewDataInfoAdapter reviewDataInfoAdapter, GeneralComment comment) {
291
292 }
293
294 }
295 }