Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java9
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties6
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java108
-rw-r--r--org.eclipse.egit.ui/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.egit.ui/plugin.properties3
-rw-r--r--org.eclipse.egit.ui/plugin.xml6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java72
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java25
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SWTUtils.java7
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java57
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java183
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java15
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchSelectionDialog.java27
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java223
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java553
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties28
16 files changed, 1285 insertions, 40 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
index 3fda27862..9c27f0875 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
@@ -235,6 +235,15 @@ public class CoreText extends NLS {
/** */
public static String BranchOperation_performingBranch;
+ /** */
+ public static String TagOperation_performingTagging;
+
+ /** */
+ public static String TagOperation_taggingFailure;
+
+ /** */
+ public static String TagOperation_objectIdNotFound;
+
static {
initializeMessages("org.eclipse.egit.core.coretext", //$NON-NLS-1$
CoreText.class);
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
index 9d9221fbe..ded3690c6 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
@@ -96,4 +96,8 @@ AddToIndexOperation_failed=Failed to add resource to index
TrackOperation_writingIndex=Writing index for {0}
-BranchOperation_performingBranch=Performing branch to {0} \ No newline at end of file
+BranchOperation_performingBranch=Performing branch to {0}
+
+TagOperation_performingTagging=Making tag {0}
+TagOperation_taggingFailure=Tag {0} creation failed (cause: {1})
+TagOperation_objectIdNotFound=Could not find object Id associated with tag {0} (cause: {1}) \ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java
new file mode 100644
index 000000000..abcfe6ee0
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.core.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectWriter;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.Tag;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Tags repository with given {@link Tag} object.
+ */
+public class TagOperation implements IEGitOperation {
+
+ private final Tag tag;
+ private final Repository repo;
+ private final boolean shouldMoveTag;
+
+ /**
+ * Construct TagOperation
+ *
+ * @param repo
+ * @param tag
+ * @param shouldMoveTag if <code>true</code> it will replace tag with same name
+ */
+ public TagOperation(Repository repo, Tag tag, boolean shouldMoveTag) {
+ this.tag = tag;
+ this.repo = repo;
+ this.shouldMoveTag = shouldMoveTag;
+ }
+
+
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ try {
+ monitor.beginTask(NLS.bind(CoreText.TagOperation_performingTagging,
+ tag.getTag()), 3);
+
+ updateTagObject();
+ monitor.worked(1);
+
+ updateRepo();
+ monitor.worked(1);
+
+ ProjectUtil.refreshProjects(repo, SubMonitor.convert(monitor, 1));
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private void updateRepo() throws TeamException {
+ String refName = Constants.R_TAGS + tag.getTag();
+
+ try {
+ RefUpdate tagRef = repo.updateRef(refName);
+ tagRef.setNewObjectId(tag.getTagId());
+
+ tagRef.setForceUpdate(shouldMoveTag);
+ Result updateResult = tagRef.update();
+
+ if (updateResult != Result.NEW && updateResult != Result.FORCED)
+ throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
+ tag.getTag(), updateResult));
+ } catch (IOException e) {
+ throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
+ tag.getTag(), e.getMessage()), e);
+ }
+ }
+
+ private void updateTagObject() throws TeamException {
+ ObjectId startPointRef = tag.getObjId();
+
+ try {
+ ObjectLoader object = repo.openObject(startPointRef);
+ tag.setType(Constants.typeString(object.getType()));
+ ObjectWriter objWriter = new ObjectWriter(repo);
+ tag.setTagId(objWriter.writeTag(tag));
+ } catch (IOException e) {
+ throw new TeamException(NLS.bind(CoreText.TagOperation_objectIdNotFound,
+ tag.getTag(), e.getMessage()), e);
+ }
+ }
+
+
+ public ISchedulingRule getSchedulingRule() {
+ return null;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
index 2003a7ac3..b9e73e2e0 100644
--- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
@@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jsch.ui;bundle-version="[1.1.100,2.0.0)",
org.eclipse.jsch.core;bundle-version="[1.1.100,2.0.0)",
org.eclipse.ui.editors;bundle-version="[3.4.0,4.0.0)",
- com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)"
+ com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)",
+ org.eclipse.ui.forms;bundle-version="[3.3.100,4.0.0)"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.eclipse.egit.core;version="[0.8.0,0.9.0)",
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 6f0759644..7e8248cf3 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -66,6 +66,9 @@ ResetAction_tooltip=Reset the current branch to the same or another commit
BranchAction_label=&Branch...
BranchAction_tooltip=Switch to another branch
+TagAction_label=&Tag...
+TagAction_tooltip=Create or edit tag
+
FetchAction_label=&Fetch From...
FetchAction_tooltip=Fetch from another repository
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 9d721485b..202611aff 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -59,6 +59,12 @@
tooltip="%ResetAction_tooltip">
</action>
<action
+ class="org.eclipse.egit.ui.internal.actions.TagAction"
+ id="org.eclipse.egit.ui.internal.actions.TagAction"
+ label="%TagAction_label"
+ menubarPath="team.main/projectGroup"
+ tooltip="%TagAction_tooltip"/>
+ <action
class="org.eclipse.egit.ui.internal.actions.BranchAction"
id="org.eclipse.egit.ui.internal.actions.BranchAction"
label="%BranchAction_label"
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 e10cebd56..575d8fcb9 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
@@ -1962,6 +1962,78 @@ public class UIText extends NLS {
/** */
public static String Update_update;
+ /** */
+ public static String TagAction_cannotCheckout;
+
+ /** */
+ public static String TagAction_cannotGetBranchName;
+
+ /** */
+ public static String TagAction_repositoryState;
+
+ /** */
+ public static String TagAction_errorCreatingTag;
+
+ /** */
+ public static String TagAction_unableToCreateTag;
+
+ /** */
+ public static String TagAction_errorDuringTagging;
+
+ /** */
+ public static String TagAction_errorWhileGettingRevCommits;
+
+ /** */
+ public static String TagAction_unableToResolveHeadObjectId;
+
+ /** */
+ public static String TagAction_errorWhileMappingRevTag;
+
+ /** */
+ public static String TagAction_creating;
+
+ /** */
+ public static String TagAction_taggingFailed;
+
+ /** */
+ public static String CreateTagDialog_tagName;
+
+ /** */
+ public static String CreateTagDialog_tagMessage;
+
+ /** */
+ public static String CreateTagDialog_questionNewTagTitle;
+
+ /** */
+ public static String CreateTagDialog_overwriteTag;
+
+ /** */
+ public static String CreateTagDialog_overwriteTagToolTip;
+
+ /** */
+ public static String CreateTagDialog_existingTags;
+
+ /** */
+ public static String CreateTagDialog_advanced;
+
+ /** */
+ public static String CreateTagDialog_advancedToolTip;
+
+ /** */
+ public static String CreateTagDialog_advancedMessage;
+
+ /** */
+ public static String CreateTagDialog_tagNameToolTip;
+
+ /** */
+ public static String CreateTagDialog_clearButton;
+
+ /** */
+ public static String CreateTagDialog_clearButtonTooltip;
+
+ /** */
+ public static String CommitCombo_showSuggestedCommits;
+
static {
initializeMessages("org.eclipse.egit.ui.uitext", UIText.class); //$NON-NLS-1$
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java
index 58e3672a2..f81199249 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java
@@ -10,8 +10,12 @@
*******************************************************************************/
package org.eclipse.egit.ui;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
/**
@@ -37,4 +41,25 @@ public class UIUtils {
.getFontRegistry().getBold(id);
}
+ /**
+ * Adds little bulb decoration to given control. Bulb will appear in top left
+ * corner of control after giving focus for this control.
+ *
+ * After clicking on bulb image text from <code>tooltip</code> will appear.
+ *
+ * @param control instance of {@link Control} object with should be decorated
+ * @param tooltip text value which should appear after clicking on bulb image.
+ */
+ public static void addBulbDecorator(final Control control, final String tooltip) {
+ ControlDecoration dec = new ControlDecoration(control, SWT.TOP | SWT.LEFT);
+
+ dec.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(
+ FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage());
+
+ dec.setShowOnlyOnFocus(true);
+ dec.setShowHover(true);
+
+ dec.setDescriptionText(tooltip);
+ }
+
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SWTUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SWTUtils.java
index 976bc0687..7b2912017 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SWTUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SWTUtils.java
@@ -19,7 +19,12 @@ import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PreferenceLinkArea;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java
new file mode 100644
index 000000000..5f17754fe
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.egit.ui.internal;
+
+import java.io.IOException;
+
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A collection of validators
+ */
+public class ValidationUtils {
+
+ /**
+ * Creates and returns input validator for refNames
+ *
+ * @param repo
+ * @param refPrefix
+ * @return input validator for refNames
+ */
+ public static IInputValidator getRefNameInputValidator(final Repository repo, final String refPrefix) {
+ return new IInputValidator() {
+ public String isValid(String newText) {
+ if (newText.length() == 0) {
+ // nothing entered, just don't let the user proceed,
+ // no need to prompt them with an error message
+ return ""; //$NON-NLS-1$
+ }
+
+ String testFor = refPrefix + newText;
+ try {
+ if (repo.resolve(testFor) != null)
+ return UIText.BranchSelectionDialog_ErrorAlreadyExists;
+ } catch (IOException e1) {
+ Activator.logError(NLS.bind(
+ UIText.BranchSelectionDialog_ErrorCouldNotResolve, testFor), e1);
+ return e1.getMessage();
+ }
+ if (!Repository.isValidRefName(testFor))
+ return UIText.BranchSelectionDialog_ErrorInvalidRefName;
+ return null;
+ }
+ };
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java
new file mode 100644
index 000000000..ef6d19831
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.actions;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.internal.ValidationUtils;
+import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
+import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.Tag;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * An action for creating tag.
+ *
+ * @see TagOperation
+ */
+public class TagAction extends RepositoryAction {
+
+ private Repository repo;
+
+ @Override
+ public boolean isEnabled() {
+ return getRepository(false) != null;
+ }
+
+ @Override
+ protected void execute(IAction action) throws InvocationTargetException,
+ InterruptedException {
+ repo = getRepository(true);
+ if (repo == null)
+ return;
+
+ if (!repo.getRepositoryState().canCheckout()) {
+ MessageDialog.openError(getShell(),
+ UIText.TagAction_cannotCheckout, NLS.bind(
+ UIText.TagAction_repositoryState, repo
+ .getRepositoryState().getDescription()));
+ return;
+ }
+
+ String currentBranchName;
+ try {
+ currentBranchName = repo.getBranch();
+ } catch (IOException e) {
+ throw new InvocationTargetException(e,
+ UIText.TagAction_cannotGetBranchName);
+ }
+
+ CreateTagDialog dialog = new CreateTagDialog(getShell(),
+ ValidationUtils
+ .getRefNameInputValidator(repo, Constants.R_TAGS),
+ currentBranchName);
+
+ // get and set commits
+ RevWalk revCommits = getRevCommits();
+ dialog.setRevCommitList(revCommits);
+
+ // get and set existing tags
+ List<Tag> tags = getRevTags();
+ dialog.setExistingTags(tags);
+
+ if (dialog.open() != IDialogConstants.OK_ID)
+ return;
+
+ final Tag tag = new Tag(repo);
+ PersonIdent personIdent = new PersonIdent(repo);
+ String tagName = dialog.getTagName();
+
+ tag.setTag(tagName);
+ tag.setTagger(personIdent);
+ tag.setMessage(dialog.getTagMessage());
+
+ ObjectId tagCommit = getTagCommit(dialog.getTagCommit());
+ tag.setObjId(tagCommit);
+
+ String tagJobName = NLS.bind(UIText.TagAction_creating, tagName);
+ final boolean shouldMoveTag = dialog.shouldOverWriteTag();
+
+ Job tagJob = new Job(tagJobName) {
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ new TagOperation(repo, tag, shouldMoveTag).execute(monitor);
+ } catch (CoreException e) {
+ return Activator.createErrorStatus(
+ UIText.TagAction_taggingFailed, e);
+ } finally {
+ GitLightweightDecorator.refresh();
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ };
+
+ tagJob.setUser(true);
+ tagJob.schedule();
+ }
+
+ private List<Tag> getRevTags() {
+ Collection<Ref> revTags = repo.getTags().values();
+ List<Tag> tags = new ArrayList<Tag>();
+ for (Ref ref : revTags) {
+ try {
+ Tag tag = repo.mapTag(ref.getName());
+ tags.add(tag);
+ } catch (IOException e) {
+ ErrorDialog.openError(getShell(),
+ UIText.TagAction_errorDuringTagging, NLS.bind(
+ UIText.TagAction_errorWhileMappingRevTag, ref
+ .getName()), new Status(IStatus.ERROR,
+ Activator.getPluginId(), e.getMessage(), e));
+ }
+ }
+ return tags;
+ }
+
+ private RevWalk getRevCommits() {
+ RevWalk revWalk = new RevWalk(repo);
+ revWalk.sort(RevSort.COMMIT_TIME_DESC, true);
+ revWalk.sort(RevSort.BOUNDARY, true);
+
+ try {
+ AnyObjectId headId = repo.resolve(Constants.HEAD);
+ if (headId != null)
+ revWalk.markStart(revWalk.parseCommit(headId));
+ } catch (IOException e) {
+ ErrorDialog.openError(getShell(),
+ UIText.TagAction_errorDuringTagging,
+ UIText.TagAction_errorWhileGettingRevCommits, new Status(
+ IStatus.ERROR, Activator.getPluginId(), e
+ .getMessage(), e));
+ }
+
+ return revWalk;
+ }
+
+ private ObjectId getTagCommit(ObjectId objectId)
+ throws InvocationTargetException {
+ ObjectId result = null;
+ if (objectId == null) {
+ try {
+ result = repo.resolve(Constants.HEAD);
+ } catch (IOException e) {
+ throw new InvocationTargetException(e,
+ UIText.TagAction_unableToResolveHeadObjectId);
+ }
+ } else {
+ result = objectId;
+ }
+ return result;
+ }
+}
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 d45e0fc04..694e55e85 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
@@ -24,9 +24,8 @@ 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.egit.ui.UIUtils;
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;
@@ -847,17 +846,7 @@ public class RepositorySelectionPage extends BaseWizardPage {
private void addContentProposalToUriText(Text uriTextField) {
- ControlDecoration dec = new ControlDecoration(uriTextField, SWT.TOP
- | SWT.LEFT);
-
- dec.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(
- FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage());
-
- dec.setShowOnlyOnFocus(true);
- dec.setShowHover(true);
-
- dec
- .setDescriptionText(UIText.RepositorySelectionPage_ShowPreviousURIs_HoverText);
+ UIUtils.addBulbDecorator(uriTextField, UIText.RepositorySelectionPage_ShowPreviousURIs_HoverText);
IContentProposalProvider cp = new IContentProposalProvider() {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchSelectionDialog.java
index 07723587d..171d2c6c4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchSelectionDialog.java
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
* Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
* Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com.dewire.com>
* Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
@@ -22,9 +22,9 @@ 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.egit.ui.internal.ValidationUtils;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
@@ -308,28 +308,7 @@ public class BranchSelectionDialog extends Dialog {
getShell(),
UIText.BranchSelectionDialog_QuestionNewBranchTitle,
prompt,
- null, new IInputValidator() {
- public String isValid(String newText) {
- if (newText.length() == 0) {
- // nothing entered, just don't let the user proceed,
- // no need to prompt them with an error message
- return ""; //$NON-NLS-1$
- }
-
- String testFor = refPrefix + newText;
- try {
- if (repo.resolve(testFor) != null)
- return UIText.BranchSelectionDialog_ErrorAlreadyExists;
- } catch (IOException e1) {
- Activator.logError(NLS.bind(
- UIText.BranchSelectionDialog_ErrorCouldNotResolve, testFor), e1);
- return e1.getMessage();
- }
- if (!Repository.isValidRefName(testFor))
- return UIText.BranchSelectionDialog_ErrorInvalidRefName;
- return null;
- }
- });
+ null, ValidationUtils.getRefNameInputValidator(repo, refPrefix));
labelDialog.setBlockOnOpen(true);
return labelDialog;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java
new file mode 100644
index 000000000..bfd7a74e9
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This is an extended version of {@link Combo} widget with is specialized in
+ * displaying commits and simplifying selection process.
+ *
+ * It is integrated with {@link ContentProposalAdapter} that helps select
+ * preferred tag by user. To get activate proposal provider simply just start
+ * writing commit SHA-1 or part of commit's message first line
+ */
+public class CommitCombo extends Composite {
+
+ private final List<ComboCommitEnt> commits;
+
+ private final Combo combo;
+
+ private class ComboCommitEnt {
+
+ private final String message;
+
+ private final ObjectId objectId;
+
+ public ComboCommitEnt(ObjectId objecId, String message) {
+ this.objectId = objecId;
+ this.message = message;
+ }
+
+ }
+
+ private class CommitContentProposalProvider implements
+ IContentProposalProvider {
+
+ public IContentProposal[] getProposals(String contents, int position) {
+ List<IContentProposal> list = new ArrayList<IContentProposal>();
+ Pattern pattern = Pattern.compile(contents,
+ Pattern.CASE_INSENSITIVE);
+ for (int i = 0; i < commits.size(); i++) {
+ String message = commits.get(i).message;
+ if (message.length() >= contents.length()
+ && pattern.matcher(message).find()) {
+ list.add(makeContentProposal(message));
+ }
+ }
+ return list.toArray(new IContentProposal[] {});
+ }
+
+ /*
+ * Make an IContentProposal for showing the specified String.
+ */
+ private IContentProposal makeContentProposal(final String proposal) {
+ return new IContentProposal() {
+ public String getContent() {
+ return proposal;
+ }
+
+ public String getDescription() {
+ return null;
+ }
+
+ public String getLabel() {
+ return null;
+ }
+
+ public int getCursorPosition() {
+ return proposal.length();
+ }
+ };
+ }
+ }
+
+ /**
+ * Constructs a new instance of this class given its parent and a style
+ * value describing its behavior and appearance.
+ *
+ * @param parent
+ * a widget which will be the parent of the new instance (cannot
+ * be null)
+ * @param style
+ * the SWT style bits
+ */
+ public CommitCombo(Composite parent, int style) {
+ super(parent, style);
+
+ combo = new Combo(this, SWT.DROP_DOWN);
+ commits = new ArrayList<ComboCommitEnt>();
+
+ setLayout(GridLayoutFactory.swtDefaults().create());
+ setLayoutData(GridDataFactory.fillDefaults().create());
+
+ GridData totalLabelData = new GridData();
+ totalLabelData.horizontalAlignment = SWT.FILL;
+ totalLabelData.grabExcessHorizontalSpace = true;
+ combo.setLayoutData(totalLabelData);
+ combo.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ if (null == getValue())
+ combo.setText(""); //$NON-NLS-1$
+ }
+ });
+
+ UIUtils
+ .addBulbDecorator(combo,
+ UIText.CommitCombo_showSuggestedCommits);
+
+ ContentProposalAdapter adapter = new ContentProposalAdapter(combo,
+ new ComboContentAdapter(), new CommitContentProposalProvider(),
+ null, null);
+ adapter.setPropagateKeys(true);
+ adapter
+ .setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+ }
+
+ /**
+ * Add a {@link RevCommit} to widget.
+ *
+ * @param revCommit
+ */
+ public void add(RevCommit revCommit) {
+ Assert.isNotNull(revCommit);
+ checkWidget();
+
+ String shortSha1 = revCommit.getName().substring(0, 8);
+ String message = shortSha1 + ": " + revCommit.getShortMessage(); //$NON-NLS-1$
+ combo.add(message);
+ commits.add(new ComboCommitEnt(revCommit.getId(), message));
+ }
+
+ /**
+ * Returns value of SHA-1 for selected commit.
+ *
+ * @param index
+ * index of item in check box
+ * @return SHA-1 of selected commit
+ */
+ public ObjectId getItem(int index) {
+ checkWidget();
+
+ if (!(0 <= index && index < commits.size())) {
+ SWT.error(SWT.ERROR_INVALID_RANGE);
+ }
+ return commits.get(index).objectId;
+ }
+
+ /**
+ * @return index of selected element
+ */
+ public int getSelectedIndex() {
+ return combo.getSelectionIndex();
+ }
+
+ /**
+ * @return SHA-1 of selected commit
+ */
+ public ObjectId getValue() {
+ int selectionIndex = combo.getSelectionIndex();
+ return -1 != selectionIndex ? getItem(selectionIndex) : null;
+ }
+
+ /**
+ * Selects the item with is associated with given <code>objectId</code>
+ *
+ * @param objectId
+ */
+ public void setSelectedElement(ObjectId objectId) {
+ if (objectId == null) {
+ return;
+ }
+
+ for (int i = 0; i < commits.size(); i++)
+ if (objectId.equals(commits.get(i).objectId)) {
+ combo.select(i);
+ break;
+ }
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ combo.setEnabled(enabled);
+ super.setEnabled(enabled);
+ }
+
+ /**
+ * Sets the selection in the receiver's text field to an empty selection
+ * starting just before the first character. If the text field is editable,
+ * this has the effect of placing the i-beam at the start of the text.
+ */
+ public void clearSelection() {
+ combo.clearSelection();
+ combo.setText(""); //$NON-NLS-1$
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java
new file mode 100644
index 000000000..6bc60318c
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java
@@ -0,0 +1,553 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.dialogs;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.Tag;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * Dialog for creating and editing tags.
+ *
+ */
+public class CreateTagDialog extends Dialog {
+
+ /**
+ * Button id for a "Clear" button (value 22).
+ */
+ public static final int CLEAR_ID = 22;
+
+ private String tagName;
+
+ private String tagMessage;
+
+ private ObjectId tagCommit;
+
+ private boolean overwriteTag;
+
+ private RevWalk revCommits;
+
+ private List<Tag> existingTags;
+
+ private Tag tag;
+
+ private Text tagNameText;
+
+ private Text tagMessageText;
+
+ private Text tagNameErrorText;
+
+ private Button overwriteButton;
+
+ private TableViewer tagViewer;
+
+ private CommitCombo commitCombo;
+
+ private Pattern tagNamePattern;
+
+ private final String branchName;
+
+ private final IInputValidator tagNameValidator;
+
+ class TagInputList extends LabelProvider implements IWorkbenchAdapter {
+
+ private final List<Tag> tagList;
+
+ public TagInputList(List<Tag> tagList) {
+ this.tagList = tagList;
+ }
+
+ public Object[] getChildren(Object o) {
+ return tagList.toArray(new Object[] {});
+ }
+
+ public ImageDescriptor getImageDescriptor(Object object) {
+ return null;
+ }
+
+ public String getLabel(Object o) {
+ if (o instanceof Tag)
+ return ((Tag) o).getTag();
+
+ return null;
+ }
+
+ public Object getParent(Object o) {
+ return null;
+ }
+
+ public Object getAdapter(Class adapter) {
+ if (adapter == IWorkbenchAdapter.class)
+ return this;
+
+ return null;
+ }
+ }
+
+ class TagLabelProvider extends WorkbenchLabelProvider implements
+ ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ return ((Tag) element).getTag();
+ }
+
+ }
+
+ /**
+ * Construct dialog to creating or editing tag.
+ *
+ * @param parent
+ * @param tagNameValidator
+ * @param branchName
+ */
+ public CreateTagDialog(Shell parent, IInputValidator tagNameValidator,
+ String branchName) {
+ super(parent);
+ this.tagNameValidator = tagNameValidator;
+ this.branchName = branchName;
+ }
+
+ /**
+ * @return {@link ObjectId} of commit with new or edited tag should be
+ * associated with
+ */
+ public ObjectId getTagCommit() {
+ return tagCommit;
+ }
+
+ /**
+ * @return message for created or edited tag.
+ */
+ public String getTagMessage() {
+ return tagMessage;
+ }
+
+ /**
+ * @return name of new tag
+ */
+ public String getTagName() {
+ return tagName;
+ }
+
+ /**
+ * Indicates does tag should be forced to update (overwritten) or created.
+ *
+ * @return <code>true</code> if tag should be forced to update,
+ * <code>false</code> if tag should be created
+ */
+ public boolean shouldOverWriteTag() {
+ return overwriteTag;
+ }
+
+ /**
+ * Sets list of already existing tags. This list will be loaded in
+ * <code>Details</code> section of this dialog.
+ *
+ * @param existingTags
+ */
+ public void setExistingTags(List<Tag> existingTags) {
+ this.existingTags = existingTags;
+ }
+
+ /**
+ * Sets list of existing commits. This list will be loaded in
+ * {@link CommitCombo} widget in <code>Advanced</code> section of this
+ * dialog.
+ *
+ * @param revCommits
+ */
+ public void setRevCommitList(RevWalk revCommits) {
+ this.revCommits = revCommits;
+ }
+
+ /**
+ * Data from <code>tag</code> argument will be set in this dialog box.
+ *
+ * @param tag
+ */
+ public void setTag(Tag tag) {
+ this.tag = tag;
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+
+ if (branchName != null) {
+ newShell.setText(NLS.bind(
+ UIText.CreateTagDialog_questionNewTagTitle, branchName));
+ }
+
+ newShell.setMinimumSize(703, 345);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayout(GridLayoutFactory.swtDefaults().create());
+ parent.setLayoutData(GridDataFactory.fillDefaults().grab(true, false)
+ .create());
+
+ Button clearButton = createButton(parent, CLEAR_ID,
+ UIText.CreateTagDialog_clearButton, false);
+ clearButton.setToolTipText(UIText.CreateTagDialog_clearButtonTooltip);
+ setButtonLayoutData(clearButton);
+
+ Composite margin = new Composite(parent, SWT.NONE);
+ margin.setLayoutData(GridDataFactory.fillDefaults().grab(true, false)
+ .create());
+
+ super.createButtonsForButtonBar(parent);
+
+ validateInput();
+ }
+
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ final SashForm mainForm = new SashForm(composite, SWT.HORIZONTAL | SWT.FILL);
+ mainForm.setLayoutData(GridDataFactory.fillDefaults().grab(true, true)
+ .create());
+
+ createLeftSection(mainForm);
+ createExistingTagsSection(mainForm);
+
+ mainForm.setWeights(new int[] { 70, 30 });
+ if (tag != null) {
+ setTagImpl();
+ }
+
+ applyDialogFont(parent);
+ return composite;
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case CLEAR_ID:
+ tagNameText.setText(""); //$NON-NLS-1$
+ tagMessageText.setText(""); //$NON-NLS-1$
+ commitCombo.clearSelection();
+
+ commitCombo.setEnabled(true);
+ tagNameText.setEnabled(true);
+ tagMessageText.setEnabled(true);
+ overwriteButton.setEnabled(false);
+ overwriteButton.setSelection(false);
+ break;
+ case IDialogConstants.OK_ID:
+ // read and store data from widgets
+ tagName = tagNameText.getText();
+ tagCommit = commitCombo.getValue();
+ tagMessage = tagMessageText.getText();
+ overwriteTag = overwriteButton.getSelection();
+ //$FALL-THROUGH$ continue propagating OK button action
+ default:
+ super.buttonPressed(buttonId);
+ }
+ }
+
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ private void createLeftSection(SashForm mainForm) {
+ Composite left = new Composite(mainForm, SWT.RESIZE);
+ left.setLayout(GridLayoutFactory.swtDefaults().margins(10, 5).create());
+ left.setLayoutData(GridDataFactory.fillDefaults().grab(true, true)
+ .create());
+
+ Label label = new Label(left, SWT.WRAP);
+ label.setText(UIText.CreateTagDialog_tagName);
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL
+ | GridData.VERTICAL_ALIGN_CENTER);
+ data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+ label.setLayoutData(data);
+ label.setFont(left.getFont());
+
+ tagNameText = new Text(left, SWT.SINGLE | SWT.BORDER);
+ tagNameText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL));
+ tagNameText.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ String textValue = Pattern.quote(tagNameText.getText());
+ tagNamePattern = Pattern.compile(textValue,
+ Pattern.CASE_INSENSITIVE);
+ tagViewer.refresh();
+ validateInput();
+ }
+ });
+
+ UIUtils.addBulbDecorator(tagNameText,
+ UIText.CreateTagDialog_tagNameToolTip);
+
+ tagNameErrorText = new Text(left, SWT.READ_ONLY | SWT.WRAP);
+ tagNameErrorText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL));
+ tagNameErrorText.setBackground(tagNameErrorText.getDisplay()
+ .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+
+ new Label(left, SWT.WRAP).setText(UIText.CreateTagDialog_tagMessage);
+
+ tagMessageText = new Text(left, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+ tagMessageText.setLayoutData(GridDataFactory.fillDefaults().minSize(50,
+ 50).grab(true, true).create());
+
+ // key listener taken from CommitDialog.createDialogArea() allow to
+ // commit with ctrl-enter
+ tagMessageText.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent arg0) {
+ if (arg0.keyCode == SWT.CR
+ && (arg0.stateMask & SWT.CONTROL) > 0) {
+ Control button = getButton(IDialogConstants.OK_ID);
+ // fire OK action only when button is enabled
+ if (button != null && button.isEnabled())
+ buttonPressed(IDialogConstants.OK_ID);
+ } else if (arg0.keyCode == SWT.TAB
+ && (arg0.stateMask & SWT.SHIFT) == 0) {
+ arg0.doit = false;
+ tagMessageText.traverse(SWT.TRAVERSE_TAB_NEXT);
+ }
+ validateInput();
+ }
+ });
+
+ overwriteButton = new Button(left, SWT.CHECK);
+ overwriteButton.setEnabled(false);
+ overwriteButton.setText(UIText.CreateTagDialog_overwriteTag);
+ overwriteButton
+ .setToolTipText(UIText.CreateTagDialog_overwriteTagToolTip);
+ overwriteButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean state = overwriteButton.getSelection();
+ tagNameText.setEnabled(state);
+ commitCombo.setEnabled(state);
+ tagMessageText.setEnabled(state);
+ validateInput();
+ }
+ });
+
+ createAdvancedSection(left);
+ }
+
+ private void createAdvancedSection(final Composite composite) {
+ ExpandableComposite advanced = new ExpandableComposite(composite,
+ ExpandableComposite.TREE_NODE
+ | ExpandableComposite.CLIENT_INDENT);
+
+ advanced.setText(UIText.CreateTagDialog_advanced);
+ advanced.setToolTipText(UIText.CreateTagDialog_advancedToolTip);
+ advanced.setLayoutData(GridDataFactory.fillDefaults().grab(true, false)
+ .create());
+
+ Composite advancedComposite = new Composite(advanced, SWT.WRAP);
+ advancedComposite.setLayout(GridLayoutFactory.swtDefaults().create());
+ advancedComposite.setLayoutData(GridDataFactory.fillDefaults().grab(
+ true, true).create());
+
+ Label advancedLabel = new Label(advancedComposite, SWT.WRAP);
+ advancedLabel.setText(UIText.CreateTagDialog_advancedMessage);
+ advancedLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true,
+ false).create());
+
+ commitCombo = new CommitCombo(advancedComposite, SWT.NORMAL);
+ commitCombo.setLayoutData(GridDataFactory.fillDefaults().grab(true,
+ false).create());
+
+ for (RevCommit revCommit : revCommits)
+ commitCombo.add(revCommit);
+
+ advanced.setClient(advancedComposite);
+ advanced.addExpansionListener(new ExpansionAdapter() {
+ public void expansionStateChanged(ExpansionEvent e) {
+ composite.layout();
+ }
+ });
+ }
+
+ private void createExistingTagsSection(Composite parent) {
+ Composite right = new Composite(parent, SWT.NORMAL);
+ right.setLayout(GridLayoutFactory.swtDefaults().create());
+ right.setLayoutData(GridLayoutFactory.fillDefaults().create());
+
+ new Label(right, SWT.WRAP).setText(UIText.CreateTagDialog_existingTags);
+
+ Table table = new Table(right, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER
+ | SWT.SINGLE);
+ table.setLayoutData(GridDataFactory.fillDefaults().grab(true, true)
+ .hint(80, 100).create());
+
+ TableLayout layout = new TableLayout();
+ layout.addColumnData(new ColumnWeightData(100, 20));
+ table.setLayout(layout);
+
+ tagViewer = new TableViewer(table);
+ tagViewer.setLabelProvider(new TagLabelProvider());
+ tagViewer.setContentProvider(new WorkbenchContentProvider());
+ tagViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ fillTagDialog();
+ }
+ });
+
+ tagViewer.setInput(new TagInputList(existingTags));
+ tagViewer.addFilter(new ViewerFilter() {
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement,
+ Object element) {
+ Tag tag = (Tag) element;
+
+ if (tagNamePattern != null)
+ return tagNamePattern.matcher(tag.getTag()).find();
+ else
+ return true;
+ }
+ });
+
+ applyDialogFont(parent);
+ }
+
+ private void validateInput() {
+ // don't validate if dialog is disposed
+ if (getShell() == null) {
+ return;
+ }
+
+ // validate tag name
+ String tagNameMessage = tagNameValidator.isValid(tagNameText.getText());
+ setTagNameError(tagNameMessage);
+
+ String tagMessageVal = tagMessageText.getText().trim();
+
+ Control button = getButton(IDialogConstants.OK_ID);
+ if (button != null) {
+ boolean containsTagNameAndMessage = (tagNameMessage == null || tagMessageVal
+ .length() == 0)
+ && tagMessageVal.length() != 0;
+ boolean shouldOverwriteTag = (overwriteButton.getSelection() && Repository
+ .isValidRefName(Constants.R_TAGS + tagNameText.getText()));
+
+ button.setEnabled(containsTagNameAndMessage || shouldOverwriteTag);
+ }
+ }
+
+ private void fillTagDialog() {
+ IStructuredSelection selection = (IStructuredSelection) tagViewer
+ .getSelection();
+ Object firstSelected = selection.getFirstElement();
+
+ if (firstSelected instanceof Tag) {
+ tag = (Tag) firstSelected;
+
+ if (!overwriteButton.isEnabled()) {
+ String tagMessageValue = tag.getMessage();
+ // don't enable OK button if we are dealing with un-annotated
+ // tag because JGit doesn't support them
+ if (tagMessageValue != null
+ && tagMessageValue.trim().length() != 0)
+ overwriteButton.setEnabled(true);
+
+ tagNameText.setEnabled(false);
+ commitCombo.setEnabled(false);
+ tagMessageText.setEnabled(false);
+ }
+
+ setTagImpl();
+ }
+ }
+
+ private void setTagImpl() {
+ tagNameText.setText(tag.getTag());
+ commitCombo.setSelectedElement(tag.getObjId());
+
+ // handle un-annotated tags
+ String message = tag.getMessage();
+ tagMessageText.setText(null != message ? message : ""); //$NON-NLS-1$
+ }
+
+ private void setTagNameError(String tagNameMessage) {
+ // copied form
+ // org.eclipse.jface.dialogs.InputDialog.setErrorMessage(String)
+ if (tagNameErrorText != null && !tagNameErrorText.isDisposed()) {
+ tagNameErrorText
+ .setText(tagNameMessage == null ? " \n " : tagNameMessage); //$NON-NLS-1$
+ // Disable the error message text control if there is no error, or
+ // no error text (empty or whitespace only). Hide it also to avoid
+ // color change.
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130281
+ boolean hasError = tagNameMessage != null
+ && (StringConverter.removeWhiteSpaces(tagNameMessage))
+ .length() > 0;
+ tagNameErrorText.setEnabled(hasError);
+ tagNameErrorText.setVisible(hasError);
+ tagNameErrorText.getParent().update();
+ }
+ }
+
+}
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 3d26a4c08..232a28330 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
@@ -514,6 +514,7 @@ BranchSelectionDialog_NewBranch=&New branch
BranchSelectionDialog_OkCheckout=&Checkout
BranchSelectionDialog_OkReset=&Reset
BranchSelectionDialog_QuestionNewBranchMessage=Enter name of the new branch. It will branch from the selected branch {0}. {1} will be prepended to the name you type
+BranchSelectionDialog_QuestionNewBranchNameMessage=Enter new name of the {0} branch. refs/heads/ will be prepended to the name you type
BranchSelectionDialog_QuestionNewBranchNameMessage=Enter new name of the {0} branch. {1} will be prepended to the name you type
BranchSelectionDialog_QuestionNewBranchTitle=New branch
BranchSelectionDialog_QuestionNewBranchNameTitle=Rename branch
@@ -699,3 +700,30 @@ UIIcons_errorDeterminingIconBase=Can't determine icon base.
UIIcons_errorLoadingPluginImage=Can't load plugin image.
Untrack_untrack=Untrack
Update_update=Update
+
+TagAction_cannotCheckout=Cannot checkout now
+TagAction_cannotGetBranchName=Cannot get actual branch name
+TagAction_repositoryState=Cannot checkout repository because it is in state: {0}
+TagAction_errorCreatingTag=Error while creating tag {0}
+TagAction_unableToCreateTag=Unable to create tag {0}
+TagAction_errorDuringTagging=Error during tagging
+TagAction_errorWhileMappingRevTag=Unable to get information about {0} tag.
+TagAction_errorWhileGettingRevCommits=An error occurred while getting list of commits.
+TagAction_unableToResolveHeadObjectId=Unable to resolve object id associated with current HEAD.
+TagAction_creating=Creating {0} tag.
+TagAction_taggingFailed=Tagging failed
+
+CreateTagDialog_tagName=Tag &name*:
+CreateTagDialog_tagMessage=Tag &message*:
+CreateTagDialog_questionNewTagTitle=Create new tag on branch "{0}"
+CreateTagDialog_overwriteTag=Force &replace existing tag
+CreateTagDialog_overwriteTagToolTip=Select this option if you want to change message or commit associated with already existing tag.
+CreateTagDialog_existingTags=Existing tags:
+CreateTagDialog_advanced=&Advanced
+CreateTagDialog_advancedToolTip=In the advanced section you may choose the commit to be tagged.
+CreateTagDialog_advancedMessage=Choose commit that should be associated with this tag.
+CreateTagDialog_tagNameToolTip=Start typing tag name to filter list of existing tags.
+CreateTagDialog_clearButton=C&lear
+CreateTagDialog_clearButtonTooltip=Clear all dialog fields.
+
+CommitCombo_showSuggestedCommits=Start typing SHA-1 of existing commit or part of first line in commit message to see suggested commits.

Back to the top