Esempio n. 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));
        }
Esempio n. 2
0
        private void setDiffContextText(Control diffContextControl)
        {
            double fontSizePx = WinFormsHelpers.GetFontSizeInPixels(diffContextControl);

            DiscussionNote note = getNoteFromControl(diffContextControl);

            Debug.Assert(note.Type == "DiffNote");
            DiffPosition position = PositionConverter.Convert(note.Position);

            Debug.Assert(diffContextControl is HtmlPanel);
            HtmlPanel htmlPanel = diffContextControl as HtmlPanel;

            // We need to zero the control size before SetText call to allow HtmlPanel to compute the size
            int prevWidth = htmlPanel.Width;

            htmlPanel.Width  = 0;
            htmlPanel.Height = 0;

            string html = getContext(_panelContextMaker, position, _diffContextDepth, fontSizePx, out string css);

            htmlPanel.BaseStylesheet = css;
            htmlPanel.Text           = html;
            resizeLimitedWidthHtmlPanel(htmlPanel, prevWidth);

            string tooltipHtml = getContext(_tooltipContextMaker, position,
                                            _tooltipContextDepth, fontSizePx, out string tooltipCSS);

            _htmlDiffContextToolTip.BaseStylesheet =
                String.Format("{0} .htmltooltip {{ padding: 1px; }}", tooltipCSS);
            _htmlDiffContextToolTip.SetToolTip(htmlPanel, tooltipHtml);
        }
