Пример #1
0
        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));
        }
Пример #2
0
 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;
 }
Пример #3
0
 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;
 }
Пример #4
0
        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;
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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);
        }
Пример #7
0
 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;
 }
Пример #8
0
        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();
        }
Пример #9
0
        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;
        }
Пример #10
0
        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);
        }
Пример #11
0
        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;
            }));
        }
Пример #12
0
 /// <summary>
 /// Note: filename1 or filename2 can be 'null'
 /// Throws GitDiffAnalyzerException.
 /// </summary>
 public GitDiffAnalyzer(IGitCommandService git)
 {
     _git = git;
 }
Пример #13
0
 public SimpleContextMaker(IGitCommandService git)
 {
     Debug.Assert(git != null);
     _git = git;
 }
Пример #14
0
 internal GitHub(IGitCommandService gitCommandService)
 {
     _gitCommandService = gitCommandService;
 }
 public GitRepositoryRenameDetector(IGitCommandService git)
 {
     _git = git;
 }
Пример #16
0
 /// <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;
 }
Пример #18
0
 public LineNumberMatcher(IGitCommandService git)
 {
     _git = git;
 }
Пример #19
0
 internal AzureDevOps(IGitCommandService gitCommandService)
 {
     _gitCommandService = gitCommandService;
 }
Пример #20
0
 internal FileStorageRenameDetector(IGitCommandService commandService, IFileStorage fileStorage)
 {
     _commandService  = commandService;
     _comparisonCache = fileStorage.ComparisonCache;
     _fileCache       = fileStorage.FileCache;
 }
Пример #21
0
 public GitRepositoryFullContextDiffProvider(IGitCommandService git)
 {
     _git = git;
 }
Пример #22
0
 public FullContextDiffProvider(IGitCommandService git)
 {
     _git = git;
 }
Пример #23
0
        /// <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;
 }