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
;
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
) {
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())
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
,
141 modeViewer
.setLabelProvider(new CenteredImageLabelProvider() {
143 public Image
getImage(Object element
) {
144 if (((RefUpdateElement
) element
).isDelete())
145 return imageRegistry
.get(IMAGE_DELETE
);
146 return imageRegistry
.get(IMAGE_ADD
);
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() {
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() {
170 public String
getText(Object element
) {
171 return ((RefUpdateElement
) element
).getDstRefName();
175 if (result
== null) {
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(
189 tableViewer
.setInput(result
);
193 Control
getControl() {
197 private TableViewerColumn
createColumn(
198 final TableColumnLayout columnLayout
, final String text
,
199 final int weight
, final int style
) {
200 final TableViewerColumn viewerColumn
= new TableViewerColumn(
202 final TableColumn column
= viewerColumn
.getColumn();
203 column
.setText(text
);
204 columnLayout
.setColumnData(column
, new ColumnWeightData(weight
));
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
;
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()) {
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();
241 return UIText
.PushResultTable_statusUpToDate
;
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
;
251 throw new IllegalArgumentException(NLS
.bind(
252 UIText
.PushResultTable_statusUnexpected
, rru
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();
266 return colorRegistry
.get(COLOR_UPDATED_KEY
);
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
);
276 throw new IllegalArgumentException(NLS
.bind(
277 UIText
.PushResultTable_statusUnexpected
, status
));
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()) {
292 return NLS
.bind(UIText
.PushResultTable_statusDetailDeleted
,
293 oldRef
.getObjectId().abbreviate(localDb
).name());
296 if (rru
.isFastForward())
297 return UIText
.PushResultTable_statusDetailFastForward
;
298 return UIText
.PushResultTable_statusDetailForcedUpdate
;
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
;
310 if (remoteRef
== null)
311 curVal
= UIText
.PushResultTable_refNonExisting
;
313 curVal
= remoteRef
.getObjectId().abbreviate(localDb
).name();
315 final ObjectId expectedOldObjectId
= rru
316 .getExpectedOldObjectId();
318 if (expectedOldObjectId
.equals(ObjectId
.zeroId()))
319 expVal
= UIText
.PushResultTable_refNonExisting
;
321 expVal
= expectedOldObjectId
.abbreviate(localDb
).name();
322 return NLS
.bind(UIText
.PushResultTable_statusDetailChanged
,
324 case REJECTED_OTHER_REASON
:
325 return rru
.getMessage();
327 throw new IllegalArgumentException(NLS
.bind(
328 UIText
.PushResultTable_statusUnexpected
, rru