Initial EGit contribution to eclipse.org
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / components / RefSpecPage.java
blob959da2cb0d2fe7c7c83a4dd3dc24dd1963d44af4
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;
36 /**
37 * This wizard page allows user easy selection of specifications for push or
38 * fetch (configurable).
39 * <p>
40 * Page is relying highly on {@link RefSpecPanel} component, see its description
41 * for details.
42 * <p>
43 * Page is designed to be successor of {@link RepositorySelectionPage} in
44 * wizard.
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;
68 /**
69 * Create specifications selection page for provided context.
71 * @param local
72 * local repository.
73 * @param pushPage
74 * true if this page is used for push specifications selection,
75 * false if it used for fetch specifications selection.
76 * @param repoPage
77 * repository selection page - must be predecessor of this page
78 * in wizard.
80 public RefSpecPage(final Repository local, final boolean pushPage,
81 final RepositorySelectionPage repoPage) {
82 super(RefSpecPage.class.getName());
83 this.local = local;
84 this.repoPage = repoPage;
85 this.pushPage = pushPage;
86 if (pushPage) {
87 setTitle(UIText.RefSpecPage_titlePush);
88 setDescription(UIText.RefSpecPage_descriptionPush);
89 } else {
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);
98 else
99 checkPage();
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();
114 checkPage();
118 final SelectionAdapter changesNotifier = new SelectionAdapter() {
119 @Override
120 public void widgetSelected(SelectionEvent e) {
121 notifySelectionChanged();
124 if (!pushPage) {
125 final Group tagsGroup = new Group(panel, SWT.NULL);
126 tagsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
127 false));
128 tagsGroup.setText(UIText.RefSpecPage_annotatedTagsGroup);
129 tagsGroup.setLayout(new GridLayout());
130 tagsAutoFollowButton = new Button(tagsGroup, SWT.RADIO);
131 tagsAutoFollowButton
132 .setText(UIText.RefSpecPage_annotatedTagsAutoFollow);
133 tagsFetchTagsButton = new Button(tagsGroup, SWT.RADIO);
134 tagsFetchTagsButton
135 .setText(UIText.RefSpecPage_annotatedTagsFetchTags);
136 tagsNoTagsButton = new Button(tagsGroup, SWT.RADIO);
137 tagsNoTagsButton
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);
148 setControl(panel);
149 notifySelectionChanged();
150 checkPage();
153 @Override
154 public void setVisible(final boolean visible) {
155 if (visible)
156 revalidate();
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();
167 else
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
181 * fetch page.
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.
194 * @param specs
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
208 checkPage();
209 return;
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() {
220 public void run() {
221 revalidateImpl(newRepoSelection);
226 private void revalidateImpl(final RepositorySelection newRepoSelection) {
227 final ListRemoteOperation listRemotesOp;
228 try {
229 final URIish uri;
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));
241 return;
242 } catch (InterruptedException e) {
243 transportError(UIText.RefSpecPage_operationCancelled);
244 return;
247 this.validatedRepoSelection = newRepoSelection;
248 final String remoteName = validatedRepoSelection.getConfigName();
249 specsPanel.setAssistanceData(local, listRemotesOp.getRemoteRefs(),
250 remoteName);
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,
259 remoteName));
260 saveButton.getParent().layout();
261 final TagOpt tagOpt = newRepoSelection.getConfig().getTagOpt();
262 switch (tagOpt) {
263 case AUTO_FOLLOW:
264 tagsAutoFollowButton.setSelection(true);
265 break;
266 case FETCH_TAGS:
267 tagsFetchTagsButton.setSelection(true);
268 break;
269 case NO_TAGS:
270 tagsNoTagsButton.setSelection(true);
271 break;
273 } else
274 tagsAutoFollowButton.setSelection(true);
276 checkPage();
279 private void transportError(final String message) {
280 transportError = message;
281 checkPage();
284 private void checkPage() {
285 if (transportError != null) {
286 setErrorMessage(transportError);
287 setPageComplete(false);
288 return;
290 if (!specsPanel.isEmpty() && specsPanel.isValid()
291 && !specsPanel.isMatchingAnyRefs()) {
292 setErrorMessage(UIText.RefSpecPage_errorDontMatchSrc);
293 setPageComplete(false);
294 return;
296 setErrorMessage(specsPanel.getErrorMessage());
297 setPageComplete(!specsPanel.isEmpty() && specsPanel.isValid());