Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
213 lines (189 sloc) 7.53 KB
using System;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Collections.Generic;
using System.Linq;
using GG.Models;
using GG.Libraries;
using System.Windows.Documents;
namespace GG.UserControls
{
/// <summary>
/// Interaction logic for ChangesetHistoryContextMenu.xaml
/// </summary>
public partial class ChangesetHistoryContextMenu : ContextMenu
{
public ChangesetHistoryContextMenu()
{
InitializeComponent();
}
/// <summary>
/// Returns the currently selected commit.
/// </summary>
/// <returns></returns>
private Commit GetCurrentSelectedCommit()
{
return ((DataGrid) PlacementTarget).SelectedItem as Commit;
}
/// <summary>
/// Returns the current repository view model instance being used.
/// </summary>
/// <returns></returns>
private RepositoryViewModel GetRepositoryViewModel()
{
return ((DataGrid) PlacementTarget).DataContext as RepositoryViewModel;
}
/// <summary>
/// Preprocessing prior to menu opening.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnOpened(object sender, System.Windows.RoutedEventArgs e)
{
var menuItemIndex = 0;
var commit = GetCurrentSelectedCommit();
var repositoryViewModel = GetRepositoryViewModel();
var highlightColor = new SolidColorBrush()
{
Color = Color.FromRgb(8, 94, 160)
};
// Remove previously added Dynamic menu items. We determine dynamically added menu items by their Tag == "Dynamic".
RemoveDynamicallyAddedMenuItems();
if (commit == null)
{
return;
}
// Add Checkout menu items. TODO: Add also non-branch-checkouts.
var numberOfCheckoutItems = 0;
foreach (var branch in commit.Branches)
{
// Only if the right clicked commit is the tip of the branch, AND the branch is not already checkout out, continue.
if (branch.Tip == commit && (repositoryViewModel.Head) != branch && branch.IsRemote == false)
{
var text = new TextBlock();
text.Inlines.AddRange(new Inline[]
{
new Run("Checkout "),
new Run(branch.Name) {Foreground = highlightColor}
});
Items.Insert(menuItemIndex++, CreateMenuItem(text, "Checkout"));
numberOfCheckoutItems++;
}
}
if (numberOfCheckoutItems == 0)
{
var text = new TextBlock();
text.Inlines.AddRange(new Inline[]
{
new Run("Checkout commit "),
new Run(commit.HashShort) {Foreground = highlightColor}
});
Items.Insert(menuItemIndex++, CreateMenuItem(text, "Checkout"));
numberOfCheckoutItems++;
}
if (numberOfCheckoutItems > 1)
{
Items.Insert(menuItemIndex++, new Separator
{
Tag = "Dynamic"
});
}
// Add Merge menu items.
var numberOfMergeItems = 0;
foreach (Branch branch in commit.Branches)
{
if (branch.Tip == commit && branch != (Branch) repositoryViewModel.Head)
{
// Add those that track this branch.
foreach (Branch branchThatTracks in RepoUtil.GetBranchesThatTrack(branch, repositoryViewModel.Branches))
{
if (branchThatTracks.BehindBy > 0 &&
branchThatTracks.IsRemote == false &&
branch.Tip != branchThatTracks.Tip &&
repositoryViewModel.Head is DetachedHead == false &&
branch.Tip != branchThatTracks.Tip)
{
var text = new TextBlock();
text.Inlines.AddRange(new Inline[]
{
new Run("Merge "),
new Run(branch.Name) {Foreground = highlightColor},
new Run(" into "),
new Run(branchThatTracks.Name) {Foreground = highlightColor}
});
Items.Insert(menuItemIndex++, CreateMenuItem(text, "Merge"));
numberOfCheckoutItems++;
}
}
}
if (branch.Tip == commit &&
branch != (Branch) repositoryViewModel.Head &&
repositoryViewModel.Head is DetachedHead == false &&
commit != ((Branch) repositoryViewModel.Head).Tip)
{
var text = new TextBlock();
text.Inlines.AddRange(new Inline[]
{
new Run("Merge "),
new Run(branch.Name) {Foreground = highlightColor},
new Run(" into "),
new Run(((Branch) repositoryViewModel.Head).Name) {Foreground = highlightColor}
});
Items.Insert(menuItemIndex++, CreateMenuItem(text, "Merge"));
numberOfCheckoutItems++;
}
}
if (numberOfMergeItems > 1)
{
Items.Insert(menuItemIndex++, new Separator
{
Tag = "Dynamic"
});
}
}
/// <summary>
/// Removes all dynamically added menu items.
/// </summary>
private void RemoveDynamicallyAddedMenuItems()
{
IList<object> itemsToRemove = Items.Cast<object>().Where(mi =>
{
if (mi is MenuItem == false)
return false;
var tag = ((MenuItem) mi).Tag;
return tag != null && tag.ToString() == "Dynamic";
}).ToList();
foreach (MenuItem item in itemsToRemove)
{
Items.Remove(item);
}
}
/// <summary>
/// Creates and returns a new menu item.
/// </summary>
/// <returns></returns>
private MenuItem CreateMenuItem(object header, string icon)
{
return new MenuItem
{
Header = header,
Tag = "Dynamic",
Icon = new Image
{
Stretch = Stretch.None,
Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/Icons/" + icon + ".png", UriKind.Absolute))
}
};
}
private void OnContextMenuOpening(object sender, ContextMenuEventArgs e)
{
var commit = GetCurrentSelectedCommit();
if (commit == null)
{
e.Handled = true;
return;
}
}
}
}