Initial EGit contribution to eclipse.org
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / push / PushResultTable.java
blob31d854c55b7e176c92f9fe8958d3873852915235
1 /*******************************************************************************
2 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org.eclipse.egit.ui.internal.push;
11 import org.eclipse.egit.core.op.PushOperationResult;
12 import org.eclipse.egit.ui.UIIcons;
13 import org.eclipse.egit.ui.UIText;
14 import org.eclipse.egit.ui.internal.components.CenteredImageLabelProvider;
15 import org.eclipse.jface.layout.TableColumnLayout;
16 import org.eclipse.jface.resource.ColorRegistry;
17 import org.eclipse.jface.resource.ImageRegistry;
18 import org.eclipse.jface.viewers.ColumnLabelProvider;
19 import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
20 import org.eclipse.jface.viewers.ColumnWeightData;
21 import org.eclipse.jface.viewers.IElementComparer;
22 import org.eclipse.jface.viewers.TableViewer;
23 import org.eclipse.jface.viewers.TableViewerColumn;
24 import org.eclipse.osgi.util.NLS;
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.events.DisposeEvent;
27 import org.eclipse.swt.events.DisposeListener;
28 import org.eclipse.swt.graphics.Color;
29 import org.eclipse.swt.graphics.Image;
30 import org.eclipse.swt.graphics.RGB;
31 import org.eclipse.swt.layout.GridData;
32 import org.eclipse.swt.layout.GridLayout;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Table;
36 import org.eclipse.swt.widgets.TableColumn;
37 import org.eclipse.jgit.lib.Constants;
38 import org.eclipse.jgit.lib.ObjectId;
39 import org.eclipse.jgit.lib.Ref;
40 import org.eclipse.jgit.lib.Repository;
41 import org.eclipse.jgit.transport.RemoteRefUpdate;
42 import org.eclipse.jgit.transport.URIish;
43 import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
45 /**
46 * Table displaying push operation results.
48 class PushResultTable {
49 private static final int TABLE_PREFERRED_WIDTH = 650;
51 private static final int TABLE_PREFERRED_HEIGHT = 300;
53 private static final int COLUMN_STATUS_WEIGHT = 40;
55 private static final int COLUMN_DST_WEIGHT = 40;
57 private static final int COLUMN_SRC_WEIGHT = 40;
59 private static final int COLUMN_MODE_WEIGHT = 15;
61 private static final String IMAGE_DELETE = "MODE_DELETE";
63 private static final String IMAGE_ADD = "MODE_ADD";
65 private static final String COLOR_REJECTED_KEY = "REJECTED";
67 private static final RGB COLOR_REJECTED = new RGB(255, 0, 0);
69 private static final String COLOR_UPDATED_KEY = "UPDATED";
71 private static final RGB COLOR_UPDATED = new RGB(0, 255, 0);
73 private static final String COLOR_UP_TO_DATE_KEY = "UP_TO_DATE";
75 private static final RGB COLOR_UP_TO_DATE = new RGB(245, 245, 245);
77 private final TableViewer tableViewer;
79 private final Composite tablePanel;
81 private final ImageRegistry imageRegistry;
83 private final ColorRegistry colorRegistry;
85 PushResultTable(final Composite parent) {
86 tablePanel = new Composite(parent, SWT.NONE);
87 tablePanel.setLayout(new GridLayout());
88 final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
89 layoutData.heightHint = TABLE_PREFERRED_HEIGHT;
90 layoutData.widthHint = TABLE_PREFERRED_WIDTH;
91 tableViewer = new TableViewer(tablePanel);
92 ColumnViewerToolTipSupport.enableFor(tableViewer);
93 final Table table = tableViewer.getTable();
94 table.setLinesVisible(true);
95 table.setHeaderVisible(true);
97 imageRegistry = new ImageRegistry(table.getDisplay());
98 imageRegistry.put(IMAGE_ADD, UIIcons.ELCL16_ADD);
99 imageRegistry.put(IMAGE_DELETE, UIIcons.ELCL16_DELETE);
101 colorRegistry = new ColorRegistry(table.getDisplay());
102 colorRegistry.put(COLOR_REJECTED_KEY, COLOR_REJECTED);
103 colorRegistry.put(COLOR_UPDATED_KEY, COLOR_UPDATED);
104 colorRegistry.put(COLOR_UP_TO_DATE_KEY, COLOR_UP_TO_DATE);
106 tablePanel.addDisposeListener(new DisposeListener() {
107 public void widgetDisposed(DisposeEvent e) {
108 imageRegistry.dispose();
112 tableViewer.setComparer(new IElementComparer() {
113 // we need this to keep refresh() working while having custom
114 // equals() in PushOperationResult
115 public boolean equals(Object a, Object b) {
116 return a == b;
119 public int hashCode(Object element) {
120 return element.hashCode();
123 tableViewer.setContentProvider(new RefUpdateContentProvider());
124 tableViewer.setInput(null);
127 void setData(final Repository localDb, final PushOperationResult result) {
128 // We have to recreate columns.
129 for (final TableColumn tc : tableViewer.getTable().getColumns())
130 tc.dispose();
131 // Set empty result for a while.
132 tableViewer.setInput(null);
134 // Layout should be recreated to work properly.
135 final TableColumnLayout layout = new TableColumnLayout();
136 tablePanel.setLayout(layout);
138 final TableViewerColumn modeViewer = createColumn(layout,
139 UIText.PushResultTable_columnMode, COLUMN_MODE_WEIGHT,
140 SWT.CENTER);
141 modeViewer.setLabelProvider(new CenteredImageLabelProvider() {
142 @Override
143 public Image getImage(Object element) {
144 if (((RefUpdateElement) element).isDelete())
145 return imageRegistry.get(IMAGE_DELETE);
146 return imageRegistry.get(IMAGE_ADD);
149 @Override
150 public String getToolTipText(Object element) {
151 if (((RefUpdateElement) element).isDelete())
152 return UIText.RefSpecPanel_modeDeleteDescription;
153 return UIText.RefSpecPanel_modeUpdateDescription;
157 final TableViewerColumn srcViewer = createColumn(layout,
158 UIText.PushResultTable_columnSrc, COLUMN_SRC_WEIGHT, SWT.LEFT);
159 srcViewer.setLabelProvider(new ColumnLabelProvider() {
160 @Override
161 public String getText(Object element) {
162 return ((RefUpdateElement) element).getSrcRefName();
166 final TableViewerColumn dstViewer = createColumn(layout,
167 UIText.PushResultTable_columnDst, COLUMN_DST_WEIGHT, SWT.LEFT);
168 dstViewer.setLabelProvider(new ColumnLabelProvider() {
169 @Override
170 public String getText(Object element) {
171 return ((RefUpdateElement) element).getDstRefName();
175 if (result == null) {
176 tablePanel.layout();
177 return;
180 int i = 0;
181 for (final URIish uri : result.getURIs()) {
182 final TableViewerColumn statusViewer = createColumn(layout, NLS
183 .bind(UIText.PushResultTable_columnStatusRepo, Integer
184 .toString(++i)), COLUMN_STATUS_WEIGHT, SWT.CENTER);
185 statusViewer.getColumn().setToolTipText(uri.toString());
186 statusViewer.setLabelProvider(new UpdateStatusLabelProvider(
187 localDb, uri));
189 tableViewer.setInput(result);
190 tablePanel.layout();
193 Control getControl() {
194 return tablePanel;
197 private TableViewerColumn createColumn(
198 final TableColumnLayout columnLayout, final String text,
199 final int weight, final int style) {
200 final TableViewerColumn viewerColumn = new TableViewerColumn(
201 tableViewer, style);
202 final TableColumn column = viewerColumn.getColumn();
203 column.setText(text);
204 columnLayout.setColumnData(column, new ColumnWeightData(weight));
205 return viewerColumn;
208 private class UpdateStatusLabelProvider extends ColumnLabelProvider {
209 private Repository localDb;
211 private final URIish uri;
213 UpdateStatusLabelProvider(final Repository localDb, final URIish uri) {
214 this.localDb = localDb;
215 this.uri = uri;
218 @Override
219 public String getText(Object element) {
220 final RefUpdateElement rue = (RefUpdateElement) element;
221 if (!rue.isSuccessfulConnection(uri))
222 return UIText.PushResultTable_statusConnectionFailed;
224 final RemoteRefUpdate rru = rue.getRemoteRefUpdate(uri);
225 switch (rru.getStatus()) {
226 case OK:
227 if (rru.isDelete())
228 return UIText.PushResultTable_statusOkDeleted;
230 final Ref oldRef = rue.getAdvertisedRemoteRef(uri);
231 if (oldRef == null) {
232 if (rue.getDstRefName().startsWith(Constants.R_TAGS))
233 return UIText.PushResultTable_statusOkNewTag;
234 return UIText.PushResultTable_statusOkNewBranch;
237 return oldRef.getObjectId().abbreviate(localDb).name()
238 + (rru.isFastForward() ? ".." : "...")
239 + rru.getNewObjectId().abbreviate(localDb).name();
240 case UP_TO_DATE:
241 return UIText.PushResultTable_statusUpToDate;
242 case NON_EXISTING:
243 return UIText.PushResultTable_statusNoMatch;
244 case REJECTED_NODELETE:
245 case REJECTED_NONFASTFORWARD:
246 case REJECTED_REMOTE_CHANGED:
247 return UIText.PushResultTable_statusRejected;
248 case REJECTED_OTHER_REASON:
249 return UIText.PushResultTable_statusRemoteRejected;
250 default:
251 throw new IllegalArgumentException(NLS.bind(
252 UIText.PushResultTable_statusUnexpected, rru
253 .getStatus()));
257 @Override
258 public Color getBackground(Object element) {
259 final RefUpdateElement rue = (RefUpdateElement) element;
260 if (!rue.isSuccessfulConnection(uri))
261 return colorRegistry.get(COLOR_REJECTED_KEY);
263 final Status status = rue.getRemoteRefUpdate(uri).getStatus();
264 switch (status) {
265 case OK:
266 return colorRegistry.get(COLOR_UPDATED_KEY);
267 case UP_TO_DATE:
268 case NON_EXISTING:
269 return colorRegistry.get(COLOR_UP_TO_DATE_KEY);
270 case REJECTED_NODELETE:
271 case REJECTED_NONFASTFORWARD:
272 case REJECTED_REMOTE_CHANGED:
273 case REJECTED_OTHER_REASON:
274 return colorRegistry.get(COLOR_REJECTED_KEY);
275 default:
276 throw new IllegalArgumentException(NLS.bind(
277 UIText.PushResultTable_statusUnexpected, status));
281 @Override
282 public String getToolTipText(Object element) {
283 final RefUpdateElement rue = (RefUpdateElement) element;
284 if (!rue.isSuccessfulConnection(uri))
285 return rue.getErrorMessage(uri);
287 final RemoteRefUpdate rru = rue.getRemoteRefUpdate(uri);
288 final Ref oldRef = rue.getAdvertisedRemoteRef(uri);
289 switch (rru.getStatus()) {
290 case OK:
291 if (rru.isDelete())
292 return NLS.bind(UIText.PushResultTable_statusDetailDeleted,
293 oldRef.getObjectId().abbreviate(localDb).name());
294 if (oldRef == null)
295 return null;
296 if (rru.isFastForward())
297 return UIText.PushResultTable_statusDetailFastForward;
298 return UIText.PushResultTable_statusDetailForcedUpdate;
299 case UP_TO_DATE:
300 return null;
301 case NON_EXISTING:
302 return UIText.PushResultTable_statusDetailNonExisting;
303 case REJECTED_NODELETE:
304 return UIText.PushResultTable_statusDetailNoDelete;
305 case REJECTED_NONFASTFORWARD:
306 return UIText.PushResultTable_statusDetailNonFastForward;
307 case REJECTED_REMOTE_CHANGED:
308 final Ref remoteRef = oldRef;
309 final String curVal;
310 if (remoteRef == null)
311 curVal = UIText.PushResultTable_refNonExisting;
312 else
313 curVal = remoteRef.getObjectId().abbreviate(localDb).name();
315 final ObjectId expectedOldObjectId = rru
316 .getExpectedOldObjectId();
317 final String expVal;
318 if (expectedOldObjectId.equals(ObjectId.zeroId()))
319 expVal = UIText.PushResultTable_refNonExisting;
320 else
321 expVal = expectedOldObjectId.abbreviate(localDb).name();
322 return NLS.bind(UIText.PushResultTable_statusDetailChanged,
323 curVal, expVal);
324 case REJECTED_OTHER_REASON:
325 return rru.getMessage();
326 default:
327 throw new IllegalArgumentException(NLS.bind(
328 UIText.PushResultTable_statusUnexpected, rru
329 .getStatus()));