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 java
.io
.IOException
;
12 import java
.lang
.reflect
.InvocationTargetException
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Collection
;
15 import java
.util
.List
;
17 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
18 import org
.eclipse
.core
.runtime
.IStatus
;
19 import org
.eclipse
.core
.runtime
.Status
;
20 import org
.eclipse
.egit
.core
.op
.PushOperation
;
21 import org
.eclipse
.egit
.core
.op
.PushOperationResult
;
22 import org
.eclipse
.egit
.core
.op
.PushOperationSpecification
;
23 import org
.eclipse
.egit
.ui
.Activator
;
24 import org
.eclipse
.egit
.ui
.UIText
;
25 import org
.eclipse
.egit
.ui
.internal
.components
.RefSpecPage
;
26 import org
.eclipse
.egit
.ui
.internal
.components
.RepositorySelection
;
27 import org
.eclipse
.egit
.ui
.internal
.components
.RepositorySelectionPage
;
28 import org
.eclipse
.egit
.ui
.internal
.components
.SelectionChangeListener
;
29 import org
.eclipse
.jface
.dialogs
.Dialog
;
30 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
31 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
32 import org
.eclipse
.jface
.wizard
.WizardPage
;
33 import org
.eclipse
.osgi
.util
.NLS
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.layout
.GridData
;
36 import org
.eclipse
.swt
.layout
.GridLayout
;
37 import org
.eclipse
.swt
.widgets
.Button
;
38 import org
.eclipse
.swt
.widgets
.Composite
;
39 import org
.eclipse
.swt
.widgets
.Control
;
40 import org
.eclipse
.jgit
.lib
.Repository
;
41 import org
.eclipse
.jgit
.transport
.RefSpec
;
42 import org
.eclipse
.jgit
.transport
.RemoteRefUpdate
;
43 import org
.eclipse
.jgit
.transport
.Transport
;
44 import org
.eclipse
.jgit
.transport
.URIish
;
46 class ConfirmationPage
extends WizardPage
{
47 static Collection
<RemoteRefUpdate
> copyUpdates(
48 final Collection
<RemoteRefUpdate
> refUpdates
) throws IOException
{
49 final Collection
<RemoteRefUpdate
> copy
= new ArrayList
<RemoteRefUpdate
>(
51 for (final RemoteRefUpdate rru
: refUpdates
)
52 copy
.add(new RemoteRefUpdate(rru
, null));
56 private final Repository local
;
58 private final RepositorySelectionPage repoPage
;
60 private final RefSpecPage refSpecPage
;
62 private RepositorySelection displayedRepoSelection
;
64 private List
<RefSpec
> displayedRefSpecs
;
66 private PushOperationResult confirmedResult
;
68 private PushResultTable resultPanel
;
70 private Button requireUnchangedButton
;
72 private Button showOnlyIfChanged
;
74 public ConfirmationPage(final Repository local
,
75 final RepositorySelectionPage repoPage
,
76 final RefSpecPage refSpecPage
) {
77 super(ConfirmationPage
.class.getName());
79 this.repoPage
= repoPage
;
80 this.refSpecPage
= refSpecPage
;
82 setTitle(UIText
.ConfirmationPage_title
);
83 setDescription(UIText
.ConfirmationPage_description
);
85 final SelectionChangeListener listener
= new SelectionChangeListener() {
86 public void selectionChanged() {
87 checkPreviousPagesSelections();
90 repoPage
.addSelectionListener(listener
);
91 refSpecPage
.addSelectionListener(listener
);
94 public void createControl(final Composite parent
) {
95 final Composite panel
= new Composite(parent
, SWT
.NONE
);
96 panel
.setLayout(new GridLayout());
98 resultPanel
= new PushResultTable(panel
);
99 final Control tableControl
= resultPanel
.getControl();
101 .setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
103 requireUnchangedButton
= new Button(panel
, SWT
.CHECK
);
104 requireUnchangedButton
105 .setText(UIText
.ConfirmationPage_requireUnchangedButton
);
107 showOnlyIfChanged
= new Button(panel
, SWT
.CHECK
);
108 showOnlyIfChanged
.setText(UIText
.ConfirmationPage_showOnlyIfChanged
);
110 Dialog
.applyDialogFont(panel
);
115 public void setVisible(final boolean visible
) {
118 super.setVisible(visible
);
121 boolean isConfirmed() {
122 return confirmedResult
!= null;
125 PushOperationResult
getConfirmedResult() {
126 return confirmedResult
;
129 boolean isRequireUnchangedSelected() {
130 return requireUnchangedButton
.getSelection();
133 boolean isShowOnlyIfChangedSelected() {
134 return showOnlyIfChanged
.getSelection();
137 private void checkPreviousPagesSelections() {
138 if (!repoPage
.selectionEquals(displayedRepoSelection
)
139 || !refSpecPage
.specsSelectionEquals(displayedRefSpecs
)) {
140 // Allow user to finish by skipping confirmation...
141 setPageComplete(true);
143 // ... but if user doesn't skip confirmation, allow only when no
144 // critical errors occurred
145 setPageComplete(confirmedResult
!= null);
149 private void revalidate() {
150 // always update this page
151 resultPanel
.setData(local
, null);
152 confirmedResult
= null;
153 displayedRepoSelection
= repoPage
.getSelection();
154 displayedRefSpecs
= refSpecPage
.getRefSpecs();
155 setErrorMessage(null);
156 setPageComplete(false);
157 getControl().getDisplay().asyncExec(new Runnable() {
164 private void revalidateImpl() {
165 if (getControl().isDisposed() || !isCurrentPage())
168 final List
<RefSpec
> fetchSpecs
;
169 if (displayedRepoSelection
.isConfigSelected())
170 fetchSpecs
= displayedRepoSelection
.getConfig().getPushRefSpecs();
174 final PushOperation operation
;
176 final Collection
<RemoteRefUpdate
> updates
= Transport
177 .findRemoteRefUpdatesFor(local
, displayedRefSpecs
,
179 if (updates
.isEmpty()) {
180 // It can happen only when local refs changed in the mean time.
181 setErrorMessage(UIText
.ConfirmationPage_errorRefsChangedNoMatch
);
182 setPageComplete(false);
186 final PushOperationSpecification spec
= new PushOperationSpecification();
187 for (final URIish uri
: displayedRepoSelection
.getPushURIs())
188 spec
.addURIRefUpdates(uri
, copyUpdates(updates
));
190 operation
= new PushOperation(local
, spec
, true,
191 displayedRepoSelection
.getConfig());
192 getContainer().run(true, true, new IRunnableWithProgress() {
193 public void run(IProgressMonitor monitor
)
194 throws InvocationTargetException
, InterruptedException
{
195 operation
.run(monitor
);
198 } catch (final IOException e
) {
199 setErrorMessage(NLS
.bind(
200 UIText
.ConfirmationPage_errorCantResolveSpecs
, e
203 } catch (final InvocationTargetException e
) {
204 setErrorMessage(NLS
.bind(UIText
.ConfirmationPage_errorUnexpected
, e
205 .getCause().getMessage()));
207 } catch (final InterruptedException e
) {
208 setErrorMessage(UIText
.ConfirmationPage_errorInterrupted
);
209 setPageComplete(true);
210 displayedRefSpecs
= null;
211 displayedRepoSelection
= null;
215 final PushOperationResult result
= operation
.getOperationResult();
216 resultPanel
.setData(local
, result
);
217 if (result
.isSuccessfulConnectionForAnyURI()) {
218 setPageComplete(true);
219 confirmedResult
= result
;
221 final String message
= NLS
.bind(
222 UIText
.ConfirmationPage_cantConnectToAny
, result
223 .getErrorStringForAllURis());
224 setErrorMessage(message
);
226 .openError(getShell(),
227 UIText
.ConfirmationPage_cantConnectToAnyTitle
,
229 new Status(IStatus
.ERROR
, Activator
.getPluginId(),