private void InitializeEditor() { // Obtain line counts. conflictBlocks = new List<int>(); lineCount = new int[content[0].Count]; for (int i = 0; i < content[0].Count; i++) { lineCount[i] = Math.Max(content[0][i].lines.Count, content[1][i].lines.Count); if (content[0][i].type != BlockType.Normal) { conflictBlocks.Add(i); } } int lines = lineCount.Sum(); for (int i = 0; i < lines; i++) { grid.RowDefinitions.Insert(0, new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Insert(0, new RowDefinition { Height = GridLength.Auto }); conflictNav.RowDefinitions.Insert(0, new RowDefinition()); } // Only show the scroll helper if it's a long file. if (lines > 25) { conflictNav.Visibility = Visibility.Visible; } // Create grid cells for text blocks. lineTexts = new List<RichTextBox>[2]; lineNums = new List<TextBlock>[2]; lineTextBackgrounds = new List<Border>[2]; lineNumBackgrounds = new List<Border>[2]; for (int i = 0; i < 2; i++) { lineTexts[i] = new List<RichTextBox>(); lineNums[i] = new List<TextBlock>(); for (int j = 0; j < lines; j++) { var lineNum = new TextBlock { Style = GetStyle("lineNumber") }; Panel.SetZIndex(lineNum, 5); Grid.SetRow(lineNum, 2 * j); Grid.SetColumn(lineNum, 2 * i); grid.Children.Add(lineNum); lineNums[i].Add(lineNum); var text = new RichTextBox { Style = GetStyle("lineText"), HorizontalAlignment = HorizontalAlignment.Stretch }; Panel.SetZIndex(text, 5); Grid.SetRow(text, 2 * j); Grid.SetColumn(text, 1 + 2 * i); var doc = new FlowDocument(); var p = new Paragraph(); doc.Blocks.Add(p); text.Document = doc; grid.Children.Add(text); lineTexts[i].Add(text); } } // Draw the actual text blocks. scrollNavBorders = new List<Border>(); for (int side = 0; side < 2; side++) { int prevLine = 0; int lineNum = 1; lineNumBackgrounds[side] = new List<Border>(); lineTextBackgrounds[side] = new List<Border>(); for (int g = 0; g < content[side].Count; g++) { LineBlock lblock = content[side][g]; for (int i = 0; i < lblock.lines.Count; i++) { Line line = lblock.lines[i]; var p = (Paragraph)lineTexts[side][prevLine + i].Document.Blocks.First(); foreach (Block b in line.blocks) { string text = b.text; if (text.EndsWith(SentenceFilter.SentenceDelim)) { text = text.Substring(0, text.Length - SentenceFilter.SentenceDelim.Length); } var run = new Run(text); if (b.type != BlockType.Normal) { if (lblock.type == BlockType.Conflict || lblock.type == BlockType.Edited) { b.type = lblock.type; } run.Style = GetStyle("text" + b.type); } p.Inlines.Add(run); } lineNums[side][prevLine + i].Text = lineNum++.ToString(); } var numBorder = new Border(); Panel.SetZIndex(numBorder, 3); Grid.SetRow(numBorder, 2 * prevLine); Grid.SetColumn(numBorder, side * 2); Grid.SetRowSpan(numBorder, 2 * lineCount[g]); grid.Children.Add(numBorder); lineNumBackgrounds[side].Add(numBorder); var textBorder = new Border(); Panel.SetZIndex(textBorder, 2); Grid.SetRow(textBorder, 2 * prevLine); Grid.SetColumn(textBorder, side * 2 + 1); Grid.SetRowSpan(textBorder, 2 * lineCount[g]); grid.Children.Add(textBorder); lineTextBackgrounds[side].Add(textBorder); if (lblock.type != BlockType.Normal) { numBorder.Style = GetStyle("numBackground" + lblock.type); textBorder.Style = GetStyle("textBackground" + lblock.type); int cIndex = conflictBlocks.BinarySearch(g); for (int line = 0; line < lineCount[g]; line++) { TextBlock num = lineNums[side][prevLine + line]; RichTextBox text = lineTexts[side][prevLine + line]; num.Style = GetStyle("lineNum" + lblock.type); text.Style = GetStyle("lineText" + lblock.type); if (cIndex >= 0) { int mySide = side; // for lambda scoping text.PreviewMouseLeftButtonUp += (o, e) => { ChooseConflict(cIndex, mySide); SelectConflict(cIndex, false); }; text.PreviewMouseDoubleClick += (o, e) => EditConflict(cIndex, mySide); // text.ContextMenu = new ContextMenu(); text.MouseEnter += (o, e) => HoverConflict(cIndex, mySide, true); text.MouseLeave += (o, e) => HoverConflict(cIndex, mySide, false); } } if (side == 0) { var scrollBorder = new Border(); Grid.SetRow(scrollBorder, prevLine); Grid.SetRowSpan(scrollBorder, lineCount[g]); conflictNav.Children.Add(scrollBorder); scrollBorder.Style = GetStyle("scrollBorder" + (scrollNavBorders.Count == 0 ? "Active" : "")); scrollBorder.MouseUp += (o, e) => SelectConflict(cIndex); scrollBorder.ToolTip = String.Format("Conflict {0}/{1}", cIndex+1, conflictBlocks.Count); scrollNavBorders.Add(scrollBorder); } } prevLine += lineCount[g]; } } }