Esempio n. 3
0
        private string getContext(IContextMaker contextMaker, DiffPosition position,
                                  ContextDepth depth, double fontSizePx, out string stylesheet)
        {
            stylesheet = String.Empty;
            if (contextMaker == null)
            {
                return("<html><body>Cannot access file storage and render diff context</body></html>");
            }

            try
            {
                DiffContext          context   = contextMaker.GetContext(position, depth);
                DiffContextFormatter formatter = new DiffContextFormatter(fontSizePx, 2);
                stylesheet = formatter.GetStylesheet();
                return(formatter.GetBody(context));
            }
            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;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Throws ArgumentException, ContextMakingException.
        /// </summary>
        public DiffContext GetContext(DiffPosition position, ContextDepth depth)
        {
            if (!Context.Helpers.IsValidPosition(position))
            {
                throw new ArgumentException(
                          String.Format("Bad \"position\": {0}", position.ToString()));
            }

            if (!Context.Helpers.IsValidContextDepth(depth))
            {
                throw new ArgumentException(
                          String.Format("Bad \"depth\": {0}", depth.ToString()));
            }

            // If RightLine is valid, then it points to either added/modified or unchanged line, handle them the same way
            bool   isRightSideContext = position.RightLine != null;
            int    linenumber         = isRightSideContext ? int.Parse(position.RightLine) : int.Parse(position.LeftLine);
            string leftFilename       = position.LeftPath;
            string rightFilename      = position.RightPath;
            string leftSHA            = position.Refs.LeftSHA;
            string rightSHA           = position.Refs.RightSHA;

            FullContextDiffProvider provider = new FullContextDiffProvider(_git);
            FullContextDiff         context  = provider.GetFullContextDiff(leftSHA, rightSHA, leftFilename, rightFilename);

            Debug.Assert(context.Left.Count == context.Right.Count);
            if (linenumber > context.Left.Count)
            {
                throw new ArgumentException(
                          String.Format("Line number {0} is greater than total line number count, invalid \"position\": {1}",
                                        linenumber.ToString(), position.ToString()));
            }

            return(createDiffContext(linenumber, isRightSideContext, context, depth));
        }
Esempio n. 5
0
        /// <summary>
        /// Throws ArgumentException.
        /// Throws GitOperationException in case of problems with git.
        /// </summary>
        public DiffContext GetContext(DiffPosition position, ContextDepth depth)
        {
            if (!Context.Helpers.IsValidPosition(position))
            {
                throw new ArgumentException(
                          String.Format("Bad \"position\": {0}", position.ToString()));
            }

            if (!Context.Helpers.IsValidContextDepth(depth))
            {
                throw new ArgumentException(
                          String.Format("Bad \"depth\": {0}", depth.ToString()));
            }

            bool   isRightSideContext = position.RightLine != null;
            int    linenumber         = isRightSideContext ? int.Parse(position.RightLine) : int.Parse(position.LeftLine);
            string filename           = isRightSideContext ? position.RightPath : position.LeftPath;
            string sha = isRightSideContext ? position.Refs.RightSHA : position.Refs.LeftSHA;

            List <string> contents = _gitRepository.ShowFileByRevision(filename, sha);

            if (linenumber > contents.Count)
            {
                throw new ArgumentException(
                          String.Format("Line number {0} is greater than total line number count, invalid \"position\": {1}",
                                        linenumber.ToString(), position.ToString()));
            }

            return(createDiffContext(linenumber, contents, isRightSideContext, depth));
        }
Esempio n. 6
0
        private MatchResult doFullMatch(MergeRequestKey mrk, Core.Matching.DiffRefs refs,
                                        MatchInfo matchInfo, out DiffPosition position)
        {
            if (!matchInfo.IsValid())
            {
                position = null;
                return(MatchResult.Error);
            }

            MatchResult fileMatchResult = matchFileName(mrk, refs, matchInfo.LeftFileName, matchInfo.RightFileName,
                                                        matchInfo.IsLeftSideLineNumber, out string leftFileName, out string rightFileName);

            if (fileMatchResult != MatchResult.Success)
            {
                position = null;
                return(fileMatchResult);
            }

            MatchResult lineMatchResult = matchLineNumber(leftFileName, rightFileName, refs, matchInfo.LineNumber,
                                                          matchInfo.IsLeftSideLineNumber, out string leftLineNumber, out string rightLineNumber);

            if (lineMatchResult != MatchResult.Success)
            {
                position = null;
                return(fileMatchResult);
            }

            position = new DiffPosition(leftFileName, rightFileName, leftLineNumber, rightLineNumber, refs);
            return(MatchResult.Success);
        }
Esempio n. 7
0
        private HtmlPanel createDiffContext(DiscussionNote firstNote)
        {
            if (firstNote.Type != "DiffNote")
            {
                return(null);
            }

            int fontSizePx     = 12;
            int rowsVPaddingPx = 2;
            int rowHeight      = (fontSizePx + rowsVPaddingPx * 2 + 1 /* border of control */ + 2);
            // we're adding 2 extra pixels for each row because HtmlRenderer does not support CSS line-height property
            // this value was found experimentally

            int panelHeight = (_diffContextDepth.Size + 1) * rowHeight;

            HtmlPanel htmlPanel = new HtmlPanel
            {
                BorderStyle = BorderStyle.FixedSingle,
                Height      = panelHeight,
                MinimumSize = new Size(600, 0),
                TabStop     = false
            };

            DiffPosition position = convertToDiffPosition(firstNote.Position);

            htmlPanel.Text = getContext(_panelContextMaker, position,
                                        _diffContextDepth, fontSizePx, rowsVPaddingPx);
            _htmlToolTip.SetToolTip(htmlPanel, getContext(_tooltipContextMaker, position,
                                                          _tooltipContextDepth, fontSizePx, rowsVPaddingPx));

            return(htmlPanel);
        }
        private string getContextHtmlText(DiffPosition position, HtmlPanel htmlPanel, out string stylesheet)
        {
            stylesheet = String.Empty;
            double fontSizePx = WinFormsHelpers.GetFontSizeInPixels(htmlPanel);
            var    getContext = isCurrentNoteNew() ? _getNewDiscussionDiffContext(position) : _getDiffContext(position);

            return(DiffContextFormatter.GetHtml(getContext, fontSizePx, 2, true));
        }
Esempio n. 9
0
 public ReportedDiscussionNote(int id, string discussionId, DiffPosition diffPosition,
                               string body, string authorName, DateTime createdAt)
 {
     Key      = new ReportedDiscussionNoteKey(id, discussionId);
     Position = new ReportedDiscussionNotePosition(diffPosition);
     Details  = new ReportedDiscussionNoteDetails(authorName, createdAt);
     Content  = new ReportedDiscussionNoteContent(body);
 }
Esempio n. 10
0
        public static bool IsValidPosition(DiffPosition position)
        {
            var leftLine  = position.LeftLine;
            var rightLine = position.RightLine;

            return((leftLine != null && int.TryParse(leftLine, out int LeftLineNumber) && LeftLineNumber > 0) ||
                   (rightLine != null && int.TryParse(rightLine, out int RightLineNumber) && RightLineNumber > 0));
        }
Esempio n. 11
0
        // Collect discussions started for lines within DiffContextDepth range near `position`
        private IEnumerable <ReportedDiscussionNote> getRelatedDiscussions(
            MergeRequestKey mrk, ReportedDiscussionNoteKey?keyOpt, DiffPosition position)
        {
            // Obtain a context for a passed position.
            DiffContext ctx = getDiffContext <CombinedContextMaker>(position, UnchangedLinePolicy.TakeFromRight);

            if (!ctx.IsValid())
            {
                return(Array.Empty <ReportedDiscussionNote>());
            }

            string leftFileName  = position.LeftPath;
            string rightFileName = position.RightPath;

            Core.Matching.DiffRefs refs = position.Refs;
            List <DiffPosition>    neighborPositions = new List <DiffPosition>();

            // CombinedContextMaker provides a context where line numbers are matched so no need to
            // match them manually here.
            foreach (DiffContext.Line line in ctx.Lines)
            {
                Debug.Assert(line.Left.HasValue || line.Right.HasValue);
                string leftLineNumber  = null;
                string rightLineNumber = null;
                if (line.Left.HasValue)
                {
                    leftLineNumber = line.Left.Value.Number.ToString();
                }
                if (line.Right.HasValue)
                {
                    rightLineNumber = line.Right.Value.Number.ToString();
                }
                neighborPositions.Add(new DiffPosition(leftFileName, rightFileName, leftLineNumber, rightLineNumber, refs));
            }

            // Find discussions that reported on each line from the diff context.
            List <ReportedDiscussionNote> relatedNotes = new List <ReportedDiscussionNote>();

            foreach (Discussion discussion in _getDiscussions(mrk))
            {
                DiscussionNote firstNote         = discussion.Notes.First();
                DiffPosition   firstNotePosition = PositionConverter.Convert(firstNote.Position);
                if (firstNotePosition != null)
                {
                    foreach (DiffPosition neighbor in neighborPositions)
                    {
                        if (doPositionsReferenceTheSameLine(neighbor, firstNotePosition) &&
                            (!keyOpt.HasValue || keyOpt.Value.Id != firstNote.Id))
                        {
                            ReportedDiscussionNote note = new ReportedDiscussionNote(firstNote.Id, discussion.Id,
                                                                                     firstNotePosition, firstNote.Body, firstNote.Author.Name, firstNote.Created_At);
                            relatedNotes.Add(note);
                        }
                    }
                }
            }
            return(relatedNotes.GroupBy(note => note.Key.Id).Select(c => c.First()));
        }
 public static bool IsLeftSidePosition(DiffPosition position,
                                       UnchangedLinePolicy unchangedLinePolicy = UnchangedLinePolicy.TakeFromLeft)
 {
     if (position.RightLine != null && position.LeftLine != null)
     {
         return(unchangedLinePolicy == UnchangedLinePolicy.TakeFromLeft);
     }
     return(position.LeftLine != null);
 }
Esempio n. 13
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);
        }
