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  package com.atlassian.theplugin.idea.bamboo;
17  
18  import com.atlassian.theplugin.cfg.CfgUtil;
19  import com.atlassian.theplugin.commons.cfg.ConfigurationListenerAdapter;
20  import com.atlassian.theplugin.commons.cfg.ProjectConfiguration;
21  import com.atlassian.theplugin.commons.cfg.ProjectId;
22  import com.atlassian.theplugin.configuration.BambooWorkspaceConfiguration;
23  import com.atlassian.theplugin.configuration.WorkspaceConfigurationBean;
24  import com.atlassian.theplugin.idea.Constants;
25  import com.atlassian.theplugin.idea.IdeaHelper;
26  import com.atlassian.theplugin.idea.bamboo.tree.BuildTree;
27  import com.atlassian.theplugin.idea.bamboo.tree.BuildTreeModel;
28  import com.atlassian.theplugin.idea.config.ProjectCfgManagerImpl;
29  import com.atlassian.theplugin.idea.ui.PopupAwareMouseAdapter;
30  import com.intellij.openapi.actionSystem.*;
31  import com.intellij.openapi.project.Project;
32  import com.intellij.openapi.util.Pair;
33  import com.intellij.ui.SearchTextField;
34  import org.jetbrains.annotations.NonNls;
35  import org.jetbrains.annotations.NotNull;
36  import org.jetbrains.annotations.Nullable;
37  
38  import javax.swing.*;
39  import javax.swing.event.DocumentEvent;
40  import javax.swing.event.DocumentListener;
41  import javax.swing.event.ListSelectionEvent;
42  import javax.swing.event.ListSelectionListener;
43  import javax.swing.tree.TreePath;
44  import java.awt.*;
45  import java.awt.event.KeyAdapter;
46  import java.awt.event.KeyEvent;
47  import java.awt.event.KeyListener;
48  import java.awt.event.MouseEvent;
49  import java.util.Collection;
50  
51  /**
52   * @author Wojciech Seliga
53   */
54  public class BambooToolWindowPanel extends TwoPanePanel implements DataProvider {
55  
56  	public static final String PLACE_PREFIX = BambooToolWindowPanel.class.getSimpleName();
57  	private final Project project;
58  	private final BuildListModelImpl bambooModel;
59  	private final BuildTree buildTree;
60  	private final BambooFilterList filterList;
61  	private SearchTextField searchField = new SearchTextField();
62  	private JComponent toolBar;
63  	private BambooWorkspaceConfiguration bambooConfiguration;
64  	private BuildGroupBy groupBy = BuildGroupBy.NONE;
65  	private SearchBuildListModel searchBuildModel;
66  
67  	public BambooFilterType getBambooFilterType() {
68  		return filterList.getBambooFilterType();
69  	}
70  
71  	public BambooToolWindowPanel(@NotNull final Project project,
72  			@NotNull final BuildListModelImpl bambooModel,
73  			@NotNull final WorkspaceConfigurationBean projectConfiguration,
74  			@NotNull final ProjectCfgManagerImpl projectCfgManager) {
75  
76  		this.project = project;
77  		this.bambooModel = bambooModel;
78  		this.bambooConfiguration = projectConfiguration.getBambooConfiguration();
79  
80  		final ProjectId projectId = CfgUtil.getProjectId(project);
81  		filterList = new BambooFilterList(projectCfgManager, projectId, bambooModel);
82  		projectCfgManager.getCfgManager().addProjectConfigurationListener(projectId, new ConfigurationListenerAdapter() {
83  			@Override
84  			public void bambooServersChanged(final ProjectConfiguration newConfiguration) {
85  				filterList.update();
86  			}
87  		});
88  
89  		filterList.addListSelectionListener(new ListSelectionListener() {
90  			public void valueChanged(final ListSelectionEvent e) {
91  				if (!e.getValueIsAdjusting()) {
92  					final BambooBuildFilter filter = filterList.getSelection();
93  					bambooModel.setFilter(filter);
94  				}
95  			}
96  		});
97  
98  		bambooModel.addListener(new BuildListModelListener() {
99  			public void modelChanged() {
100 			}
101 
102 			public void generalProblemsHappened(@Nullable Collection<Exception> generalExceptions) {
103 				if (generalExceptions != null && generalExceptions.size() > 0) {
104 					Exception e = generalExceptions.iterator().next();
105 					setErrorMessage(e.getMessage(), e);
106 				}
107 			}
108 
109 			public void buildsChanged(@Nullable final Collection<String> additionalInfo,
110 					@Nullable final Collection<Pair<String, Throwable>> errors) {
111 
112 				// we do not support multiple messages in status bar yet (waiting for inbox to be implemented)
113 				if (errors != null && !errors.isEmpty()) {
114 
115 					// get last error message
116 					Pair<String, Throwable> error = (Pair<String, Throwable>) errors.toArray()[errors.size() - 1];
117 
118 					setErrorMessage(error.getFirst(), error.getSecond());
119 				} else if (additionalInfo != null && !additionalInfo.isEmpty()) {
120 					setStatusMessage(additionalInfo.toArray(new String[1])[additionalInfo.size() - 1]);
121 				}
122 				filterList.update();
123 			}
124 		});
125 
126 		searchBuildModel = new SearchBuildListModel(bambooModel);
127 		buildTree = new BuildTree(groupBy, new BuildTreeModel(searchBuildModel), getRightScrollPane());
128 		toolBar = createToolBar();
129 		init();
130 		addBuildTreeListeners();
131 		addSearchBoxListener();
132 
133 		// restore GroupBy and FilterBy setting
134 		if (bambooConfiguration != null && bambooConfiguration.getView() != null) {
135 			if (bambooConfiguration.getView().getGroupBy() != null) {
136 				groupBy = bambooConfiguration.getView().getGroupBy();
137                 setGroupingType(groupBy);
138 			}
139 			if (bambooConfiguration.getView().getFilterType() != null) {
140 				setBambooFilterType(bambooConfiguration.getView().getFilterType());
141 			}
142 		}
143 
144 		setLeftPaneVisible(filterList.getBambooFilterType() != null);
145 	}
146 
147 	private void addBuildTreeListeners() {
148 		buildTree.addKeyListener(new KeyAdapter() {
149 			@Override
150 			public void keyPressed(KeyEvent e) {
151 				final BambooBuildAdapterIdea buildDetailsInfo = buildTree.getSelectedBuild();
152 				if (e.getKeyCode() == KeyEvent.VK_ENTER && buildDetailsInfo != null) {
153 					openBuild(buildDetailsInfo);
154 				}
155 			}
156 		});
157 
158 		buildTree.addMouseListener(new PopupAwareMouseAdapter() {
159 
160 			@Override
161 			public void mouseClicked(final MouseEvent e) {
162 				final BambooBuildAdapterIdea buildDetailsInfo = buildTree.getSelectedBuild();
163 				if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2 && buildDetailsInfo != null) {
164 					openBuild(buildDetailsInfo);
165 				}
166 			}
167 
168 			@Override
169 			protected void onPopup(MouseEvent e) {
170 				int selRow = buildTree.getRowForLocation(e.getX(), e.getY());
171 				TreePath selPath = buildTree.getPathForLocation(e.getX(), e.getY());
172 				if (selRow != -1 && selPath != null) {
173 					buildTree.setSelectionPath(selPath);
174 					final BambooBuildAdapterIdea buildDetailsInfo = buildTree.getSelectedBuild();
175 					if (buildDetailsInfo != null) {
176 						launchContextMenu(e);
177 					}
178 				}
179 			}
180 		});
181 	}
182 
183 	private void launchContextMenu(MouseEvent e) {
184 		final DefaultActionGroup actionGroup = new DefaultActionGroup();
185 		final ActionGroup configActionGroup = (ActionGroup) ActionManager
186 				.getInstance().getAction("ThePlugin.Bamboo.BuildPopupMenuNew");
187 		actionGroup.addAll(configActionGroup);
188 
189 		final ActionPopupMenu popup = ActionManager.getInstance().createActionPopupMenu(getActionPlaceName(), actionGroup);
190 
191 		final JPopupMenu jPopupMenu = popup.getComponent();
192 		jPopupMenu.show(e.getComponent(), e.getX(), e.getY());
193 	}
194 
195 	private String getActionPlaceName() {
196 		return PLACE_PREFIX + project.getName();
197 	}
198 
199 	private void openBuild(final BambooBuildAdapterIdea buildDetailsInfo) {
200 		if (buildDetailsInfo != null && buildDetailsInfo.isBamboo2()
201 				&& buildDetailsInfo.areActionsAllowed()) {
202 			IdeaHelper.getBuildToolWindow(project).showBuild(buildDetailsInfo);
203 		}
204 	}
205 
206 	protected void addSearchBoxListener() {
207 		searchField.addDocumentListener(new DocumentListener() {
208 			public void insertUpdate(DocumentEvent e) {
209 				searchBuildModel.setSearchTerm(getSearchField().getText());
210 			}
211 
212 			public void removeUpdate(DocumentEvent e) {
213 				searchBuildModel.setSearchTerm(getSearchField().getText());
214 			}
215 
216 			public void changedUpdate(DocumentEvent e) {
217 				searchBuildModel.setSearchTerm(getSearchField().getText());
218 			}
219 		});
220 
221 		searchField.addKeyboardListener(new KeyListener() {
222 			public void keyTyped(KeyEvent e) {
223 			}
224 
225 			public void keyPressed(KeyEvent e) {
226 				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
227 					searchField.addCurrentTextToHistory();
228 				}
229 			}
230 
231 			public void keyReleased(KeyEvent e) {
232 			}
233 		});
234 	}
235 
236 	private SearchTextField getSearchField() {
237 		return searchField;
238 	}
239 
240 	@Override
241 	public JTree getRightTree() {
242 		return buildTree;
243 	}
244 
245 	public Object getData(@NonNls final String dataId) {
246 		if (dataId.equals(Constants.SERVER)) {
247 			// return server of selected build
248 			if (buildTree.getSelectedBuild() != null) {
249 				return buildTree.getSelectedBuild().getServer();
250 			}
251 
252 			final BambooBuildFilter filter = filterList.getSelection();
253 
254 			// return server of selected filter in case of server filtering
255 			if (getBambooFilterType() == BambooFilterType.SERVER
256 					&& filter != null && filter instanceof BambooCompositeOrFilter) {
257 
258 				BambooCompositeOrFilter filterImpl = (BambooCompositeOrFilter) filter;
259 
260 				Collection<BambooBuildFilter> filters = filterImpl.getFilters();
261 				for (BambooBuildFilter buildFilter : filters) {
262 					if (buildFilter instanceof BambooFilterList.BambooServerFilter) {
263 						BambooFilterList.BambooServerFilter serverFilter =
264 								(BambooFilterList.BambooServerFilter) buildFilter;
265 
266 						return serverFilter.getBambooServerCfg();
267 					}
268 				}
269 			}
270 		}
271 
272 		return null;
273 	}
274 
275 	public void setGroupingType(@NonNls final BuildGroupBy groupingType) {
276 		if (groupingType != null) {
277 			this.groupBy = groupingType;
278 			buildTree.groupBy(groupingType);
279 			bambooConfiguration.getView().setGroupBy(groupingType);
280 		}
281 	}
282 
283 	public void setBambooFilterType(@Nullable final BambooFilterType bambooFilterType) {
284 		filterList.setBambooFilterType(bambooFilterType);
285 		setLeftPaneVisible(filterList.getBambooFilterType() != null);
286 		bambooModel.setFilter(null);
287 		// by default there should be "ALL", which means null filter
288 //		buildTree.updateModel(bambooModel.getBuilds());
289 
290 		bambooConfiguration.getView().setFilterType(bambooFilterType);
291 	}
292 
293 	@Override
294 	protected JComponent getLeftPanel() {
295 		return filterList;
296 	}
297 
298 	@Override
299 	protected JComponent getToolBar() {
300 		return toolBar;
301 	}
302 
303 	private JComponent createToolBar() {
304 		final JPanel toolBarPanel = new JPanel(new GridBagLayout());
305 
306 		GridBagConstraints gbc = new GridBagConstraints();
307 		gbc.gridx = 0;
308 		gbc.gridy = 0;
309 		gbc.weighty = 0.0;
310 		gbc.fill = GridBagConstraints.HORIZONTAL;
311 		gbc.weightx = 1.0;
312 		toolBarPanel.add(loadToolBar("ThePlugin.Bamboo.ToolBar"), gbc);
313 		gbc.gridx++;
314 		gbc.weightx = 0.0;
315 		gbc.fill = GridBagConstraints.NONE;
316 		gbc.anchor = GridBagConstraints.FIRST_LINE_END;
317 		searchField.setMinimumSize(searchField.getPreferredSize());
318 		toolBarPanel.add(searchField, gbc);
319 
320 		return toolBarPanel;
321 	}
322 
323 	@Nullable
324 	private JComponent loadToolBar(final String toolbarName) {
325 		ActionManager actionManager = ActionManager.getInstance();
326 		ActionGroup toolbar = (ActionGroup) actionManager.getAction(toolbarName);
327 		if (toolbar != null) {
328 			final ActionToolbar actionToolbar =
329 					actionManager.createActionToolbar(PLACE_PREFIX + project.getName(), toolbar, true);
330 			actionToolbar.setTargetComponent(this);
331 			return actionToolbar.getComponent();
332 		}
333 		return null;
334 	}
335 
336 	public BuildGroupBy getGroupBy() {
337 		return groupBy;
338 	}
339 
340 	public BambooBuildAdapterIdea getSelectedBuild() {
341 		return buildTree.getSelectedBuild();
342 	}
343 }