Skip to content

Commit

Permalink
Merge pull request gitextensions#5422 from Yiabiten/feature-5359
Browse files Browse the repository at this point in the history
Copy multiple commits to clipboard
  • Loading branch information
RussKie committed Sep 20, 2018
2 parents 3445604 + 1765077 commit 5f2d023
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 51 deletions.
2 changes: 1 addition & 1 deletion GitUI/CommandsDialogs/FormFileHistory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private FormFileHistory([NotNull] GitUICommands commands)
_commitDataManager = new CommitDataManager(() => Module);
_fullPathResolver = new FullPathResolver(() => Module.WorkingDir);

copyToClipboardToolStripMenuItem.SetRevisionFunc(() => FileChanges.GetSelectedRevisions().FirstOrDefault());
copyToClipboardToolStripMenuItem.SetRevisionFunc(() => FileChanges.GetSelectedRevisions());

InitializeComplete();

Expand Down
10 changes: 5 additions & 5 deletions GitUI/Translation/English.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -8764,23 +8764,23 @@ When OpenSSH is used, command line dialogs are shown!
<file datatype="plaintext" original="Strings" source-language="en">
<body>
<trans-unit id="_authorDateText.Text">
<source>Author date</source>
<source>{0:Author date|Author dates}</source>
<target />
</trans-unit>
<trans-unit id="_authorText.Text">
<source>Author</source>
<source>{0:Author|Authors}</source>
<target />
</trans-unit>
<trans-unit id="_childrenText.Text">
<source>{0:Child|Children}</source>
<target />
</trans-unit>
<trans-unit id="_commitDateText.Text">
<source>Commit date</source>
<source>{0:Commit date|Commits dates}</source>
<target />
</trans-unit>
<trans-unit id="_commitHashText.Text">
<source>Commit hash</source>
<source>{0:Commit hash|Commits hashs}</source>
<target />
</trans-unit>
<trans-unit id="_committerText.Text">
Expand Down Expand Up @@ -8812,7 +8812,7 @@ When OpenSSH is used, command line dialogs are shown!
<target />
</trans-unit>
<trans-unit id="_messageText.Text">
<source>Message</source>
<source>{0:Message|Messages}</source>
<target />
</trans-unit>
<trans-unit id="_minutesAgo.Text">
Expand Down
70 changes: 38 additions & 32 deletions GitUI/UserControls/RevisionGrid/CopyContextMenuItem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GitCommands;
using GitUI.Properties;
Expand All @@ -11,34 +13,51 @@ namespace GitUI.UserControls.RevisionGrid
{
public sealed class CopyContextMenuItem : ToolStripMenuItem
{
[CanBeNull] private Func<GitRevision> _revisionFunc;
[CanBeNull] private Func<IReadOnlyList<GitRevision>> _revisionFunc;

public CopyContextMenuItem()
{
Image = Images.CopyToClipboard;
Text = "Copy to clipboard";

// Action template
Action<Func<GitRevision, string>> extractText = (Func<GitRevision, string> extractRevisionText) =>
{
var gitRevisions = _revisionFunc?.Invoke();
var sb = new StringBuilder();
foreach (var revision in gitRevisions)
{
sb.AppendLine(extractRevisionText(revision));
}
Clipboard.SetText(sb.ToString());
};

// Add a dummy copy item, so that the shortcut key works.
// This item will never be seen by the user, as the submenu is rebuilt on opening.
AddItem("Dummy item", r => r.Guid, image: null, Keys.Control | Keys.C, showShortcutKeys: false);
AddItem("Dummy item", () => extractText(r => r.Guid), image: null, Keys.Control | Keys.C, showShortcutKeys: false);

DropDownOpening += OnDropDownOpening;

void OnDropDownOpening(object sender, EventArgs e)
{
var revision = _revisionFunc?.Invoke();

if (revision == null)
var revisions = _revisionFunc?.Invoke();
if (revisions == null || revisions.Count == 0)
{
HideDropDown();
return;
}

DropDownItems.Clear();

var refLists = new GitRefListsForRevision(revision);
var branchNames = refLists.GetAllBranchNames();
var tagNames = refLists.GetAllTagNames();
List<string> branchNames = new List<string>();
List<string> tagNames = new List<string>();
foreach (var revision in revisions)
{
var refLists = new GitRefListsForRevision(revision);
branchNames.AddRange(refLists.GetAllBranchNames());
tagNames.AddRange(refLists.GetAllTagNames());
}

// Add items for branches
if (branchNames.Any())
Expand All @@ -49,7 +68,7 @@ void OnDropDownOpening(object sender, EventArgs e)

foreach (var name in branchNames)
{
AddItem(name, _ => name, Images.Branch);
AddItem(name, () => Clipboard.SetText(name), Images.Branch);
}

DropDownItems.Add(new ToolStripSeparator());
Expand All @@ -64,29 +83,21 @@ void OnDropDownOpening(object sender, EventArgs e)

foreach (var name in tagNames)
{
AddItem(name, _ => name, Images.Tag);
AddItem(name, () => Clipboard.SetText(name), Images.Tag);
}

DropDownItems.Add(new ToolStripSeparator());
}

// Add other items
AddItem($"{Strings.CommitHash} ({revision.ObjectId.ToShortString()}...)", r => r.Guid, Images.CommitId, Keys.Control | Keys.C);
AddItem($"{Strings.Message} ({revision.Subject.ShortenTo(30)})", r => r.Body ?? r.Subject, Images.Message);
AddItem($"{Strings.Author} ({revision.Author})", r => r.Author, Images.Author);

if (revision.AuthorDate == revision.CommitDate)
{
AddItem($"{Strings.Date} ({revision.CommitDate})", r => r.CommitDate.ToString(), Images.Date);
}
else
{
AddItem($"{Strings.AuthorDate} ({revision.AuthorDate})", r => r.AuthorDate.ToString(), Images.Date);
AddItem($"{Strings.CommitDate} ({revision.CommitDate})", r => r.CommitDate.ToString(), Images.Date);
}
var count = revisions.Count();
AddItem(Strings.GetCommitHash(count), () => extractText(r => r.Guid), Images.CommitId, Keys.Control | Keys.C);
AddItem(Strings.GetMessage(count), () => extractText(r => r.Body ?? r.Subject), Images.Message);
AddItem(Strings.GetAuthor(count), () => extractText(r => r.Author), Images.Author);
AddItem(Strings.GetAuthorDate(count), () => extractText(r => r.AuthorDate.ToString()), Images.Date);
AddItem(Strings.GetCommitDate(count), () => extractText(r => r.CommitDate.ToString()), Images.Date);
}

void AddItem(string displayText, Func<GitRevision, string> clipboardText, Image image, Keys shortcutKeys = Keys.None, bool showShortcutKeys = true)
void AddItem(string displayText, Action clickAction, Image image, Keys shortcutKeys = Keys.None, bool showShortcutKeys = true)
{
var item = new ToolStripMenuItem
{
Expand All @@ -95,21 +106,16 @@ void AddItem(string displayText, Func<GitRevision, string> clipboardText, Image
ShowShortcutKeys = showShortcutKeys,
Image = image
};

item.Click += delegate
{
var revision = _revisionFunc?.Invoke();
if (revision != null)
{
Clipboard.SetText(clipboardText(revision));
}
clickAction();
};

DropDownItems.Add(item);
}
}

public void SetRevisionFunc(Func<GitRevision> revisionFunc)
public void SetRevisionFunc(Func<IReadOnlyList<GitRevision>> revisionFunc)
{
_revisionFunc = revisionFunc;
}
Expand Down
2 changes: 1 addition & 1 deletion GitUI/UserControls/RevisionGrid/RevisionGridControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public RevisionGridControl()
_authorHighlighting = new AuthorRevisionHighlighting();
_indexWatcher = new Lazy<IndexWatcher>(() => new IndexWatcher(UICommandsSource));

copyToClipboardToolStripMenuItem.SetRevisionFunc(() => LatestSelectedRevision);
copyToClipboardToolStripMenuItem.SetRevisionFunc(() => GetSelectedRevisions());

MenuCommands = new RevisionGridMenuCommands(this);
MenuCommands.CreateOrUpdateMenuCommands();
Expand Down
50 changes: 38 additions & 12 deletions ResourceManager/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public static void Reinitialize()
}

public static string Date => _instance.Value._dateText.Text;
public static string Author => _instance.Value._authorText.Text;
public static string AuthorDate => _instance.Value._authorDateText.Text;
public static string Author => GetAuthor(1);
public static string AuthorDate => GetAuthorDate(1);
public static string Committer => _instance.Value._committerText.Text;
public static string CommitDate => _instance.Value._commitDateText.Text;
public static string CommitHash => _instance.Value._commitHashText.Text;
public static string Message => _instance.Value._messageText.Text;
public static string CommitDate => GetCommitDate(1);
public static string CommitHash => GetCommitHash(1);
public static string Message => GetMessage(1);
public static string Workspace => _instance.Value._workspaceText.Text;
public static string Index => _instance.Value._indexText.Text;
public static string LoadingData => _instance.Value._loadingDataText.Text;
Expand All @@ -42,12 +42,12 @@ public static void Reinitialize()
public static string Tags => _instance.Value._tagsText.Text;

private readonly TranslationString _dateText = new TranslationString("Date");
private readonly TranslationString _authorText = new TranslationString("Author");
private readonly TranslationString _authorDateText = new TranslationString("Author date");
private readonly TranslationString _authorText = new TranslationString("{0:Author|Authors}");
private readonly TranslationString _authorDateText = new TranslationString("{0:Author date|Author dates}");
private readonly TranslationString _committerText = new TranslationString("Committer");
private readonly TranslationString _commitDateText = new TranslationString("Commit date");
private readonly TranslationString _commitHashText = new TranslationString("Commit hash");
private readonly TranslationString _messageText = new TranslationString("Message");
private readonly TranslationString _commitDateText = new TranslationString("{0:Commit date|Commits dates}");
private readonly TranslationString _commitHashText = new TranslationString("{0:Commit hash|Commits hashs}");
private readonly TranslationString _messageText = new TranslationString("{0:Message|Messages}");
private readonly TranslationString _workspaceText = new TranslationString("Working directory");
private readonly TranslationString _indexText = new TranslationString("Commit index");
private readonly TranslationString _loadingDataText = new TranslationString("Loading data...");
Expand All @@ -56,6 +56,9 @@ public static void Reinitialize()
private readonly TranslationString _remotesText = new TranslationString("Remotes");
private readonly TranslationString _tagsText = new TranslationString("Tags");

private readonly TranslationString _parentsText = new TranslationString("{0:Parent|Parents}");
private readonly TranslationString _childrenText = new TranslationString("{0:Child|Children}");

public static string GetParents(int value)
{
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._parentsText.Text, value, Math.Abs(value));
Expand All @@ -66,8 +69,31 @@ public static string GetChildren(int value)
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._childrenText.Text, value, Math.Abs(value));
}

private readonly TranslationString _parentsText = new TranslationString("{0:Parent|Parents}");
private readonly TranslationString _childrenText = new TranslationString("{0:Child|Children}");
public static string GetCommitDate(int value)
{
string v = Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._commitDateText.Text, value, Math.Abs(value));
return v;
}

public static string GetCommitHash(int value)
{
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._commitHashText.Text, value, Math.Abs(value));
}

public static string GetMessage(int value)
{
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._messageText.Text, value, Math.Abs(value));
}

public static string GetAuthor(int value)
{
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._authorText.Text, value, Math.Abs(value));
}

public static string GetAuthorDate(int value)
{
return Smart.Format(AppSettings.CurrentCultureInfo, _instance.Value._authorDateText.Text, value, Math.Abs(value));
}

public static string GetNSecondsAgoText(int value)
{
Expand Down

0 comments on commit 5f2d023

Please sign in to comment.