/GitUI/FormBrowse.cs
C# | 2484 lines | 2357 code | 91 blank | 36 comment | 76 complexity | a754b2455a0e0d098630f5d2bdcf37ed 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.Collections.Specialized;
- using System.Diagnostics;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
- using GitCommands;
- using GitCommands.Repository;
- using GitUI.Hotkey;
- using GitUI.Plugin;
- using GitUI.RepoHosting;
- using GitUI.Script;
- using GitUI.Statistics;
- using GitUIPluginInterfaces;
- using ICSharpCode.TextEditor.Util;
- #if !__MonoCS__
- using Microsoft.WindowsAPICodePack.Taskbar;
- #endif
- using ResourceManager.Translation;
-
- namespace GitUI
- {
- public partial class FormBrowse : GitExtensionsForm
- {
- #region Translation
-
- private readonly TranslationString _stashCount =
- new TranslationString("{0} saved {1}");
- private readonly TranslationString _stashPlural =
- new TranslationString("stashes");
- private readonly TranslationString _stashSingular =
- new TranslationString("stash");
-
- private readonly TranslationString _warningMiddleOfBisect =
- new TranslationString("Your are in the middle of a bisect");
- private readonly TranslationString _warningMiddleOfRebase =
- new TranslationString("You are in the middle of a rebase");
- private readonly TranslationString _warningMiddleOfPatchApply =
- new TranslationString("You are in the middle of a patch apply");
-
- private readonly TranslationString _hintUnresolvedMergeConflicts =
- new TranslationString("There are unresolved merge conflicts!");
-
- private static readonly TranslationString _noBranchTitle =
- new TranslationString("no branch");
-
- private readonly TranslationString _noSubmodulesPresent =
- new TranslationString("No submodules");
-
- private readonly TranslationString _saveFileFilterCurrentFormat =
- new TranslationString("Current format");
- private readonly TranslationString _saveFileFilterAllFiles =
- new TranslationString("All files");
-
- private readonly TranslationString _indexLockDeleted =
- new TranslationString("index.lock deleted.");
- private readonly TranslationString _indexLockNotFound =
- new TranslationString("index.lock not found at:");
-
- private readonly TranslationString _errorCaption =
- new TranslationString("Error");
-
- private readonly TranslationString _noReposHostPluginLoaded =
- new TranslationString("No repository host plugin loaded.");
-
- private readonly TranslationString _noReposHostFound =
- new TranslationString("Could not find any relevant repository hosts for the currently open repository.");
-
- private readonly TranslationString _noRevisionFoundError =
- new TranslationString("No revision found.");
-
- private readonly TranslationString _configureWorkingDirMenu =
- new TranslationString("Configure this menu");
-
- private readonly TranslationString _UnsupportedMultiselectAction =
- new TranslationString("Operation not supported");
-
- #endregion
-
- private string _NoDiffFilesChangesText;
-
- private readonly SynchronizationContext syncContext;
- private readonly IndexWatcher _indexWatcher = new IndexWatcher();
-
- private Dashboard _dashboard;
- private ToolStripItem _rebase;
- private ToolStripItem _bisect;
- private ToolStripItem _warning;
-
- #if !__MonoCS__
- private ThumbnailToolBarButton _commitButton;
- private ThumbnailToolBarButton _pushButton;
- private ThumbnailToolBarButton _pullButton;
- private bool _toolbarButtonsCreated;
- #endif
- private bool _dontUpdateOnIndexChange;
- private ToolStripGitStatus _toolStripGitStatus;
- private FilterRevisionsHelper filterRevisionsHelper;
- private FilterBranchHelper _FilterBranchHelper;
-
- public FormBrowse(string filter)
- {
- syncContext = SynchronizationContext.Current;
-
- InitializeComponent();
- filterRevisionsHelper = new FilterRevisionsHelper(toolStripTextBoxFilter, toolStripDropDownButton1, RevisionGrid, toolStripLabel2, this);
- _FilterBranchHelper = new FilterBranchHelper(toolStripBranches, toolStripDropDownButton2, RevisionGrid);
- Translate();
- _NoDiffFilesChangesText = DiffFiles.GetNoFilesText();
-
- #if !__MonoCS__
- if (Settings.RunningOnWindows() && TaskbarManager.IsPlatformSupported)
- {
- TaskbarManager.Instance.ApplicationId = "HenkWesthuis.GitExtensions";
- }
- #endif
- if (Settings.ShowGitStatusInBrowseToolbar)
- {
- _toolStripGitStatus = new ToolStripGitStatus
- {
- ImageTransparentColor = System.Drawing.Color.Magenta
- };
- _toolStripGitStatus.Click += StatusClick;
- ToolStrip.Items.Insert(ToolStrip.Items.IndexOf(toolStripButton1), _toolStripGitStatus);
- ToolStrip.Items.Remove(toolStripButton1);
- _toolStripGitStatus.CommitTranslatedString = toolStripButton1.Text;
- }
- RevisionGrid.SelectionChanged += RevisionGridSelectionChanged;
- DiffText.ExtraDiffArgumentsChanged += DiffTextExtraDiffArgumentsChanged;
- filterRevisionsHelper.SetFilter(filter);
- DiffText.SetFileLoader(getNextPatchFile);
-
- GitTree.ImageList = new ImageList();
- GitTree.ImageList.Images.Add(Properties.Resources.New); //File
- GitTree.ImageList.Images.Add(Properties.Resources.Folder); //Folder
- GitTree.ImageList.Images.Add(Properties.Resources.Submodule); //Submodule
-
- GitTree.MouseDown += GitTree_MouseDown;
- GitTree.MouseMove += GitTree_MouseMove;
-
- this.HotkeysEnabled = true;
- this.Hotkeys = HotkeySettingsManager.LoadHotkeys(HotkeySettingsName);
- this.toolPanel.SplitterDistance = this.ToolStrip.Height;
- this._dontUpdateOnIndexChange = false;
- Settings.WorkingDirChanged += (a, b, c) => RefreshPullIcon();
- RefreshPullIcon();
- dontSetAsDefaultToolStripMenuItem.Checked = Settings.DonSetAsLastPullAction;
-
- GitUICommands.Instance.BrowseInitialize += (a, b) => Initialize();
- }
-
- private void ShowDashboard()
- {
- if (_dashboard == null)
- {
- _dashboard = new Dashboard();
- _dashboard.WorkingDirChanged += DashboardWorkingDirChanged;
- toolPanel.Panel2.Controls.Add(_dashboard);
- _dashboard.Dock = DockStyle.Fill;
- }
- else
- _dashboard.Refresh();
- _dashboard.Visible = true;
- _dashboard.BringToFront();
- _dashboard.ShowRecentRepositories();
- }
-
- private void HideDashboard()
- {
- if (_dashboard != null)
- _dashboard.Visible = false;
- }
-
- private void DashboardWorkingDirChanged(object sender, EventArgs e)
- {
- WorkingDirChanged(false);
- }
-
- private void GitTree_AfterSelect(object sender, TreeViewEventArgs e)
- {
- var item = e.Node.Tag as GitItem;
- if (item == null)
- return;
-
- if (item.IsBlob)
- FileText.ViewGitItem(item.FileName, item.Guid);
- else
- FileText.ViewText("", "");
- }
-
- private void BrowseLoad(object sender, EventArgs e)
- {
- RevisionGrid.Load();
-
- RestorePosition("browse");
-
- Cursor.Current = Cursors.WaitCursor;
- InternalInitialize(false);
- RevisionGrid.Focus();
- RevisionGrid.ActionOnRepositoryPerformed += ActionOnRepositoryPerformed;
- IndexWatcher.Reset();
-
- IndexWatcher.Changed += _indexWatcher_Changed;
-
- Cursor.Current = Cursors.Default;
-
-
- try
- {
- if (Settings.PlaySpecialStartupSound)
- {
- new System.Media.SoundPlayer(Properties.Resources.cow_moo).Play();
- }
- }
- catch // This code is just for fun, we do not want the program to crash because of it.
- {
- }
- }
-
- void _indexWatcher_Changed(bool indexChanged)
- {
- syncContext.Post(o =>
- {
- RefreshButton.Image = indexChanged && Settings.UseFastChecks && Settings.Module.ValidWorkingDir()
- ? GitUI.Properties.Resources.arrow_refresh_dirty
- : GitUI.Properties.Resources.arrow_refresh;
- }, this);
- }
-
- private bool pluginsLoaded;
- private void LoadPluginsInPluginMenu()
- {
- if (!pluginsLoaded)
- {
- foreach (var plugin in LoadedPlugins.Plugins)
- {
- var item = new ToolStripMenuItem { Text = plugin.Description, Tag = plugin };
- item.Click += ItemClick;
- pluginsToolStripMenuItem.DropDownItems.Add(item);
- }
- pluginsLoaded = true;
- UpdatePluginMenu(Settings.Module.ValidWorkingDir());
- }
- }
-
- /// <summary>
- /// Execute plugin
- /// </summary>
- private void ItemClick(object sender, EventArgs e)
- {
- var menuItem = sender as ToolStripMenuItem;
- if (menuItem == null)
- return;
-
- var plugin = menuItem.Tag as IGitPlugin;
- if (plugin == null)
- return;
-
- var eventArgs = new GitUIEventArgs(this, GitUICommands.Instance);
-
- string workingDirBefore = Settings.WorkingDir;
- bool refresh = plugin.Execute(eventArgs);
- if (workingDirBefore != Settings.WorkingDir)
- WorkingDirChanged(false);
- else if (refresh)
- RefreshToolStripMenuItemClick(null, null);
- }
-
- private void UpdatePluginMenu(bool validWorkingDir)
- {
- foreach (ToolStripItem item in pluginsToolStripMenuItem.DropDownItems)
- {
- var plugin = item.Tag as IGitPluginForRepository;
-
- item.Enabled = plugin == null || validWorkingDir;
- }
- }
-
- private void ActionOnRepositoryPerformed(object sender, EventArgs e)
- {
- InternalInitialize(false);
- }
-
- protected void Initialize()
- {
- try
- {
- InternalInitialize(true);
- }
- catch (Exception exception)
- {
- MessageBox.Show(this, exception.Message, _errorCaption.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- private void InternalInitialize(bool hard)
- {
- Cursor.Current = Cursors.WaitCursor;
-
- GitUICommands.Instance.RaisePreBrowseInitialize(this);
-
- bool validWorkingDir = Settings.Module.ValidWorkingDir();
- bool hasWorkingDir = !string.IsNullOrEmpty(Settings.WorkingDir);
- branchSelect.Text = validWorkingDir ? Settings.Module.GetSelectedBranch() : "";
- if (hasWorkingDir)
- HideDashboard();
- else
- ShowDashboard();
- CommitInfoTabControl.Visible = validWorkingDir;
- fileExplorerToolStripMenuItem.Enabled = validWorkingDir;
- commandsToolStripMenuItem.Enabled = validWorkingDir;
- manageRemoteRepositoriesToolStripMenuItem1.Enabled = validWorkingDir;
- branchSelect.Enabled = validWorkingDir;
- toolStripButton1.Enabled = validWorkingDir;
- if (_toolStripGitStatus != null)
- _toolStripGitStatus.Enabled = validWorkingDir;
- toolStripButtonPull.Enabled = validWorkingDir;
- toolStripButtonPush.Enabled = validWorkingDir;
- submodulesToolStripMenuItem.Enabled = validWorkingDir;
- UpdatePluginMenu(validWorkingDir);
- gitMaintenanceToolStripMenuItem.Enabled = validWorkingDir;
- editgitignoreToolStripMenuItem1.Enabled = validWorkingDir;
- editgitattributesToolStripMenuItem.Enabled = validWorkingDir;
- editmailmapToolStripMenuItem.Enabled = validWorkingDir;
- toolStripSplitStash.Enabled = validWorkingDir;
- commitcountPerUserToolStripMenuItem.Enabled = validWorkingDir;
- _createPullRequestsToolStripMenuItem.Enabled = validWorkingDir;
- _viewPullRequestsToolStripMenuItem.Enabled = validWorkingDir;
- //Only show "Repository hosts" menu item when there is at least 1 repository host plugin loaded
- _repositoryHostsToolStripMenuItem.Visible = RepoHosts.GitHosters.Count > 0;
- if (RepoHosts.GitHosters.Count == 1)
- _repositoryHostsToolStripMenuItem.Text = RepoHosts.GitHosters[0].Description;
- _FilterBranchHelper.InitToolStripBranchFilter();
- if (hard)
- ShowRevisions();
- RefreshWorkingDirCombo();
- Text = GenerateWindowTitle(Settings.WorkingDir, validWorkingDir, branchSelect.Text);
- DiffText.Font = Settings.DiffFont;
- UpdateJumplist(validWorkingDir);
-
- CheckForMergeConflicts();
- UpdateStashCount();
- // load custom user menu
- LoadUserMenu();
-
- GitUICommands.Instance.RaisePostBrowseInitialize(this);
-
- Cursor.Current = Cursors.Default;
- }
-
- private void RefreshWorkingDirCombo()
- {
- if (Settings.RecentReposComboMinWidth > 0)
- {
- _NO_TRANSLATE_Workingdir.AutoSize = false;
- _NO_TRANSLATE_Workingdir.Width = Settings.RecentReposComboMinWidth;
- }
- else
- _NO_TRANSLATE_Workingdir.AutoSize = true;
-
- Repository r = null;
- if (Repositories.RepositoryHistory.Repositories.Count > 0)
- r = Repositories.RepositoryHistory.Repositories[0];
-
- List<RecentRepoInfo> mostRecentRepos = new List<RecentRepoInfo>();
-
- if (r == null || !r.Path.Equals(Settings.WorkingDir, StringComparison.InvariantCultureIgnoreCase))
- Repositories.AddMostRecentRepository(Settings.WorkingDir);
-
- using (var graphics = CreateGraphics())
- {
- var splitter = new RecentRepoSplitter
- {
- measureFont = _NO_TRANSLATE_Workingdir.Font,
- graphics = graphics
- };
- splitter.SplitRecentRepos(Repositories.RepositoryHistory.Repositories, mostRecentRepos, mostRecentRepos);
- }
-
- RecentRepoInfo ri = mostRecentRepos.Find((e) => e.Repo.Path.Equals(Settings.WorkingDir, StringComparison.InvariantCultureIgnoreCase));
-
- if (ri == null)
- _NO_TRANSLATE_Workingdir.Text = Settings.WorkingDir;
- else
- _NO_TRANSLATE_Workingdir.Text = ri.Caption;
- }
-
- /// <summary>
- /// Returns a short name for repository.
- /// If the repository contains a description it is returned,
- /// otherwise the last part of path is returned.
- /// </summary>
- /// <param name="repositoryDir">Path to repository.</param>
- /// <returns>Short name for repository</returns>
- private static String GetRepositoryShortName(string repositoryDir)
- {
- DirectoryInfo dirInfo = new DirectoryInfo(repositoryDir);
- if (dirInfo.Exists)
- {
- string desc = ReadRepositoryDescription(repositoryDir);
- if (desc.IsNullOrEmpty())
- {
- desc = Repositories.RepositoryHistory.Repositories
- .Where(repo => repo.Path.Equals(repositoryDir, StringComparison.CurrentCultureIgnoreCase)).Select(repo => repo.Title)
- .FirstOrDefault();
- }
- return desc ?? dirInfo.Name;
- }
- return dirInfo.Name;
- }
-
- private void LoadUserMenu()
- {
- var scripts = ScriptManager.GetScripts().Where(script => script.Enabled
- && script.OnEvent == ScriptEvent.ShowInUserMenuBar).ToList();
-
- for (int i = ToolStrip.Items.Count - 1; i >= 0; i--)
- if (ToolStrip.Items[i].Tag != null &&
- ToolStrip.Items[i].Tag as String == "userscript")
- ToolStrip.Items.RemoveAt(i);
-
- if (scripts.Count == 0)
- return;
-
- ToolStripSeparator toolstripseparator = new ToolStripSeparator();
- toolstripseparator.Tag = "userscript";
- ToolStrip.Items.Add(toolstripseparator);
-
- foreach (ScriptInfo scriptInfo in scripts)
- {
- ToolStripButton tempButton = new ToolStripButton();
- //store scriptname
- tempButton.Text = scriptInfo.Name;
- tempButton.Tag = "userscript";
- //add handler
- tempButton.Click += UserMenu_Click;
- tempButton.Enabled = true;
- tempButton.Visible = true;
- //tempButton.Image = GitUI.Properties.Resources.bug;
- //scriptInfo.Icon = "Cow";
- tempButton.Image = scriptInfo.GetIcon();
- tempButton.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
- //add to toolstrip
- ToolStrip.Items.Add(tempButton);
- }
- }
-
- private void UserMenu_Click(object sender, EventArgs e)
- {
- ScriptRunner.RunScript(((ToolStripButton)sender).Text, null);
- RevisionGrid.RefreshRevisions();
- }
-
- private void UpdateJumplist(bool validWorkingDir)
- {
- #if !__MonoCS__
- if (Settings.RunningOnWindows() && TaskbarManager.IsPlatformSupported)
- {
- //Call this method using reflection. This is a workaround to *not* reference WPF libraries, becuase of how the WindowsAPICodePack was implimented.
- TaskbarManager.Instance.GetType().InvokeMember("SetApplicationIdForSpecificWindow", System.Reflection.BindingFlags.InvokeMethod, null, TaskbarManager.Instance, new object[] { Handle, "GitExtensions" });
-
- if (validWorkingDir)
- {
- string repositoryDescription = GetRepositoryShortName(Settings.WorkingDir);
- string baseFolder = Path.Combine(Settings.ApplicationDataPath, "Recent");
- if (!Directory.Exists(baseFolder))
- {
- Directory.CreateDirectory(baseFolder);
- }
-
- //Remove InvalidPathChars
- StringBuilder sb = new StringBuilder(repositoryDescription);
- foreach (char c in Path.GetInvalidFileNameChars())
- {
- sb.Replace(c, '_');
- }
-
- string path = Path.Combine(baseFolder, String.Format("{0}.{1}", sb, "gitext"));
- File.WriteAllText(path, Settings.WorkingDir);
- JumpList.AddToRecent(path);
- }
-
- CreateOrUpdateTaskBarButtons(validWorkingDir);
- }
- #endif
- }
-
- private void CreateOrUpdateTaskBarButtons(bool validRepo)
- {
- #if !__MonoCS__
- if (Settings.RunningOnWindows() && TaskbarManager.IsPlatformSupported)
- {
- if (!_toolbarButtonsCreated)
- {
- _commitButton = new ThumbnailToolBarButton(MakeIcon(toolStripButton1.Image, 48, true), toolStripButton1.Text);
- _commitButton.Click += ToolStripButton1Click;
-
- _pushButton = new ThumbnailToolBarButton(MakeIcon(toolStripButtonPush.Image, 48, true), toolStripButtonPush.Text);
- _pushButton.Click += PushToolStripMenuItemClick;
-
- _pullButton = new ThumbnailToolBarButton(MakeIcon(toolStripButtonPull.Image, 48, true), toolStripButtonPull.Text);
- _pullButton.Click += PullToolStripMenuItemClick;
-
- _toolbarButtonsCreated = true;
- ThumbnailToolBarButton[] buttons = new[] { _commitButton, _pullButton, _pushButton };
-
- //Call this method using reflection. This is a workaround to *not* reference WPF libraries, becuase of how the WindowsAPICodePack was implimented.
- TaskbarManager.Instance.ThumbnailToolBars.GetType().InvokeMember("AddButtons", System.Reflection.BindingFlags.InvokeMethod, null, TaskbarManager.Instance.ThumbnailToolBars,
- new object[] { Handle, buttons });
- }
-
- _commitButton.Enabled = validRepo;
- _pushButton.Enabled = validRepo;
- _pullButton.Enabled = validRepo;
- }
- #endif
- }
-
- /// <summary>
- /// Converts an image into an icon. This was taken off of the interwebs.
- /// It's on a billion different sites and forum posts, so I would say its creative commons by now. -tekmaven
- /// </summary>
- /// <param name="img">The image that shall become an icon</param>
- /// <param name="size">The width and height of the icon. Standard
- /// sizes are 16x16, 32x32, 48x48, 64x64.</param>
- /// <param name="keepAspectRatio">Whether the image should be squashed into a
- /// square or whether whitespace should be put around it.</param>
- /// <returns>An icon!!</returns>
- private static Icon MakeIcon(Image img, int size, bool keepAspectRatio)
- {
- Bitmap square = new Bitmap(size, size); // create new bitmap
- Graphics g = Graphics.FromImage(square); // allow drawing to it
-
- int x, y, w, h; // dimensions for new image
-
- if (!keepAspectRatio || img.Height == img.Width)
- {
- // just fill the square
- x = y = 0; // set x and y to 0
- w = h = size; // set width and height to size
- }
- else
- {
- // work out the aspect ratio
- float r = (float)img.Width / (float)img.Height;
-
- // set dimensions accordingly to fit inside size^2 square
- if (r > 1)
- { // w is bigger, so divide h by r
- w = size;
- h = (int)((float)size / r);
- x = 0; y = (size - h) / 2; // center the image
- }
- else
- { // h is bigger, so multiply w by r
- w = (int)((float)size * r);
- h = size;
- y = 0; x = (size - w) / 2; // center the image
- }
- }
-
- // make the image shrink nicely by using HighQualityBicubic mode
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
- g.DrawImage(img, x, y, w, h); // draw image with specified dimensions
- g.Flush(); // make sure all drawing operations complete before we get the icon
-
- // following line would work directly on any image, but then
- // it wouldn't look as nice.
- return Icon.FromHandle(square.GetHicon());
- }
-
- private void UpdateStashCount()
- {
- if (Settings.ShowStashCount)
- {
- int stashCount = Settings.Module.GetStashes().Count;
- toolStripSplitStash.Text = string.Format(_stashCount.Text, stashCount,
- stashCount != 1 ? _stashPlural.Text : _stashSingular.Text);
- }
- else
- {
- toolStripSplitStash.Text = string.Empty;
- }
- }
-
- private void CheckForMergeConflicts()
- {
- bool validWorkingDir = Settings.Module.ValidWorkingDir();
-
- if (validWorkingDir && Settings.Module.InTheMiddleOfBisect())
- {
-
- if (_bisect == null)
- {
- _bisect = new WarningToolStripItem { Text = _warningMiddleOfBisect.Text };
- _bisect.Click += BisectClick;
- statusStrip.Items.Add(_bisect);
- }
- }
- else
- {
- if (_bisect != null)
- {
- _bisect.Click -= BisectClick;
- statusStrip.Items.Remove(_bisect);
- _bisect = null;
- }
- }
-
- if (validWorkingDir &&
- (Settings.Module.InTheMiddleOfRebase() || Settings.Module.InTheMiddleOfPatch()))
- {
- if (_rebase == null)
- {
- _rebase = new WarningToolStripItem
- {
- Text = Settings.Module.InTheMiddleOfRebase()
- ? _warningMiddleOfRebase.Text
- : _warningMiddleOfPatchApply.Text
- };
- _rebase.Click += RebaseClick;
- statusStrip.Items.Add(_rebase);
- }
- }
- else
- {
- if (_rebase != null)
- {
- _rebase.Click -= RebaseClick;
- statusStrip.Items.Remove(_rebase);
- _rebase = null;
- }
- }
-
- if (validWorkingDir && Settings.Module.InTheMiddleOfConflictedMerge() &&
- !Directory.Exists(Settings.Module.GetGitDirectory() + "rebase-apply\\"))
- {
- if (_warning == null)
- {
- _warning = new WarningToolStripItem { Text = _hintUnresolvedMergeConflicts.Text };
- _warning.Click += WarningClick;
- statusStrip.Items.Add(_warning);
- }
- }
- else
- {
- if (_warning != null)
- {
- _warning.Click -= WarningClick;
- statusStrip.Items.Remove(_warning);
- _warning = null;
- }
- }
-
- //Only show status strip when there are status items on it.
- //There is always a close (x) button, do not count first item.
- if (statusStrip.Items.Count > 1)
- statusStrip.Show();
- else
- statusStrip.Hide();
- }
-
- /// <summary>
- /// Generates main window title according to given repository.
- /// </summary>
- /// <param name="workingDir">Path to repository.</param>
- /// <param name="isWorkingDirValid">If the given path contains valid repository.</param>
- /// <param name="branchName">Current branch name.</param>
- private static string GenerateWindowTitle(string workingDir, bool isWorkingDirValid, string branchName)
- {
- #if DEBUG
- const string defaultTitle = "Git Extensions -> DEBUG <-";
- const string repositoryTitleFormat = "{0} ({1}) - Git Extensions -> DEBUG <-";
- #else
- const string defaultTitle = "Git Extensions";
- const string repositoryTitleFormat = "{0} ({1}) - Git Extensions";
- #endif
- if (!isWorkingDirValid)
- return defaultTitle;
- string repositoryDescription = GetRepositoryShortName(workingDir);
- if (string.IsNullOrEmpty(branchName))
- branchName = _noBranchTitle.Text;
- return string.Format(repositoryTitleFormat, repositoryDescription, branchName.Trim('(', ')'));
- }
-
- /// <summary>
- /// Reads repository description's first line from ".git\description" file.
- /// </summary>
- /// <param name="workingDir">Path to repository.</param>
- /// <returns>If the repository has description, returns that description, else returns <c>null</c>.</returns>
- private static string ReadRepositoryDescription(string workingDir)
- {
- const string repositoryDescriptionFileName = "description";
- const string defaultDescription = "Unnamed repository; edit this file 'description' to name the repository.";
-
- var repositoryPath = GitModule.GetGitDirectory(workingDir);
- var repositoryDescriptionFilePath = Path.Combine(repositoryPath, repositoryDescriptionFileName);
- if (!File.Exists(repositoryDescriptionFilePath))
- return null;
- try
- {
- var repositoryDescription = File.ReadAllLines(repositoryDescriptionFilePath).FirstOrDefault();
- return string.Equals(repositoryDescription, defaultDescription, StringComparison.CurrentCulture)
- ? null
- : repositoryDescription;
- }
- catch (IOException)
- {
- return null;
- }
- }
-
- private void RebaseClick(object sender, EventArgs e)
- {
- if (Settings.Module.InTheMiddleOfRebase())
- GitUICommands.Instance.StartRebaseDialog(this, null);
- else
- GitUICommands.Instance.StartApplyPatchDialog(this);
- Initialize();
- }
-
-
- private void ShowRevisions()
- {
- if (IndexWatcher.IndexChanged)
- {
- RevisionGrid.RefreshRevisions();
- FillFileTree();
- FillDiff();
- FillCommitInfo();
- }
- IndexWatcher.Reset();
- }
-
- //store strings to not keep references to nodes
- private readonly Stack<string> lastSelectedNodes = new Stack<string>();
-
- private void FillFileTree()
- {
- if (CommitInfoTabControl.SelectedTab != Tree)
- return;
-
- try
- {
- GitTree.SuspendLayout();
- // Save state only when there is selected node
- if (GitTree.SelectedNode != null)
- {
- TreeNode node = GitTree.SelectedNode;
- FileText.SaveCurrentScrollPos();
- lastSelectedNodes.Clear();
- while (node != null)
- {
- lastSelectedNodes.Push(node.Text);
- node = node.Parent;
- }
- }
-
- // Refresh tree
- GitTree.Nodes.Clear();
- //restore selected file and scroll position when new selection is done
- if (RevisionGrid.GetSelectedRevisions().Count > 0)
- {
- LoadInTree(RevisionGrid.GetSelectedRevisions()[0].SubItems, GitTree.Nodes);
- //GitTree.Sort();
- TreeNode lastMatchedNode = null;
- // Load state
- var currenNodes = GitTree.Nodes;
- TreeNode matchedNode = null;
- while (lastSelectedNodes.Count > 0 && currenNodes != null)
- {
- var next = lastSelectedNodes.Pop();
- foreach (TreeNode node in currenNodes)
- {
- if (node.Text != next && next.Length != 40)
- continue;
-
- node.Expand();
- matchedNode = node;
- break;
- }
- if (matchedNode == null)
- currenNodes = null;
- else
- {
- lastMatchedNode = matchedNode;
- currenNodes = matchedNode.Nodes;
- }
- }
- //if there is no exact match, don't restore scroll position
- if (lastMatchedNode != matchedNode)
- FileText.ResetCurrentScrollPos();
- GitTree.SelectedNode = lastMatchedNode;
- }
- if (GitTree.SelectedNode == null)
- {
- FileText.ViewText("", "");
- }
- }
- finally
- {
- GitTree.ResumeLayout();
- }
- }
-
- private void FillDiff()
- {
- if (CommitInfoTabControl.SelectedTab != Diff)
- return;
-
- var revisions = RevisionGrid.GetSelectedRevisions();
-
- DiffText.SaveCurrentScrollPos();
-
- DiffFiles.SetNoFilesText(_NoDiffFilesChangesText);
- switch (revisions.Count)
- {
- case 2:
- bool artificialRevSelected = revisions[0].IsArtificial() || revisions[1].IsArtificial();
- if (artificialRevSelected)
- {
- DiffFiles.SetNoFilesText(_UnsupportedMultiselectAction.Text);
- DiffFiles.GitItemStatuses = null;
- }
- else
- DiffFiles.GitItemStatuses =
- Settings.Module.GetDiffFiles(revisions[0].Guid, revisions[1].Guid);
- break;
- case 0:
- DiffFiles.GitItemStatuses = null;
- return;
- default:
- var revision = revisions[0];
-
- DiffFiles.Revision = revision;
-
- if (revision == null)
- DiffFiles.GitItemStatuses = null;
- else if (revision.ParentGuids == null || revision.ParentGuids.Length == 0)
- DiffFiles.GitItemStatuses = Settings.Module.GetTreeFiles(revision.TreeGuid, true);
- else
- {
- if (revision.Guid == GitRevision.UncommittedWorkingDirGuid) //working dir changes
- DiffFiles.GitItemStatuses = Settings.Module.GetUnstagedFiles();
- else if (revision.Guid == GitRevision.IndexGuid) //index
- DiffFiles.GitItemStatuses = Settings.Module.GetStagedFiles();
- else
- DiffFiles.GitItemStatuses = Settings.Module.GetDiffFiles(revision.Guid, revision.ParentGuids[0]);
- }
- break;
- }
- }
-
- private void FillCommitInfo()
- {
- if (CommitInfoTabControl.SelectedTab != CommitInfo)
- return;
-
- if (RevisionGrid.GetSelectedRevisions().Count == 0)
- return;
-
- var revision = RevisionGrid.GetSelectedRevisions()[0];
-
- if (revision != null)
- RevisionInfo.SetRevision(revision.Guid);
- }
-
- public void FileHistoryOnClick(object sender, EventArgs e)
- {
- var item = GitTree.SelectedNode.Tag as GitItem;
-
- if (item == null)
- return;
-
- if (item.IsBlob || item.IsTree)
- {
- IList<GitRevision> revisions = RevisionGrid.GetSelectedRevisions();
-
- if (revisions.Count == 0)
- GitUICommands.Instance.StartFileHistoryDialog(this, item.FileName);
- else
- GitUICommands.Instance.StartFileHistoryDialog(this, item.FileName, revisions[0], false, false);
- }
- }
-
- public void FindFileOnClick(object sender, EventArgs e)
- {
- var searchWindow = new SearchWindow<string>(FindFileMatches)
- {
- Owner = this
- };
- searchWindow.ShowDialog(this);
- string selectedItem = searchWindow.SelectedItem;
- if (string.IsNullOrEmpty(selectedItem))
- {
- return;
- }
-
- string[] items = selectedItem.Split(new[] { '/' });
- TreeNodeCollection nodes = GitTree.Nodes;
-
- for (int i = 0; i < items.Length - 1; i++)
- {
- TreeNode selectedNode = Find(nodes, items[i]);
-
- if (selectedNode == null)
- {
- return; //Item does not exist in the tree
- }
-
- selectedNode.Expand();
- nodes = selectedNode.Nodes;
- }
-
- var lastItem = Find(nodes, items[items.Length - 1]);
- if (lastItem != null)
- {
- GitTree.SelectedNode = lastItem;
- }
- }
-
- private static TreeNode Find(TreeNodeCollection nodes, string label)
- {
- for (int i = 0; i < nodes.Count; i++)
- {
- if (nodes[i].Text == label)
- {
- return nodes[i];
- }
- }
- return null;
- }
-
- private IList<string> FindFileMatches(string name)
- {
- var candidates = Settings.Module.GetFullTree(RevisionGrid.GetSelectedRevisions()[0].TreeGuid);
-
- string nameAsLower = name.ToLower();
-
- return candidates.Where(fileName => fileName.ToLower().Contains(nameAsLower)).ToList();
- }
-
- public void OpenWithOnClick(object sender, EventArgs e)
- {
- var gitItem = GitTree.SelectedNode.Tag as GitItem;
- if (gitItem == null || !gitItem.IsBlob)
- return;
-
- var fileName = gitItem.FileName;
- if (fileName.Contains("\\") && fileName.LastIndexOf("\\") < fileName.Length)
- fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
- if (fileName.Contains("/") && fileName.LastIndexOf("/") < fileName.Length)
- fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
-
- fileName = (Path.GetTempPath() + fileName).Replace(Settings.PathSeparatorWrong, Settings.PathSeparator);
- Settings.Module.SaveBlobAs(fileName, gitItem.Guid);
- OpenWith.OpenAs(fileName);
- }
-
- private void FileTreeContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
- {
- var gitItem = (GitTree.SelectedNode != null) ? GitTree.SelectedNode.Tag as GitItem : null;
- var enableItems = gitItem != null && gitItem.IsBlob;
-
- saveAsToolStripMenuItem.Enabled = enableItems;
- openFileToolStripMenuItem.Enabled = enableItems;
- openFileWithToolStripMenuItem.Enabled = enableItems;
- openWithToolStripMenuItem.Enabled = enableItems;
- copyFilenameToClipboardToolStripMenuItem.Enabled = enableItems;
- fileHistoryToolStripMenuItem.Enabled = enableItems;
- editCheckedOutFileToolStripMenuItem.Enabled = enableItems;
- }
-
- public void OpenOnClick(object sender, EventArgs e)
- {
- try
- {
- var gitItem = GitTree.SelectedNode.Tag as GitItem;
- if (gitItem == null || !gitItem.IsBlob)
- return;
-
- var fileName = gitItem.FileName;
- if (fileName.Contains("\\") && fileName.LastIndexOf("\\") < fileName.Length)
- fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
- if (fileName.Contains("/") && fileName.LastIndexOf("/") < fileName.Length)
- fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
-
- fileName = (Path.GetTempPath() + fileName).Replace(Settings.PathSeparatorWrong, Settings.PathSeparator);
-
- Settings.Module.SaveBlobAs(fileName, (gitItem).Guid);
-
- Process.Start(fileName);
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, ex.Message);
- }
- }
-
- protected void LoadInTree(List<IGitItem> items, TreeNodeCollection node)
- {
- items.Sort(new GitFileTreeComparer());
-
- foreach (var item in items)
- {
- var subNode = node.Add(item.Name);
- subNode.Tag = item;
-
- var gitItem = item as GitItem;
-
- if (gitItem == null)
- subNode.Nodes.Add(new TreeNode());
- else
- {
- if (gitItem.IsTree)
- {
- subNode.ImageIndex = 1;
- subNode.SelectedImageIndex = 1;
- subNode.Nodes.Add(new TreeNode());
- }
- else
- if (gitItem.IsCommit)
- {
- subNode.ImageIndex = 2;
- subNode.SelectedImageIndex = 2;
- subNode.Text = item.Name + " (Submodule)";
- }
- }
- }
- }
-
- private void RevisionGridSelectionChanged(object sender, EventArgs e)
- {
- try
- {
- var revisions = RevisionGrid.GetSelectedRevisions();
-
- if (revisions.Count > 0 &&
- (revisions[0].Guid == GitRevision.UncommittedWorkingDirGuid ||
- revisions[0].Guid == GitRevision.IndexGuid))
- {
- CommitInfoTabControl.RemoveIfExists(CommitInfo);
- CommitInfoTabControl.RemoveIfExists(Tree);
- }
- else
- {
- CommitInfoTabControl.InsertIfNotExists(0, CommitInfo);
- CommitInfoTabControl.InsertIfNotExists(1, Tree);
- }
-
- FillFileTree();
- FillDiff();
- FillCommitInfo();
- }
- catch (Exception ex)
- {
- Trace.WriteLine(ex.Message);
- }
- }
-
- private void OpenToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (new Open().ShowDialog(this) == DialogResult.OK)
- {
- WorkingDirChanged(false);
- }
- }
-
- private void CheckoutToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartCheckoutRevisionDialog(this))
- Initialize();
- }
-
- private void GitTreeDoubleClick(object sender, EventArgs e)
- {
- if (GitTree.SelectedNode == null || !(GitTree.SelectedNode.Tag is IGitItem))
- return;
-
- var item = GitTree.SelectedNode.Tag as GitItem;
- if (item == null)
- return;
-
- if (!item.IsBlob)
- return;
-
- if (GitUICommands.Instance.StartFileHistoryDialog(this, item.FileName, null))
- Initialize();
- }
-
- private void ViewDiffToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartCompareRevisionsDialog(this))
- Initialize();
- }
-
- private void CloneToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartCloneDialog(this))
- Initialize();
- }
-
- private void CommitToolStripMenuItemClick(object sender, EventArgs e)
- {
- GitUICommands.Instance.StartCommitDialog(Initialize, this);
- }
-
- private void InitNewRepositoryToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartInitializeDialog(this))
- Initialize();
- }
-
- private void PushToolStripMenuItemClick(object sender, EventArgs e)
- {
- bool bSilent = (ModifierKeys & Keys.Shift) != 0;
- if (GitUICommands.Instance.StartPushDialog(this, bSilent))
- Initialize();
- }
-
- private void PullToolStripMenuItemClick(object sender, EventArgs e)
- {
- bool bSilent;
- if (sender == toolStripButtonPull || sender == pullToolStripMenuItem)
- {
- if (Settings.LastPullAction == Settings.PullAction.None)
- {
- bSilent = (ModifierKeys & Keys.Shift) != 0;
- }
- else
- {
- bSilent = true;
- Settings.LastPullActionToPullMerge();
- }
- }
- else
- {
- bSilent = sender != pullToolStripMenuItem1;
- RefreshPullIcon();
- Settings.LastPullActionToPullMerge();
- }
-
- if (GitUICommands.Instance.StartPullDialog(this, bSilent))
- Initialize();
-
- }
-
- private void RefreshToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (_dashboard != null)
- {
- _dashboard.Refresh();
- }
-
- if (_dashboard == null || !_dashboard.Visible)
- {
- RevisionGrid.ForceRefreshRevisions();
- InternalInitialize(false);
- IndexWatcher.Reset();
- }
- }
-
- private void AboutToolStripMenuItemClick(object sender, EventArgs e)
- {
- new AboutBox().ShowDialog(this);
- }
-
- private void PatchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartViewPatchDialog(this))
- Initialize();
- }
-
- private void ApplyPatchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartApplyPatchDialog(this))
- Initialize();
- }
-
- private void GitBashToolStripMenuItemClick1(object sender, EventArgs e)
- {
- Settings.Module.RunBash();
- }
-
- private void GitGuiToolStripMenuItemClick(object sender, EventArgs e)
- {
- Settings.Module.RunGui();
- }
-
- private void FormatPatchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartFormatPatchDialog(this))
- Initialize();
- }
-
- private void GitcommandLogToolStripMenuItemClick(object sender, EventArgs e)
- {
- GitLogForm.ShowOrActivate(this);
- }
-
- private void CheckoutBranchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartCheckoutBranchDialog(this))
- Initialize();
- }
-
- private void StashToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartStashDialog(this))
- Initialize();
- }
-
- private void RunMergetoolToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartResolveConflictsDialog(this))
- Initialize();
- }
-
- private void WarningClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartResolveConflictsDialog(this))
- Initialize();
- }
-
- private void WorkingdirClick(object sender, EventArgs e)
- {
- _NO_TRANSLATE_Workingdir.ShowDropDown();
- }
-
- private void CurrentBranchClick(object sender, EventArgs e)
- {
- branchSelect.ShowDropDown();
- }
-
- private void DeleteBranchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartDeleteBranchDialog(this, null))
- Initialize();
- }
-
- private void CherryPickToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartCherryPickDialog(this))
- Initialize();
- }
-
- private void MergeBranchToolStripMenuItemClick(object sender, EventArgs e)
- {
- if (GitUICommands.Instance.StartMergeBranchDialog(this, null))
- Initialize();
- }
-
- private void ToolStripButton1Click(object sender, EventArgs e)
- {
- CommitToolStripMenuItemClick(sender, e);
- }
-
- private void Set…
Large files files are truncated, but you can click here to view the full file