Esempio n. 14
0
        private void showDiscussionContext(DiffPosition position, HtmlPanel htmlPanel)
        {
            if (position == null)
            {
                htmlPanel.Text = "This discussion is not associated with code";
                return;
            }

            string html = getContextHtmlText(position, htmlPanel, out string stylesheet);

            htmlPanel.BaseStylesheet = stylesheet;
            htmlPanel.Text           = html;
        }
Esempio n. 15
0
 private static PositionParameters createPositionParameters(DiffPosition position)
 {
     return(new PositionParameters
     {
         OldPath = position.LeftPath,
         OldLine = position.LeftLine,
         NewPath = position.RightPath,
         NewLine = position.RightLine,
         BaseSHA = position.Refs.LeftSHA,
         HeadSHA = position.Refs.RightSHA,
         StartSHA = position.Refs.LeftSHA
     });
 }
        // linenumber is one-based
        private DiffContext.Line getLineContext(int linenumber, bool isRightSideContext,
                                                IEnumerable <string> contents, DiffPosition position)
        {
            Debug.Assert(linenumber > 0 && linenumber <= contents.Count());

            // this maker supports all three states
            DiffContext.Line.Side side = new DiffContext.Line.Side(
                linenumber, getLineState(linenumber, isRightSideContext, position));

            return(new DiffContext.Line(contents.ElementAt(linenumber - 1),
                                        isRightSideContext ? new DiffContext.Line.Side?() : side,
                                        isRightSideContext ? side : new DiffContext.Line.Side?()));
        }
