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
.components
;
11 import java
.lang
.reflect
.InvocationTargetException
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Collections
;
14 import java
.util
.List
;
16 import org
.eclipse
.core
.runtime
.IStatus
;
17 import org
.eclipse
.core
.runtime
.Status
;
18 import org
.eclipse
.egit
.core
.op
.ListRemoteOperation
;
19 import org
.eclipse
.egit
.ui
.Activator
;
20 import org
.eclipse
.egit
.ui
.UIText
;
21 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
22 import org
.eclipse
.osgi
.util
.NLS
;
23 import org
.eclipse
.swt
.SWT
;
24 import org
.eclipse
.swt
.events
.SelectionAdapter
;
25 import org
.eclipse
.swt
.events
.SelectionEvent
;
26 import org
.eclipse
.swt
.layout
.GridData
;
27 import org
.eclipse
.swt
.layout
.GridLayout
;
28 import org
.eclipse
.swt
.widgets
.Button
;
29 import org
.eclipse
.swt
.widgets
.Composite
;
30 import org
.eclipse
.swt
.widgets
.Group
;
31 import org
.eclipse
.jgit
.lib
.Repository
;
32 import org
.eclipse
.jgit
.transport
.RefSpec
;
33 import org
.eclipse
.jgit
.transport
.TagOpt
;
34 import org
.eclipse
.jgit
.transport
.URIish
;
37 * This wizard page allows user easy selection of specifications for push or
38 * fetch (configurable).
40 * Page is relying highly on {@link RefSpecPanel} component, see its description
43 * Page is designed to be successor of {@link RepositorySelectionPage} in
46 public class RefSpecPage
extends BaseWizardPage
{
48 private final Repository local
;
50 private final RepositorySelectionPage repoPage
;
52 private final boolean pushPage
;
54 private RepositorySelection validatedRepoSelection
;
56 private RefSpecPanel specsPanel
;
58 private Button saveButton
;
60 private Button tagsAutoFollowButton
;
62 private Button tagsFetchTagsButton
;
64 private Button tagsNoTagsButton
;
66 private String transportError
;
69 * Create specifications selection page for provided context.
74 * true if this page is used for push specifications selection,
75 * false if it used for fetch specifications selection.
77 * repository selection page - must be predecessor of this page
80 public RefSpecPage(final Repository local
, final boolean pushPage
,
81 final RepositorySelectionPage repoPage
) {
82 super(RefSpecPage
.class.getName());
84 this.repoPage
= repoPage
;
85 this.pushPage
= pushPage
;
87 setTitle(UIText
.RefSpecPage_titlePush
);
88 setDescription(UIText
.RefSpecPage_descriptionPush
);
90 setTitle(UIText
.RefSpecPage_titleFetch
);
91 setDescription(UIText
.RefSpecPage_descriptionFetch
);
94 repoPage
.addSelectionListener(new SelectionChangeListener() {
95 public void selectionChanged() {
96 if (!repoPage
.selectionEquals(validatedRepoSelection
))
97 setPageComplete(false);
104 public void createControl(Composite parent
) {
105 final Composite panel
= new Composite(parent
, SWT
.NULL
);
106 panel
.setLayout(new GridLayout());
108 specsPanel
= new RefSpecPanel(panel
, pushPage
);
109 specsPanel
.getControl().setLayoutData(
110 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
111 specsPanel
.addRefSpecTableListener(new SelectionChangeListener() {
112 public void selectionChanged() {
113 notifySelectionChanged();
118 final SelectionAdapter changesNotifier
= new SelectionAdapter() {
120 public void widgetSelected(SelectionEvent e
) {
121 notifySelectionChanged();
125 final Group tagsGroup
= new Group(panel
, SWT
.NULL
);
126 tagsGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
128 tagsGroup
.setText(UIText
.RefSpecPage_annotatedTagsGroup
);
129 tagsGroup
.setLayout(new GridLayout());
130 tagsAutoFollowButton
= new Button(tagsGroup
, SWT
.RADIO
);
132 .setText(UIText
.RefSpecPage_annotatedTagsAutoFollow
);
133 tagsFetchTagsButton
= new Button(tagsGroup
, SWT
.RADIO
);
135 .setText(UIText
.RefSpecPage_annotatedTagsFetchTags
);
136 tagsNoTagsButton
= new Button(tagsGroup
, SWT
.RADIO
);
138 .setText(UIText
.RefSpecPage_annotatedTagsNoTags
);
139 tagsAutoFollowButton
.addSelectionListener(changesNotifier
);
140 tagsFetchTagsButton
.addSelectionListener(changesNotifier
);
141 tagsNoTagsButton
.addSelectionListener(changesNotifier
);
144 saveButton
= new Button(panel
, SWT
.CHECK
);
145 saveButton
.setLayoutData(new GridData(SWT
.LEFT
, SWT
.FILL
, true, false));
146 saveButton
.addSelectionListener(changesNotifier
);
149 notifySelectionChanged();
154 public void setVisible(final boolean visible
) {
157 super.setVisible(visible
);
161 * @return ref specifications as selected by user. Returned collection is a
162 * copy, so it may be modified by caller.
164 public List
<RefSpec
> getRefSpecs() {
165 if (specsPanel
== null)
166 return Collections
.emptyList();
168 return new ArrayList
<RefSpec
>(specsPanel
.getRefSpecs());
172 * @return true if user chosen to save selected specification in remote
173 * configuration, false otherwise.
175 public boolean isSaveRequested() {
176 return saveButton
.getSelection();
180 * @return selected tag fetching strategy. This result is relevant only for
183 public TagOpt
getTagOpt() {
184 if (tagsAutoFollowButton
.getSelection())
185 return TagOpt
.AUTO_FOLLOW
;
186 if (tagsFetchTagsButton
.getSelection())
187 return TagOpt
.FETCH_TAGS
;
188 return TagOpt
.NO_TAGS
;
192 * Compare provided specifications to currently selected ones.
195 * specifications to compare to. May be null.
196 * @return true if provided specifications are equal to currently selected
197 * ones, false otherwise.
199 public boolean specsSelectionEquals(final List
<RefSpec
> specs
) {
200 return getRefSpecs().equals(specs
);
203 private void revalidate() {
204 final RepositorySelection newRepoSelection
= repoPage
.getSelection();
206 if (repoPage
.selectionEquals(validatedRepoSelection
)) {
207 // nothing changed on previous page
212 specsPanel
.clearRefSpecs();
213 specsPanel
.setEnable(false);
214 saveButton
.setVisible(false);
215 saveButton
.setSelection(false);
216 notifySelectionChanged();
217 validatedRepoSelection
= null;
218 transportError
= null;
219 getControl().getDisplay().asyncExec(new Runnable() {
221 revalidateImpl(newRepoSelection
);
226 private void revalidateImpl(final RepositorySelection newRepoSelection
) {
227 final ListRemoteOperation listRemotesOp
;
230 uri
= newRepoSelection
.getURI();
231 listRemotesOp
= new ListRemoteOperation(local
, uri
);
232 getContainer().run(true, true, listRemotesOp
);
233 } catch (InvocationTargetException e
) {
234 final Throwable cause
= e
.getCause();
235 transportError(cause
.getMessage());
236 ErrorDialog
.openError(getShell(),
237 UIText
.RefSpecPage_errorTransportDialogTitle
,
238 UIText
.RefSpecPage_errorTransportDialogMessage
, new Status(
239 IStatus
.ERROR
, Activator
.getPluginId(), 0, cause
240 .getMessage(), cause
));
242 } catch (InterruptedException e
) {
243 transportError(UIText
.RefSpecPage_operationCancelled
);
247 this.validatedRepoSelection
= newRepoSelection
;
248 final String remoteName
= validatedRepoSelection
.getConfigName();
249 specsPanel
.setAssistanceData(local
, listRemotesOp
.getRemoteRefs(),
252 tagsAutoFollowButton
.setSelection(false);
253 tagsFetchTagsButton
.setSelection(false);
254 tagsNoTagsButton
.setSelection(false);
256 if (newRepoSelection
.isConfigSelected()) {
257 saveButton
.setVisible(true);
258 saveButton
.setText(NLS
.bind(UIText
.RefSpecPage_saveSpecifications
,
260 saveButton
.getParent().layout();
261 final TagOpt tagOpt
= newRepoSelection
.getConfig().getTagOpt();
264 tagsAutoFollowButton
.setSelection(true);
267 tagsFetchTagsButton
.setSelection(true);
270 tagsNoTagsButton
.setSelection(true);
274 tagsAutoFollowButton
.setSelection(true);
279 private void transportError(final String message
) {
280 transportError
= message
;
284 private void checkPage() {
285 if (transportError
!= null) {
286 setErrorMessage(transportError
);
287 setPageComplete(false);
290 if (!specsPanel
.isEmpty() && specsPanel
.isValid()
291 && !specsPanel
.isMatchingAnyRefs()) {
292 setErrorMessage(UIText
.RefSpecPage_errorDontMatchSrc
);
293 setPageComplete(false);
296 setErrorMessage(specsPanel
.getErrorMessage());
297 setPageComplete(!specsPanel
.isEmpty() && specsPanel
.isValid());