/GitUI/RevisionGrid.cs
C# | 2372 lines | 1952 code | 370 blank | 50 comment | 366 complexity | c320cf16e8d9c7602f49af41767b31c6 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.IO;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Windows.Forms;
- using GitCommands;
- using GitCommands.Git;
- using GitUI.Hotkey;
- using GitUI.Script;
- using GitUI.Tag;
- using Gravatar;
- using ResourceManager.Translation;
- using System.DirectoryServices;
-
- namespace GitUI
- {
- public enum RevisionGridLayout
- {
- FilledBranchesSmall = 1,
- FilledBranchesSmallWithGraph = 2,
- Small = 3,
- SmallWithGraph = 4,
- Card = 5,
- CardWithGraph = 6,
- LargeCard = 7,
- LargeCardWithGraph = 8
- }
-
- [DefaultEvent("DoubleClick")]
- public sealed partial class RevisionGrid : GitExtensionsControl
- {
- private readonly IndexWatcher _indexWatcher = new IndexWatcher();
- private readonly TranslationString _currentWorkingDirChanges = new TranslationString("Current uncommitted changes");
- private readonly TranslationString _currentIndex = new TranslationString("Commit index");
- private readonly TranslationString _areYouSureYouWantCheckout = new TranslationString("Are you sure to checkout the selected revision?");
- private readonly TranslationString _areYouSureYouWantCheckoutCaption = new TranslationString("Checkout revision");
- private readonly TranslationString _droppingFilesBlocked = new TranslationString("For you own protection dropping more than 10 patch files at once is blocked!");
-
- private const int NODE_DIMENSION = 8;
- private const int LANE_WIDTH = 13;
- private const int LANE_LINE_WIDTH = 2;
- private Brush selectedItemBrush;
-
- private readonly FormRevisionFilter _revisionFilter = new FormRevisionFilter();
-
- private readonly SynchronizationContext _syncContext;
- public string LogParam = "HEAD --all --boundary";
-
- private bool _initialLoad = true;
- private string _initialSelectedRevision;
- private string _lastQuickSearchString = string.Empty;
- private Label _quickSearchLabel;
- private string _quickSearchString;
- private RevisionGraph _revisionGraphCommand;
-
- private RevisionGridLayout layout;
- private int rowHeigth;
-
- public RevisionGrid()
- {
- _syncContext = SynchronizationContext.Current;
-
- InitLayout();
- InitializeComponent();
- this.Loading.Image = global::GitUI.Properties.Resources.loadingpanel;
-
- Translate();
-
- NormalFont = SystemFonts.DefaultFont;
- Loading.Paint += Loading_Paint;
-
- Revisions.CellPainting += RevisionsCellPainting;
- Revisions.CellFormatting += RevisionsCellFormatting;
- Revisions.KeyDown += RevisionsKeyDown;
-
- showAuthorDateToolStripMenuItem.Checked = Settings.ShowAuthorDate;
- orderRevisionsByDateToolStripMenuItem.Checked = Settings.OrderRevisionByDate;
- showRelativeDateToolStripMenuItem.Checked = Settings.RelativeDate;
- drawNonrelativesGrayToolStripMenuItem.Checked = Settings.RevisionGraphDrawNonRelativesGray;
- showGitNotesToolStripMenuItem.Checked = Settings.ShowGitNotes;
-
- BranchFilter = String.Empty;
- SetShowBranches();
- Filter = "";
- FixedFilter = "";
- InMemFilterIgnoreCase = false;
- InMemAuthorFilter = "";
- InMemCommitterFilter = "";
- InMemMessageFilter = "";
- AllowGraphWithFilter = false;
- _quickSearchString = "";
- quickSearchTimer.Tick += QuickSearchTimerTick;
-
- Revisions.Loading += RevisionsLoading;
-
- //Allow to drop patch file on revisiongrid
- Revisions.DragEnter += Revisions_DragEnter;
- Revisions.DragDrop += Revisions_DragDrop;
- Revisions.AllowDrop = true;
- Revisions.ColumnHeadersVisible = false;
-
- this.HotkeysEnabled = true;
- try
- {
- SetRevisionsLayout((RevisionGridLayout)Settings.RevisionGraphLayout);
- }
- catch
- {
- SetRevisionsLayout(RevisionGridLayout.SmallWithGraph);
- }
- }
-
- void Loading_Paint(object sender, PaintEventArgs e)
- {
- // If our loading state has changed since the last paint, update it.
- if (Loading != null)
- {
- if (Loading.Visible != _isLoading)
- {
- Loading.Visible = _isLoading;
- }
- }
- }
-
- [Browsable(false)]
- public Font HeadFont { get; private set; }
- [Browsable(false)]
- public Font SuperprojectFont { get; private set; }
- [Browsable(false)]
- public int LastScrollPos { get; private set; }
- [Browsable(false)]
- public IComparable[] LastSelectedRows { get; private set; }
- [Browsable(false)]
- public Font RefsFont { get; private set; }
- private Font _normalFont;
- [Category("Appearance")]
- public Font NormalFont
- {
- get { return _normalFont; }
- set
- {
- _normalFont = value;
- Message.DefaultCellStyle.Font = _normalFont;
- Date.DefaultCellStyle.Font = _normalFont;
-
- RefsFont = IsFilledBranchesLayout() ? _normalFont : new Font(_normalFont, FontStyle.Bold);
- HeadFont = new Font(_normalFont, FontStyle.Bold);
- SuperprojectFont = new Font(_normalFont, FontStyle.Underline);
- }
- }
-
- [Category("Filter")]
- public string Filter { get; set; }
- [Category("Filter")]
- public string FixedFilter { get; set; }
- [Category("Filter")]
- [DefaultValue(false)]
- public bool InMemFilterIgnoreCase { get; set; }
- [Category("Filter")]
- public string InMemAuthorFilter { get; set; }
- [Category("Filter")]
- public string InMemCommitterFilter { get; set; }
- [Category("Filter")]
- public string InMemMessageFilter { get; set; }
- [Category("Filter")]
- public string BranchFilter { get; set; }
- [Category("Filter")]
- [DefaultValue(false)]
- public bool AllowGraphWithFilter { get; set; }
-
- [Browsable(false)]
- public string CurrentCheckout { get; set; }
- [Browsable(false)]
- public string SuperprojectCurrentCheckout { get; set; }
- [Browsable(false)]
- public int LastRow { get; set; }
-
- [Description("Indicates whether the user is allowed to select more than one commit at a time.")]
- [Category("Behavior")]
- [DefaultValue(true)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
- public bool MultiSelect
- {
- get { return Revisions.MultiSelect; }
- set { Revisions.MultiSelect = value; }
- }
-
- public void SetInitialRevision(GitRevision initialSelectedRevision)
- {
- _initialSelectedRevision = initialSelectedRevision != null ? initialSelectedRevision.Guid : null;
- }
-
- public event EventHandler ActionOnRepositoryPerformed;
-
- private void OnActionOnRepositoryPerformed()
- {
- if (ActionOnRepositoryPerformed != null)
- ActionOnRepositoryPerformed(this, null);
- }
-
- private bool _isLoading;
- private void RevisionsLoading(bool isLoading)
- {
- // Since this can happen on a background thread, we'll just set a
- // flag and deal with it next time we paint (a bit of a hack, but
- // it works)
- _isLoading = isLoading;
- }
-
- private void ShowQuickSearchString()
- {
- if (_quickSearchLabel == null)
- {
- _quickSearchLabel
- = new Label
- {
- Location = new Point(10, 10),
- BorderStyle = BorderStyle.FixedSingle,
- ForeColor = SystemColors.InfoText,
- BackColor = SystemColors.Info
- };
- Controls.Add(_quickSearchLabel);
- }
-
- _quickSearchLabel.Visible = true;
- _quickSearchLabel.BringToFront();
- _quickSearchLabel.Text = _quickSearchString;
- _quickSearchLabel.AutoSize = true;
- }
-
- private void HideQuickSearchString()
- {
- if (_quickSearchLabel != null)
- _quickSearchLabel.Visible = false;
- }
-
- private void QuickSearchTimerTick(object sender, EventArgs e)
- {
- quickSearchTimer.Stop();
- _quickSearchString = "";
- HideQuickSearchString();
- }
-
- private void RestartQuickSearchTimer()
- {
- quickSearchTimer.Stop();
- quickSearchTimer.Interval = Settings.RevisionGridQuickSearchTimeout;
- quickSearchTimer.Start();
- }
-
- private void RevisionsKeyDown(object sender, KeyEventArgs e)
- {
- var curIndex = -1;
- if (Revisions.SelectedRows.Count > 0)
- curIndex = Revisions.SelectedRows[0].Index;
- if (e.Alt && (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down))
- {
- RestartQuickSearchTimer();
-
- bool reverse = e.KeyCode == Keys.Up;
- var nextIndex = 0;
- if (curIndex >= 0)
- nextIndex = reverse ? curIndex - 1 : curIndex + 1;
- _quickSearchString = _lastQuickSearchString;
- FindNextMatch(nextIndex, _quickSearchString, reverse);
- ShowQuickSearchString();
- e.Handled = true;
- return;
- }
-
- curIndex = curIndex >= 0 ? curIndex : 0;
- int key = e.KeyValue;
- if (!e.Alt && !e.Control && key == 8 && _quickSearchString.Length > 1) //backspace
- {
- RestartQuickSearchTimer();
-
- _quickSearchString = _quickSearchString.Substring(0, _quickSearchString.Length - 1);
-
- FindNextMatch(curIndex, _quickSearchString, false);
- _lastQuickSearchString = _quickSearchString;
-
- e.Handled = true;
- ShowQuickSearchString();
- }
- else if (!e.Alt && !e.Control && (char.IsLetterOrDigit((char)key) || char.IsNumber((char)key) || char.IsSeparator((char)key) || key == 191))
- {
- RestartQuickSearchTimer();
-
- //The code below is meant to fix the weird keyvalues when pressing keys e.g. ".".
- switch (key)
- {
- case 51:
- _quickSearchString = e.Shift ? string.Concat(_quickSearchString, "#").ToLower() : string.Concat(_quickSearchString, "3").ToLower();
- break;
- case 188:
- _quickSearchString = string.Concat(_quickSearchString, ",").ToLower();
- break;
- case 189:
- _quickSearchString = e.Shift ? string.Concat(_quickSearchString, "_").ToLower() : string.Concat(_quickSearchString, "-").ToLower();
- break;
- case 190:
- _quickSearchString = string.Concat(_quickSearchString, ".").ToLower();
- break;
- case 191:
- _quickSearchString = string.Concat(_quickSearchString, "/").ToLower();
- break;
- default:
- _quickSearchString = string.Concat(_quickSearchString, (char)e.KeyValue).ToLower();
- break;
- }
-
- FindNextMatch(curIndex, _quickSearchString, false);
- _lastQuickSearchString = _quickSearchString;
-
- e.Handled = true;
- ShowQuickSearchString();
- }
- else
- {
- _quickSearchString = "";
- HideQuickSearchString();
- e.Handled = false;
- }
- }
-
- private void FindNextMatch(int startIndex, string searchString, bool reverse)
- {
- if (Revisions.RowCount == 0)
- return;
-
- var searchResult =
- reverse
- ? SearchInReverseOrder(startIndex, searchString)
- : SearchForward(startIndex, searchString);
-
- if (!searchResult.HasValue)
- return;
-
- Revisions.ClearSelection();
- Revisions.Rows[searchResult.Value].Selected = true;
-
- Revisions.CurrentCell = Revisions.Rows[searchResult.Value].Cells[1];
- }
-
- private int? SearchForward(int startIndex, string searchString)
- {
- // Check for out of bounds roll over if required
- int index;
- if (startIndex < 0 || startIndex >= Revisions.RowCount)
- startIndex = 0;
-
- for (index = startIndex; index < Revisions.RowCount; ++index)
- {
- if (GetRevision(index).MatchesSearchString(searchString))
- return index;
- }
-
- // We didn't find it so start searching from the top
- for (index = 0; index < startIndex; ++index)
- {
- if (GetRevision(index).MatchesSearchString(searchString))
- return index;
- }
-
- return null;
- }
-
- private int? SearchInReverseOrder(int startIndex, string searchString)
- {
- // Check for out of bounds roll over if required
- int index;
- if (startIndex < 0 || startIndex >= Revisions.RowCount)
- startIndex = Revisions.RowCount - 1;
-
- for (index = startIndex; index >= 0; --index)
- {
- if (GetRevision(index).MatchesSearchString(searchString))
- return index;
- }
-
- // We didn't find it so start searching from the bottom
- for (index = Revisions.RowCount - 1; index > startIndex; --index)
- {
- if (GetRevision(index).MatchesSearchString(searchString))
- return index;
- }
-
-
- return null;
- }
-
- public void DisableContextMenu()
- {
- Revisions.ContextMenuStrip = null;
- }
-
- public void FormatQuickFilter(string filter,
- bool[] parameters,
- out string revListArgs,
- out string inMemMessageFilter,
- out string inMemCommitterFilter,
- out string inMemAuthorFilter)
- {
- revListArgs = string.Empty;
- inMemMessageFilter = string.Empty;
- inMemCommitterFilter = string.Empty;
- inMemAuthorFilter = string.Empty;
- if (!string.IsNullOrEmpty(filter))
- {
- // hash filtering only possible in memory
- var cmdLineSafe = GitCommandHelpers.VersionInUse.IsRegExStringCmdPassable(filter);
- revListArgs = " --regexp-ignore-case ";
- if (parameters[0])
- if (cmdLineSafe)
- revListArgs += "--grep=\"" + filter + "\" ";
- else
- inMemMessageFilter = filter;
- if (parameters[1])
- if (cmdLineSafe)
- revListArgs += "--committer=\"" + filter + "\" ";
- else
- inMemCommitterFilter = filter;
- if (parameters[2])
- if (cmdLineSafe)
- revListArgs += "--author=\"" + filter + "\" ";
- else
- inMemAuthorFilter = filter;
- if (parameters[3])
- if (cmdLineSafe)
- revListArgs += "\"-S" + filter + "\" ";
- else
- throw new InvalidOperationException("Filter text not valid for \"Diff contains\" filter.");
- }
- }
-
- public bool SetAndApplyBranchFilter(string filter)
- {
- if (filter.Equals(_revisionFilter.GetBranchFilter()))
- return false;
- if (filter.Equals(""))
- {
- Settings.BranchFilterEnabled = false;
- Settings.ShowCurrentBranchOnly = true;
- }
- else
- {
- Settings.BranchFilterEnabled = true;
- Settings.ShowCurrentBranchOnly = false;
- _revisionFilter.SetBranchFilter(filter);
- }
- SetShowBranches();
- return true;
- }
-
- public void SetLimit(int limit)
- {
- _revisionFilter.SetLimit(limit);
- }
-
- public override void Refresh()
- {
- SetRevisionsLayout();
-
- base.Refresh();
-
- Revisions.Refresh();
- }
-
- protected override void OnCreateControl()
- {
- base.OnCreateControl();
-
- _isLoading = true;
- Error.Visible = false;
- NoCommits.Visible = false;
- NoGit.Visible = false;
- Revisions.Visible = false;
- Loading.Visible = true;
- Loading.BringToFront();
- }
-
- public new void Load()
- {
- if (!DesignMode)
- ReloadHotkeys();
- ForceRefreshRevisions();
- }
-
- public event EventHandler SelectionChanged;
-
- public void SetSelectedIndex(int index)
- {
- if (Revisions.Rows[index].Selected)
- return;
-
- Revisions.ClearSelection();
-
- Revisions.Rows[index].Selected = true;
- Revisions.CurrentCell = Revisions.Rows[index].Cells[1];
-
- Revisions.Select();
- }
-
- public void SetSelectedRevision(GitRevision revision)
- {
- if (revision != null)
- {
- for (var i = 0; i < Revisions.RowCount; i++)
- {
- if (GetRevision(i).Guid == revision.Guid)
- {
- SetSelectedIndex(i);
- return;
- }
- }
- }
-
- Revisions.ClearSelection();
- Revisions.Select();
- }
-
- private void RevisionsSelectionChanged(object sender, EventArgs e)
- {
- if (Revisions.SelectedRows.Count > 0)
- LastRow = Revisions.SelectedRows[0].Index;
-
- SelectionTimer.Enabled = false;
- SelectionTimer.Stop();
- SelectionTimer.Enabled = true;
- SelectionTimer.Start();
- }
-
- public List<GitRevision> GetSelectedRevisions()
- {
- return GetSelectedRevisions(null);
- }
-
- public List<GitRevision> GetSelectedRevisions(SortDirection? direction)
- {
- var rows = Revisions
- .SelectedRows
- .Cast<DataGridViewRow>()
- .Where(row => Revisions.RowCount > row.Index);
-
-
- if (direction.HasValue)
- {
- int d = direction.Value == SortDirection.Ascending ? 1 : -1;
- rows = rows.OrderBy((row) => row.Index, (r1, r2) => d * (r1 - r2));
- }
-
- return rows
- .Select(row => GetRevision(row.Index))
- .ToList();
- }
-
- public GitRevision GetRevision(int aRow)
- {
- return Revisions.GetRowData(aRow);
- }
-
- public GitRevision GetCurrentRevision()
- {
- const string formatString =
- /* Tree */ "%T%n" +
- /* Author Name */ "%aN%n" +
- /* Author Date */ "%ai%n" +
- /* Committer Name */ "%cN%n" +
- /* Committer Date */ "%ci%n" +
- /* Commit Message */ "%s";
- string cmd = "log -n 1 --pretty=format:" + formatString + " " + CurrentCheckout;
- var RevInfo = Settings.Module.RunGitCmd(cmd);
- string[] Infos = RevInfo.Split('\n');
- var Revision = new GitRevision(CurrentCheckout)
- {
- TreeGuid = Infos[0],
- Author = Infos[1],
- Committer = Infos[3],
- Message = Infos[5]
- };
- DateTime date;
- DateTime.TryParse(Infos[2], out date);
- Revision.AuthorDate = date;
- DateTime.TryParse(Infos[4], out date);
- Revision.CommitDate = date;
- List<GitHead> heads = Settings.Module.GetHeads(true, true);
- foreach (GitHead head in heads)
- {
- if (head.Guid.Equals(Revision.Guid))
- Revision.Heads.Add(head);
- }
- return Revision;
- }
-
- public void RefreshRevisions()
- {
- if (IndexWatcher.IndexChanged)
- ForceRefreshRevisions();
- }
-
- private class RevisionGraphInMemFilterOr : RevisionGraphInMemFilter
- {
- private RevisionGraphInMemFilter fFilter1;
- private RevisionGraphInMemFilter fFilter2;
- public RevisionGraphInMemFilterOr(RevisionGraphInMemFilter aFilter1,
- RevisionGraphInMemFilter aFilter2)
- {
- fFilter1 = aFilter1;
- fFilter2 = aFilter2;
- }
-
- public override bool PassThru(GitRevision rev)
- {
- return fFilter1.PassThru(rev) || fFilter2.PassThru(rev);
- }
- }
-
- private class RevisionGridInMemFilter : RevisionGraphInMemFilter
- {
- private readonly bool _IgnoreCase;
- private readonly string _AuthorFilter;
- private readonly Regex _AuthorFilterRegex;
- private readonly string _CommitterFilter;
- private readonly Regex _CommitterFilterRegex;
- private readonly string _MessageFilter;
- private readonly Regex _MessageFilterRegex;
-
- public RevisionGridInMemFilter(string authorFilter, string committerFilter, string messageFilter, bool ignoreCase)
- {
- _IgnoreCase = ignoreCase;
- SetUpVars(authorFilter, ref _AuthorFilter, ref _AuthorFilterRegex);
- SetUpVars(committerFilter, ref _CommitterFilter, ref _CommitterFilterRegex);
- SetUpVars(messageFilter, ref _MessageFilter, ref _MessageFilterRegex);
- }
-
- private void SetUpVars(string filterValue,
- ref string filterStr,
- ref Regex filterRegEx)
- {
- RegexOptions opts = RegexOptions.None;
- if (_IgnoreCase) opts = opts | RegexOptions.IgnoreCase;
- filterStr = filterValue != null ? filterValue.Trim() : string.Empty;
- try
- {
- filterRegEx = new Regex(filterStr, opts);
- }
- catch (ArgumentException)
- {
- filterRegEx = null;
- }
- }
-
- private static bool CheckCondition(string filter, Regex regex, string value)
- {
- return string.IsNullOrEmpty(filter) ||
- ((regex != null) && regex.Match(value).Success);
- }
-
- public override bool PassThru(GitRevision rev)
- {
- return CheckCondition(_AuthorFilter, _AuthorFilterRegex, rev.Author) &&
- CheckCondition(_CommitterFilter, _CommitterFilterRegex, rev.Committer) &&
- CheckCondition(_MessageFilter, _MessageFilterRegex, rev.Message);
- }
-
- public static RevisionGridInMemFilter CreateIfNeeded(string authorFilter,
- string committerFilter,
- string messageFilter,
- bool ignoreCase)
- {
- if (!(string.IsNullOrEmpty(authorFilter) &&
- string.IsNullOrEmpty(committerFilter) &&
- string.IsNullOrEmpty(messageFilter)))
- return new RevisionGridInMemFilter(authorFilter,
- committerFilter,
- messageFilter,
- ignoreCase);
- else
- return null;
- }
- }
-
- public void ReloadHotkeys()
- {
- this.Hotkeys = HotkeySettingsManager.LoadHotkeys(HotkeySettingsName);
- }
-
- public void ReloadTranslation()
- {
- Translate();
- }
-
- public void ForceRefreshRevisions()
- {
- try
- {
- ApplyFilterFromRevisionFilterDialog();
-
- _initialLoad = true;
-
- LastScrollPos = Revisions.FirstDisplayedScrollingRowIndex;
-
- DisposeRevisionGraphCommand();
-
- var newCurrentCheckout = Settings.Module.GetCurrentCheckout();
- var newSuperprojectCurrentCheckout = Settings.Module.GetSuperprojectCurrentCheckout();
-
- // If the current checkout changed, don't get the currently selected rows, select the
- // new current checkout instead.
- if (newCurrentCheckout == CurrentCheckout)
- {
- LastSelectedRows = Revisions.SelectedIds;
- }
- else
- {
- // This is a new checkout, so ensure the variable is cleared out.
- LastSelectedRows = null;
- }
-
- Revisions.ClearSelection();
- CurrentCheckout = newCurrentCheckout;
- SuperprojectCurrentCheckout = newSuperprojectCurrentCheckout;
- Revisions.Clear();
- Error.Visible = false;
-
- if (!Settings.Module.ValidWorkingDir())
- {
- Revisions.Visible = false;
- NoCommits.Visible = true;
- Loading.Visible = false;
- NoGit.Visible = true;
- string dir = Settings.Module.WorkingDir;
- if (String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ||
- Directory.GetDirectories(dir).Length == 0 &&
- Directory.GetFiles(dir).Length == 0)
- CloneRepository.Show();
- else
- CloneRepository.Hide();
- NoGit.BringToFront();
- return;
- }
-
- NoCommits.Visible = false;
- NoGit.Visible = false;
- Revisions.Visible = true;
- Revisions.BringToFront();
- Revisions.Enabled = false;
- Loading.Visible = true;
- Loading.BringToFront();
- _isLoading = true;
- base.Refresh();
-
- IndexWatcher.Reset();
-
- if (!Settings.ShowGitNotes && !LogParam.Contains(" --not --glob=notes --not"))
- LogParam = LogParam + " --not --glob=notes --not";
-
- if (Settings.ShowGitNotes && LogParam.Contains(" --not --glob=notes --not"))
- LogParam = LogParam.Replace(" --not --glob=notes --not", string.Empty);
-
- RevisionGridInMemFilter revisionFilterIMF = RevisionGridInMemFilter.CreateIfNeeded(_revisionFilter.GetInMemAuthorFilter(),
- _revisionFilter.GetInMemCommitterFilter(),
- _revisionFilter.GetInMemMessageFilter(),
- _revisionFilter.GetIgnoreCase());
- RevisionGridInMemFilter filterBarIMF = RevisionGridInMemFilter.CreateIfNeeded(InMemAuthorFilter,
- InMemCommitterFilter,
- InMemMessageFilter,
- InMemFilterIgnoreCase);
- RevisionGraphInMemFilter revGraphIMF;
- if (revisionFilterIMF != null && filterBarIMF != null)
- revGraphIMF = new RevisionGraphInMemFilterOr(revisionFilterIMF, filterBarIMF);
- else if (revisionFilterIMF != null)
- revGraphIMF = revisionFilterIMF;
- else
- revGraphIMF = filterBarIMF;
-
- _revisionGraphCommand = new RevisionGraph { BranchFilter = BranchFilter, LogParam = LogParam + _revisionFilter.GetFilter() + Filter + FixedFilter };
- _revisionGraphCommand.Updated += GitGetCommitsCommandUpdated;
- _revisionGraphCommand.Exited += GitGetCommitsCommandExited;
- _revisionGraphCommand.Error += _revisionGraphCommand_Error;
- _revisionGraphCommand.InMemFilter = revGraphIMF;
- //_revisionGraphCommand.BeginUpdate += ((s, e) => Revisions.Invoke((Action) (() => Revisions.Clear())));
- _revisionGraphCommand.Execute();
- LoadRevisions();
- SetRevisionsLayout();
- }
- catch (Exception exception)
- {
- Error.Visible = true;
- Error.BringToFront();
- MessageBox.Show(this, exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- private void _revisionGraphCommand_Error(object sender, EventArgs e)
- {
- // This has to happen on the UI thread
- _syncContext.Send(o =>
- {
- Error.Visible = true;
- //Error.BringToFront();
- NoGit.Visible = false;
- NoCommits.Visible = false;
- Revisions.Visible = false;
- Loading.Visible = false;
- }, this);
- }
-
- private void GitGetCommitsCommandUpdated(object sender, EventArgs e)
- {
- var updatedEvent = (RevisionGraph.RevisionGraphUpdatedEventArgs)e;
- UpdateGraph(updatedEvent.Revision);
- }
-
- private bool FilterIsApplied(bool inclBranchFilter)
- {
- return (inclBranchFilter && !string.IsNullOrEmpty(BranchFilter)) ||
- !(string.IsNullOrEmpty(Filter) &&
- !_revisionFilter.FilterEnabled() &&
- string.IsNullOrEmpty(InMemAuthorFilter) &&
- string.IsNullOrEmpty(InMemCommitterFilter) &&
- string.IsNullOrEmpty(InMemMessageFilter));
- }
-
- private bool ShouldHideGraph(bool inclBranchFilter)
- {
- return (inclBranchFilter && !string.IsNullOrEmpty(BranchFilter)) ||
- !(!_revisionFilter.ShouldHideGraph() &&
- string.IsNullOrEmpty(InMemAuthorFilter) &&
- string.IsNullOrEmpty(InMemCommitterFilter) &&
- string.IsNullOrEmpty(InMemMessageFilter));
- }
-
- private void DisposeRevisionGraphCommand()
- {
- if (_revisionGraphCommand != null)
- {
- //Dispose command, it is not needed anymore
- _revisionGraphCommand.Updated -= GitGetCommitsCommandUpdated;
- _revisionGraphCommand.Exited -= GitGetCommitsCommandExited;
- _revisionGraphCommand.Error -= _revisionGraphCommand_Error;
-
- _revisionGraphCommand.Dispose();
- _revisionGraphCommand = null;
- }
- }
-
- private void GitGetCommitsCommandExited(object sender, EventArgs e)
- {
- _isLoading = false;
-
- if (_revisionGraphCommand.RevisionCount == 0 &&
- !FilterIsApplied(true))
- {
- // This has to happen on the UI thread
- _syncContext.Send(o =>
- {
- NoGit.Visible = false;
- NoCommits.Visible = true;
- //NoCommits.BringToFront();
- Revisions.Visible = false;
- Loading.Visible = false;
- }, this);
- }
- else
- {
- // This has to happen on the UI thread
- _syncContext.Send(o =>
- {
- UpdateGraph(null);
- Loading.Visible = false;
- SelectInitialRevision();
- _isLoading = false;
- }, this);
- }
- }
-
- private void SelectInitialRevision()
- {
- if (string.IsNullOrEmpty(_initialSelectedRevision) || Revisions.SelectedRows.Count != 0)
- return;
-
- for (var i = 0; i < Revisions.RowCount; i++)
- {
- if (GetRevision(i).Guid == _initialSelectedRevision)
- SetSelectedIndex(i);
- }
- }
-
- private static string GetDateHeaderText()
- {
- return Settings.ShowAuthorDate ? Strings.GetAuthorDateText() : Strings.GetCommitDateText();
- }
-
- private void LoadRevisions()
- {
- if (_revisionGraphCommand == null)
- {
- return;
- }
-
- Revisions.SuspendLayout();
-
- Revisions.Columns[1].HeaderText = Strings.GetMessageText();
- Revisions.Columns[2].HeaderText = Strings.GetAuthorText();
- Revisions.Columns[3].HeaderText = GetDateHeaderText();
-
- Revisions.SelectionChanged -= RevisionsSelectionChanged;
-
- if (LastSelectedRows != null)
- {
- Revisions.SelectedIds = LastSelectedRows;
- LastSelectedRows = null;
- }
- else if (_initialSelectedRevision == null)
- {
- Revisions.SelectedIds = new IComparable[] { CurrentCheckout };
- }
-
- if (LastScrollPos > 0 && Revisions.RowCount > LastScrollPos)
- {
- Revisions.FirstDisplayedScrollingRowIndex = LastScrollPos;
- LastScrollPos = -1;
- }
-
- Revisions.Enabled = true;
- Revisions.Focus();
- Revisions.SelectionChanged += RevisionsSelectionChanged;
-
- Revisions.ResumeLayout();
-
- if (!_initialLoad)
- return;
-
- _initialLoad = false;
- SelectionTimer.Enabled = false;
- SelectionTimer.Stop();
- SelectionTimer.Enabled = true;
- SelectionTimer.Start();
- }
-
- private void RevisionsCellPainting(object sender, DataGridViewCellPaintingEventArgs e)
- {
- // If our loading state has changed since the last paint, update it.
- if (Loading != null)
- {
- if (Loading.Visible != _isLoading)
- {
- Loading.Visible = _isLoading;
- }
- }
-
- // The graph column is handled by the DvcsGraph
- if (e.ColumnIndex == 0)
- {
- return;
- }
-
- var column = e.ColumnIndex;
- if (e.RowIndex < 0 || (e.State & DataGridViewElementStates.Visible) == 0)
- return;
-
- if (Revisions.RowCount <= e.RowIndex)
- return;
-
- var revision = GetRevision(e.RowIndex);
- if (revision == null)
- return;
-
- e.Handled = true;
-
- bool isRowSelected = ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected);
-
- if (isRowSelected /*&& !showRevisionCards*/)
- e.Graphics.FillRectangle(selectedItemBrush, e.CellBounds);
- else
- e.Graphics.FillRectangle(new SolidBrush(Color.White), e.CellBounds);
-
- Color foreColor;
-
- if (!Settings.RevisionGraphDrawNonRelativesGray || !Settings.RevisionGraphDrawNonRelativesTextGray || Revisions.RowIsRelative(e.RowIndex))
- {
- foreColor = isRowSelected && IsFilledBranchesLayout()
- ? SystemColors.HighlightText
- : e.CellStyle.ForeColor;
- }
- else
- {
- foreColor = Color.LightGray;
- }
-
- Brush foreBrush = new SolidBrush(foreColor);
- var rowFont = NormalFont;
- if (revision.Guid == CurrentCheckout /*&& !showRevisionCards*/)
- rowFont = HeadFont;
- else if (revision.Guid == SuperprojectCurrentCheckout)
- rowFont = SuperprojectFont;
-
- switch (column)
- {
- case 1: //Description!!
- {
- int baseOffset = 0;
- if (IsCardLayout())
- {
- baseOffset = 5;
-
- Rectangle cellRectangle = new Rectangle(e.CellBounds.Left + baseOffset, e.CellBounds.Top + 1, e.CellBounds.Width - (baseOffset * 2), e.CellBounds.Height - 4);
-
- if (!Settings.RevisionGraphDrawNonRelativesGray || Revisions.RowIsRelative(e.RowIndex))
- {
- e.Graphics.FillRectangle(
- new LinearGradientBrush(cellRectangle,
- Color.FromArgb(255, 220, 220, 231),
- Color.FromArgb(255, 240, 240, 250), 90, false), cellRectangle);
- e.Graphics.DrawRectangle(new Pen(Color.FromArgb(255, 200, 200, 200), 1), cellRectangle);
- }
- else
- {
- e.Graphics.FillRectangle(
- new LinearGradientBrush(cellRectangle,
- Color.FromArgb(255, 240, 240, 240),
- Color.FromArgb(255, 250, 250, 250), 90, false), cellRectangle);
- }
-
- if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
- e.Graphics.DrawRectangle(new Pen(Revisions.RowTemplate.DefaultCellStyle.SelectionBackColor, 1), cellRectangle);
- }
-
- float offset = baseOffset;
- var heads = revision.Heads;
-
- if (heads.Count > 0)
- {
- heads.Sort((left, right) =>
- {
- if (left.IsTag != right.IsTag)
- return right.IsTag.CompareTo(left.IsTag);
- if (left.IsRemote != right.IsRemote)
- return left.IsRemote.CompareTo(right.IsRemote);
- return left.Name.CompareTo(right.Name);
- });
-
- foreach (var head in heads)
- {
- if ((head.IsRemote && !ShowRemoteBranches.Checked))
- continue;
-
- Font refsFont;
-
- if (IsFilledBranchesLayout())
- {
- //refsFont = head.Selected ? rowFont : new Font(rowFont, FontStyle.Regular);
- refsFont = rowFont;
-
- //refsFont = head.Selected
- // ? new Font(rowFont, rowFont.Style | FontStyle.Italic)
- // : rowFont;
- }
- else
- {
- refsFont = RefsFont;
- }
-
- Color headColor = GetHeadColor(head);
- Brush textBrush = new SolidBrush(headColor);
-
- string headName;
- PointF location;
-
- if (IsCardLayout())
- {
- headName = head.Name;
- offset += e.Graphics.MeasureString(headName, refsFont).Width + 6;
- location = new PointF(e.CellBounds.Right - offset, e.CellBounds.Top + 4);
- var size = new SizeF(e.Graphics.MeasureString(headName, refsFont).Width,
- e.Graphics.MeasureString(headName, RefsFont).Height);
- e.Graphics.FillRectangle(new SolidBrush(SystemColors.Info), location.X - 1,
- location.Y - 1, size.Width + 3, size.Height + 2);
- e.Graphics.DrawRectangle(new Pen(SystemColors.InfoText), location.X - 1,
- location.Y - 1, size.Width + 3, size.Height + 2);
- e.Graphics.DrawString(headName, refsFont, textBrush, location);
- }
- else
- {
- headName = IsFilledBranchesLayout()
- ? head.Name
- : string.Concat("[", head.Name, "] ");
-
- var headBounds = AdjustCellBounds(e.CellBounds, offset);
- SizeF textSize = e.Graphics.MeasureString(headName, refsFont);
-
- offset += textSize.Width;
-
- if (IsFilledBranchesLayout())
- {
- offset += 9;
-
- float extraOffset = DrawHeadBackground(isRowSelected, e.Graphics,
- headColor, headBounds.X,
- headBounds.Y,
- RoundToEven(textSize.Width + 3),
- RoundToEven(textSize.Height), 3,
- head.Selected,
- head.SelectedHeadMergeSource);
-
- offset += extraOffset;
- headBounds.Offset((int)(extraOffset + 1), 0);
- }
-
- DrawColumnText(e.Graphics, headName, refsFont, headColor, headBounds);
- }
- }
- }
-
- if (IsCardLayout())
- offset = baseOffset;
-
- var text = (string)e.FormattedValue;
- var bounds = AdjustCellBounds(e.CellBounds, offset);
- DrawColumnText(e.Graphics, text, rowFont, foreColor, bounds);
-
- if (IsCardLayout())
- {
- int textHeight = (int)e.Graphics.MeasureString(text, rowFont).Height;
- int gravatarSize = rowHeigth - textHeight - 12;
- int gravatarTop = e.CellBounds.Top + textHeight + 6;
- int gravatarLeft = e.CellBounds.Left + baseOffset + 2;
-
-
- Image gravatar = Gravatar.GravatarService.GetImageFromCache(revision.AuthorEmail + gravatarSize.ToString() + ".png", revision.AuthorEmail, Settings.AuthorImageCacheDays, gravatarSize, Settings.GravatarCachePath, FallBackService.MonsterId);
-
- if (gravatar == null && !string.IsNullOrEmpty(revision.AuthorEmail))
- {
- ThreadPool.QueueUserWorkItem(o =>
- Gravatar.GravatarService.LoadCachedImage(revision.AuthorEmail + gravatarSize.ToString() + ".png", revision.AuthorEmail, null, Settings.AuthorImageCacheDays, gravatarSize, Settings.GravatarCachePath, RefreshGravatar, FallBackService.MonsterId));
- }
-
- if (gravatar != null)
- e.Graphics.DrawImage(gravatar, gravatarLeft + 1, gravatarTop + 1, gravatarSize, gravatarSize);
-
- e.Graphics.DrawRectangle(Pens.Black, gravatarLeft, gravatarTop, gravatarSize + 1, gravatarSize + 1);
-
- string authorText;
- string timeText;
-
- if (rowHeigth >= 60)
- {
- authorText = revision.Author;
- timeText = TimeToString(Settings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate);
- }
- else
- {
- timeText = string.Concat(revision.Author, " (", TimeToString(Settings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate), ")");
- authorText = string.Empty;
- }
-
-
-
- e.Graphics.DrawString(authorText, rowFont, foreBrush,
- new PointF(gravatarLeft + gravatarSize + 5, gravatarTop + 6));
- e.Graphics.DrawString(timeText, rowFont, foreBrush,
- new PointF(gravatarLeft + gravatarSize + 5, e.CellBounds.Bottom - textHeight - 4));
- }
- }
- break;
- case 2:
- {
- var text = (string)e.FormattedValue;
- e.Graphics.DrawString(text, rowFont, foreBrush,
- new PointF(e.CellBounds.Left, e.CellBounds.Top + 4));
- }
- break;
- case 3:
- {
- var time = Settings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate;
- var text = TimeToString(time);
- e.Graphics.DrawString(text, rowFont, foreBrush,
- new PointF(e.CellBounds.Left, e.CellBounds.Top + 4));
- }
- break;
- }
- }
-
- private void RevisionsCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
- {
- var column = e.ColumnIndex;
- if (…
Large files files are truncated, but you can click here to view the full file