Esempio n. 17
0
        bool doPositionsReferenceTheSameLine(DiffPosition position1, DiffPosition position2)
        {
            bool matchRight =
                position1.RightLine != null &&
                (position1.RightLine == position2.RightLine || position1.RightLine == position2.LeftLine) &&
                position1.RightPath == position2.RightPath;
            bool matchLeft =
                position1.LeftLine != null &&
                (position1.LeftLine == position2.LeftLine || position1.LeftLine == position2.RightLine) &&
                position1.LeftPath == position2.LeftPath;

            return(matchRight || matchLeft);
        }
Esempio n. 18
0
        private void showNewDiscussionDialog(MatchInfo matchInfo, Snapshot snapshot, MergeRequestKey mrk,
                                             DiffPosition initialNewDiscussionPosition)
        {
            DiffPosition fnOnScroll(DiffPosition position, bool scrollUp) =>
            scrollPosition(position, scrollUp, matchInfo.IsLeftSideLineNumber);

            async Task fnOnSubmitNewDiscussion(string body, bool includeContext, DiffPosition position) =>
            await actOnGitLab("create", () =>
                              submitDiscussionAsync(mrk, matchInfo, snapshot.Refs, position, body, includeContext));

            async Task fnOnEditOldNote(ReportedDiscussionNoteKey notePosition, ReportedDiscussionNoteContent content) =>
            await actOnGitLab("edit", () =>
                              editDiscussionNoteAsync(mrk, notePosition.DiscussionId, notePosition.Id, content.Body));

            async Task fnOnDeleteOldNote(ReportedDiscussionNoteKey notePosition) =>
            await actOnGitLab("delete", () =>
                              deleteDiscussionNoteAsync(mrk, notePosition.DiscussionId, notePosition.Id));

            IEnumerable <ReportedDiscussionNote> fnGetRelatedDiscussions(ReportedDiscussionNoteKey?keyOpt, DiffPosition position) =>
            getRelatedDiscussions(mrk, keyOpt, position).ToArray();

            // We need separate functors for `new` and `old` positions because for a new discussion we need
            // to distinct cases when user points at unchanged line at left and right sides because it is
            // important to show proper file content in a diff context window.
            // And for old discussions we don't have a chance to guess at what side they were created.
            DiffContext fnGetNewDiscussionDiffContext(DiffPosition position) =>
            getDiffContext <EnhancedContextMaker>(position,
                                                  matchInfo.IsLeftSideLineNumber ? UnchangedLinePolicy.TakeFromLeft : UnchangedLinePolicy.TakeFromRight);

            DiffContext fnGetDiffContext(DiffPosition position) =>
            getDiffContext <EnhancedContextMaker>(position, UnchangedLinePolicy.TakeFromRight);

            void fnOnDialogClosed() =>
            _onDiscussionSubmitted?.Invoke(mrk);

            ReportedDiscussionNote[] reportedDiscussions = getReportedDiscussions(mrk).ToArray();

            NewDiscussionForm form = new NewDiscussionForm(
                initialNewDiscussionPosition,
                reportedDiscussions,
                fnOnScroll,
                fnOnDialogClosed,
                fnOnSubmitNewDiscussion,
                fnOnEditOldNote,
                fnOnDeleteOldNote,
                fnGetRelatedDiscussions,
                fnGetNewDiscussionDiffContext,
                fnGetDiffContext);

            form.Show();
        }
Esempio n. 19
0
        private void showFileName(DiffPosition position)
        {
            if (position == null)
            {
                textBoxFileName.Text = "This discussion is not associated with code";
                return;
            }

            string leftSideFileName  = position.LeftPath;
            string rightSideFileName = position.RightPath;

            textBoxFileName.Text = "Left: " + (leftSideFileName == String.Empty ? "N/A" : leftSideFileName)
                                   + "  Right: " + (rightSideFileName == String.Empty ? "N/A" : rightSideFileName);
        }
