From efa8d43adc065ce72910ee3555fb65a3782f5c1e Mon Sep 17 00:00:00 2001 From: Mathias Kinzler Date: Thu, 6 May 2010 09:54:12 +0200 Subject: [PATCH] Git Import Wizard This is the new Import wizard for importing Projects from Git. Similar to CVS, it first shows a list of Git Repositories. The user may select one from the list (the same list as shown in the Git Repositories View) and continues from there. Alternatively, the user can clone or add a Repository to the list. Then all continues like with the Import Projects... wizard used in the Git Repositories View. Bug: 281394 Change-Id: I7647bcbe7870500ef145b0100e5843d5b2930e94 Signed-off-by: Mathias Kinzler Signed-off-by: Chris Aniszczyk --- org.eclipse.egit.ui/plugin.properties | 4 +- org.eclipse.egit.ui/plugin.xml | 2 +- .../src/org/eclipse/egit/ui/UIText.java | 39 ++++ .../ui/internal/clone/CloneDestinationPage.java | 32 +-- .../egit/ui/internal/clone/GitCloneWizard.java | 70 +++---- .../clone/GitCreateGeneralProjectPage.java | 59 ++++-- .../clone/GitCreateProjectViaWizardWizard.java | 27 ++- .../ui/internal/clone/GitImportProjectsWizard.java | 65 ------ .../clone/GitImportWithDirectoriesPage.java | 138 ++++++++++++ ...ctViaWizardWizard.java => GitImportWizard.java} | 233 ++++++++++----------- .../ui/internal/clone/GitProjectsImportPage.java | 91 ++------ .../ui/internal/clone/GitSelectRepositoryPage.java | 180 ++++++++++++++++ .../ui/internal/clone/GitSelectWizardPage.java | 26 ++- .../ui/internal/clone/GitShareProjectsPage.java | 17 +- .../egit/ui/internal/clone/ProjectCreator.java | 25 +++ .../egit/ui/internal/clone/SourceBranchPage.java | 4 +- .../ui/internal/repository/RepositoriesView.java | 104 ++++++--- .../RepositoriesViewContentProvider.java | 26 +-- .../repository/RepositoriesViewLabelProvider.java | 6 +- .../repository/RepositorySearchDialog.java | 2 +- .../ui/internal/repository/RepositoryTreeNode.java | 120 +++++++++-- .../src/org/eclipse/egit/ui/uitext.properties | 19 +- 22 files changed, 826 insertions(+), 463 deletions(-) delete mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportProjectsWizard.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWithDirectoriesPage.java copy org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/{GitCreateProjectViaWizardWizard.java => GitImportWizard.java} (62%) create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectCreator.java diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index 0779d7d9..fdf95d2d 100644 --- a/org.eclipse.egit.ui/plugin.properties +++ b/org.eclipse.egit.ui/plugin.properties @@ -12,8 +12,8 @@ provider_name=Eclipse EGit Git=Git Git_clone_category=Git -Git_clone_wizard=Git Repository -Git_clone_description=Clone an existing Git repository. +Git_clone_wizard=Projects from Git +Git_clone_description=Import one or more projects from a Git Repository. SharingWizard_name=Git GitRemoteQuickDiffProvider_label=A Git Revision diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml index 2ec09608..ed36ab33 100644 --- a/org.eclipse.egit.ui/plugin.xml +++ b/org.eclipse.egit.ui/plugin.xml @@ -10,7 +10,7 @@ id="org.eclipse.egit.ui.internal.clone.gitclonecategory"/> %Git_clone_description diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index 29ee9765..12b71e57 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -250,6 +250,9 @@ public class UIText extends NLS { public static String GitProjectPropertyPage_ValueUnbornBranch; /** */ + public static String GitProjectsImportPage_NoProjectsMessage; + + /** */ public static String RepositoryPropertySource_ConfigureKeysAction; /** */ @@ -1750,6 +1753,42 @@ public class UIText extends NLS { public static String GitImportProjectsWizard_ImportExistingProjects0; /** */ + public static String GitImportWithDirectoriesPage_PageMessage; + + /** */ + public static String GitImportWithDirectoriesPage_PageTitle; + + /** */ + public static String GitImportWithDirectoriesPage_SelectFolderMessage; + + /** */ + public static String GitImportWizard_WizardTitle; + + /** */ + public static String GitSelectRepositoryPage_AddButton; + + /** */ + public static String GitSelectRepositoryPage_AddTooltip; + + /** */ + public static String GitSelectRepositoryPage_CloneButton; + + /** */ + public static String GitSelectRepositoryPage_CloneTooltip; + + /** */ + public static String GitSelectRepositoryPage_NoRepoFoundMessage; + + /** */ + public static String GitSelectRepositoryPage_PageMessage; + + /** */ + public static String GitSelectRepositoryPage_PageTitle; + + /** */ + public static String GitSelectRepositoryPage_PleaseSelectMessage; + + /** */ public static String GitSelectWizardPage_AutoShareButton; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java index a8491fd8..c9f16546 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java @@ -20,6 +20,8 @@ import org.eclipse.egit.ui.internal.components.RepositorySelection; import org.eclipse.egit.ui.internal.components.RepositorySelectionPage; import org.eclipse.egit.ui.internal.components.SelectionChangeListener; import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; @@ -35,8 +37,6 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.Ref; /** * Wizard page that allows the user entering the location of a repository to be @@ -59,10 +59,6 @@ class CloneDestinationPage extends WizardPage { private Text remoteText; - Button showImportWizard; - - String alreadyClonedInto; - CloneDestinationPage(final RepositorySelectionPage sp, final SourceBranchPage bp) { super(CloneDestinationPage.class.getName()); @@ -87,7 +83,6 @@ class CloneDestinationPage extends WizardPage { createDestinationGroup(panel); createConfigGroup(panel); - createWorkbenchGroup(panel); setControl(panel); checkPage(); } @@ -97,8 +92,6 @@ class CloneDestinationPage extends WizardPage { if (visible) { if (branchPage.isSourceRepoEmpty()) { initialBranch.setEnabled(false); - showImportWizard.setSelection(false); - showImportWizard.setEnabled(false); } revalidate(); } @@ -178,20 +171,6 @@ class CloneDestinationPage extends WizardPage { }); } - private void createWorkbenchGroup(Composite parent) { - final Group g = createGroup(parent, UIText.CloneDestinationPage_workspaceImport); - showImportWizard = new Button(g, SWT.CHECK); - showImportWizard.setSelection(true); - showImportWizard.setText(UIText.CloneDestinationPage_importProjectsAfterClone); - showImportWizard.setLayoutData(createFieldGridData()); - showImportWizard.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - checkPage(); - } - }); - } - private static Group createGroup(final Composite parent, final String text) { final Group g = new Group(parent, SWT.NONE); final GridLayout layout = new GridLayout(); @@ -249,8 +228,7 @@ class CloneDestinationPage extends WizardPage { return; } final File absoluteFile = new File(dstpath).getAbsoluteFile(); - if (!absoluteFile.getAbsolutePath().equals(alreadyClonedInto) - && !isEmptyDir(absoluteFile)) { + if (!isEmptyDir(absoluteFile)) { setErrorMessage(NLS.bind( UIText.CloneDestinationPage_errorNotEmptyDir, absoluteFile .getPath())); @@ -336,8 +314,4 @@ class CloneDestinationPage extends WizardPage { checkPage(); } - @Override - public boolean canFlipToNextPage() { - return super.canFlipToNextPage() && showImportWizard.getSelection(); - } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java index 4b15c40d..a9229e07 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java @@ -3,6 +3,7 @@ * Copyright (C) 2008, Shawn O. Pearce * Copyright (C) 2008, Marek Zawirski * Copyright (C) 2008, Robin Rosenberg + * Copyright (C) 2010, Mathias Kinzler * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -29,73 +30,63 @@ import org.eclipse.egit.ui.internal.repository.RepositoriesView; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.transport.URIish; import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IImportWizard; import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; /** * Import Git Repository Wizard. A front end to a git clone operation. */ -public class GitCloneWizard extends Wizard implements IImportWizard { +public class GitCloneWizard extends Wizard { private RepositorySelectionPage cloneSource; private SourceBranchPage validSource; private CloneDestinationPage cloneDestination; - private GitProjectsImportPage importProject; + String alreadyClonedInto; - public void init(IWorkbench arg0, IStructuredSelection arg1) { + /** + * The default constructor + */ + public GitCloneWizard() { setWindowTitle(UIText.GitCloneWizard_title); setDefaultPageImageDescriptor(UIIcons.WIZBAN_IMPORT_REPO); setNeedsProgressMonitor(true); cloneSource = new RepositorySelectionPage(true, null); validSource = new SourceBranchPage(cloneSource); cloneDestination = new CloneDestinationPage(cloneSource, validSource); - importProject = new GitProjectsImportPage() { - @Override - public void setVisible(boolean visible) { - if (visible) { - if (cloneDestination.alreadyClonedInto == null) { - if (performClone(false)) - cloneDestination.alreadyClonedInto = cloneDestination - .getDestinationFile().getAbsolutePath(); - } - setProjectsList(cloneDestination.alreadyClonedInto); - } - super.setVisible(visible); - } - }; } @Override public boolean performCancel() { - if (cloneDestination.alreadyClonedInto != null) { - if (MessageDialog - .openQuestion(getShell(), UIText.GitCloneWizard_abortingCloneTitle, + if (alreadyClonedInto != null) { + File test = new File(alreadyClonedInto); + if (test.exists() + && MessageDialog.openQuestion(getShell(), + UIText.GitCloneWizard_abortingCloneTitle, UIText.GitCloneWizard_abortingCloneMsg)) { - deleteRecursively(new File(cloneDestination.alreadyClonedInto)); + deleteRecursively(new File(alreadyClonedInto)); } } return true; } private void deleteRecursively(File f) { - for (File i : f.listFiles()) { - if (i.isDirectory()) { - deleteRecursively(i); - } else { - if (!i.delete()) { - i.deleteOnExit(); + File[] children = f.listFiles(); + if (children != null) + for (File i : children) { + if (i.isDirectory()) { + deleteRecursively(i); + } else { + if (!i.delete()) { + i.deleteOnExit(); + } } } - } if (!f.delete()) f.deleteOnExit(); } @@ -105,21 +96,16 @@ public class GitCloneWizard extends Wizard implements IImportWizard { addPage(cloneSource); addPage(validSource); addPage(cloneDestination); - addPage(importProject); } @Override public boolean canFinish() { - return cloneDestination.isPageComplete() - && !cloneDestination.showImportWizard.getSelection() - || importProject.isPageComplete(); + return cloneDestination.isPageComplete(); } @Override public boolean performFinish() { - if (!cloneDestination.showImportWizard.getSelection()) - return performClone(true); - return importProject.createProjects(); + return performClone(false); } boolean performClone(boolean background) { @@ -139,6 +125,7 @@ public class GitCloneWizard extends Wizard implements IImportWizard { final String remoteName = cloneDestination.getRemote(); workdir.mkdirs(); + if (!workdir.isDirectory()) { final String errorMessage = NLS.bind( UIText.GitCloneWizard_errorCannotCreate, workdir.getPath()); @@ -160,7 +147,9 @@ public class GitCloneWizard extends Wizard implements IImportWizard { final CloneOperation op = new CloneOperation(uri, allSelected, selectedBranches, workdir, branch, remoteName); - importProject.setGitDir(op.getGitDir()); + + alreadyClonedInto = workdir.getPath(); + if (background) { final Job job = new Job(NLS.bind(UIText.GitCloneWizard_jobName, uri .toString())) { @@ -196,8 +185,11 @@ public class GitCloneWizard extends Wizard implements IImportWizard { throws InvocationTargetException, InterruptedException { op.run(monitor); + if (monitor.isCanceled()) + throw new InterruptedException(); } }); + RepositorySelectionPage.saveUriInPrefs(uri.toString()); RepositoriesView.addDir(op.getGitDir()); if (view != null) diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateGeneralProjectPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateGeneralProjectPage.java index 9282ac93..77fc94b9 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateGeneralProjectPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateGeneralProjectPage.java @@ -17,6 +17,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; import org.eclipse.egit.ui.UIText; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.layout.GridDataFactory; @@ -35,12 +36,10 @@ import org.eclipse.swt.widgets.Text; * Allows to import a directory in the local file system as "General" project *

* Asks the user to provide a project name and shows the directory to be shared. - *

- * TODO String externalization */ public class GitCreateGeneralProjectPage extends WizardPage { - private final File myDirectory; + private File myDirectory; private Text projectText; @@ -62,6 +61,26 @@ public class GitCreateGeneralProjectPage extends WizardPage { setDescription(UIText.WizardProjectsImportPage_ImportProjectsDescription); } + /** + * The path must be initialized using setPath() + */ + public GitCreateGeneralProjectPage() { + super(GitCreateGeneralProjectPage.class.getName()); + setPageComplete(false); + setTitle(UIText.WizardProjectsImportPage_ImportProjectsTitle); + setDescription(UIText.WizardProjectsImportPage_ImportProjectsDescription); + } + + /** + * @param path + */ + public void setPath(String path) { + if (path != null) + myDirectory = new File(path); + else + myDirectory = null; + } + public void createControl(Composite parent) { initializeDialogUnits(parent); @@ -73,7 +92,8 @@ public class GitCreateGeneralProjectPage extends WizardPage { workArea.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); - new Label(workArea, SWT.NONE).setText(UIText.GitCreateGeneralProjectPage_ProjectNameLabel); + new Label(workArea, SWT.NONE) + .setText(UIText.GitCreateGeneralProjectPage_ProjectNameLabel); projectText = new Text(workArea, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).applyTo(projectText); projectText.addModifyListener(new ModifyListener() { @@ -83,7 +103,8 @@ public class GitCreateGeneralProjectPage extends WizardPage { } }); - new Label(workArea, SWT.NONE).setText(UIText.GitCreateGeneralProjectPage_DirLabel); + new Label(workArea, SWT.NONE) + .setText(UIText.GitCreateGeneralProjectPage_DirLabel); directoryText = new Text(workArea, SWT.BORDER); directoryText.setEnabled(false); GridDataFactory.fillDefaults().grab(true, false).applyTo(directoryText); @@ -115,13 +136,15 @@ public class GitCreateGeneralProjectPage extends WizardPage { try { // make sure the directory exists if (!myDirectory.exists()) { - setErrorMessage(NLS.bind(UIText.GitCreateGeneralProjectPage_DirNotExistMessage, + setErrorMessage(NLS.bind( + UIText.GitCreateGeneralProjectPage_DirNotExistMessage, myDirectory.getPath())); return; } // make sure we don't have a file if (!myDirectory.isDirectory()) { - setErrorMessage(NLS.bind(UIText.GitCreateGeneralProjectPage_FileNotDirMessage, + setErrorMessage(NLS.bind( + UIText.GitCreateGeneralProjectPage_FileNotDirMessage, myDirectory.getPath())); return; } @@ -134,9 +157,10 @@ public class GitCreateGeneralProjectPage extends WizardPage { return false; } }).length > 0) { - setErrorMessage(NLS.bind( - UIText.GitCreateGeneralProjectPage_FileExistsInDirMessage, - ".project", myDirectory.getPath())); //$NON-NLS-1$ + setErrorMessage(NLS + .bind( + UIText.GitCreateGeneralProjectPage_FileExistsInDirMessage, + ".project", myDirectory.getPath())); //$NON-NLS-1$ return; } // project name empty @@ -153,8 +177,19 @@ public class GitCreateGeneralProjectPage extends WizardPage { } // project already exists if (isProjectInWorkspace(projectName)) { - setErrorMessage(NLS.bind(UIText.GitCreateGeneralProjectPage_PorjectAlreadyExistsMessage, - projectName)); + setErrorMessage(NLS + .bind( + UIText.GitCreateGeneralProjectPage_PorjectAlreadyExistsMessage, + projectName)); + return; + } + IProject newProject = ResourcesPlugin.getWorkspace().getRoot() + .getProject(projectName); + IStatus locationResult = ResourcesPlugin.getWorkspace() + .validateProjectLocation(newProject, + new Path(myDirectory.getPath())); + if (!locationResult.isOK()) { + setErrorMessage(locationResult.getMessage()); return; } } finally { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java index 0068c41d..aa1bdb79 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java @@ -37,7 +37,8 @@ import org.eclipse.ui.actions.WorkspaceModifyOperation; /** * A wizard used to import existing projects from a {@link Repository} */ -public class GitCreateProjectViaWizardWizard extends Wizard { +public class GitCreateProjectViaWizardWizard extends Wizard implements + ProjectCreator { private final Repository myRepository; @@ -87,14 +88,10 @@ public class GitCreateProjectViaWizardWizard extends Wizard { addPage(mySelectionPage); myCreateGeneralProjectPage = new GitCreateGeneralProjectPage(myGitDir); addPage(myCreateGeneralProjectPage); - // for "Import Existing Projects" - // TODO new constructor with repository and directory once we - // remove this page from the GitCloneWizard - myProjectsImportPage = new GitProjectsImportPage(false) { + myProjectsImportPage = new GitProjectsImportPage() { @Override public void setVisible(boolean visible) { - setGitDir(myRepository.getDirectory()); setProjectsList(myGitDir); super.setVisible(visible); } @@ -165,11 +162,10 @@ public class GitCreateProjectViaWizardWizard extends Wizard { final int actionSelection = mySelectionPage.getActionSelection(); final IProject[] projectsToShare; - if (actionSelection != GitSelectWizardPage.ACTION_DIALOG_SHARE) { - projectsToShare = getAddedProjects(); - } else { + if (actionSelection == GitSelectWizardPage.ACTION_DIALOG_SHARE) projectsToShare = mySharePage.getSelectedProjects(); - } + else + projectsToShare = null; getContainer().run(true, true, new IRunnableWithProgress() { @@ -188,7 +184,12 @@ public class GitCreateProjectViaWizardWizard extends Wizard { if (actionSelection != GitSelectWizardPage.ACTION_NO_SHARE) { // TODO scheduling rule? - for (IProject prj : projectsToShare) { + IProject[] projects; + if (projectsToShare == null) + projects = getAddedProjects(); + else + projects = projectsToShare; + for (IProject prj : projects) { if (monitor.isCanceled()) throw new InterruptedException(); // @@ -283,10 +284,6 @@ public class GitCreateProjectViaWizardWizard extends Wizard { }); } - /** - * @return the projects added to the workspace since the start of this - * wizard - */ public IProject[] getAddedProjects() { IProject[] currentProjects = ResourcesPlugin.getWorkspace().getRoot() diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportProjectsWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportProjectsWizard.java deleted file mode 100644 index 99926d38..00000000 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportProjectsWizard.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 SAP AG. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathias Kinzler (SAP AG) - initial implementation - *******************************************************************************/ -package org.eclipse.egit.ui.internal.clone; - -import java.io.File; - -import org.eclipse.egit.ui.UIText; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jgit.lib.Repository; - -/** - * A wizard used to import existing projects from a {@link Repository} - */ -public class GitImportProjectsWizard extends Wizard { - - private final String myWorkingDir; - - private final File myGitDir; - - /** - * @param repository - * the repository - * @param path - * a path, either the working directory of the repository or a - * sub-directory thereof - */ - public GitImportProjectsWizard(Repository repository, String path) { - super(); - myWorkingDir = path; - myGitDir = repository.getDirectory(); - setWindowTitle(UIText.GitImportProjectsWizard_ImportExistingProjects0); - } - - @Override - public void addPages() { - - GitProjectsImportPage page = new GitProjectsImportPage() { - - @Override - public void setVisible(boolean visible) { - setGitDir(myGitDir); - setProjectsList(myWorkingDir); - super.setVisible(visible); - } - - }; - addPage(page); - } - - @Override - public boolean performFinish() { - GitProjectsImportPage page = (GitProjectsImportPage) getPages()[0]; - return page.createProjects(); - - } - -} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWithDirectoriesPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWithDirectoriesPage.java new file mode 100644 index 00000000..5db5551f --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWithDirectoriesPage.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2010 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathias Kinzler (SAP AG) - initial implementation + *******************************************************************************/ +package org.eclipse.egit.ui.internal.clone; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider; +import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider; +import org.eclipse.egit.ui.internal.repository.RepositoryTreeNode; +import org.eclipse.egit.ui.internal.repository.RepositoryTreeNode.RepositoryTreeNodeType; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Composite; + +/** + * Select a wizard and a directory from a Git Working Directory + */ +public class GitImportWithDirectoriesPage extends GitSelectWizardPage { + + private TreeViewer tv; + + /** + * + */ + public GitImportWithDirectoriesPage() { + super(); + setTitle(UIText.GitImportWithDirectoriesPage_PageTitle); + setMessage(UIText.GitImportWithDirectoriesPage_PageMessage); + } + + /** + * @param repo + */ + public void setRepository(Repository repo) { + List> input = new ArrayList>(); + if (repo != null) + input.add(new RepositoryTreeNode(null, + RepositoryTreeNodeType.WORKINGDIR, repo, repo)); + tv.setInput(input); + // select the working directory as default + tv.setSelection(new StructuredSelection(input.get(0))); + } + + public void createControl(Composite parent) { + super.createControl(parent); + + Composite main = (Composite) getControl(); + + tv = new TreeViewer(main, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.BORDER); + tv.setContentProvider(new RepositoriesViewContentProvider()); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tv.getTree()); + new RepositoriesViewLabelProvider(tv); + + SelectionListener sl = new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + tv.getTree().setEnabled(!newProjectWizard.getSelection()); + } + + }; + + generalWizard.addSelectionListener(sl); + importExisting.addSelectionListener(sl); + newProjectWizard.addSelectionListener(sl); + + tv.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + checkPage(); + } + }); + + checkPage(); + setControl(main); + } + + /** + * @return the selected path + */ + public String getPath() { + IStructuredSelection sel = (IStructuredSelection) tv.getSelection(); + RepositoryTreeNode node = (RepositoryTreeNode) sel.getFirstElement(); + if (node != null && node.getType() == RepositoryTreeNodeType.FOLDER) + return ((File) node.getObject()).getPath(); + if (node != null && node.getType() == RepositoryTreeNodeType.WORKINGDIR) + return node.getRepository().getWorkDir().getPath(); + return null; + } + + protected void checkPage() { + super.checkPage(); + if (getErrorMessage() != null) + return; + + if (newProjectWizard.getSelection()) + return; + + IStructuredSelection sel = (IStructuredSelection) tv.getSelection(); + try { + if (sel.isEmpty()) { + setErrorMessage(UIText.GitImportWithDirectoriesPage_SelectFolderMessage); + return; + } + RepositoryTreeNode node = (RepositoryTreeNode) sel + .getFirstElement(); + if (node.getType() != RepositoryTreeNodeType.FOLDER + && node.getType() != RepositoryTreeNodeType.WORKINGDIR) { + setErrorMessage(UIText.GitImportWithDirectoriesPage_SelectFolderMessage); + return; + } + } finally { + setPageComplete(getErrorMessage() == null); + } + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java similarity index 62% copy from org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java copy to org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java index 0068c41d..11170834 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.clone; +import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; @@ -23,153 +24,69 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.egit.core.op.ConnectProviderOperation; import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIIcons; import org.eclipse.egit.ui.UIText; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.NewWizardAction; import org.eclipse.ui.actions.WorkspaceModifyOperation; /** - * A wizard used to import existing projects from a {@link Repository} + * The import wizard including options to clone/add repositories */ -public class GitCreateProjectViaWizardWizard extends Wizard { - - private final Repository myRepository; - - private final String myGitDir; +public class GitImportWizard extends Wizard implements ProjectCreator, + IImportWizard { private final IProject[] previousProjects; - private GitSelectWizardPage mySelectionPage; + private GitSelectRepositoryPage selectRepoPage = new GitSelectRepositoryPage(); + + private GitImportWithDirectoriesPage importWithDirectoriesPage = new GitImportWithDirectoriesPage(); - private GitCreateGeneralProjectPage myCreateGeneralProjectPage; + private GitProjectsImportPage projectsImportPage = new GitProjectsImportPage(); - private GitProjectsImportPage myProjectsImportPage; + private GitCreateGeneralProjectPage createGeneralProjectPage = new GitCreateGeneralProjectPage(); - private GitShareProjectsPage mySharePage; + private GitShareProjectsPage shareProjectsPage = new GitShareProjectsPage(); /** - * @param repository - * @param path + * Default constructor */ - public GitCreateProjectViaWizardWizard(Repository repository, String path) { - super(); + public GitImportWizard() { + setWindowTitle(UIText.GitImportWizard_WizardTitle); + setDefaultPageImageDescriptor(UIIcons.WIZBAN_IMPORT_REPO); previousProjects = ResourcesPlugin.getWorkspace().getRoot() .getProjects(); - myRepository = repository; - myGitDir = path; - setWindowTitle(NLS.bind( - UIText.GitCreateProjectViaWizardWizard_WizardTitle, - myRepository.getDirectory().getPath())); - - // the "Import" wizard could be started like this, - // but throws an Exception if started within a wizard - // context (no active workbench window found) and the - // list of available wizards is empty - // -> investigate if we can include that wizard - // - // IHandlerService handlerService = (IHandlerService) - // PlatformUI.getWorkbench().getService(IHandlerService.class); - // - // handlerService.executeCommand("org.eclipse.ui.file.import", - } @Override public void addPages() { - - mySelectionPage = new GitSelectWizardPage(); - addPage(mySelectionPage); - myCreateGeneralProjectPage = new GitCreateGeneralProjectPage(myGitDir); - addPage(myCreateGeneralProjectPage); - // for "Import Existing Projects" - // TODO new constructor with repository and directory once we - // remove this page from the GitCloneWizard - myProjectsImportPage = new GitProjectsImportPage(false) { - - @Override - public void setVisible(boolean visible) { - setGitDir(myRepository.getDirectory()); - setProjectsList(myGitDir); - super.setVisible(visible); - } - - }; - addPage(myProjectsImportPage); - mySharePage = new GitShareProjectsPage(); - addPage(mySharePage); - } - - @Override - public IWizardPage getNextPage(IWizardPage page) { - - if (page == mySelectionPage) { - - switch (mySelectionPage.getWizardSelection()) { - case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: - return myProjectsImportPage; - case GitSelectWizardPage.NEW_WIZARD: - if (mySelectionPage.getActionSelection() != GitSelectWizardPage.ACTION_DIALOG_SHARE) - return null; - else - return mySharePage; - - case GitSelectWizardPage.GENERAL_WIZARD: - return myCreateGeneralProjectPage; - - } - - return super.getNextPage(page); - - } else if (page == myCreateGeneralProjectPage - || page == myProjectsImportPage) { - - if (mySelectionPage.getActionSelection() != GitSelectWizardPage.ACTION_DIALOG_SHARE) - return null; - else - return mySharePage; - } - return super.getNextPage(page); - } - - @Override - public boolean canFinish() { - - boolean showSharePage = mySelectionPage.getActionSelection() == GitSelectWizardPage.ACTION_DIALOG_SHARE; - boolean showShareComplete = !showSharePage - || mySharePage.isPageComplete(); - - switch (mySelectionPage.getWizardSelection()) { - case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: - return myProjectsImportPage.isPageComplete() && showShareComplete; - case GitSelectWizardPage.NEW_WIZARD: - return showShareComplete; - case GitSelectWizardPage.GENERAL_WIZARD: - return myCreateGeneralProjectPage.isPageComplete() - && showShareComplete; - } - return super.canFinish(); - + addPage(selectRepoPage); + addPage(importWithDirectoriesPage); + addPage(projectsImportPage); + addPage(createGeneralProjectPage); + addPage(shareProjectsPage); } @Override public boolean performFinish() { - try { - - final int actionSelection = mySelectionPage.getActionSelection(); + final int actionSelection = importWithDirectoriesPage + .getActionSelection(); final IProject[] projectsToShare; - if (actionSelection != GitSelectWizardPage.ACTION_DIALOG_SHARE) { - projectsToShare = getAddedProjects(); - } else { - projectsToShare = mySharePage.getSelectedProjects(); - } + if (actionSelection == GitSelectWizardPage.ACTION_DIALOG_SHARE) + projectsToShare = shareProjectsPage.getSelectedProjects(); + else + projectsToShare = null; + + final File repoDir = selectRepoPage.getRepository().getDirectory(); getContainer().run(true, true, new IRunnableWithProgress() { @@ -188,12 +105,17 @@ public class GitCreateProjectViaWizardWizard extends Wizard { if (actionSelection != GitSelectWizardPage.ACTION_NO_SHARE) { // TODO scheduling rule? - for (IProject prj : projectsToShare) { + IProject[] projects; + if (projectsToShare == null) + projects = getAddedProjects(); + else + projects = projectsToShare; + for (IProject prj : projects) { if (monitor.isCanceled()) throw new InterruptedException(); // ConnectProviderOperation connectProviderOperation = new ConnectProviderOperation( - prj, myRepository.getDirectory()); + prj, repoDir); try { connectProviderOperation.execute(monitor); } catch (CoreException e) { @@ -216,22 +138,74 @@ public class GitCreateProjectViaWizardWizard extends Wizard { return false; } return true; + } + + @Override + public IWizardPage getNextPage(IWizardPage page) { + if (page == selectRepoPage) { + importWithDirectoriesPage.setRepository(selectRepoPage + .getRepository()); + return importWithDirectoriesPage; + } else if (page == importWithDirectoriesPage) { + + switch (importWithDirectoriesPage.getWizardSelection()) { + case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: + projectsImportPage.setProjectsList(importWithDirectoriesPage + .getPath()); + return projectsImportPage; + case GitSelectWizardPage.NEW_WIZARD: + if (importWithDirectoriesPage.getActionSelection() != GitSelectWizardPage.ACTION_DIALOG_SHARE) + return null; + else + return shareProjectsPage; + case GitSelectWizardPage.GENERAL_WIZARD: + createGeneralProjectPage.setPath(importWithDirectoriesPage + .getPath()); + return createGeneralProjectPage; + + } + + } else if (page == createGeneralProjectPage + || page == projectsImportPage) { + + if (importWithDirectoriesPage.getActionSelection() != GitSelectWizardPage.ACTION_DIALOG_SHARE) + return null; + else + return shareProjectsPage; + } + return super.getNextPage(page); } - /** - * - */ - public void importProjects() { + @Override + public boolean canFinish() { + + boolean showSharePage = importWithDirectoriesPage.getActionSelection() == GitSelectWizardPage.ACTION_DIALOG_SHARE; + boolean showShareComplete = !showSharePage + || shareProjectsPage.isPageComplete(); + + switch (importWithDirectoriesPage.getWizardSelection()) { + case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: + return projectsImportPage.isPageComplete() && showShareComplete; + case GitSelectWizardPage.NEW_WIZARD: + return showShareComplete; + case GitSelectWizardPage.GENERAL_WIZARD: + return createGeneralProjectPage.isPageComplete() + && showShareComplete; + } + return super.canFinish(); + + } + public void importProjects() { // TODO progress monitoring and cancellation Display.getDefault().syncExec(new Runnable() { public void run() { - switch (mySelectionPage.getWizardSelection()) { + switch (importWithDirectoriesPage.getWizardSelection()) { case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: - myProjectsImportPage.createProjects(); + projectsImportPage.createProjects(); break; case GitSelectWizardPage.NEW_WIZARD: new NewWizardAction(PlatformUI.getWorkbench() @@ -239,8 +213,10 @@ public class GitCreateProjectViaWizardWizard extends Wizard { break; case GitSelectWizardPage.GENERAL_WIZARD: try { - final String projectName = myCreateGeneralProjectPage + + final String projectName = createGeneralProjectPage .getProjectName(); + final String path = importWithDirectoriesPage.getPath(); getContainer().run(true, false, new WorkspaceModifyOperation() { @@ -255,7 +231,7 @@ public class GitCreateProjectViaWizardWizard extends Wizard { .getWorkspace() .newProjectDescription( projectName); - desc.setLocation(new Path(myGitDir)); + desc.setLocation(new Path(path)); IProject prj = ResourcesPlugin .getWorkspace().getRoot() @@ -281,12 +257,9 @@ public class GitCreateProjectViaWizardWizard extends Wizard { } } }); + } - /** - * @return the projects added to the workspace since the start of this - * wizard - */ public IProject[] getAddedProjects() { IProject[] currentProjects = ResourcesPlugin.getWorkspace().getRoot() @@ -310,4 +283,8 @@ public class GitCreateProjectViaWizardWizard extends Wizard { return newProjects.toArray(new IProject[0]); } + public void init(IWorkbench workbench, IStructuredSelection selection) { + // nothing to do + } + } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java index 69095bff..cf3ae8f1 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java @@ -37,7 +37,6 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.egit.core.op.ConnectProviderOperation; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.UIText; import org.eclipse.jface.dialogs.Dialog; @@ -83,8 +82,6 @@ public class GitProjectsImportPage extends WizardPage { private IImportStructureProvider structureProvider; - private File gitRepositoryDir; - class ProjectRecord { File projectSystemFile; @@ -204,35 +201,20 @@ public class GitProjectsImportPage extends WizardPage { // to minimize searches private long lastModified; - private Button shareCheckBox; - private Button selectAll; private Button deselectAll; - private boolean share; - - private final boolean showShare; - /** * Creates a new project creation wizard page. - * @param showShareCheckbox */ - public GitProjectsImportPage(boolean showShareCheckbox) { - super("gitWizardExternalProjectsPage"); //$NON-NLS-1$ - this.showShare = showShareCheckbox; + public GitProjectsImportPage() { + super(GitProjectsImportPage.class.getName()); setPageComplete(false); setTitle(UIText.WizardProjectsImportPage_ImportProjectsTitle); setDescription(UIText.WizardProjectsImportPage_ImportProjectsDescription); } - /** - * - */ - public GitProjectsImportPage(){ - this(true); - } - public void createControl(Composite parent) { initializeDialogUnits(parent); @@ -246,37 +228,11 @@ public class GitProjectsImportPage extends WizardPage { createProjectsRoot(workArea); createProjectsList(workArea); - createOptionsArea(workArea); Dialog.applyDialogFont(workArea); } /** - * Create the area with the extra options. - * - * @param workArea - */ - private void createOptionsArea(Composite workArea) { - Composite optionsGroup = new Composite(workArea, SWT.NONE); - optionsGroup.setLayout(new GridLayout()); - optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - if (showShare) { - shareCheckBox = new Button(optionsGroup, SWT.CHECK); - shareCheckBox.setText(UIText.WizardProjectsImportPage_enableGit); - shareCheckBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - shareCheckBox.setSelection(share = true); - shareCheckBox.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - share = shareCheckBox.getSelection(); - } - }); - } else { - share = false; - } - } - - /** * Create the checkbox list for the found projects. * * @param workArea @@ -325,7 +281,8 @@ public class GitProjectsImportPage extends WizardPage { } }; - + // we have to use the old constructor in order to be 3.4 compatible + // TODO once we drop 3.4 support, we should change to the new constructor FilteredTree filteredTree = new FilteredTree(listComposite, SWT.CHECK | SWT.BORDER, filter); filteredTree.setInitialText(UIText.WizardProjectsImportPage_filterText); @@ -353,11 +310,12 @@ public class GitProjectsImportPage extends WizardPage { } public void dispose() { - + // ignore } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // ignore } }); @@ -470,15 +428,6 @@ public class GitProjectsImportPage extends WizardPage { } /** - * Set the git directory which will contain the repository - * - * @param gitDir - */ - public void setGitDir(File gitDir) { - this.gitRepositoryDir = gitDir; - } - - /** * Update the list of projects based on path. This will not check any * projects. * @@ -487,11 +436,11 @@ public class GitProjectsImportPage extends WizardPage { void setProjectsList(final String path) { // on an empty path empty selectedProjects if (path == null || path.length() == 0) { - setMessage(UIText.WizardProjectsImportPage_ImportProjectsDescription); selectedProjects = new ProjectRecord[0]; projectsList.refresh(true); setPageComplete(checkedItems.size() > 0); lastPath = path; + setErrorMessage(UIText.GitProjectsImportPage_NoProjectsMessage); return; } @@ -503,6 +452,8 @@ public class GitProjectsImportPage extends WizardPage { return; } + setErrorMessage(null); + lastPath = path; lastModified = modified; @@ -535,6 +486,9 @@ public class GitProjectsImportPage extends WizardPage { checkedItems.add(selectedProjects[index]); index++; } + + if (files.isEmpty()) + setErrorMessage(UIText.GitProjectsImportPage_NoProjectsMessage); } else { monitor.worked(60); } @@ -560,7 +514,7 @@ public class GitProjectsImportPage extends WizardPage { } private void enableSelectAllButtons() { - if (projectsList.getTree().getItemCount()>0){ + if (projectsList.getTree().getItemCount() > 0) { selectAll.setEnabled(true); deselectAll.setEnabled(true); } else { @@ -601,8 +555,8 @@ public class GitProjectsImportPage extends WizardPage { directoriesVisited.add(directory.getCanonicalPath()); } catch (IOException exception) { StatusManager.getManager().handle( - new Status(IStatus.ERROR, Activator.getPluginId(), exception - .getLocalizedMessage(), exception)); + new Status(IStatus.ERROR, Activator.getPluginId(), + exception.getLocalizedMessage(), exception)); } } @@ -629,7 +583,8 @@ public class GitProjectsImportPage extends WizardPage { } } catch (IOException exception) { StatusManager.getManager().handle( - new Status(IStatus.ERROR, Activator.getPluginId(), exception + new Status(IStatus.ERROR, Activator + .getPluginId(), exception .getLocalizedMessage(), exception)); } @@ -674,7 +629,8 @@ public class GitProjectsImportPage extends WizardPage { } catch (InvocationTargetException e) { // one of the steps resulted in a core exception Throwable t = e.getTargetException(); - Activator.handleError(UIText.WizardProjectImportPage_errorMessage, t, true); + Activator.handleError(UIText.WizardProjectImportPage_errorMessage, + t, true); return false; } return true; @@ -716,15 +672,8 @@ public class GitProjectsImportPage extends WizardPage { UIText.WizardProjectsImportPage_CreateProjectsTask, 100); project.create(record.description, new SubProgressMonitor(monitor, 30)); - int openTicks = share ? 50 : 70; project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor( - monitor, openTicks)); - if (share) { - ConnectProviderOperation connectProviderOperation = new ConnectProviderOperation( - project, gitRepositoryDir); - connectProviderOperation - .execute(new SubProgressMonitor(monitor, 20)); - } + monitor, 50)); } catch (CoreException e) { throw new InvocationTargetException(e); } finally { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java new file mode 100644 index 00000000..305fc27f --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2010 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathias Kinzler (SAP AG) - initial implementation + *******************************************************************************/ +package org.eclipse.egit.ui.internal.clone; + +import java.io.File; +import java.util.List; +import java.util.Set; + +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.internal.repository.RepositoriesView; +import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider; +import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider; +import org.eclipse.egit.ui.internal.repository.RepositorySearchDialog; +import org.eclipse.egit.ui.internal.repository.RepositoryTreeNode; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; + +/** + * Select a repository, add or clone + */ +public class GitSelectRepositoryPage extends WizardPage { + + private TableViewer tv; + + private Button addRepo; + + private Button cloneRepo; + + /** + * + */ + public GitSelectRepositoryPage() { + super(GitSelectRepositoryPage.class.getName()); + setTitle(UIText.GitSelectRepositoryPage_PageTitle); + setMessage(UIText.GitSelectRepositoryPage_PageMessage); + } + + /** + * @return the repository + */ + public Repository getRepository() { + Object obj = ((IStructuredSelection) tv.getSelection()) + .getFirstElement(); + if (obj == null) + return null; + return ((RepositoryTreeNode) obj).getRepository(); + } + + public void createControl(Composite parent) { + Composite main = new Composite(parent, SWT.NONE); + + GridLayoutFactory.fillDefaults().numColumns(2).margins(0, 0).applyTo( + main); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(main); + + tv = new TableViewer(main, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.BORDER); + tv.setContentProvider(new RepositoriesViewContentProvider()); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tv.getTable()); + new RepositoriesViewLabelProvider(tv); + + Composite tb = new Composite(main, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(tb); + GridDataFactory.fillDefaults().grab(false, true).applyTo(tb); + + cloneRepo = new Button(tb, SWT.PUSH); + cloneRepo.setText(UIText.GitSelectRepositoryPage_CloneButton); + cloneRepo + .setToolTipText(UIText.GitSelectRepositoryPage_CloneTooltip); + + GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, + SWT.BEGINNING).applyTo(cloneRepo); + + cloneRepo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + WizardDialog dlg = new WizardDialog(getShell(), + new GitCloneWizard()); + + if (dlg.open() == Window.OK) { + try { + tv.setInput(RepositoriesView + .getRepositoriesFromDirs(null)); + checkPage(); + } catch (InterruptedException e1) { + // ignore + } + } + } + + }); + + addRepo = new Button(tb, SWT.PUSH); + GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, + SWT.BEGINNING).applyTo(addRepo); + addRepo.setText(UIText.GitSelectRepositoryPage_AddButton); + addRepo + .setToolTipText(UIText.GitSelectRepositoryPage_AddTooltip); + addRepo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + RepositorySearchDialog dlg = new RepositorySearchDialog( + getShell(), RepositoriesView.getDirs()); + if (dlg.open() == Window.OK && dlg.getDirectories().size() > 0) { + try { + Set dirs = dlg.getDirectories(); + for (String dir : dirs) + RepositoriesView.addDir(new File(dir)); + + tv.setInput(RepositoriesView + .getRepositoriesFromDirs(null)); + checkPage(); + } catch (InterruptedException e1) { + // ignore + } + } + } + + }); + + tv.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + checkPage(); + } + }); + + try { + tv.setInput(RepositoriesView.getRepositoriesFromDirs(null)); + checkPage(); + } catch (InterruptedException e) { + // ignore + } + + setControl(main); + + } + + private void checkPage() { + setErrorMessage(null); + try { + if (((List) tv.getInput()).isEmpty()) { + setErrorMessage(UIText.GitSelectRepositoryPage_NoRepoFoundMessage); + return; + } + + if (tv.getSelection().isEmpty()) { + setErrorMessage(UIText.GitSelectRepositoryPage_PleaseSelectMessage); + return; + } + } finally { + setPageComplete(getErrorMessage() == null); + } + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java index 5217deb6..47aa5d75 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java @@ -51,9 +51,9 @@ public class GitSelectWizardPage extends WizardPage { /** */ public static final int ACTION_NO_SHARE = 2; - private static final String PREF_WIZ = "GitSelectWizardPageWizardSel"; //$NON-NLS-1$ + private final String PREF_WIZ = getName() + "WizardSel"; //$NON-NLS-1$ - private static final String PREF_ACT = "GitSelectWizardPageActionSel"; //$NON-NLS-1$ + private final String PREF_ACT = getName() + "ActionSel"; //$NON-NLS-1$ Button importExisting; @@ -75,6 +75,14 @@ public class GitSelectWizardPage extends WizardPage { setTitle(UIText.GitSelectWizardPage_WizardTitle); } + /** + * @param name + * the page name + */ + protected GitSelectWizardPage(String name) { + super(name); + } + public void createControl(Composite parent) { Composite main = new Composite(parent, SWT.NO_RADIO_GROUP); @@ -99,7 +107,8 @@ public class GitSelectWizardPage extends WizardPage { importExisting.addSelectionListener(sl); newProjectWizard = new Button(wizardType, SWT.RADIO); - newProjectWizard.setText(UIText.GitSelectWizardPage_UseNewProjectsWizardButton); + newProjectWizard + .setText(UIText.GitSelectWizardPage_UseNewProjectsWizardButton); newProjectWizard.addSelectionListener(sl); generalWizard = new Button(wizardType, SWT.RADIO); @@ -114,12 +123,12 @@ public class GitSelectWizardPage extends WizardPage { afterImportAction.setLayout(new GridLayout(1, false)); actionAutoShare = new Button(afterImportAction, SWT.RADIO); - actionAutoShare - .setText(UIText.GitSelectWizardPage_AutoShareButton); + actionAutoShare.setText(UIText.GitSelectWizardPage_AutoShareButton); actionAutoShare.addSelectionListener(sl); actionDialogShare = new Button(afterImportAction, SWT.RADIO); - actionDialogShare.setText(UIText.GitSelectWizardPage_InteractiveShareButton); + actionDialogShare + .setText(UIText.GitSelectWizardPage_InteractiveShareButton); actionDialogShare.addSelectionListener(sl); actionNothing = new Button(afterImportAction, SWT.RADIO); @@ -194,7 +203,10 @@ public class GitSelectWizardPage extends WizardPage { return -1; } - private void checkPage() { + /** + * check routine + */ + protected void checkPage() { // we save the selected radio button in the preferences IDialogSettings settings = Activator.getDefault().getDialogSettings(); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitShareProjectsPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitShareProjectsPage.java index 3aef17ca..6debfadd 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitShareProjectsPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitShareProjectsPage.java @@ -150,7 +150,7 @@ public class GitShareProjectsPage extends WizardPage { if (visible) { // when this becomes visible, we have to ask the wizard to import // the projects - final GitCreateProjectViaWizardWizard wiz = (GitCreateProjectViaWizardWizard) getWizard(); + final ProjectCreator wiz = (ProjectCreator) getWizard(); // TODO scheduling rule try { getContainer().run(false, true, new IRunnableWithProgress() { @@ -167,7 +167,8 @@ public class GitShareProjectsPage extends WizardPage { Activator.handleError(e.getCause().getMessage(), e.getCause(), true); } catch (InterruptedException e) { - Activator.handleError(UIText.GitShareProjectsPage_AbortedMessage, e, true); + Activator.handleError( + UIText.GitShareProjectsPage_AbortedMessage, e, true); } setProjects(wiz.getAddedProjects()); @@ -229,13 +230,17 @@ public class GitShareProjectsPage extends WizardPage { for (Object obj : selected) { IProject prj = (IProject) obj; if (getRepository(prj) == null) { - setErrorMessage(NLS.bind( - UIText.GitShareProjectsPage_NoRepoForProjectMessage, prj.getName())); + setErrorMessage(NLS + .bind( + UIText.GitShareProjectsPage_NoRepoForProjectMessage, + prj.getName())); return; } if (RepositoryProvider.getProvider(prj) != null) - setErrorMessage(NLS.bind(UIText.GitShareProjectsPage_ProjectAlreadySharedMessage, prj - .getName())); + setErrorMessage(NLS + .bind( + UIText.GitShareProjectsPage_ProjectAlreadySharedMessage, + prj.getName())); } } finally { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectCreator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectCreator.java new file mode 100644 index 00000000..700b0e3d --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectCreator.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathias Kinzler (SAP AG) - initial implementation + *******************************************************************************/ +package org.eclipse.egit.ui.internal.clone; + +import org.eclipse.core.resources.IProject; + +/** + * Helper interface for the wizards + * + */ +interface ProjectCreator { + + public void importProjects(); + + public IProject[] getAddedProjects(); + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java index 7f91f0bf..e1af8973 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java @@ -99,8 +99,8 @@ class SourceBranchPage extends BaseWizardPage { return availableRefs.size() == selectedRefs.size(); } - boolean selectionEquals(final List selectedRefs, final Ref head) { - return this.selectedRefs.equals(selectedRefs) && this.head == head; + boolean selectionEquals(final List actSelectedRef, final Ref actHead) { + return this.selectedRefs.equals(actSelectedRef) && this.head == actHead; } public void createControl(final Composite parent) { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java index 629a2326..da2e7c1a 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java @@ -167,7 +167,12 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, private IAction linkWithSelectionAction; - private static List getDirs() { + /** + * TODO move to utility class + * + * @return the directories as configured for this view + */ + public static List getDirs() { List resultStrings = new ArrayList(); String dirs = getPrefs().get(PREFS_DIRECTORIES, ""); //$NON-NLS-1$ if (dirs != null && dirs.length() > 0) { @@ -475,7 +480,8 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, ConnectProviderOperation connectProviderOperation = new ConnectProviderOperation( project, gitDir); connectProviderOperation - .execute(new SubProgressMonitor(monitor, 20)); + .execute(new SubProgressMonitor( + monitor, 20)); } @@ -530,9 +536,7 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, @Override public void widgetSelected(SelectionEvent e) { - checkoutBranch(node, ref.getLeaf().getName()); - } }); @@ -1280,9 +1284,10 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, @Override public void run() { - GitCloneWizard wiz = new GitCloneWizard(); - wiz.init(null, null); - new WizardDialog(getSite().getShell(), wiz).open(); + WizardDialog dlg = new WizardDialog(getSite().getShell(), + new GitCloneWizard()); + if (dlg.open() == Window.OK) + scheduleRefresh(); } }; importAction.setToolTipText(UIText.RepositoriesView_Clone_Tooltip); @@ -1402,7 +1407,7 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, @Override protected IStatus run(IProgressMonitor monitor) { - final List input; + final List> input; try { input = getRepositoriesFromDirs(monitor); } catch (InterruptedException e) { @@ -1410,6 +1415,21 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, .getMessage(), e); } + boolean needsNewInput = tv.getInput() == null; + List oldInput = (List) tv.getInput(); + if (!needsNewInput) + needsNewInput = oldInput.size() != input.size(); + + if (!needsNewInput) { + for (int i = 0; i < input.size(); i++) { + needsNewInput = !input.get(i).equals(oldInput.get(i)); + if (needsNewInput) + break; + } + } + + final boolean updateInput = needsNewInput; + Display.getDefault().syncExec(new Runnable() { public void run() { @@ -1419,7 +1439,10 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, Object[] expanded = tv.getExpandedElements(); IStructuredSelection sel = (IStructuredSelection) tv .getSelection(); - tv.setInput(input); + if (updateInput) + tv.setInput(input); + else + tv.refresh(); tv.setExpandedElements(expanded); Object selected = sel.getFirstElement(); @@ -1454,30 +1477,6 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, } - private List getRepositoriesFromDirs(IProgressMonitor monitor) - throws InterruptedException { - - List gitDirStrings = getDirs(); - List input = new ArrayList(); - for (String dirString : gitDirStrings) { - if (monitor.isCanceled()) { - throw new InterruptedException( - UIText.RepositoriesView_ActionCanceled_Message); - } - try { - File dir = new File(dirString); - if (dir.exists() && dir.isDirectory()) { - input.add(new Repository(dir)); - } - } catch (IOException e) { - IStatus error = new Status(IStatus.ERROR, Activator - .getPluginId(), e.getMessage(), e); - Activator.getDefault().getLog().log(error); - } - } - return input; - } - /** * Adds a directory to the list if it is not already there * @@ -1505,6 +1504,45 @@ public class RepositoriesView extends ViewPart implements ISelectionProvider, } } + /** + * Converts the directories as configured for this view into a list of + * {@link Repository} objects suitable for the tree content provider + *

+ * TODO move to some utility class + * + * @param monitor + * @return a list of nodes + * @throws InterruptedException + */ + public static List> getRepositoriesFromDirs( + IProgressMonitor monitor) throws InterruptedException { + + List gitDirStrings = getDirs(); + List> input = new ArrayList>(); + + for (String dirString : gitDirStrings) { + if (monitor != null && monitor.isCanceled()) { + throw new InterruptedException( + UIText.RepositoriesView_ActionCanceled_Message); + } + try { + File dir = new File(dirString); + if (dir.exists() && dir.isDirectory()) { + Repository repo = new Repository(dir); + RepositoryTreeNode node = new RepositoryTreeNode( + null, RepositoryTreeNodeType.REPO, repo, repo); + input.add(node); + } + } catch (IOException e) { + IStatus error = new Status(IStatus.ERROR, Activator + .getPluginId(), e.getMessage(), e); + Activator.getDefault().getLog().log(error); + } + } + Collections.sort(input); + return input; + } + private static void saveDirs(Set gitDirStrings) { StringBuilder sb = new StringBuilder(); for (String gitDirString : gitDirStrings) { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java index 7af8be9b..2d30bf4a 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java @@ -21,7 +21,6 @@ import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.TreeSet; import java.util.Map.Entry; import org.eclipse.core.resources.IProjectDescription; @@ -48,25 +47,9 @@ public class RepositoriesViewContentProvider implements ITreeContentProvider { @SuppressWarnings("unchecked") public Object[] getElements(Object inputElement) { - Comparator> sorter = new Comparator>() { - - public int compare(RepositoryTreeNode o1, - RepositoryTreeNode o2) { - return getRepositoryName(o1.getObject()).compareTo( - getRepositoryName(o2.getObject())); - } - - }; - - Set> output = new TreeSet>( - sorter); - - for (Repository repo : ((List) inputElement)) { - output.add(new RepositoryTreeNode(null, - RepositoryTreeNodeType.REPO, repo, repo)); - } - - return output.toArray(); + List nodes = (List) inputElement; + Collections.sort(nodes); + return nodes.toArray(); } public void dispose() { @@ -427,7 +410,4 @@ public class RepositoriesViewContentProvider implements ITreeContentProvider { return true; } - private static String getRepositoryName(Repository repository) { - return repository.getDirectory().getParentFile().getName(); - } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java index 11d5d613..40cf3650 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java @@ -21,8 +21,8 @@ import org.eclipse.core.runtime.Path; import org.eclipse.egit.ui.UIIcons; import org.eclipse.egit.ui.UIText; import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.swt.graphics.Image; @@ -45,7 +45,7 @@ public class RepositoriesViewLabelProvider extends LabelProvider { * * @param viewer */ - RepositoriesViewLabelProvider(final TreeViewer viewer) { + public RepositoriesViewLabelProvider(final ColumnViewer viewer) { viewer.setLabelProvider(this); // we could implement some hover here to display additional information @@ -224,7 +224,7 @@ public class RepositoriesViewLabelProvider extends LabelProvider { // shorten the name String refName = node.getRepository().shortenRefName(ref.getName()); try { - String branch = node.getBranch(); + String branch = node.getRepository().getBranch(); if (refName.equals(branch)) { return getDecoratedImage(image); } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java index ae581057..40dd4313 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java @@ -122,7 +122,7 @@ public class RepositorySearchDialog extends Dialog { * @param parentShell * @param existingDirs */ - protected RepositorySearchDialog(Shell parentShell, + public RepositorySearchDialog(Shell parentShell, Collection existingDirs) { super(parentShell); this.existingRepositoryDirs.addAll(existingDirs); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNode.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNode.java index e1dc3d91..2e585e79 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNode.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryTreeNode.java @@ -11,7 +11,6 @@ package org.eclipse.egit.ui.internal.repository; import java.io.File; -import java.io.IOException; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.UIIcons; @@ -28,7 +27,7 @@ import org.eclipse.ui.ide.IDE.SharedImages; * @param * the type */ -class RepositoryTreeNode { +public class RepositoryTreeNode implements Comparable { private final Repository myRepository; @@ -38,10 +37,20 @@ class RepositoryTreeNode { private final RepositoryTreeNode myParent; - private String branch; - - RepositoryTreeNode(RepositoryTreeNode parent, RepositoryTreeNodeType type, - Repository repository, T treeObject) { + /** + * Constructs a node + * + * @param parent + * the parent (may be null) + * @param type + * the type + * @param repository + * the {@link Repository} + * @param treeObject + * an object (depending on the type) + */ + public RepositoryTreeNode(RepositoryTreeNode parent, + RepositoryTreeNodeType type, Repository repository, T treeObject) { myParent = parent; myRepository = repository; myType = type; @@ -58,22 +67,6 @@ class RepositoryTreeNode { } /** - * We keep this cached in the repository node to avoid repeated lookups - * - * @return the full branch - * @throws IOException - */ - public String getBranch() throws IOException { - if (myType != RepositoryTreeNodeType.REPO) { - return getRepositoryNode().getBranch(); - } - if (branch == null) { - branch = getRepository().getBranch(); - } - return branch; - } - - /** * @return the parent, or null */ public RepositoryTreeNode getParent() { @@ -249,6 +242,61 @@ class RepositoryTreeNode { return true; } + public int compareTo(RepositoryTreeNode otherNode) { + int typeDiff = otherNode.getType().ordinal() - this.myType.ordinal(); + if (typeDiff != 0) + return typeDiff; + + // we only implement this for sorting, so we only have to + // implement this for nodes that can be on the same level + // i.e. siblings to each other + + switch (myType) { + + case BRANCHES: + // fall through + case PROJECTS: + // fall through + case REMOTES: + // fall through + case WORKINGDIR: + return 0; + + case FETCH: + // fall through + case PROJ: + // fall through + case PUSH: + // fall through + case REMOTE: + return ((String) myObject) + .compareTo((String) otherNode.getObject()); + case FILE: + // fall through + case FOLDER: + return ((File) myObject).getName().compareTo( + ((File) otherNode.getObject()).getName()); + case REF: + return ((Ref) myObject).getName().compareTo( + ((Ref) otherNode.getObject()).getName()); + case REPO: + int nameCompare = ((Repository) myObject).getDirectory() + .getParentFile().getName().compareTo( + (((Repository) otherNode.getObject()) + .getDirectory().getParentFile().getName())); + if (nameCompare != 0) + return nameCompare; + // if the name is not unique, let's look at the whole path + return ((Repository) myObject).getDirectory().getParentFile() + .getParentFile().getPath().compareTo( + (((Repository) otherNode.getObject()) + .getDirectory().getParentFile() + .getParentFile().getPath())); + + } + return 0; + } + private boolean checkObjectsEqual(Object otherObject) { switch (myType) { case REPO: @@ -298,38 +346,61 @@ class RepositoryTreeNode { return false; } - enum RepositoryTreeNodeType { + /** + * Specifies the type of a {@link RepositoryTreeNode} + */ + public enum RepositoryTreeNodeType { + /** */ REPO(UIIcons.REPOSITORY.createImage()), // + /** */ PROJ(PlatformUI.getWorkbench().getSharedImages().getImage( SharedImages.IMG_OBJ_PROJECT_CLOSED)), // + /** */ BRANCHES(UIIcons.BRANCHES.createImage()), // + /** */ REF(UIIcons.BRANCH.createImage()), // + /** */ HEAD(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE)), // TODO icon + /** */ LOCALBRANCHES(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ REMOTEBRANCHES(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ TAGS(UIIcons.TAGS.createImage()), // + /** */ SYMBOLICREFS(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ SYMBOLICREF(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE)), // TODO icon + /** */ TAG(UIIcons.TAG.createImage()), // + /** */ FILE(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE)), // + /** */ FOLDER(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ PROJECTS(PlatformUI.getWorkbench().getSharedImages().getImage( SharedImages.IMG_OBJ_PROJECT_CLOSED)), // + /** */ REMOTES(UIIcons.REMOTE_REPOSITORY.createImage()), // + /** */ REMOTE(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ FETCH(UIIcons.IMPORT.createImage()), // TODO icon + /** */ PUSH(UIIcons.EXPORT.createImage()), // TODO icon + /** */ WORKINGDIR(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER)), // + /** */ ERROR(PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_ELCL_STOP)) // TODO icon? @@ -353,6 +424,9 @@ class RepositoryTreeNode { } + /** + * @return the icon for this type + */ public Image getIcon() { return myImage; } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties index e06ede10..3a6cb809 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties @@ -17,7 +17,7 @@ AddToIndexAction_indexesWithUnmergedEntries=The indexes of the following files c AddToIndexAction_addingFilesFailed=Adding Files to the Git Index failed WizardProjectsImportPage_projectLabel={0} ({1}) WizardProjectsImportPage_ImportProjectsTitle=Import Projects -WizardProjectsImportPage_ImportProjectsDescription=Import projects from cloned repository into workbench +WizardProjectsImportPage_ImportProjectsDescription=Import projects from a Git repository WizardProjectsImportPage_ProjectsListTitle=&Projects WizardProjectsImportPage_selectAll = &Select All WizardProjectsImportPage_deselectAll = &Deselect All @@ -56,11 +56,11 @@ ExistingOrNewPage_HeaderProject=Project ExistingOrNewPage_HeaderRepository=Repository ExistingOrNewPage_SymbolicValueEmptyMapping= -GitCloneWizard_abortingCloneMsg=A complete clone was already made. Do you want to delete it? +GitCloneWizard_abortingCloneMsg=A partial or complete clone was already made. Do you want to delete it? GitCloneWizard_abortingCloneTitle=Aborting clone GitCloneWizard_CloneFailedHeading=Cloning Git Repository failed GitCloneWizard_CloneCanceledMessage=Clone operation was canceled by the user -GitCloneWizard_title=Import Git Repository +GitCloneWizard_title=Clone Git Repository GitCloneWizard_jobName=Cloning from {0} GitCloneWizard_failed=Git repository clone failed. GitCloneWizard_errorCannotCreate=Cannot create directory {0}. @@ -88,6 +88,7 @@ GitProjectPropertyPage_LabelState=Current state: GitProjectPropertyPage_LabelWorkdir=Working directory: GitProjectPropertyPage_ValueEmptyRepository=None (empty repository) GitProjectPropertyPage_ValueUnbornBranch=None (unborn branch) +GitProjectsImportPage_NoProjectsMessage=No projects found RepositoryAction_errorFindingRepo=Could not find a repository associated with this project RepositoryAction_errorFindingRepoTitle=Cannot Find Repository @@ -626,6 +627,18 @@ GitCreateGeneralProjectPage_ProjectNameLabel=Project name GitCreateProjectViaWizardWizard_AbortedMessage=Action was aborted GitCreateProjectViaWizardWizard_WizardTitle=Import projects from Git Repository {0} GitImportProjectsWizard_ImportExistingProjects0=Import existing projects +GitImportWithDirectoriesPage_PageMessage=Depending on the wizard, you may select a directory to determine the wizard's scope +GitImportWithDirectoriesPage_PageTitle=Select a wizard and decide how to share the imported projects +GitImportWithDirectoriesPage_SelectFolderMessage=Please select a folder +GitImportWizard_WizardTitle=Import Projects from Git +GitSelectRepositoryPage_AddButton=Add... +GitSelectRepositoryPage_AddTooltip=Add a Git Repository from the local file system +GitSelectRepositoryPage_CloneButton=Clone... +GitSelectRepositoryPage_CloneTooltip=Clone a Git Repository and add it to the list +GitSelectRepositoryPage_NoRepoFoundMessage=No repositories found, please clone or add a repository +GitSelectRepositoryPage_PageMessage=You can also clone a repository or add local repositories to the list +GitSelectRepositoryPage_PageTitle=Select a Git Repository +GitSelectRepositoryPage_PleaseSelectMessage=Please select a repository from the list GitSelectWizardPage_AutoShareButton=Try to share newly created projects automatically GitSelectWizardPage_ImportAsGeneralButton=Import as General Project GitSelectWizardPage_ImportExistingButton=Import Existing Projects -- 2.11.4.GIT