Git Repositories View: Simple fetch and push
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / sharing / ExistingOrNewPage.java
blob92c4e41d19780a204b16fdbb4d6474f5e442c5d1
1 /*******************************************************************************
2 * Copyright (C) 2009, Robin Rosenberg
3 * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
9 *******************************************************************************/
10 package org.eclipse.egit.ui.internal.sharing;
12 import java.io.File;
13 import java.io.IOException;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.Map;
19 import java.util.Set;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IPath;
25 import org.eclipse.core.runtime.NullProgressMonitor;
26 import org.eclipse.core.runtime.Path;
27 import org.eclipse.egit.core.project.RepositoryFinder;
28 import org.eclipse.egit.core.project.RepositoryMapping;
29 import org.eclipse.egit.ui.UIIcons;
30 import org.eclipse.egit.ui.UIText;
31 import org.eclipse.jface.layout.GridDataFactory;
32 import org.eclipse.jface.wizard.WizardPage;
33 import org.eclipse.jgit.lib.Constants;
34 import org.eclipse.jgit.lib.Repository;
35 import org.eclipse.osgi.util.NLS;
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.events.SelectionAdapter;
38 import org.eclipse.swt.events.SelectionEvent;
39 import org.eclipse.swt.events.SelectionListener;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Button;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.swt.widgets.Event;
44 import org.eclipse.swt.widgets.Group;
45 import org.eclipse.swt.widgets.Listener;
46 import org.eclipse.swt.widgets.Text;
47 import org.eclipse.swt.widgets.Tree;
48 import org.eclipse.swt.widgets.TreeColumn;
49 import org.eclipse.swt.widgets.TreeItem;
51 /**
52 * Wizard page for connecting projects to Git repositories.
54 class ExistingOrNewPage extends WizardPage {
56 private final SharingWizard myWizard;
57 private Button button;
58 private Tree tree;
59 private Text repositoryToCreate;
60 private IPath minumumPath;
61 private Text dotGitSegment;
63 ExistingOrNewPage(SharingWizard w) {
64 super(ExistingOrNewPage.class.getName());
65 setTitle(UIText.ExistingOrNewPage_title);
66 setDescription(UIText.ExistingOrNewPage_description);
67 setImageDescriptor(UIIcons.WIZBAN_CONNECT_REPO);
68 this.myWizard = w;
71 public void createControl(Composite parent) {
72 Group g = new Group(parent, SWT.NONE);
73 g.setLayout(new GridLayout(3,false));
74 g.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
75 tree = new Tree(g, SWT.BORDER|SWT.MULTI|SWT.FULL_SELECTION);
76 tree.setHeaderVisible(true);
77 tree.setLayout(new GridLayout());
78 tree.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).span(3,1).create());
79 tree.addSelectionListener(new SelectionAdapter() {
81 public void widgetSelected(SelectionEvent e) {
82 TreeItem t = (TreeItem) e.item;
83 for(TreeItem ti : t.getItems())
84 tree.deselect(ti);
85 if (t.getParentItem() != null) {
86 tree.deselect(t.getParentItem());
87 for(TreeItem ti : t.getParentItem().getItems())
88 if (ti != t)
89 tree.deselect(ti);
91 Set<IProject> projects = new HashSet<IProject>();
92 for (TreeItem treeItem : tree.getSelection()) {
93 if (treeItem.getData() == null && treeItem.getParentItem() != null) {
94 treeItem = treeItem.getParentItem();
96 final IProject project = (IProject) treeItem.getData();
97 if (projects.contains(project))
98 tree.deselect(treeItem);
99 projects.add(project);
103 TreeColumn c1 = new TreeColumn(tree,SWT.NONE);
104 c1.setText(UIText.ExistingOrNewPage_HeaderProject);
105 c1.setWidth(100);
106 TreeColumn c2 = new TreeColumn(tree,SWT.NONE);
107 c2.setText(UIText.ExistingOrNewPage_HeaderPath);
108 c2.setWidth(400);
109 TreeColumn c3 = new TreeColumn(tree,SWT.NONE);
110 c3.setText(UIText.ExistingOrNewPage_HeaderRepository);
111 c3.setWidth(200);
112 for (IProject project : myWizard.projects) {
113 TreeItem treeItem = new TreeItem(tree, SWT.NONE);
114 treeItem.setData(project);
115 treeItem.setText(0, project.getName());
116 treeItem.setText(1, project.getLocation().toOSString());
117 RepositoryFinder repositoryFinder = new RepositoryFinder(project);
118 Collection<RepositoryMapping> mappings;
119 try {
120 mappings = repositoryFinder.find(new NullProgressMonitor());
121 Iterator<RepositoryMapping> mi = mappings.iterator();
122 RepositoryMapping m = mi.hasNext() ? mi.next() : null;
123 if (m == null) {
124 // no mapping found, enable repository creation
125 treeItem.setText(2, ""); //$NON-NLS-1$
126 } else {
127 // at least one mapping found
128 fillTreeItemWithGitDirectory(m, treeItem, false);
131 while (mi.hasNext()) { // fill in additional mappings
132 m = mi.next();
133 TreeItem treeItem2 = new TreeItem(treeItem, SWT.NONE);
134 treeItem2.setData(m.getContainer().getProject());
135 fillTreeItemWithGitDirectory(m, treeItem2, true);
137 } catch (CoreException e) {
138 TreeItem treeItem2 = new TreeItem(treeItem, SWT.BOLD|SWT.ITALIC);
139 treeItem2.setText(e.getMessage());
143 button = new Button(g, SWT.PUSH);
144 button.setLayoutData(GridDataFactory.fillDefaults().create());
145 button.setText(UIText.ExistingOrNewPage_CreateButton);
146 button.addSelectionListener(new SelectionListener() {
147 public void widgetSelected(SelectionEvent e) {
148 File gitDir = new File(repositoryToCreate.getText(),Constants.DOT_GIT);
149 try {
150 Repository repository = new Repository(gitDir);
151 repository.create();
152 for (IProject project : getProjects().keySet()) {
153 // If we don't refresh the project directories right
154 // now we won't later know that a .git directory
155 // exists within it and we won't mark the .git
156 // directory as a team-private member. Failure
157 // to do so might allow someone to delete
158 // the .git directory without us stopping them.
159 // (Half lie, we should optimize so we do not
160 // refresh when the .git is not within the project)
162 if (!gitDir.toString().contains("..")) //$NON-NLS-1$
163 project.refreshLocal(IResource.DEPTH_ONE,
164 new NullProgressMonitor());
166 } catch (IOException e1) {
167 String msg = NLS
168 .bind(
169 UIText.ExistingOrNewPage_ErrorFailedToCreateRepository,
170 gitDir.toString());
171 org.eclipse.egit.ui.Activator.handleError(msg, e1, true);
172 } catch (CoreException e2) {
173 String msg = NLS
174 .bind(
175 UIText.ExistingOrNewPage_ErrorFailedToRefreshRepository,
176 gitDir);
177 org.eclipse.egit.ui.Activator.handleError(msg, e2, true);
179 for (TreeItem ti : tree.getSelection()) {
180 ti.setText(2, gitDir.toString());
182 updateCreateOptions();
183 getContainer().updateButtons();
185 public void widgetDefaultSelected(SelectionEvent e) {
188 repositoryToCreate = new Text(g, SWT.SINGLE | SWT.BORDER);
189 repositoryToCreate.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(1,1).create());
190 repositoryToCreate.addListener(SWT.Modify, new Listener() {
191 public void handleEvent(Event e) {
192 if (e.text == null)
193 return;
194 IPath fromOSString = Path.fromOSString(e.text);
195 button.setEnabled(minumumPath
196 .matchingFirstSegments(fromOSString) == fromOSString
197 .segmentCount());
200 dotGitSegment = new Text(g ,SWT.NONE);
201 dotGitSegment.setEnabled(false);
202 dotGitSegment.setEditable(false);
203 dotGitSegment.setText(File.separatorChar + Constants.DOT_GIT);
204 dotGitSegment.setLayoutData(GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).create());
206 tree.addSelectionListener(new SelectionListener() {
207 public void widgetSelected(SelectionEvent e) {
208 updateCreateOptions();
210 public void widgetDefaultSelected(SelectionEvent e) {
211 // Empty
214 updateCreateOptions();
215 setControl(g);
218 private void fillTreeItemWithGitDirectory(RepositoryMapping m, TreeItem treeItem2, boolean isAlternative) {
219 if (m.getGitDir() == null)
220 treeItem2.setText(2, UIText.ExistingOrNewPage_SymbolicValueEmptyMapping);
221 else {
222 IPath container = m.getContainerPath();
223 if (!container.isEmpty())
224 container = container.addTrailingSeparator();
225 IPath relativePath = container.append(m.getGitDir());
226 if (isAlternative)
227 treeItem2.setText(0, relativePath.removeLastSegments(1).addTrailingSeparator().toString());
228 treeItem2.setText(2, relativePath.toString());
232 private void updateCreateOptions() {
233 minumumPath = null;
234 IPath p = null;
235 for (TreeItem ti : tree.getSelection()) {
236 String path = ti.getText(2);
237 if (!path.equals("")) { //$NON-NLS-1$
238 p = null;
239 break;
241 String gitDirParentCandidate = ti.getText(1);
242 IPath thisPath = Path.fromOSString(gitDirParentCandidate);
243 if (p == null)
244 p = thisPath;
245 else {
246 int n = p.matchingFirstSegments(thisPath);
247 p = p.removeLastSegments(p.segmentCount() - n);
250 minumumPath = p;
251 if (p != null) {
252 repositoryToCreate.setText(p.toOSString());
253 } else {
254 repositoryToCreate.setText(""); //$NON-NLS-1$
256 button.setEnabled(p != null);
257 repositoryToCreate.setEnabled(p != null);
258 dotGitSegment.setEnabled(p != null);
259 getContainer().updateButtons();
262 @Override
263 public boolean isPageComplete() {
264 if (tree.getSelectionCount() == 0)
265 return false;
266 for (TreeItem ti : tree.getSelection()) {
267 String path = ti.getText(2);
268 if (path.equals("")) { //$NON-NLS-1$
269 return false;
272 return true;
276 * @return map between project and repository root directory (converted to an
277 * absolute path) for all projects selected by user
279 public Map<IProject, File> getProjects() {
280 final TreeItem[] selection = tree.getSelection();
281 Map<IProject, File> ret = new HashMap<IProject, File>(selection.length);
282 for (int i = 0; i < selection.length; ++i) {
283 TreeItem treeItem = selection[i];
284 while (treeItem.getData() == null && treeItem.getParentItem() != null) {
285 treeItem = treeItem.getParentItem();
288 final IProject project = (IProject) treeItem.getData();
289 final IPath selectedRepo = Path.fromOSString(treeItem.getText(2));
290 IPath localPathToRepo = selectedRepo;
291 if (!selectedRepo.isAbsolute()) {
292 localPathToRepo = project.getLocation().append(selectedRepo);
294 ret.put(project, localPathToRepo.toFile());
296 return ret;