diff options
| author | Mathias Kinzler | 2010-03-09 17:29:58 +0000 |
|---|---|---|
| committer | Matthias Sohn | 2010-03-11 00:07:07 +0000 |
| commit | 25f1acdd2f2176380aaac397f69597e3e26c9f0b (patch) | |
| tree | 1ddb6a13743e79ca3084926cbb36e5efe80a87fc | |
| parent | 296a3675df1116bfaff47df141ff6ce1f14c3ec5 (diff) | |
| download | egit-25f1acdd2f2176380aaac397f69597e3e26c9f0b.tar.gz egit-25f1acdd2f2176380aaac397f69597e3e26c9f0b.tar.xz egit-25f1acdd2f2176380aaac397f69597e3e26c9f0b.zip | |
Add content proposal to Git Wizards URI field
Add a content proposal to the URI field so that
the end user can see a list of previously used
URIs in the Git wizards (GitCloneWizard, PushWizard)
for easy re-use of these URIs.
The URIs are only added if an import or push was
completed successfully.
Bug: 303402
Change-Id: Id047009c079540db6dd1404ce48ae707fe1b642b
Signed-off-by: Mathias Kinzler <mathias.kinzler@sap.com>
6 files changed, 183 insertions, 6 deletions
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 983f0f9443..0073e09b9d 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 @@ -208,6 +208,9 @@ public class UIText extends NLS { public static String RepositorySelectionPage_configuredRemoteChoice; /** */ + public static String RepositorySelectionPage_ShowPreviousURIs_HoverText; + + /** */ public static String RepositorySelectionPage_uriChoice; /** */ 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 d69f4898c9..0db5952710 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 @@ -147,6 +147,7 @@ public class GitCloneWizard extends Wizard implements IImportWizard { protected IStatus run(final IProgressMonitor monitor) { try { op.run(monitor); + cloneSource.saveUriInPrefs(uri.toString()); return Status.OK_STATUS; } catch (InterruptedException e) { return Status.CANCEL_STATUS; @@ -156,6 +157,7 @@ public class GitCloneWizard extends Wizard implements IImportWizard { .getPluginId(), 0, thr.getMessage(), thr); } } + }; job.setUser(true); job.schedule(); @@ -165,6 +167,7 @@ public class GitCloneWizard extends Wizard implements IImportWizard { // Perform clone in ModalContext thread with progress // reporting on the wizard. getContainer().run(true, true, op); + cloneSource.saveUriInPrefs(uri.toString()); return true; } catch (InterruptedException e) { MessageDialog.openInformation(getShell(), diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java index 0ef09825a9..b6b9657aa5 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java @@ -14,12 +14,31 @@ package org.eclipse.egit.ui.internal.components; import java.io.File; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.UIText; +import org.eclipse.jface.fieldassist.ContentProposalAdapter; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalProvider; +import org.eclipse.jface.fieldassist.TextContentAdapter; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.util.FS; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; @@ -38,17 +57,17 @@ import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.transport.RemoteConfig; -import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.util.FS; +import org.osgi.service.prefs.BackingStoreException; + /** * Wizard page that allows the user entering the location of a remote repository * by specifying URL manually or selecting a preconfigured remote repository. */ public class RepositorySelectionPage extends BaseWizardPage { + private final static String USED_URIS_PREF = "RepositorySelectionPage.UsedUris"; //$NON-NLS-1$ + private final static String USED_URIS_LENGTH_PREF = "RepositorySelectionPage.UsedUrisLength"; //$NON-NLS-1$ + private static final int REMOTE_CONFIG_TEXT_MAX_LENGTH = 80; private static final int S_GIT = 0; @@ -324,6 +343,8 @@ public class RepositorySelectionPage extends BaseWizardPage { } }); + addContentProposalToUriText(uriText); + Button browseButton = new Button(g, SWT.NULL); browseButton.setText(UIText.RepositorySelectionPage_BrowseLocalFile); browseButton.addSelectionListener(new SelectionAdapter() { @@ -709,4 +730,150 @@ public class RepositorySelectionPage extends BaseWizardPage { if (visible) uriText.setFocus(); } + + /** + * Adds a URI string to the list of previously added ones + * + * @param stringToAdd + */ + public void saveUriInPrefs(String stringToAdd) { + + Set<String> uriStrings = getUrisFromPrefs(); + + if (uriStrings.add(stringToAdd)) { + + IEclipsePreferences prefs = new InstanceScope().getNode(Activator + .getPluginId()); + + StringBuilder sb = new StringBuilder(); + StringBuilder lb = new StringBuilder(); + + // there is no "good" separator for URIish, so we + // keep track of the URI lengths separately + for (String uriString : uriStrings) { + sb.append(uriString); + lb.append(uriString.length()); + lb.append(" "); //$NON-NLS-1$ + } + prefs.put(USED_URIS_PREF, sb.toString()); + prefs.put(USED_URIS_LENGTH_PREF, lb.toString()); + + try { + prefs.flush(); + } catch (BackingStoreException e) { + // we simply ignore this here + } + } + } + + /** + * Gets the previously added URIs from the preferences + * + * @return a (possibly empty) list of URIs, never <code>null</code> + */ + public Set<String> getUrisFromPrefs() { + + // use a TreeSet to get the same sorting always + Set<String> uriStrings = new TreeSet<String>(); + + IEclipsePreferences prefs = new InstanceScope().getNode(Activator + .getPluginId()); + // since there is no "good" separator for URIish, so we + // keep track of the URI lengths separately + String uriLengths = prefs.get(USED_URIS_LENGTH_PREF, ""); //$NON-NLS-1$ + String uris = prefs.get(USED_URIS_PREF, ""); //$NON-NLS-1$ + + StringTokenizer tok = new StringTokenizer(uriLengths, " "); //$NON-NLS-1$ + int offset = 0; + while (tok.hasMoreTokens()) { + try { + int length = Integer.parseInt(tok.nextToken()); + if (uris.length() >= (offset + length)) { + uriStrings.add(uris.substring(offset, offset + length)); + offset += length; + } + } catch (NumberFormatException nfe) { + // ignore here + } + + } + + return uriStrings; + } + + private void addContentProposalToUriText(Text uriTextField) { + + ControlDecoration dec = new ControlDecoration(uriTextField, SWT.TOP + | SWT.LEFT); + + if (Platform.isRunning()) { + dec.setImage(FieldDecorationRegistry.getDefault() + .getFieldDecoration( + FieldDecorationRegistry.DEC_CONTENT_PROPOSAL) + .getImage()); + } + dec.setShowOnlyOnFocus(true); + dec.setShowHover(true); + + dec.setDescriptionText(UIText.RepositorySelectionPage_ShowPreviousURIs_HoverText); + + IContentProposalProvider cp = new IContentProposalProvider() { + + public IContentProposal[] getProposals(String contents, int position) { + List<IContentProposal> resultList = new ArrayList<IContentProposal>(); + + // make the simplest possible pattern check: allow "*" + // for multiple characters + String patternString = contents.replaceAll("\\x2A", ".*"); //$NON-NLS-1$ //$NON-NLS-2$ + // make sure we add a (logical) * at the end + if (!patternString.endsWith(".*")) { //$NON-NLS-1$ + patternString = patternString + ".*"; //$NON-NLS-1$ + } + // let's compile a case-insensitive pattern (assumes ASCII only) + Pattern pattern; + try { + pattern = Pattern.compile(patternString, + Pattern.CASE_INSENSITIVE); + } catch (PatternSyntaxException e) { + pattern = null; + } + + Set<String> uriStrings = getUrisFromPrefs(); + for (final String uriString : uriStrings) { + + if (pattern!=null && !pattern.matcher(uriString).matches()) + continue; + + IContentProposal propsal = new IContentProposal() { + + public String getLabel() { + return null; + } + + public String getDescription() { + return null; + } + + public int getCursorPosition() { + return 0; + } + + public String getContent() { + return uriString; + } + }; + resultList.add(propsal); + } + + return resultList.toArray(new IContentProposal[resultList + .size()]); + } + }; + + // set the acceptance style to always replace the complete content + new ContentProposalAdapter(uriTextField, new TextContentAdapter(), cp, + null, null) + .setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); + + } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java index 29dd30474e..e8ec1d8fc1 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java @@ -106,6 +106,9 @@ public class FetchWizard extends Wizard { getSourceString()); fetchJob.setUser(true); fetchJob.schedule(); + + repoPage.saveUriInPrefs(repoPage.getSelection().getURI().toString()); + return true; } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java index bc0ef80b39..b35584aadd 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java @@ -117,6 +117,7 @@ public class PushWizard extends Wizard { job.setUser(true); job.schedule(); + repoPage.saveUriInPrefs(repoPage.getSelection().getURI().toString()); return true; } 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 ca1c132b79..191dccd3c3 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 @@ -76,7 +76,7 @@ RepositorySelectionPage_fieldRequired={0} required for {1} protocol. RepositorySelectionPage_fieldNotSupported={0} not supported on {1} protocol. RepositorySelectionPage_fileNotFound={0} does not exist. RepositorySelectionPage_internalError=Internal error; consult Eclipse error log. - +RepositorySelectionPage_ShowPreviousURIs_HoverText=Start typing to see previously used URIs (use "*" as wildcard) SourceBranchPage_title=Branch Selection SourceBranchPage_description=Select branches to clone from remote repository. SourceBranchPage_branchList=Branches &of {0}: |
