1 /*******************************************************************************
2 * Copyright (C) 2009, Robin Rosenberg
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
.sharing
;
12 import java
.io
.IOException
;
13 import java
.util
.Collection
;
14 import java
.util
.Iterator
;
16 import org
.eclipse
.core
.resources
.IProject
;
17 import org
.eclipse
.core
.resources
.IResource
;
18 import org
.eclipse
.core
.runtime
.CoreException
;
19 import org
.eclipse
.core
.runtime
.IPath
;
20 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
21 import org
.eclipse
.core
.runtime
.Path
;
22 import org
.eclipse
.egit
.core
.Activator
;
23 import org
.eclipse
.egit
.core
.project
.RepositoryFinder
;
24 import org
.eclipse
.egit
.core
.project
.RepositoryMapping
;
25 import org
.eclipse
.egit
.ui
.UIIcons
;
26 import org
.eclipse
.egit
.ui
.UIText
;
27 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
28 import org
.eclipse
.jface
.layout
.GridDataFactory
;
29 import org
.eclipse
.jface
.wizard
.WizardPage
;
30 import org
.eclipse
.swt
.SWT
;
31 import org
.eclipse
.swt
.events
.SelectionEvent
;
32 import org
.eclipse
.swt
.events
.SelectionListener
;
33 import org
.eclipse
.swt
.layout
.GridLayout
;
34 import org
.eclipse
.swt
.widgets
.Button
;
35 import org
.eclipse
.swt
.widgets
.Composite
;
36 import org
.eclipse
.swt
.widgets
.Event
;
37 import org
.eclipse
.swt
.widgets
.Group
;
38 import org
.eclipse
.swt
.widgets
.Listener
;
39 import org
.eclipse
.swt
.widgets
.Text
;
40 import org
.eclipse
.swt
.widgets
.Tree
;
41 import org
.eclipse
.swt
.widgets
.TreeColumn
;
42 import org
.eclipse
.swt
.widgets
.TreeItem
;
43 import org
.eclipse
.jgit
.lib
.Repository
;
46 * Wizard page for connecting projects to Git repositories.
48 class ExistingOrNewPage
extends WizardPage
{
50 private final SharingWizard myWizard
;
51 private Button button
;
53 private Text repositoryToCreate
;
54 private IPath minumumPath
;
56 ExistingOrNewPage(SharingWizard w
) {
57 super(ExistingOrNewPage
.class.getName());
58 setTitle(UIText
.ExistingOrNewPage_title
);
59 setDescription(UIText
.ExistingOrNewPage_description
);
60 setImageDescriptor(UIIcons
.WIZBAN_CONNECT_REPO
);
64 public void createControl(Composite parent
) {
65 Group g
= new Group(parent
, SWT
.NONE
);
66 g
.setLayout(new GridLayout(3,false));
67 g
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, true).create());
68 tree
= new Tree(g
, SWT
.BORDER
|SWT
.MULTI
);
69 tree
.setHeaderVisible(true);
70 tree
.setLayout(new GridLayout());
71 tree
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, true).span(3,1).create());
72 TreeColumn c1
= new TreeColumn(tree
,SWT
.NONE
);
73 c1
.setText(UIText
.ExistingOrNewPage_HeaderProject
);
75 TreeColumn c2
= new TreeColumn(tree
,SWT
.NONE
);
76 c2
.setText(UIText
.ExistingOrNewPage_HeaderPath
);
78 TreeColumn c3
= new TreeColumn(tree
,SWT
.NONE
);
79 c3
.setText(UIText
.ExistingOrNewPage_HeaderRepository
);
81 for (IProject project
: myWizard
.projects
) {
82 TreeItem treeItem
= new TreeItem(tree
, SWT
.NONE
);
83 treeItem
.setData(project
);
84 treeItem
.setText(0, project
.getName());
85 treeItem
.setText(1, project
.getLocation().toOSString());
86 RepositoryFinder repositoryFinder
= new RepositoryFinder(project
);
87 Collection
<RepositoryMapping
> find
;
89 find
= repositoryFinder
.find(new NullProgressMonitor());
91 treeItem
.setText(2, ""); //$NON-NLS-1$
93 Iterator
<RepositoryMapping
> mi
= find
.iterator();
94 RepositoryMapping m
= mi
.next();
95 if (m
.getGitDir() == null)
96 treeItem
.setText(2,UIText
.ExistingOrNewPage_SymbolicValueEmptyMapping
);
98 treeItem
.setText(2, m
.getGitDir());
99 while (mi
.hasNext()) {
100 TreeItem treeItem2
= new TreeItem(treeItem
, SWT
.NONE
);
101 if (m
.getGitDir() == null)
102 treeItem2
.setText(2,UIText
.ExistingOrNewPage_SymbolicValueEmptyMapping
);
104 treeItem2
.setText(2,m
.getGitDir());
107 } catch (CoreException e
) {
108 TreeItem treeItem2
= new TreeItem(treeItem
, SWT
.BOLD
|SWT
.ITALIC
);
109 treeItem2
.setText(e
.getMessage());
113 button
= new Button(g
, SWT
.PUSH
);
114 button
.setLayoutData(GridDataFactory
.fillDefaults().create());
115 button
.setText(UIText
.ExistingOrNewPage_CreateButton
);
116 button
.addSelectionListener(new SelectionListener() {
117 public void widgetSelected(SelectionEvent e
) {
118 File gitDir
= new File(repositoryToCreate
.getText(),".git");
120 Repository repository
= new Repository(gitDir
);
122 for (IProject project
: getProjects()) {
123 // If we don't refresh the project directories right
124 // now we won't later know that a .git directory
125 // exists within it and we won't mark the .git
126 // directory as a team-private member. Failure
127 // to do so might allow someone to delete
128 // the .git directory without us stopping them.
129 // (Half lie, we should optimize so we do not
130 // refresh when the .git is not within the project)
132 if (!gitDir
.toString().contains("..")) //$NON-NLS-1$
133 project
.refreshLocal(IResource
.DEPTH_ONE
,
134 new NullProgressMonitor());
136 } catch (IOException e1
) {
137 MessageDialog
.openError(getShell(), UIText
.ExistingOrNewPage_ErrorFailedToCreateRepository
, gitDir
.toString() + ":\n" + e1
.getMessage());
138 Activator
.logError("Failed to create repository at " + gitDir
, e1
); //$NON-NLS-1$
139 } catch (CoreException e2
) {
140 Activator
.logError(UIText
.ExistingOrNewPage_ErrorFailedToRefreshRepository
+ gitDir
, e2
);
142 for (TreeItem ti
: tree
.getSelection()) {
143 ti
.setText(2, gitDir
.toString());
145 updateCreateOptions();
146 getContainer().updateButtons();
148 public void widgetDefaultSelected(SelectionEvent e
) {
151 repositoryToCreate
= new Text(g
, SWT
.SINGLE
| SWT
.BORDER
);
152 repositoryToCreate
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, false).span(1,1).create());
153 repositoryToCreate
.addListener(SWT
.Modify
, new Listener() {
154 public void handleEvent(Event e
) {
157 IPath fromOSString
= Path
.fromOSString(e
.text
);
158 button
.setEnabled(minumumPath
159 .matchingFirstSegments(fromOSString
) == fromOSString
163 Text l
= new Text(g
,SWT
.NONE
);
165 l
.setEditable(false);
166 l
.setText(File
.separatorChar
+ ".git"); //$NON-NLS-1$
167 l
.setLayoutData(GridDataFactory
.fillDefaults().create());
168 tree
.addSelectionListener(new SelectionListener() {
169 public void widgetSelected(SelectionEvent e
) {
170 updateCreateOptions();
172 public void widgetDefaultSelected(SelectionEvent e
) {
176 updateCreateOptions();
180 private void updateCreateOptions() {
183 for (TreeItem ti
: tree
.getSelection()) {
184 String path
= ti
.getText(2);
185 if (!path
.equals("")) { //$NON-NLS-1$
189 String gitDirParentCandidate
= ti
.getText(1);
190 IPath thisPath
= Path
.fromOSString(gitDirParentCandidate
);
194 int n
= p
.matchingFirstSegments(thisPath
);
195 p
= p
.removeLastSegments(p
.segmentCount() - n
);
200 repositoryToCreate
.setText(p
.toOSString());
202 repositoryToCreate
.setText(""); //$NON-NLS-1$
204 button
.setEnabled(p
!= null);
205 repositoryToCreate
.setEnabled(p
!= null);
206 getContainer().updateButtons();
210 public boolean isPageComplete() {
211 if (tree
.getSelectionCount() == 0)
213 for (TreeItem ti
: tree
.getSelection()) {
214 String path
= ti
.getText(2);
215 if (path
.equals("")) { //$NON-NLS-1$
222 public IProject
[] getProjects() {
223 IProject
[] ret
= new IProject
[tree
.getSelection().length
];
224 for (int i
= 0; i
< ret
.length
; ++i
)
225 ret
[i
] = (IProject
)tree
.getSelection()[i
].getData();