private string getContextHtmlText(DiffPosition position, IGitCommandService git, out string stylesheet) { stylesheet = String.Empty; DiffContext?context; try { ContextDepth depth = new ContextDepth(0, 3); IContextMaker textContextMaker = new SimpleContextMaker(git); context = textContextMaker.GetContext(position, depth); } catch (Exception ex) { if (ex is ArgumentException || ex is ContextMakingException) { string errorMessage = "Cannot render HTML context."; ExceptionHandlers.Handle(errorMessage, ex); return(String.Format("<html><body>{0} See logs for details</body></html>", errorMessage)); } throw; } Debug.Assert(context.HasValue); DiffContextFormatter formatter = new DiffContextFormatter(WinFormsHelpers.GetFontSizeInPixels(htmlPanelContext), 2); stylesheet = formatter.GetStylesheet(); return(formatter.GetBody(context.Value)); }
internal DiffCallHandler(IGitCommandService git, IModificationListener modificationListener, User currentUser, Action <MergeRequestKey> onDiscussionSubmitted) { _git = git ?? throw new ArgumentException("git argument cannot be null"); _modificationListener = modificationListener; _currentUser = currentUser; _onDiscussionSubmitted = onDiscussionSubmitted; }
public FileNameMatcher(IGitCommandService git, Action <string, string> onFileMove, Func <string, string, string, bool> onFileRename, Func <string, bool> onWrongMatch) { _git = git; _onFileMove = onFileMove; _onFileRename = onFileRename; _onWrongMatch = onWrongMatch; }
public DiscussionsForm( IGitCommandService git, User currentUser, MergeRequestKey mrk, IEnumerable <Discussion> discussions, string mergeRequestTitle, User mergeRequestAuthor, ColorScheme colorScheme, AsyncDiscussionLoader discussionLoader, AsyncDiscussionHelper discussionHelper, string webUrl, Shortcuts shortcuts, Func <ICommandCallback, IEnumerable <ICommand> > getCommands) { _mergeRequestKey = mrk; _mergeRequestTitle = mergeRequestTitle; _discussionLoader = discussionLoader; _discussionLoader.StatusChanged += onDiscussionLoaderStatusChanged; CommonControls.Tools.WinFormsHelpers.FixNonStandardDPIIssue(this, (float)Common.Constants.Constants.FontSizeChoices["Design"]); InitializeComponent(); applyFont(Program.Settings.MainWindowFontSizeName); applyTheme(Program.Settings.VisualThemeName); var discussionLayout = new DiscussionLayout( ConfigurationHelper.GetDiffContextPosition(Program.Settings), ConfigurationHelper.GetDiscussionColumnWidth(Program.Settings), Program.Settings.NeedShiftReplies); _discussionLayout = discussionLayout; _discussionLayout.DiffContextPositionChanged += updateSaveDefaultLayoutState; _discussionLayout.DiscussionColumnWidthChanged += updateSaveDefaultLayoutState; _discussionLayout.NeedShiftRepliesChanged += updateSaveDefaultLayoutState; updateSaveDefaultLayoutState(); Program.Settings.PropertyChanged += onSettingsPropertyChanged; var displayFilter = new DiscussionFilter(currentUser, mergeRequestAuthor, DiscussionFilterState.Default); var discussionSort = new DiscussionSort(DiscussionSortState.Default); // Includes making some boxes visible. This does not paint them because their parent (Form) is hidden so far. discussionPanel.Initialize(discussionSort, displayFilter, discussionLoader, discussions, shortcuts, git, colorScheme, mrk, mergeRequestAuthor, currentUser, discussionLayout); if (discussionPanel.DiscussionCount < 1) { throw new NoDiscussionsToShow(); } searchPanel.Initialize(discussionPanel); discussionMenu.Initialize(discussionSort, displayFilter, discussionLayout, discussionLoader, discussionHelper, getCommands(this), applyFont); linkLabelGitLabURL.Text = webUrl; toolTip.SetToolTip(linkLabelGitLabURL, webUrl); linkLabelGitLabURL.SetLinkLabelClicked(UrlHelper.OpenBrowser); Text = DefaultCaption; MainMenuStrip = discussionMenu.MenuStrip; }
/// <summary> /// Throws ContextMakingException. /// </summary> static private IEnumerable <GitDiffSection> getDiffSections(IGitCommandService git, string sha1, string sha2, string filename1, string filename2) { List <GitDiffSection> sections = new List <GitDiffSection>(); GitDiffArguments arguments = new GitDiffArguments( GitDiffArguments.DiffMode.Context, new GitDiffArguments.CommonArguments(sha1, sha2, filename1, filename2, null), new GitDiffArguments.DiffContextArguments(0)); IEnumerable <string> diff; try { diff = git?.ShowDiff(arguments); } catch (GitNotAvailableDataException ex) { throw new ContextMakingException("Cannot obtain git diff", ex); } if (diff == null) { throw new ContextMakingException("Cannot obtain git diff", null); } foreach (string line in diff) { Match m = diffSectionRe.Match(line); if (!m.Success || m.Groups.Count < 3) { continue; } if (!m.Groups["left_start"].Success || !m.Groups["right_start"].Success) { continue; } // @@ -1 +1 @@ is essentially the same as @@ -1,1 +1,1 @@ int leftSectionStart = int.Parse(m.Groups["left_start"].Value); int leftSectionLength = m.Groups["left_len"].Success ? int.Parse(m.Groups["left_len"].Value) : 1; int rightSectionStart = int.Parse(m.Groups["right_start"].Value); int rightSectionLength = m.Groups["right_len"].Success ? int.Parse(m.Groups["right_len"].Value) : 1; GitDiffSection section = new GitDiffSection( leftSectionStart, leftSectionStart + leftSectionLength, rightSectionStart, rightSectionStart + rightSectionLength); sections.Add(section); } return(sections); }
private void showDiscussionContext(string leftSideFileName, string rightSideFileName, DiffPosition position, IGitCommandService git) { string html = getContextHtmlText(position, git, out string stylesheet); htmlPanelContext.BaseStylesheet = stylesheet; htmlPanelContext.Text = html; textBoxFileName.Text = "Left: " + (leftSideFileName == String.Empty ? "N/A" : leftSideFileName) + " Right: " + (rightSideFileName == String.Empty ? "N/A" : rightSideFileName); }
internal DiffCallHandler(IGitCommandService git, User currentUser, Action <MergeRequestKey> onDiscussionSubmitted, Func <MergeRequestKey, IEnumerable <Discussion> > getDiscussions, Shortcuts shortcuts) { _git = git ?? throw new ArgumentException("git argument cannot be null"); _currentUser = currentUser; _onDiscussionSubmitted = onDiscussionSubmitted; _getDiscussions = getDiscussions; _shortcuts = shortcuts; }
internal DiscussionBox( CustomFontForm parent, SingleDiscussionAccessor accessor, IGitCommandService git, User currentUser, ProjectKey projectKey, Discussion discussion, User mergeRequestAuthor, int diffContextDepth, ColorScheme colorScheme, Action <DiscussionBox> preContentChange, Action <DiscussionBox, bool> onContentChanged, Action <Control> onControlGotFocus) { Parent = parent; Discussion = discussion; _accessor = accessor; _editor = accessor.GetDiscussionEditor(); _mergeRequestAuthor = mergeRequestAuthor; _currentUser = currentUser; _imagePath = StringUtils.GetHostWithPrefix(projectKey.HostName) + "/" + projectKey.ProjectName; _diffContextDepth = new ContextDepth(0, diffContextDepth); _tooltipContextDepth = new ContextDepth(5, 5); if (git != null) { _panelContextMaker = new EnhancedContextMaker(git); _tooltipContextMaker = new CombinedContextMaker(git); } _colorScheme = colorScheme; _preContentChange = preContentChange; _onContentChanged = onContentChanged; _onControlGotFocus = onControlGotFocus; _htmlDiffContextToolTip = new HtmlToolTip { AutoPopDelay = 20000, // 20s InitialDelay = 300 }; _htmlDiscussionNoteToolTip = new HtmlToolTip { AutoPopDelay = 20000, // 20s InitialDelay = 300, }; _specialDiscussionNoteMarkdownPipeline = MarkDownUtils.CreatePipeline(Program.ServiceManager.GetJiraServiceUrl()); onCreate(); }
internal NewDiscussionForm(string leftSideFileName, string rightSideFileName, DiffPosition position, IGitCommandService git, Func <string, bool, Task> onSubmitDiscussion) { InitializeComponent(); this.TopMost = Program.Settings.NewDiscussionIsTopMostForm; applyFont(Program.Settings.MainWindowFontSizeName); createWPFTextBox(); this.Text = Constants.StartNewThreadCaption; labelNoteAboutInvisibleCharacters.Text = Constants.WarningOnUnescapedMarkdown; showDiscussionContext(leftSideFileName, rightSideFileName, position, git); buttonCancel.ConfirmationCondition = () => textBoxDiscussionBody.Text.Length > MaximumTextLengthTocancelWithoutConfirmation; _onSubmitDiscussion = onSubmitDiscussion; }
internal void Initialize( DiscussionSort discussionSort, DiscussionFilter displayFilter, AsyncDiscussionLoader discussionLoader, IEnumerable <Discussion> discussions, Shortcuts shortcuts, IGitCommandService git, ColorScheme colorScheme, MergeRequestKey mergeRequestKey, User mergeRequestAuthor, User currentUser, DiscussionLayout discussionLayout) { _shortcuts = shortcuts; _git = git; _colorScheme = colorScheme; _mergeRequestKey = mergeRequestKey; _mergeRequestAuthor = mergeRequestAuthor; _currentUser = currentUser; _discussionSort = discussionSort; _discussionSort.SortStateChanged += onSortStateChanged; _displayFilter = displayFilter; _displayFilter.FilterStateChanged += onFilterChanged; _discussionLoader = discussionLoader; _discussionLoader.Loaded += onDiscussionsLoaded; _discussionLayout = discussionLayout; _discussionLayout.DiffContextPositionChanged += onDiffContextPositionChanged; _discussionLayout.DiscussionColumnWidthChanged += onDiscussionColumnWidthChanged; _discussionLayout.NeedShiftRepliesChanged += onNeedShiftRepliesChanged; apply(discussions); }
private FileNameMatcher getFileNameMatcher(IGitCommandService git, MergeRequestKey mrk) { return(new FileNameMatcher(git, (currentName, anotherName) => { MessageBox.Show( "Merge Request Helper detected that current file is a moved version of another file. " + "GitLab does not allow to create discussions on moved files.\n\n" + "Current file:\n" + currentName + "\n\n" + "Another file:\n" + anotherName, "Cannot create a discussion", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification); }, (currentName, anotherName, status) => { if (needSuppressWarning(currentName, mrk)) { return true; } string question = String.Empty; if (status == "new" || status == "deleted") { question = "Do you really want to review this file as a " + status + " file? "; } else if (status == "modified") { question = "Do you really want to continue reviewing this file against the selected file? "; } else { Debug.Assert(false); } bool isWarningIgnoredByUser = MessageBox.Show( "Merge Request Helper detected that current file is a renamed version of another file. " + question + "It is recommended to press \"No\" and match files manually in the diff tool.\n" + "Current file:\n" + currentName + "\n\n" + "Another file:\n" + anotherName, "Rename detected", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2, MessageBoxOptions.ServiceNotification) == DialogResult.Yes; if (isWarningIgnoredByUser) { addFileToWhitelist(currentName, mrk); } return isWarningIgnoredByUser; }, (currentName) => { if (needSuppressWarning(currentName, mrk)) { return true; } string question = "Do you really want to continue reviewing this file against the selected file? "; bool isWarningIgnoredByUser = MessageBox.Show( "Merge Request Helper detected that selected files do not match to each other. " + question, "Files do not match", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.ServiceNotification) == DialogResult.Yes; if (isWarningIgnoredByUser) { addFileToWhitelist(currentName, mrk); } return isWarningIgnoredByUser; })); }
/// <summary> /// Note: filename1 or filename2 can be 'null' /// Throws GitDiffAnalyzerException. /// </summary> public GitDiffAnalyzer(IGitCommandService git) { _git = git; }
public SimpleContextMaker(IGitCommandService git) { Debug.Assert(git != null); _git = git; }
internal GitHub(IGitCommandService gitCommandService) { _gitCommandService = gitCommandService; }
public GitRepositoryRenameDetector(IGitCommandService git) { _git = git; }
/// <summary> /// Note: filename1 or filename2 can be 'null' /// Throws ContextMakingException. /// </summary> public GitDiffAnalyzer(IGitCommandService git, string sha1, string sha2, string filename1, string filename2) { _sections = getDiffSections(git, sha1, sha2, filename1, filename2); }
public EnhancedContextMaker(IGitCommandService git) { Debug.Assert(git != null); _git = git; }
public LineNumberMatcher(IGitCommandService git) { _git = git; }
internal AzureDevOps(IGitCommandService gitCommandService) { _gitCommandService = gitCommandService; }
internal FileStorageRenameDetector(IGitCommandService commandService, IFileStorage fileStorage) { _commandService = commandService; _comparisonCache = fileStorage.ComparisonCache; _fileCache = fileStorage.FileCache; }
public GitRepositoryFullContextDiffProvider(IGitCommandService git) { _git = git; }
public FullContextDiffProvider(IGitCommandService git) { _git = git; }
/// <summary> /// Throws: /// ArgumentException /// </summary> internal DiscussionsForm( DataCache dataCache, GitLabInstance gitLabInstance, IModificationListener modificationListener, IGitCommandService git, User currentUser, MergeRequestKey mrk, IEnumerable <Discussion> discussions, string mergeRequestTitle, User mergeRequestAuthor, int diffContextDepth, ColorScheme colorScheme, Func <MergeRequestKey, IEnumerable <Discussion>, Task> updateGit, Action onDiscussionModified) { _mergeRequestKey = mrk; _mergeRequestTitle = mergeRequestTitle; _mergeRequestAuthor = mergeRequestAuthor; _git = git; _diffContextDepth = diffContextDepth; _colorScheme = colorScheme; _dataCache = dataCache; _gitLabInstance = gitLabInstance; _modificationListener = modificationListener; _updateGit = updateGit; _onDiscussionModified = onDiscussionModified; _currentUser = currentUser; if (_currentUser.Id == 0) { throw new ArgumentException("Bad user Id"); } CommonControls.Tools.WinFormsHelpers.FixNonStandardDPIIssue(this, (float)Common.Constants.Constants.FontSizeChoices["Design"], 96); InitializeComponent(); CommonControls.Tools.WinFormsHelpers.LogScaleDimensions(this); DisplayFilter = new DiscussionFilter(_currentUser, _mergeRequestAuthor, DiscussionFilterState.Default); SystemFilter = new DiscussionFilter(_currentUser, _mergeRequestAuthor, DiscussionFilterState.AllExceptSystem); FilterPanel = new DiscussionFilterPanel(DisplayFilter.Filter, () => { DisplayFilter.Filter = FilterPanel.Filter; updateLayout(null, true, true); updateSearch(); }); ActionsPanel = new DiscussionActionsPanel(() => BeginInvoke(new Action(async() => await onRefresh()))); SearchPanel = new DiscussionSearchPanel( (query, forward) => { if (query.Text == String.Empty) { resetSearch(); } else if (TextSearch == null || !query.Equals(TextSearch.Query)) { startSearch(query, true); } else { MostRecentFocusedDiscussionControl?.Focus(); continueSearch(forward); } }); DiscussionSortState sortState = DiscussionSortState.Default; DisplaySort = new DiscussionSort(sortState); SortPanel = new DiscussionSortPanel(DisplaySort.SortState, () => { DisplaySort.SortState = SortPanel.SortState; updateLayout(null, true, true); updateSearch(); }); FontSelectionPanel = new DiscussionFontSelectionPanel(font => applyFont(font)); Controls.Add(FilterPanel); Controls.Add(ActionsPanel); Controls.Add(SearchPanel); Controls.Add(SortPanel); Controls.Add(FontSelectionPanel); applyFont(Program.Settings.MainWindowFontSizeName); applyTheme(Program.Settings.VisualThemeName); if (!renderDiscussions(discussions, false)) { throw new NoDiscussionsToShow(); } }
internal FileStorageFullContextDiffProvider(IGitCommandService commandService, FileStorageComparisonCache comparisonCache) { _commandService = commandService; _comparisonCache = comparisonCache; }