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

            // 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);

            DropDownOpening += OnDropDownOpening;

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

                if (revision == null)
                {
                    HideDropDown();
                    return;
                }

                DropDownItems.Clear();

                var refLists    = new GitRefListsForRevision(revision);
                var branchNames = refLists.GetAllBranchNames();
                var tagNames    = refLists.GetAllTagNames();

                // Add items for branches
                if (branchNames.Any())
                {
                    var caption = new ToolStripMenuItem {
                        Text = Strings.Branches
                    };
                    MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                    DropDownItems.Add(caption);

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

                    DropDownItems.Add(new ToolStripSeparator());
                }

                // Add items for tags
                if (tagNames.Any())
                {
                    var caption = new ToolStripMenuItem {
                        Text = Strings.Tags
                    };
                    MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                    DropDownItems.Add(caption);

                    foreach (var name in tagNames)
                    {
                        AddItem(name, _ => 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);
                }
            }

            void AddItem(string displayText, Func <GitRevision, string> clipboardText, Image image, Keys shortcutKeys = Keys.None, bool showShortcutKeys = true)
            {
                var item = new ToolStripMenuItem
                {
                    Text             = displayText,
                    ShortcutKeys     = shortcutKeys,
                    ShowShortcutKeys = showShortcutKeys,
                    Image            = image
                };

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

                DropDownItems.Add(item);
            }
        }
        private void OnDropDownOpening(object sender, EventArgs e)
        {
            var revisions = _revisionFunc?.Invoke();

            if (revisions == null || revisions.Count == 0)
            {
                if (sender == null)
                {
                    // create the initial dummy menu on a dummy revision
                    revisions = new List <GitRevision> {
                        new GitRevision(GitUIPluginInterfaces.ObjectId.WorkTreeId)
                    };
                }
                else
                {
                    HideDropDown();
                    return;
                }
            }

            DropDownItems.Clear();

            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());
            }

            _itemNumber = 0;

            // Add items for branches
            if (branchNames.Any())
            {
                var caption = new ToolStripMenuItem {
                    Text = Strings.Branches
                };
                MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                DropDownItems.Add(caption);

                foreach (var name in branchNames)
                {
                    AddItem(name, textToCopy: name, Images.Branch, hotkey: null);
                }

                DropDownItems.Add(new ToolStripSeparator());
            }

            // Add items for tags
            if (tagNames.Any())
            {
                var caption = new ToolStripMenuItem {
                    Text = Strings.Tags
                };
                MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                DropDownItems.Add(caption);

                foreach (var name in tagNames)
                {
                    AddItem(name, textToCopy: name, Images.Tag, hotkey: null);
                }

                DropDownItems.Add(new ToolStripSeparator());
            }

            // Add other items
            int count = revisions.Count();

            AddItem(Strings.GetCommitHash(count), r => r.Guid, Images.CommitId, 'C', Keys.Control | Keys.C);
            AddItem(Strings.GetMessage(count), r => r.Body ?? r.Subject, Images.Message, 'M');
            AddItem(Strings.GetAuthor(count), r => $"{r.Author} <{r.AuthorEmail}>", Images.Author, 'A');

            if (count == 1 && revisions.First().AuthorDate == revisions.First().CommitDate)
            {
                AddItem(Strings.Date, r => r.AuthorDate.ToString(), Images.Date, 'D');
            }
            else
            {
                AddItem(Strings.GetAuthorDate(count), r => r.AuthorDate.ToString(), Images.Date, 'T');
                AddItem(Strings.GetCommitDate(count), r => r.CommitDate.ToString(), Images.Date, 'D');
            }
        }
        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", () => extractText(r => r.Guid), image: null, Keys.Control | Keys.C, showShortcutKeys: false);

            DropDownOpening += OnDropDownOpening;

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

                if (revisions == null || revisions.Count == 0)
                {
                    HideDropDown();
                    return;
                }

                DropDownItems.Clear();

                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())
                {
                    var caption = new ToolStripMenuItem {
                        Text = Strings.Branches
                    };
                    MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                    DropDownItems.Add(caption);

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

                    DropDownItems.Add(new ToolStripSeparator());
                }

                // Add items for tags
                if (tagNames.Any())
                {
                    var caption = new ToolStripMenuItem {
                        Text = Strings.Tags
                    };
                    MenuUtil.SetAsCaptionMenuItem(caption, Owner);
                    DropDownItems.Add(caption);

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

                    DropDownItems.Add(new ToolStripSeparator());
                }

                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, Action clickAction, Image image, Keys shortcutKeys = Keys.None, bool showShortcutKeys = true)
            {
                var item = new ToolStripMenuItem
                {
                    Text             = displayText,
                    ShortcutKeys     = shortcutKeys,
                    ShowShortcutKeys = showShortcutKeys,
                    Image            = image
                };

                item.Click += delegate
                {
                    clickAction();
                };

                DropDownItems.Add(item);
            }
        }