1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *******************************************************************************/
11 package org
.eclipse
.egit
.ui
.internal
.clone
;
14 import java
.io
.IOException
;
15 import java
.lang
.reflect
.InvocationTargetException
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Collections
;
18 import java
.util
.Comparator
;
19 import java
.util
.List
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.core
.runtime
.IStatus
;
23 import org
.eclipse
.core
.runtime
.Status
;
24 import org
.eclipse
.egit
.core
.op
.ListRemoteOperation
;
25 import org
.eclipse
.egit
.ui
.Activator
;
26 import org
.eclipse
.egit
.ui
.UIText
;
27 import org
.eclipse
.egit
.ui
.internal
.components
.BaseWizardPage
;
28 import org
.eclipse
.egit
.ui
.internal
.components
.RepositorySelection
;
29 import org
.eclipse
.egit
.ui
.internal
.components
.RepositorySelectionPage
;
30 import org
.eclipse
.egit
.ui
.internal
.components
.SelectionChangeListener
;
31 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
32 import org
.eclipse
.jface
.dialogs
.IMessageProvider
;
33 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
34 import org
.eclipse
.osgi
.util
.NLS
;
35 import org
.eclipse
.swt
.SWT
;
36 import org
.eclipse
.swt
.events
.SelectionAdapter
;
37 import org
.eclipse
.swt
.events
.SelectionEvent
;
38 import org
.eclipse
.swt
.layout
.GridData
;
39 import org
.eclipse
.swt
.layout
.GridLayout
;
40 import org
.eclipse
.swt
.layout
.RowLayout
;
41 import org
.eclipse
.swt
.widgets
.Button
;
42 import org
.eclipse
.swt
.widgets
.Composite
;
43 import org
.eclipse
.swt
.widgets
.Label
;
44 import org
.eclipse
.swt
.widgets
.Table
;
45 import org
.eclipse
.swt
.widgets
.TableItem
;
46 import org
.eclipse
.jgit
.lib
.Constants
;
47 import org
.eclipse
.jgit
.lib
.Ref
;
48 import org
.eclipse
.jgit
.lib
.Repository
;
49 import org
.eclipse
.jgit
.transport
.URIish
;
51 class SourceBranchPage
extends BaseWizardPage
{
52 private final RepositorySelectionPage sourcePage
;
54 private RepositorySelection validatedRepoSelection
;
58 private final List
<Ref
> availableRefs
= new ArrayList
<Ref
>();
60 private List
<Ref
> selectedRefs
= new ArrayList
<Ref
>();
64 private Table refsTable
;
66 private String transportError
;
68 SourceBranchPage(final RepositorySelectionPage sp
) {
69 super(SourceBranchPage
.class.getName());
71 setTitle(UIText
.SourceBranchPage_title
);
72 setDescription(UIText
.SourceBranchPage_description
);
74 sourcePage
.addSelectionListener(new SelectionChangeListener() {
75 public void selectionChanged() {
76 if (!sourcePage
.selectionEquals(validatedRepoSelection
))
77 setPageComplete(false);
84 List
<Ref
> getSelectedBranches() {
85 return new ArrayList
<Ref
>(selectedRefs
);
92 boolean isSourceRepoEmpty() {
93 return availableRefs
.isEmpty();
96 boolean isAllSelected() {
97 return availableRefs
.size() == selectedRefs
.size();
100 boolean selectionEquals(final List
<Ref
> actSelectedRef
, final Ref actHead
) {
101 return this.selectedRefs
.equals(actSelectedRef
) && this.head
== actHead
;
104 public void createControl(final Composite parent
) {
105 final Composite panel
= new Composite(parent
, SWT
.NULL
);
106 final GridLayout layout
= new GridLayout();
107 layout
.numColumns
= 1;
108 panel
.setLayout(layout
);
110 label
= new Label(panel
, SWT
.NONE
);
111 label
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false));
113 refsTable
= new Table(panel
, SWT
.CHECK
| SWT
.V_SCROLL
| SWT
.BORDER
);
114 refsTable
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
115 refsTable
.addSelectionListener(new SelectionAdapter() {
117 public void widgetSelected(final SelectionEvent e
) {
118 if (e
.detail
!= SWT
.CHECK
)
121 final TableItem tableItem
= (TableItem
) e
.item
;
122 final int i
= refsTable
.indexOf(tableItem
);
123 final Ref ref
= availableRefs
.get(i
);
125 if (tableItem
.getChecked()) {
126 int insertionPos
= 0;
127 for (int j
= 0; j
< i
; j
++) {
128 if (selectedRefs
.contains(availableRefs
.get(j
)))
131 selectedRefs
.add(insertionPos
, ref
);
133 selectedRefs
.remove(ref
);
135 notifySelectionChanged();
140 final Composite bPanel
= new Composite(panel
, SWT
.NONE
);
141 bPanel
.setLayout(new RowLayout());
142 final Button selectB
;
143 selectB
= new Button(bPanel
, SWT
.PUSH
);
144 selectB
.setText(UIText
.SourceBranchPage_selectAll
);
145 selectB
.addSelectionListener(new SelectionAdapter() {
146 public void widgetSelected(final SelectionEvent e
) {
147 for (int i
= 0; i
< refsTable
.getItemCount(); i
++)
148 refsTable
.getItem(i
).setChecked(true);
149 selectedRefs
.clear();
150 selectedRefs
.addAll(availableRefs
);
151 notifySelectionChanged();
155 final Button unselectB
= new Button(bPanel
, SWT
.PUSH
);
156 unselectB
.setText(UIText
.SourceBranchPage_selectNone
);
157 unselectB
.addSelectionListener(new SelectionAdapter() {
158 public void widgetSelected(final SelectionEvent e
) {
159 for (int i
= 0; i
< refsTable
.getItemCount(); i
++)
160 refsTable
.getItem(i
).setChecked(false);
161 selectedRefs
.clear();
162 notifySelectionChanged();
166 bPanel
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false));
168 addSelectionListener(new SelectionChangeListener() {
169 public void selectionChanged() {
170 selectB
.setEnabled(selectedRefs
.size() != availableRefs
.size());
171 unselectB
.setEnabled(selectedRefs
.size() != 0);
180 public void setVisible(final boolean visible
) {
183 super.setVisible(visible
);
187 * Check internal state for page completion status. This method should be
188 * called only when all necessary data from previous form is available.
190 private void checkPage() {
192 if (transportError
!= null) {
193 setErrorMessage(transportError
);
194 setPageComplete(false);
198 if (isSourceRepoEmpty()) {
199 setMessage(UIText
.SourceBranchPage_repoEmpty
, IMessageProvider
.WARNING
);
200 setPageComplete(true);
204 if ( getSelectedBranches().isEmpty()) {
205 setErrorMessage(UIText
.SourceBranchPage_errorBranchRequired
);
206 setPageComplete(false);
210 setErrorMessage(null);
211 setPageComplete(true);
214 private void revalidate() {
215 if (sourcePage
.selectionEquals(validatedRepoSelection
)) {
216 // URI hasn't changed, no need to refill the page with new data
221 final RepositorySelection newRepoSelection
= sourcePage
.getSelection();
222 label
.setText(NLS
.bind(UIText
.SourceBranchPage_branchList
,
223 newRepoSelection
.getURI().toString()));
224 label
.getParent().layout();
226 validatedRepoSelection
= null;
227 transportError
= null;
229 availableRefs
.clear();
230 selectedRefs
.clear();
231 refsTable
.removeAll();
232 setPageComplete(false);
233 setErrorMessage(null);
234 label
.getDisplay().asyncExec(new Runnable() {
236 revalidateImpl(newRepoSelection
);
241 private void revalidateImpl(final RepositorySelection newRepoSelection
) {
242 if (label
.isDisposed() || !isCurrentPage())
245 final ListRemoteOperation listRemoteOp
;
247 final URIish uri
= newRepoSelection
.getURI();
248 final Repository db
= new Repository(new File("/tmp")); //$NON-NLS-1$
249 listRemoteOp
= new ListRemoteOperation(db
, uri
);
250 getContainer().run(true, true, new IRunnableWithProgress() {
251 public void run(IProgressMonitor monitor
)
252 throws InvocationTargetException
, InterruptedException
{
253 listRemoteOp
.run(monitor
);
256 } catch (InvocationTargetException e
) {
257 Throwable why
= e
.getCause();
258 transportError(why
.getMessage());
259 ErrorDialog
.openError(getShell(),
260 UIText
.SourceBranchPage_transportError
,
261 UIText
.SourceBranchPage_cannotListBranches
, new Status(
262 IStatus
.ERROR
, Activator
.getPluginId(), 0, why
263 .getMessage(), why
.getCause()));
265 } catch (IOException e
) {
266 transportError(UIText
.SourceBranchPage_cannotCreateTemp
);
268 } catch (InterruptedException e
) {
269 transportError(UIText
.SourceBranchPage_remoteListingCancelled
);
273 final Ref idHEAD
= listRemoteOp
.getRemoteRef(Constants
.HEAD
);
275 for (final Ref r
: listRemoteOp
.getRemoteRefs()) {
276 final String n
= r
.getName();
277 if (!n
.startsWith(Constants
.R_HEADS
))
279 availableRefs
.add(r
);
280 if (idHEAD
== null || head
!= null)
282 if (r
.getObjectId().equals(idHEAD
.getObjectId()))
285 Collections
.sort(availableRefs
, new Comparator
<Ref
>() {
286 public int compare(final Ref o1
, final Ref o2
) {
287 return o1
.getName().compareTo(o2
.getName());
290 if (idHEAD
!= null && head
== null) {
292 availableRefs
.add(0, idHEAD
);
295 validatedRepoSelection
= newRepoSelection
;
296 for (final Ref r
: availableRefs
) {
297 String n
= r
.getName();
298 if (n
.startsWith(Constants
.R_HEADS
))
299 n
= n
.substring(Constants
.R_HEADS
.length());
300 final TableItem ti
= new TableItem(refsTable
, SWT
.NONE
);
305 notifySelectionChanged();
309 private void transportError(final String msg
) {
310 transportError
= msg
;