Refactor/rewrite CloneSourcePage to universal RepositorySelectionPage
[egit/zawir.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / clone / SourceBranchPage.java
blob1768dbdac09ac9e6cf7ff9596382762b78ebda52
1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org.spearce.egit.ui.internal.clone;
11 import java.io.File;
12 import java.lang.reflect.InvocationTargetException;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.List;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.NullProgressMonitor;
22 import org.eclipse.core.runtime.OperationCanceledException;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.jface.dialogs.ErrorDialog;
25 import org.eclipse.jface.operation.IRunnableWithProgress;
26 import org.eclipse.jface.wizard.WizardPage;
27 import org.eclipse.osgi.util.NLS;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.SelectionEvent;
30 import org.eclipse.swt.events.SelectionListener;
31 import org.eclipse.swt.layout.GridData;
32 import org.eclipse.swt.layout.GridLayout;
33 import org.eclipse.swt.layout.RowLayout;
34 import org.eclipse.swt.widgets.Button;
35 import org.eclipse.swt.widgets.Composite;
36 import org.eclipse.swt.widgets.Event;
37 import org.eclipse.swt.widgets.Label;
38 import org.eclipse.swt.widgets.Listener;
39 import org.eclipse.swt.widgets.Table;
40 import org.eclipse.swt.widgets.TableItem;
41 import org.spearce.egit.ui.Activator;
42 import org.spearce.egit.ui.UIText;
43 import org.spearce.egit.ui.internal.components.RepositorySelectionListener;
44 import org.spearce.egit.ui.internal.components.RepositorySelectionPage;
45 import org.spearce.jgit.lib.Constants;
46 import org.spearce.jgit.lib.Ref;
47 import org.spearce.jgit.lib.Repository;
48 import org.spearce.jgit.transport.FetchConnection;
49 import org.spearce.jgit.transport.RemoteConfig;
50 import org.spearce.jgit.transport.Transport;
51 import org.spearce.jgit.transport.URIish;
53 class SourceBranchPage extends WizardPage {
54 private final List<BranchChangeListener> branchChangeListeners;
56 private final RepositorySelectionPage sourcePage;
58 private URIish validated;
60 private Ref head;
62 private List<Ref> available = Collections.<Ref> emptyList();
64 private Label label;
66 private Table availTable;
68 private boolean allSelected;
70 private String transportError;
72 SourceBranchPage(final RepositorySelectionPage sp) {
73 super(SourceBranchPage.class.getName());
74 sourcePage = sp;
75 setTitle(UIText.SourceBranchPage_title);
76 sourcePage
77 .addRepositorySelectionListener(new RepositorySelectionListener() {
78 public void selectionChanged(final URIish newURI,
79 final RemoteConfig newConfig) {
80 if (newURI == null || !newURI.equals(validated)) {
81 validated = null;
82 setPageComplete(false);
85 });
86 branchChangeListeners = new ArrayList<BranchChangeListener>(3);
89 void addBranchChangeListener(final BranchChangeListener l) {
90 branchChangeListeners.add(l);
93 Collection<Ref> getSelectedBranches() {
94 allSelected = true;
95 final ArrayList<Ref> r = new ArrayList<Ref>(available.size());
96 for (int i = 0; i < available.size(); i++) {
97 if (availTable.getItem(i).getChecked())
98 r.add(available.get(i));
99 else
100 allSelected = false;
102 return r;
105 Ref getHEAD() {
106 return head;
109 boolean isAllSelected() {
110 return allSelected;
113 public void createControl(final Composite parent) {
114 final Composite panel = new Composite(parent, SWT.NULL);
115 final GridLayout layout = new GridLayout();
116 layout.numColumns = 1;
117 panel.setLayout(layout);
119 label = new Label(panel, SWT.NONE);
120 label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
122 availTable = new Table(panel, SWT.CHECK | SWT.V_SCROLL | SWT.BORDER);
123 availTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
124 availTable.addListener(SWT.Selection, new Listener() {
125 public void handleEvent(final Event event) {
126 if (event.detail == SWT.CHECK) {
127 notifyChanged();
128 setPageComplete(isPageComplete());
133 final Composite bPanel = new Composite(panel, SWT.NONE);
134 bPanel.setLayout(new RowLayout());
135 Button b;
136 b = new Button(bPanel, SWT.PUSH);
137 b.setText(UIText.SourceBranchPage_selectAll);
138 b.addSelectionListener(new SelectionListener() {
139 public void widgetDefaultSelected(SelectionEvent e) {
140 // Do nothing.
143 public void widgetSelected(SelectionEvent e) {
144 for (int i = 0; i < availTable.getItemCount(); i++)
145 availTable.getItem(i).setChecked(true);
146 notifyChanged();
147 setPageComplete(isPageComplete());
150 b = new Button(bPanel, SWT.PUSH);
151 b.setText(UIText.SourceBranchPage_selectNone);
152 b.addSelectionListener(new SelectionListener() {
153 public void widgetDefaultSelected(SelectionEvent e) {
154 // Do nothing.
157 public void widgetSelected(SelectionEvent e) {
158 for (int i = 0; i < availTable.getItemCount(); i++)
159 availTable.getItem(i).setChecked(false);
160 notifyChanged();
161 setPageComplete(isPageComplete());
164 bPanel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
166 setControl(panel);
167 setPageComplete(false);
170 @Override
171 public void setVisible(final boolean visible) {
172 if (visible)
173 revalidate();
174 super.setVisible(visible);
177 @Override
178 public boolean isPageComplete() {
179 if (transportError != null) {
180 setErrorMessage(transportError);
181 return false;
184 if (getSelectedBranches().isEmpty()) {
185 setErrorMessage(UIText.SourceBranchPage_errorBranchRequired);
186 return false;
189 setErrorMessage(null);
190 return true;
193 private void revalidate() {
194 final URIish newURI;
195 newURI = sourcePage.getURI();
197 label.setText(NLS.bind(UIText.SourceBranchPage_branchList, newURI
198 .toString()));
199 label.getParent().layout();
201 if (newURI.equals(validated)) {
202 setPageComplete(isPageComplete());
203 return;
206 setErrorMessage(null);
207 setPageComplete(false);
208 transportError = null;
209 head = null;
210 available = new ArrayList<Ref>();
211 availTable.removeAll();
212 allSelected = false;
213 label.getDisplay().asyncExec(new Runnable() {
214 public void run() {
215 revalidateImpl(newURI);
220 private void revalidateImpl(final URIish newURI) {
221 if (label.isDisposed() || !isCurrentPage())
222 return;
223 try {
224 getContainer().run(true, true, new IRunnableWithProgress() {
225 public void run(final IProgressMonitor pm)
226 throws InvocationTargetException, InterruptedException {
227 final IProgressMonitor monitor;
228 if (pm == null)
229 monitor = new NullProgressMonitor();
230 else
231 monitor = pm;
232 try {
233 final Repository db = new Repository(new File("/tmp"));
234 final Transport tn = Transport.open(db, newURI);
235 final Collection<Ref> adv;
236 final FetchConnection fn = tn.openFetch();
237 try {
238 adv = fn.getRefs();
239 } finally {
240 fn.close();
241 tn.close();
244 final Ref idHEAD = fn.getRef(Constants.HEAD);
245 head = null;
246 for (final Ref r : adv) {
247 final String n = r.getName();
248 if (!n.startsWith(Constants.HEADS_PREFIX + "/"))
249 continue;
250 available.add(r);
251 if (idHEAD == null || head != null)
252 continue;
253 if (r.getObjectId().equals(idHEAD.getObjectId()))
254 head = r;
256 Collections.sort(available, new Comparator<Ref>() {
257 public int compare(final Ref o1, final Ref o2) {
258 return o1.getName().compareTo(o2.getName());
261 if (idHEAD != null && head == null) {
262 head = idHEAD;
263 available.add(0, idHEAD);
265 } catch (Exception err) {
266 throw new InvocationTargetException(err);
268 monitor.done();
271 } catch (InvocationTargetException e) {
272 Throwable why = e.getCause();
273 if ((why instanceof OperationCanceledException)) {
274 transportError(UIText.SourceBranchPage_remoteListingCancelled);
275 return;
276 } else {
277 ErrorDialog.openError(getShell(),
278 UIText.SourceBranchPage_transportError,
279 UIText.SourceBranchPage_cannotListBranches, new Status(
280 IStatus.ERROR, Activator.getPluginId(), 0, why
281 .getMessage(), why.getCause()));
282 transportError(why.getMessage());
284 return;
285 } catch (InterruptedException e) {
286 transportError(UIText.SourceBranchPage_interrupted);
287 return;
290 validated = newURI;
291 allSelected = true;
292 for (final Ref r : available) {
293 String n = r.getName();
294 if (n.startsWith(Constants.HEADS_PREFIX + "/"))
295 n = n.substring((Constants.HEADS_PREFIX + "/").length());
296 final TableItem ti = new TableItem(availTable, SWT.NONE);
297 ti.setText(n);
298 ti.setChecked(true);
300 notifyChanged();
301 setErrorMessage(null);
302 setPageComplete(isPageComplete());
305 private void transportError(final String msg) {
306 transportError = msg;
307 setErrorMessage(msg);
308 setPageComplete(false);
311 private void notifyChanged() {
312 for (final BranchChangeListener l : branchChangeListeners)
313 l.branchesChanged();