View Javadoc

1   /**
2    * Copyright (C) 2008 Atlassian
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.atlassian.theplugin.idea;
18  
19  import com.atlassian.theplugin.commons.ServerType;
20  import com.atlassian.theplugin.commons.exception.ThePluginException;
21  import com.atlassian.theplugin.commons.configuration.ConfigurationFactory;
22  import com.atlassian.theplugin.util.PluginUtil;
23  import com.atlassian.theplugin.util.Util;
24  import com.intellij.openapi.actionSystem.AnActionEvent;
25  import com.intellij.openapi.project.Project;
26  import com.intellij.openapi.wm.ToolWindow;
27  import com.intellij.openapi.wm.ToolWindowAnchor;
28  import com.intellij.openapi.wm.ToolWindowManager;
29  import com.intellij.ui.content.Content;
30  import com.intellij.ui.content.ContentManager;
31  import com.intellij.ui.content.ContentManagerAdapter;
32  import com.intellij.ui.content.ContentManagerEvent;
33  import com.intellij.util.containers.HashSet;
34  import com.intellij.peer.PeerFactory;
35  
36  import java.util.Set;
37  
38  /**
39   * Created by IntelliJ IDEA.
40   * User: Jacek
41   * Date: 2008-03-20
42   * Time: 11:22:10
43   * To change this template use File | Settings | File Templates.
44   */
45  public class PluginToolWindow extends ContentManagerAdapter {
46  
47  	private Set<ToolWindowPanels> panels = new HashSet<ToolWindowPanels>(INITIAL_NUMBER_OF_TABS);
48  	private Set<ToolWindowPanels> bottomPanels = new HashSet<ToolWindowPanels>(INITIAL_NUMBER_OF_BOTTOM_TABS);
49  
50  	private ToolWindow ideaToolWindow;
51  	private Project project;
52  	//private String selectedContent = null;
53  	public static final String TOOL_WINDOW_NAME = "Atlassian";
54  	public static final String BOTTOM_WINDOW_NAME = "Atlassian Plugin";
55  	private static final int INITIAL_NUMBER_OF_TABS = 3;
56  	private static final int INITIAL_NUMBER_OF_BOTTOM_TABS = 1;
57  	private static final String CONFIGURE_TAB_NAME = "Configure";
58  	private ToolWindow bottomIdeaToolWindow;
59  
60  	public static void showHidePluginWindow(AnActionEvent event) {
61  		ToolWindow tw = IdeaHelper.getToolWindow(IdeaHelper.getCurrentProject(event.getDataContext()));
62  		if (tw != null) {
63  			if (tw.isVisible()) {
64  				tw.hide(new Runnable() {
65  					public void run() {
66  						//To change body of implemented methods use File | Settings | File Templates.
67  					}
68  				});
69  			} else {
70  
71   				tw.show(new Runnable() {
72  					public void run() {
73  						//To change body of implemented methods use File | Settings | File Templates.
74  					}
75  				});
76  			}
77  
78  		}
79  
80  	}
81  	/**
82  	 *
83  	 * @param toolWindowManager ToolWindowManager object
84  	 * @param project reference to the project
85  	 */
86  	public PluginToolWindow(ToolWindowManager toolWindowManager, Project project) {
87  		this.ideaToolWindow = toolWindowManager.registerToolWindow(
88  				TOOL_WINDOW_NAME, true, ToolWindowAnchor.RIGHT);
89  		this.project = project;
90  		this.bottomIdeaToolWindow = toolWindowManager.registerToolWindow(BOTTOM_WINDOW_NAME, true, ToolWindowAnchor.BOTTOM);
91  	}
92  
93  	/**
94  	 * Starts listening to the tab selection changes.
95  	 * It will fire {@link #selectionChanged} which store new selection in project configuration
96  	 */
97  	public void startTabChangeListener() {
98  		this.ideaToolWindow.getContentManager().addContentManagerListener(this);
99  		this.bottomIdeaToolWindow.getContentManager().addContentManagerListener(this);
100 	}
101 
102 	/**
103 	 * Stops listening to the tab selection changes.
104 	 */
105 	public void stopTabChangeListener() {
106 		this.ideaToolWindow.getContentManager().removeContentManagerListener(this);
107 		this.bottomIdeaToolWindow.getContentManager().removeContentManagerListener(this);
108 	}
109 
110 	/**
111 	 * @return {@link ToolWindow} objects wraped up by this class
112 	 */
113 	public ToolWindow getIdeaToolWindow() {
114 		return ideaToolWindow;
115 	}
116 
117 	public ToolWindow getBottomIdeaToolWindow(){
118 		return bottomIdeaToolWindow;
119 	}
120 
121 	/**
122 	 * Register type of panel. Register panel can be then shown/hidden using {@link #showHidePanels}
123 	 * @param toolWindowPanel ToolWindowPanels enum value
124 	 */
125 	public void registerPanel(ToolWindowPanels toolWindowPanel) {
126 		panels.add(toolWindowPanel);
127 	}
128 
129 	public void registerBottomPanel(ToolWindowPanels toolWindowPanel){
130 		bottomPanels.add(toolWindowPanel);
131 	}
132 
133 	/**
134 	 * Show registered panels if servers are defined for the type of panel.
135 	 * Hides registered panels if servers are not define for the type of panel.
136 	 */
137 	public void showHideBottomPanels(){
138 				
139 			for(ToolWindowPanels entry: bottomPanels){
140 			try {
141 				ServerType serverType = Util.toolWindowPanelsToServerType(entry);
142 				if (ConfigurationFactory.getConfiguration().getProductServers(serverType).transientGetServers().size() > 0) {
143 					if (bottomIdeaToolWindow.getContentManager().findContent(entry.toString()) == null) {
144 
145 						// show tab
146 						Content content = null;
147 
148 						switch (entry) {
149 							case CRUCIBLE_BOTTOM:
150 								content = project.getComponent(ThePluginProjectComponent.class).createCrucibleBottomContent();
151 								break;
152 
153 							default:
154 								break;
155 						}
156 
157 						bottomIdeaToolWindow.getContentManager().addContent(content);
158 					}
159 
160 				} else {
161 					// tab is visible
162 					Content content = bottomIdeaToolWindow.getContentManager().findContent(entry.toString());
163 					if (content != null) {
164 						// hide tab
165 						bottomIdeaToolWindow.getContentManager().removeContent(content, true);
166 					}
167 				}
168 			} catch (ThePluginException e) {
169 				PluginUtil.getLogger().error(e.getMessage(), e);
170 			}
171 
172 		}
173 
174 	}
175 	public void showHidePanels() {
176 
177 		showHideBottomPanels();
178 		//stopTabChangeListener();
179 
180 		if (!ConfigurationFactory.getConfiguration().isAnyServerDefined()) {
181 			// no servers defined, show config panel
182 			if (ideaToolWindow.getContentManager().findContent(CONFIGURE_TAB_NAME) == null) {
183 				Content content = PeerFactory.getInstance().getContentFactory().
184 						createContent(new ToolWindowConfigPanel(), CONFIGURE_TAB_NAME, false);
185 				content.setCloseable(false);
186 				ideaToolWindow.getContentManager().addContent(content);
187 			}
188 		} else {
189 			// servers defined, find config panel, hide config panel
190 			Content content = ideaToolWindow.getContentManager().findContent(CONFIGURE_TAB_NAME);
191 			if (content != null) {
192 				ideaToolWindow.getContentManager().removeContent(content, true);
193 			}
194 		}
195 
196 		 //bottomIdeaToolWindow
197 		for (ToolWindowPanels entry : panels) {
198 			try {
199 				ServerType serverType = Util.toolWindowPanelsToServerType(entry);
200 
201 				// servers are defined
202 				if (ConfigurationFactory.getConfiguration().getProductServers(serverType).transientGetServers().size() > 0) {
203 					// tab is not visible
204 					if (ideaToolWindow.getContentManager().findContent(entry.toString()) == null) {
205 
206 						// show tab
207 						Content content = null;
208 
209 						switch (entry) {
210 							case BAMBOO:
211 								content = project.getComponent(ThePluginProjectComponent.class).createBambooContent();
212 								break;
213 							case CRUCIBLE:
214 								content = project.getComponent(ThePluginProjectComponent.class).createCrucibleContent();
215 								break;
216 							case JIRA:
217 								content = project.getComponent(ThePluginProjectComponent.class).createJiraContent();
218 								break;							
219 							default:
220 								break;
221 						}
222 
223 						ideaToolWindow.getContentManager().addContent(content);
224 					}
225 				// servers are not defined
226 				} else {
227 					// tab is visible
228 					Content content = ideaToolWindow.getContentManager().findContent(entry.toString());
229 					if (content != null) {
230 						// hide tab
231 						ideaToolWindow.getContentManager().removeContent(content, true);
232 					}
233 				}
234 			} catch (ThePluginException e) {
235 				PluginUtil.getLogger().error(e.getMessage(), e);
236 			}
237 		}
238 
239 		//startTabChangeListener();
240 	}
241 
242 	/**
243 	 * Methods opens the ToolWindow and focuses on a particular component.
244 	 * If component does not exists it is created
245 	 * @param project
246 	 * @param component
247 	 */
248     public static void focusPanel(Project project, ToolWindowPanels component) {
249         ToolWindow tw = IdeaHelper.getToolWindow(project);
250         if (tw != null) {
251             ContentManager contentManager = tw.getContentManager();
252             tw.activate(null);
253 			Content content = contentManager.findContent(component.toString());
254 
255 			if (content == null) {
256 				switch (component) {
257 					case BAMBOO:
258 						content = project.getComponent(ThePluginProjectComponent.class).createBambooContent();
259 						contentManager.addContent(content);
260 						break;
261 					case CRUCIBLE:
262 						content = project.getComponent(ThePluginProjectComponent.class).createCrucibleContent();
263 						contentManager.addContent(content);
264 						break;
265 					case JIRA:
266 						content = project.getComponent(ThePluginProjectComponent.class).createJiraContent();
267 						contentManager.addContent(content);
268 						break;
269 					case CRUCIBLE_BOTTOM:
270 						content = project.getComponent(ThePluginProjectComponent.class).createCrucibleBottomContent();
271 						contentManager.addContent(content);
272 					default:
273 						break;
274 				}
275 			}
276 
277 			contentManager.setSelectedContent(content);
278         }
279     }
280 
281 	/**
282 	 * Methods opens the ToolWindow and focuses on a particular component.
283 	 * If component does not exists it is created
284 	 * @param project
285 	 * @param tabName
286 	 */
287 	public static void focusPanel(Project project, String tabName) {
288 		if (tabName.equals(ToolWindowPanels.BAMBOO.toString())) {
289 			focusPanel(project, ToolWindowPanels.BAMBOO);
290 		} else if (tabName.equals(ToolWindowPanels.CRUCIBLE.toString())) {
291 			focusPanel(project, ToolWindowPanels.CRUCIBLE);
292 		} else if (tabName.equals(ToolWindowPanels.JIRA.toString())) {
293 			focusPanel(project, ToolWindowPanels.JIRA);
294 		}
295 	}
296 
297 	/**
298 	 * Methods opens the ToolWindow and focuses on a particular component.
299 	 * If component does not exists it is created
300 	 * @param e
301 	 * @param component
302 	 */
303 	public static void focusPanel(AnActionEvent e, ToolWindowPanels component) {
304 		Project project = IdeaHelper.getCurrentProject(e.getDataContext());
305 		focusPanel(project, component);
306     }
307 
308 	/**
309 	 * Methods opens the ToolWindow and focuses on a particular component.
310 	 * If component does not exists it is not created and focused
311 	 * @param project
312 	 * @param tabName
313 	 */
314 	public static void focusPanelIfExists(Project project, String tabName) {
315 		ToolWindow tw = IdeaHelper.getToolWindow(project);
316 
317         if (tw != null) {
318 			//tw.activate(null);
319 			ContentManager contentManager = tw.getContentManager();
320 			Content content = contentManager.findContent(tabName);
321 
322 			if (content != null) {
323 				contentManager.setSelectedContent(content);
324 			}
325         }
326 	}
327 
328 	/**
329 	 * Shows/hides panel if exists at least one server configured for this panel.
330 	 * If component does not exists it is not created and focused.
331 	 * If component is not focused than is focused.
332 	 * If component is focused then is closed/hidden
333 	 * @param event
334 	 * @param component
335 	 */
336 	public static void showHidePanelIfExists(AnActionEvent event, ToolWindowPanels component) {
337 		Project project = IdeaHelper.getCurrentProject(event.getDataContext());
338 		ToolWindow tw = IdeaHelper.getToolWindow(project);
339 
340 		if (tw != null) {
341 
342 
343 			try {
344 				ServerType serverType = Util.toolWindowPanelsToServerType(component);
345 				// servers are defined
346 				if (ConfigurationFactory.getConfiguration().getProductServers(serverType).transientGetServers().size() > 0) {
347 					// tab is not visible
348 					Content content =  tw.getContentManager().findContent(component.toString());
349 					if (content == null) {
350 
351 						// doesn't exists so create and show tab
352 						switch (component) {
353 							case BAMBOO:
354 								content = project.getComponent(ThePluginProjectComponent.class).createBambooContent();
355 								break;
356 							case CRUCIBLE:
357 								content = project.getComponent(ThePluginProjectComponent.class).createCrucibleContent();
358 								break;
359 							case JIRA:
360 								content = project.getComponent(ThePluginProjectComponent.class).createJiraContent();
361 								break;
362 							default:
363 								break;
364 						}
365 
366 						tw.getContentManager().addContent(content);
367 					} else { //tab exists so close it, hide
368 
369 
370 						if (content.isSelected() && tw.isVisible()) {
371 							tw.getContentManager().removeContent(content, true);
372 						} else {
373 							tw.getContentManager().setSelectedContent(content);
374 						}
375 					}
376 				// servers are not defined
377 				} else {
378 					// tab is visible
379 					Content content = tw.getContentManager().findContent(component.toString());
380 					if (content != null) {
381 						// hide tab
382 
383 
384 						if (content.isSelected() && tw.isVisible()) {
385 							tw.getContentManager().removeContent(content, true);
386 						} else {
387 							tw.getContentManager().setSelectedContent(content);
388 						}
389 					}
390 				}
391 			} catch (ThePluginException e) {
392 				PluginUtil.getLogger().error(e.getMessage(), e);
393 			}
394 			
395 			tw.activate(null);
396 
397 			focusPanelIfExists(project, component.toString());
398 		}
399 	}
400 
401 	/**
402 	 * Methods opens the ToolWindow and focuses on a particular component.
403 	 * If component does not exists it is not created AND focused
404 	 * @param e
405 	 * @param component
406 	 */
407 	public static void focusPanelifExists(AnActionEvent e, ToolWindowPanels component) {
408 		focusPanelIfExists(IdeaHelper.getCurrentProject(e.getDataContext()), component.toString());
409 	}
410 
411 	public void contentAdded(ContentManagerEvent event) {
412 		super.contentAdded(event);	//To change body of overridden methods use File | Settings | File Templates.
413 	}
414 
415 	public void contentRemoved(ContentManagerEvent event) {
416 		super.contentRemoved(event);	//To change body of overridden methods use File | Settings | File Templates.
417 	}
418 
419 	@Override
420 	public void contentRemoveQuery(ContentManagerEvent event) {
421 		Content content = event.getContent();
422 		if (content.getTabName().equals(ToolWindowPanels.CRUCIBLE_BOTTOM.toString())) {
423 			event.consume();
424 		}
425 		super.contentRemoveQuery(event);
426 	}
427 
428 	public void selectionChanged(ContentManagerEvent event) {
429 		//this.selectedContent = event.getContent().getDisplayName();
430 
431 		project.getComponent(ThePluginProjectComponent.class).getProjectConfigurationBean().
432 				setActiveToolWindowTab(event.getContent().getDisplayName());
433 
434 	}
435 
436 	/**
437 	 * List of available panels in tool window
438 	 */
439 	public enum ToolWindowPanels {
440 		BAMBOO {
441 			public String toString() {
442 				return "Bamboo";
443 			}
444 		},
445 		CRUCIBLE {
446 			public String toString() {
447 				return "Crucible";
448 			}
449 		},
450 		JIRA {
451 			public String toString() {
452 				return "JIRA";
453 			}
454 
455 		},
456 
457 		CRUCIBLE_BOTTOM {
458 			public String toString(){
459 				return "Review Details";
460 			}
461 		}
462 	}
463 }