Merge branch 'stable-0.8'
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / clone / CloneDestinationPage.java
bloba569ea9715191a5272e77e2b430f0bcb215a7997
1 /*******************************************************************************
2 * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
5 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License v1.0
9 * which accompanies this distribution, and is available at
10 * http://www.eclipse.org/legal/epl-v10.html
11 *******************************************************************************/
12 package org.eclipse.egit.ui.internal.clone;
14 import java.io.File;
15 import java.util.List;
17 import org.eclipse.core.resources.ResourcesPlugin;
18 import org.eclipse.egit.ui.UIText;
19 import org.eclipse.egit.ui.internal.components.RepositorySelection;
20 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
21 import org.eclipse.egit.ui.internal.components.SelectionChangeListener;
22 import org.eclipse.jface.dialogs.Dialog;
23 import org.eclipse.jface.wizard.WizardPage;
24 import org.eclipse.jgit.lib.Constants;
25 import org.eclipse.jgit.lib.Ref;
26 import org.eclipse.osgi.util.NLS;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.events.ModifyEvent;
29 import org.eclipse.swt.events.ModifyListener;
30 import org.eclipse.swt.events.SelectionAdapter;
31 import org.eclipse.swt.events.SelectionEvent;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.Button;
35 import org.eclipse.swt.widgets.Combo;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.FileDialog;
38 import org.eclipse.swt.widgets.Group;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Text;
42 /**
43 * Wizard page that allows the user entering the location of a repository to be
44 * cloned.
46 class CloneDestinationPage extends WizardPage {
47 private final RepositorySelectionPage sourcePage;
49 private final SourceBranchPage branchPage;
51 private RepositorySelection validatedRepoSelection;
53 private List<Ref> validatedSelectedBranches;
55 private Ref validatedHEAD;
57 private Combo initialBranch;
59 private Text directoryText;
61 private Text remoteText;
63 CloneDestinationPage(final RepositorySelectionPage sp,
64 final SourceBranchPage bp) {
65 super(CloneDestinationPage.class.getName());
66 sourcePage = sp;
67 branchPage = bp;
68 setTitle(UIText.CloneDestinationPage_title);
70 final SelectionChangeListener listener = new SelectionChangeListener() {
71 public void selectionChanged() {
72 checkPreviousPagesSelections();
75 sourcePage.addSelectionListener(listener);
76 branchPage.addSelectionListener(listener);
79 public void createControl(final Composite parent) {
80 final Composite panel = new Composite(parent, SWT.NULL);
81 final GridLayout layout = new GridLayout();
82 layout.numColumns = 1;
83 panel.setLayout(layout);
85 createDestinationGroup(panel);
86 createConfigGroup(panel);
87 Dialog.applyDialogFont(panel);
88 setControl(panel);
89 checkPage();
92 @Override
93 public void setVisible(final boolean visible) {
94 if (visible) {
95 if (branchPage.isSourceRepoEmpty()) {
96 initialBranch.setEnabled(false);
98 revalidate();
100 super.setVisible(visible);
101 if (visible)
102 directoryText.setFocus();
105 private void checkPreviousPagesSelections() {
106 if (!sourcePage.selectionEquals(validatedRepoSelection)
107 || !branchPage.selectionEquals(validatedSelectedBranches,
108 validatedHEAD))
109 setPageComplete(false);
110 else
111 checkPage();
114 private void createDestinationGroup(final Composite parent) {
115 final Group g = createGroup(parent,
116 UIText.CloneDestinationPage_groupDestination);
118 newLabel(g, UIText.CloneDestinationPage_promptDirectory + ":"); //$NON-NLS-1$
119 final Composite p = new Composite(g, SWT.NONE);
120 final GridLayout grid = new GridLayout();
121 grid.numColumns = 2;
122 p.setLayout(grid);
123 p.setLayoutData(createFieldGridData());
124 directoryText = new Text(p, SWT.BORDER);
125 directoryText.setLayoutData(createFieldGridData());
126 directoryText.addModifyListener(new ModifyListener() {
127 public void modifyText(final ModifyEvent e) {
128 checkPage();
131 final Button b = new Button(p, SWT.PUSH);
132 b.setText(UIText.CloneDestinationPage_browseButton);
133 b.addSelectionListener(new SelectionAdapter() {
134 public void widgetSelected(final SelectionEvent e) {
135 final FileDialog d;
137 d = new FileDialog(getShell(), SWT.APPLICATION_MODAL | SWT.SAVE);
138 if (directoryText.getText().length() > 0) {
139 final File file = new File(directoryText.getText())
140 .getAbsoluteFile();
141 d.setFilterPath(file.getParent());
142 d.setFileName(file.getName());
144 final String r = d.open();
145 if (r != null)
146 directoryText.setText(r);
150 newLabel(g, UIText.CloneDestinationPage_promptInitialBranch + ":"); //$NON-NLS-1$
151 initialBranch = new Combo(g, SWT.DROP_DOWN | SWT.READ_ONLY);
152 initialBranch.setLayoutData(createFieldGridData());
153 initialBranch.addSelectionListener(new SelectionAdapter() {
154 @Override
155 public void widgetSelected(final SelectionEvent e) {
156 checkPage();
161 private void createConfigGroup(final Composite parent) {
162 final Group g = createGroup(parent,
163 UIText.CloneDestinationPage_groupConfiguration);
165 newLabel(g, UIText.CloneDestinationPage_promptRemoteName + ":"); //$NON-NLS-1$
166 remoteText = new Text(g, SWT.BORDER);
167 remoteText.setText(Constants.DEFAULT_REMOTE_NAME);
168 remoteText.setLayoutData(createFieldGridData());
169 remoteText.addModifyListener(new ModifyListener() {
170 public void modifyText(ModifyEvent e) {
171 checkPage();
176 private static Group createGroup(final Composite parent, final String text) {
177 final Group g = new Group(parent, SWT.NONE);
178 final GridLayout layout = new GridLayout();
179 layout.numColumns = 2;
180 g.setLayout(layout);
181 g.setText(text);
182 final GridData gd = new GridData();
183 gd.grabExcessHorizontalSpace = true;
184 gd.horizontalAlignment = SWT.FILL;
185 g.setLayoutData(gd);
186 return g;
189 private static void newLabel(final Group g, final String text) {
190 new Label(g, SWT.NULL).setText(text);
193 private static GridData createFieldGridData() {
194 return new GridData(SWT.FILL, SWT.DEFAULT, true, false);
198 * @return location the user wants to store this repository.
200 public File getDestinationFile() {
201 return new File(directoryText.getText());
205 * @return initial branch selected (includes refs/heads prefix).
207 public String getInitialBranch() {
208 final int ix = initialBranch.getSelectionIndex();
209 if (ix < 0)
210 return Constants.R_HEADS + Constants.MASTER;
211 return Constants.R_HEADS + initialBranch.getItem(ix);
215 * @return remote name
217 public String getRemote() {
218 return remoteText.getText();
222 * Check internal state for page completion status.
224 private void checkPage() {
225 final String dstpath = directoryText.getText();
226 if (dstpath.length() == 0) {
227 setErrorMessage(NLS.bind(UIText.CloneDestinationPage_fieldRequired,
228 UIText.CloneDestinationPage_promptDirectory));
229 setPageComplete(false);
230 return;
232 final File absoluteFile = new File(dstpath).getAbsoluteFile();
233 if (!isEmptyDir(absoluteFile)) {
234 setErrorMessage(NLS.bind(
235 UIText.CloneDestinationPage_errorNotEmptyDir, absoluteFile
236 .getPath()));
237 setPageComplete(false);
238 return;
241 if (!canCreateSubdir(absoluteFile.getParentFile())) {
242 setErrorMessage(NLS.bind(UIText.GitCloneWizard_errorCannotCreate,
243 absoluteFile.getPath()));
244 setPageComplete(false);
245 return;
247 if (!branchPage.isSourceRepoEmpty()
248 && initialBranch.getSelectionIndex() < 0) {
249 setErrorMessage(NLS.bind(UIText.CloneDestinationPage_fieldRequired,
250 UIText.CloneDestinationPage_promptInitialBranch));
251 setPageComplete(false);
252 return;
254 if (remoteText.getText().length() == 0) {
255 setErrorMessage(NLS.bind(UIText.CloneDestinationPage_fieldRequired,
256 UIText.CloneDestinationPage_promptRemoteName));
257 setPageComplete(false);
258 return;
261 setErrorMessage(null);
262 setPageComplete(true);
265 private static boolean isEmptyDir(final File dir) {
266 if (!dir.exists())
267 return true;
268 if (!dir.isDirectory())
269 return false;
270 return dir.listFiles().length == 0;
273 // this is actually just an optimistic heuristic - should be named
274 // isThereHopeThatCanCreateSubdir() as probably there is no 100% reliable
275 // way to check that in Java for Windows
276 private static boolean canCreateSubdir(final File parent) {
277 if (parent == null)
278 return true;
279 if (parent.exists())
280 return parent.isDirectory() && parent.canWrite();
281 return canCreateSubdir(parent.getParentFile());
284 private void revalidate() {
285 if (sourcePage.selectionEquals(validatedRepoSelection)
286 && branchPage.selectionEquals(validatedSelectedBranches,
287 validatedHEAD)) {
288 checkPage();
289 return;
292 if (!sourcePage.selectionEquals(validatedRepoSelection)) {
293 validatedRepoSelection = sourcePage.getSelection();
294 // update repo-related selection only if it changed
295 final String n = validatedRepoSelection.getURI().getHumanishName();
296 setDescription(NLS.bind(UIText.CloneDestinationPage_description, n));
297 directoryText.setText(new File(ResourcesPlugin.getWorkspace()
298 .getRoot().getRawLocation().toFile(), n).getAbsolutePath());
301 validatedSelectedBranches = branchPage.getSelectedBranches();
302 validatedHEAD = branchPage.getHEAD();
304 initialBranch.removeAll();
305 final Ref head = branchPage.getHEAD();
306 int newix = 0;
307 for (final Ref r : branchPage.getSelectedBranches()) {
308 String name = r.getName();
309 if (name.startsWith(Constants.R_HEADS))
310 name = name.substring((Constants.R_HEADS).length());
311 if (head != null && head.getName().equals(r.getName()))
312 newix = initialBranch.getItemCount();
313 initialBranch.add(name);
315 initialBranch.select(newix);
316 checkPage();