Esempio n. 20
0
        public void Handle(MatchInfo matchInfo, Snapshot snapshot)
        {
            FileNameMatcher   fileNameMatcher   = getFileNameMatcher(_git, getMergeRequestKey(snapshot));
            LineNumberMatcher lineNumberMatcher = new LineNumberMatcher(_git);

            DiffPosition position = new DiffPosition(null, null, null, null, snapshot.Refs);

            try
            {
                if (!fileNameMatcher.Match(matchInfo, position, out position))
                {
                    return;
                }

                lineNumberMatcher.Match(matchInfo, position, out position);
            }
            catch (Exception ex)
            {
                if (ex is ArgumentException || ex is MatchingException)
                {
                    ExceptionHandlers.Handle("Cannot create DiffPosition", ex);
                    MessageBox.Show("Cannot create a discussion. Unexpected file name and/or line number passed",
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,
                                    MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
                    return;
                }
                throw;
            }

            NewDiscussionForm form = new NewDiscussionForm(
                matchInfo.LeftFileName, matchInfo.RightFileName, position, _git,
                async(body, includeContext) =>
            {
                try
                {
                    await submitDiscussionAsync(matchInfo, snapshot, position, body, includeContext);
                    _onDiscussionSubmitted?.Invoke(getMergeRequestKey(snapshot));
                }
                catch (DiscussionCreatorException ex)
                {
                    string message = "Cannot create a discussion at GitLab";
                    ExceptionHandlers.Handle(message, ex);
                    MessageBox.Show(String.Format("{0}. Check your connection and try again.", message),
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,
                                    MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
                }
            });

            form.Show();
        }
Esempio n. 21
0
        /// <summary>
        /// Throws ArgumentException, ContextMakingException.
        /// </summary>
        public DiffContext GetContext(DiffPosition position, ContextDepth depth)
        {
            if (!Context.Helpers.IsValidPosition(position))
            {
                throw new ArgumentException(
                          String.Format("Bad \"position\": {0}", position.ToString()));
            }

            if (!Context.Helpers.IsValidContextDepth(depth))
            {
                throw new ArgumentException(
                          String.Format("Bad \"depth\": {0}", depth.ToString()));
            }

            GitDiffAnalyzer analyzer = new GitDiffAnalyzer(_git,
                                                           position.Refs.LeftSHA, position.Refs.RightSHA, position.LeftPath, position.RightPath);

            // If RightLine is valid, then it points to either added/modified or unchanged line, handle them the same way
            bool   isRightSideContext = position.RightLine != null;
            int    linenumber         = isRightSideContext ? int.Parse(position.RightLine) : int.Parse(position.LeftLine);
            string filename           = isRightSideContext ? position.RightPath : position.LeftPath;
            string sha = isRightSideContext ? position.Refs.RightSHA : position.Refs.LeftSHA;

            GitShowRevisionArguments arguments = new GitShowRevisionArguments(filename, sha);

            IEnumerable <string> contents;

            try
            {
                contents = _git?.ShowRevision(arguments);
            }
            catch (GitNotAvailableDataException ex)
            {
                throw new ContextMakingException("Cannot obtain git revision", ex);
            }

            if (contents == null)
            {
                throw new ContextMakingException("Cannot obtain git revision", null);
            }

            if (linenumber > contents.Count())
            {
                throw new ArgumentException(
                          String.Format("Line number {0} is greater than total line number count, invalid \"position\": {1}",
                                        linenumber.ToString(), position.ToString()));
            }

            return(createDiffContext(linenumber, isRightSideContext, contents, analyzer, depth));
        }
        /// <summary>
        /// Throws ArgumentException, ContextMakingException.
        /// </summary>
        public DiffContext GetContext(DiffPosition position, ContextDepth depth, UnchangedLinePolicy unchangedLinePolicy)
        {
            if (!Context.Helpers.IsValidPosition(position))
            {
                throw new ArgumentException(
                          String.Format("Bad \"position\": {0}", position.ToString()));
            }

            if (!Context.Helpers.IsValidContextDepth(depth))
            {
                throw new ArgumentException(
                          String.Format("Bad \"depth\": {0}", depth.ToString()));
            }

            bool   isRightSideContext = Helpers.IsRightSidePosition(position, unchangedLinePolicy);
            int    linenumber         = isRightSideContext ? Helpers.GetRightLineNumber(position) : Helpers.GetLeftLineNumber(position);
            string filename           = isRightSideContext ? position.RightPath : position.LeftPath;
            string sha = isRightSideContext ? position.Refs.RightSHA : position.Refs.LeftSHA;

            GitShowRevisionArguments arguments = new GitShowRevisionArguments(filename, sha);

            IEnumerable <string> contents;

            try
            {
                contents = _git?.ShowRevision(arguments);
            }
            catch (GitNotAvailableDataException ex)
            {
                throw new ContextMakingException("Cannot obtain git revision", ex);
            }

            if (contents == null)
            {
                throw new ContextMakingException("Cannot obtain git revision", null);
            }

            if (linenumber > contents.Count())
            {
                throw new ArgumentException(
                          String.Format("Line number {0} is greater than total line number count, invalid \"position\": {1}",
                                        linenumber.ToString(), position.ToString()));
            }

            return(createDiffContext(linenumber, contents, isRightSideContext, depth));
        }
Esempio n. 23
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;
        }
Esempio n. 24
0
        /// <summary>
        /// Throws GitOperationException in case of problems with git.
        /// </summary>
        internal NewDiscussionForm(Snapshot snapshot, DiffToolInfo difftoolInfo, DiffPosition position,
                                   IGitRepository gitRepository)
        {
            _interprocessSnapshot = snapshot;
            _difftoolInfo         = difftoolInfo;
            _position             = position;
            _gitRepository        = gitRepository;

            InitializeComponent();
            htmlPanel.BorderStyle = BorderStyle.FixedSingle;
            htmlPanel.Location    = new Point(12, 73);
            htmlPanel.Size        = new Size(860, 76);
            Controls.Add(htmlPanel);

            this.ActiveControl = textBoxDiscussionBody;
            showDiscussionContext(htmlPanel, textBoxFileName);
        }
        public static bool IsValidPosition(DiffPosition position)
        {
            if (position == null)
            {
                return(false);
            }
            string leftLine  = position.LeftLine;
            string rightLine = position.RightLine;

            if (leftLine != null && GetLeftLineNumber(position) < 1)
            {
                return(false);
            }
            if (rightLine != null && GetRightLineNumber(position) < 1)
            {
                return(false);
            }
            return(leftLine != null || rightLine != null);
        }
        // isRightSideContext is true when linenumber and sha correspond to the right side
        // linenumber is one-based
        private DiffContext createDiffContext(int linenumber, bool isRightSideContext, IEnumerable <string> contents,
                                              ContextDepth depth, DiffPosition position)
        {
            List <DiffContext.Line> lines = new List <DiffContext.Line>();

            int startLineNumber = Math.Max(1, linenumber - depth.Up);

            for (int iContextLine = 0; iContextLine < depth.Size + 1; ++iContextLine)
            {
                if (startLineNumber + iContextLine == contents.Count() + 1)
                {
                    // we have just reached the end
                    break;
                }
                lines.Add(getLineContext(startLineNumber + iContextLine, isRightSideContext, contents, position));
            }

            // zero-based index of a selected line in DiffContext.Lines
            return(new DiffContext(lines, linenumber - startLineNumber));
        }
Esempio n. 27
0
        internal NewDiscussionForm(
            DiffPosition newDiscussionPosition,
            ReportedDiscussionNote[] oldNotes,
            Func <DiffPosition, bool, DiffPosition> onScrollPosition,
            Action onDialogClosed,
            Func <string, bool, DiffPosition, Task> onSubmitNewDiscussion,
            Func <ReportedDiscussionNoteKey, ReportedDiscussionNoteContent, Task> onEditOldNote,
            Func <ReportedDiscussionNoteKey, Task> onDeleteOldNote,
            Func <ReportedDiscussionNoteKey?, DiffPosition, IEnumerable <ReportedDiscussionNote> > getRelatedDiscussions,
            Func <DiffPosition, DiffContext> getNewDiscussionDiffContext,
            Func <DiffPosition, DiffContext> getDiffContext)
        {
            InitializeComponent();
            this.TopMost = Program.Settings.NewDiscussionIsTopMostForm;

            applyFont(Program.Settings.MainWindowFontSizeName);
            createWPFTextBox();
            _groupBoxRelatedThreadsDefaultHeight = groupBoxRelated.Height;
            _diffContextDefaultHeight            = panelHtmlContextCanvas.Height;

            this.Text = Constants.StartNewThreadCaption;
            labelInvisibleCharactersHint.Text = Constants.WarningOnUnescapedMarkdown;

            buttonCancel.ConfirmationCondition =
                () => (getNewNoteText().Length > MaximumTextLengthTocancelWithoutConfirmation) || areHistoryModifications();

            _onDialogClosed              = onDialogClosed;
            _onScrollPosition            = onScrollPosition;
            _onSubmitNewDiscussion       = onSubmitNewDiscussion;
            _onEditOldNote               = onEditOldNote;
            _onDeleteOldNote             = onDeleteOldNote;
            _getNewDiscussionDiffContext = getNewDiscussionDiffContext;
            _getDiffContext              = getDiffContext;
            _getRelatedDiscussions       = getRelatedDiscussions;

            NewDiscussionPosition = newDiscussionPosition;
            _needIncludeContextInNewDiscussion = true;

            _reportedNotes = oldNotes.ToList();
            resetCurrentNoteIndex();
        }
        /// <summary>
        /// Throws ArgumentException, ContextMakingException.
        /// </summary>
        public DiffContext GetContext(DiffPosition position, ContextDepth depth, UnchangedLinePolicy unchangedLinePolicy)
        {
            if (!Context.Helpers.IsValidPosition(position))
            {
                throw new ArgumentException(
                          String.Format("Bad \"position\": {0}", position.ToString()));
            }

            if (!Context.Helpers.IsValidContextDepth(depth))
            {
                throw new ArgumentException(
                          String.Format("Bad \"depth\": {0}", depth.ToString()));
            }

            bool   isRightSideContext = Helpers.IsRightSidePosition(position, unchangedLinePolicy);
            int    linenumber         = isRightSideContext ? Helpers.GetRightLineNumber(position) : Helpers.GetLeftLineNumber(position);
            string leftFilename       = position.LeftPath;
            string rightFilename      = position.RightPath;
            string leftSHA            = position.Refs.LeftSHA;
            string rightSHA           = position.Refs.RightSHA;

            try
            {
                FullContextDiff context = _git.FullContextDiffProvider.GetFullContextDiff(
                    leftSHA, rightSHA, leftFilename, rightFilename);
                Debug.Assert(context.Left.Count == context.Right.Count);
                if (linenumber > context.Left.Count)
                {
                    throw new ArgumentException(
                              String.Format("Line number {0} is greater than total line number count, invalid \"position\": {1}",
                                            linenumber.ToString(), position.ToString()));
                }

                return(createDiffContext(linenumber, isRightSideContext, context, depth));
            }
            catch (FullContextDiffProviderException ex)
            {
                throw new ContextMakingException("Cannot obtain full context diff", ex);
            }
        }
Esempio n. 29
0
        private DiffContext getDiffContext <T>(DiffPosition position, UnchangedLinePolicy policy) where T : IContextMaker
        {
            if (position == null || !Core.Context.Helpers.IsValidPosition(position))
            {
                return(DiffContext.InvalidContext);
            }

            try
            {
                T maker = (T)Activator.CreateInstance(typeof(T), _git);
                return(maker.GetContext(position, DiffContextDepth, policy));
            }
            catch (ArgumentException ex)
            {
                ExceptionHandlers.Handle("Failed to obtain DiffContext", ex);
                return(DiffContext.InvalidContext);
            }
            catch (ContextMakingException ex)
            {
                ExceptionHandlers.Handle("Failed to obtain DiffContext", ex);
                return(DiffContext.InvalidContext);
            }
        }
Esempio n. 30
0
        DiffPosition scrollPosition(DiffPosition position, bool scrollUp, bool isLeftSideLine)
        {
            if (!Core.Context.Helpers.IsValidPosition(position))
            {
                return(position);
            }

            int lineNumber = isLeftSideLine
               ? Core.Context.Helpers.GetLeftLineNumber(position)
               : Core.Context.Helpers.GetRightLineNumber(position);

            lineNumber += (scrollUp ? -1 : 1);

            string leftPath  = position.LeftPath;
            string rightPath = position.RightPath;

            Core.Matching.DiffRefs refs = position.Refs;
            if (matchLineNumber(leftPath, rightPath, refs, lineNumber, isLeftSideLine,
                                out string leftLineNumber, out string rightLineNumber) == MatchResult.Success)
            {
                return(new DiffPosition(leftPath, rightPath, leftLineNumber, rightLineNumber, refs));
            }
            return(null);
        }