예제 #1
0
        public MergeEditor(LineBlock yourBlock, LineBlock updatedBlock, LineBlock originalBlock, LineBlock editBlock = null)
        {
            InitializeComponent();
              Style = (Style)FindResource(typeof(Window));

              RenderLineBlock(yourBlock, yourText);
              myStr = yourBlock.ToString();
              RenderLineBlock(updatedBlock, updatedText);
              updatedStr = updatedBlock.ToString();
              originalStr = originalBlock.ToString();
              if (editBlock != null) {
            mergedText.Text = editBlock.ToString();
              }
        }
예제 #2
0
 private void RenderLineBlock(LineBlock lineBlock, RichTextBox r)
 {
     r.Document.Blocks.Clear();
       foreach (Line line in lineBlock.lines) {
     var p = new Paragraph();
     foreach (Block block in line.blocks) {
       string text = block.text;
       if (text.EndsWith(SentenceFilter.SentenceDelim)) {
     text = text.Substring(0, text.Length - SentenceFilter.SentenceDelim.Length);
       }
       p.Inlines.Add(new Run(text) {
     Style = GetStyle("text" + block.type)
       });
     }
     r.Document.Blocks.Add(p);
       }
 }
예제 #3
0
 public void Append(LineBlock lb)
 {
     foreach (Line line in lb.lines) {
     lines.Add(line);
       }
 }
예제 #4
0
        private void ProcessDiff(string original, string myVersion, string newVersion)
        {
            // Do a line-by-line diff, marking changed line groups.
              // Also, find intersecting diffs and mark them as conflicted changes for resolution.
              var d = new Differ();
              var diffs = new DiffResult[2] {
            d.CreateLineDiffs(original, myVersion ?? "", false),
            d.CreateLineDiffs(original, newVersion ?? "", false)
              };

              string[][] newPieces = new string[2][];
              newPieces[0] = diffs[0].PiecesNew;
              newPieces[1] = diffs[1].PiecesNew;
              if (myVersion == "") newPieces[0] = new string[] { "" };
              if (newVersion == "") newPieces[1] = new string[] { "" };

              var dblocks = new List<Tuple<DiffBlock, int>>();
              for (int side = 0; side < 2; side++) {
            foreach (var block in diffs[side].DiffBlocks) {
              DiffBlock actualBlock = block;
              if (diffs[side].PiecesNew.Length == 0 && block.InsertCountB == 0 && block.InsertStartB == 0) {
            actualBlock = new DiffBlock(block.DeleteStartA, block.DeleteCountA, 0, 1);
              }
              dblocks.Add(new Tuple<DiffBlock, int>(actualBlock, side));
            }
              }
              dblocks.Sort((a, b) => a.Item1.DeleteStartA.CompareTo(b.Item1.DeleteStartA));

              content = new List<LineBlock>[2];
              for (int i = 0; i < 2; i++) {
            content[i] = new List<LineBlock>();
              }
              conflictOrigBlocks = new List<LineBlock>();

              string[] origLines = diffs[0].PiecesOld;
              int nextOriginalLine = 0;
              for (int i = 0; i < dblocks.Count; ) {
            DiffBlock block = dblocks[i].Item1;
            int owner = dblocks[i].Item2;
            // Add unchanged (original) lines.
            if (block.DeleteStartA > nextOriginalLine) {
              foreach (var lineBlocks in content) {
            lineBlocks.Add(new LineBlock(Util.ArraySlice(origLines, nextOriginalLine, block.DeleteStartA - nextOriginalLine)));
              }
              nextOriginalLine = block.DeleteStartA;
            }

            int rangeStart = block.DeleteStartA;
            int rangeEnd = rangeStart + block.DeleteCountA;
            int j = i;
            // If this change intersects any other changes, then merge them together to form a block.
            while (j < dblocks.Count && dblocks[j].Item1.DeleteStartA <= rangeEnd) {
              rangeEnd = Math.Max(rangeEnd, dblocks[j].Item1.DeleteStartA + dblocks[j].Item1.DeleteCountA);
              j++;
            }

            if (j == i + 1) {
              // A regular change.
              var oldBlock = new LineBlock(Util.ArraySlice(diffs[owner].PiecesOld, block.DeleteStartA, block.DeleteCountA), BlockType.ChangeDelete);
              var newBlock = new LineBlock(Util.ArraySlice(newPieces[owner], block.InsertStartB, block.InsertCountB), BlockType.ChangeAdd);
              if (block.DeleteCountA != 0 && block.InsertCountB != 0) {
            oldBlock.type = BlockType.Conflict;
            newBlock.type = BlockType.Conflict;
              } else if (block.DeleteCountA == 0) {
            oldBlock.type = BlockType.Blank;
              } else if (block.InsertCountB == 0) {
            newBlock.type = BlockType.Blank;
              } // can't both be empty!
              ProcessBlockDiff(oldBlock, newBlock);
              content[owner].Add(newBlock);
              content[1 - owner].Add(oldBlock);
              conflictOrigBlocks.Add(owner == 0 ? newBlock : oldBlock);
            } else {
              // Create a change block.
              for (int side = 0; side < 2; side++) {
            int curOriginalLine = rangeStart;
            var conflictBlock = new LineBlock();
            var origBlock = new LineBlock();
            conflictBlock.type = BlockType.Conflict;
            for (int k = i; k < j; k++) {
              DiffBlock subBlock = dblocks[k].Item1;
              if (dblocks[k].Item2 != side) continue;
              if (subBlock.DeleteStartA > curOriginalLine) {
                conflictBlock.AddLines(Util.ArraySlice(origLines, curOriginalLine, subBlock.DeleteStartA - curOriginalLine));
              }
              curOriginalLine = subBlock.DeleteStartA + subBlock.DeleteCountA;
              var oldBlock = new LineBlock(Util.ArraySlice(diffs[side].PiecesOld, subBlock.DeleteStartA, subBlock.DeleteCountA), BlockType.ChangeDelete);
              var newBlock = new LineBlock(Util.ArraySlice(newPieces[side], subBlock.InsertStartB, subBlock.InsertCountB), BlockType.ChangeAdd);
              ProcessBlockDiff(oldBlock, newBlock, false);
              origBlock.Append(oldBlock);
              conflictBlock.Append(newBlock);
            }
            if (rangeEnd > curOriginalLine) {
              conflictBlock.AddLines(Util.ArraySlice(origLines, curOriginalLine, rangeEnd - curOriginalLine));
            }
            if (conflictBlock.lines.Count == 0) {
              conflictBlock.type = BlockType.ChangeDelete;
            }
            content[side].Add(conflictBlock);
            if (side == 0) {
              conflictOrigBlocks.Add(origBlock);
            }
              }

              int last = content[0].Count - 1;
              if (content[0][last].ToString() == content[1][last].ToString()) {
            // Not actually a conflict if they're both the same change.
            if (content[0][last].lines.Count == 0) {
              // If both are deleted, just show nothing.
              content[0].RemoveAt(last);
              content[1].RemoveAt(last);
            } else {
              // Make them normal blocks.
              content[0][last] = new LineBlock(content[0][last].lines.Select(x => x.ToString()).ToArray());
              content[1][last] = new LineBlock(content[1][last].lines.Select(x => x.ToString()).ToArray());
            }
            conflictOrigBlocks.RemoveAt(conflictOrigBlocks.Count - 1);
              }
            }

            nextOriginalLine = rangeEnd;
            i = j;
              }

              // Add any remaining unchanged lines.
              if (origLines.Length > nextOriginalLine) {
            foreach (var lineBlocks in content) {
              lineBlocks.Add(new LineBlock(Util.ArraySlice(origLines, nextOriginalLine, origLines.Length - nextOriginalLine)));
            }
              }

              origBlocks = new LineBlock[2][];
              origBlocks[0] = new LineBlock[content[0].Count];
              origBlocks[1] = new LineBlock[content[1].Count];
              content[0].CopyTo(origBlocks[0]);
              content[1].CopyTo(origBlocks[1]);
        }
예제 #5
0
        private void ProcessBlockDiff(LineBlock oldLineBlock, LineBlock newLineBlock, bool modifyOld = true)
        {
            // Do block-by-block diffs inside LineBlocks.
              var oldBlocks = new List<Block>();
              var newBlocks = new List<Block>();

              foreach (var line in oldLineBlock.lines) {
            oldBlocks.AddRange(line.blocks);
              }

              foreach (var line in newLineBlock.lines) {
            newBlocks.AddRange(line.blocks);
              }

              var d = new Differ();
              DiffResult diff = d.CreateLineDiffs(String.Join("\n", oldBlocks.Select(x => x.ToString()).ToArray()),
            String.Join("\n", newBlocks.Select(x => x.ToString()).ToArray()), false);

              foreach (DiffBlock dblock in diff.DiffBlocks) {
            if (modifyOld) {
              for (int i = 0; i < dblock.DeleteCountA && dblock.DeleteStartA + i < oldBlocks.Count; i++) {
            oldBlocks[i + dblock.DeleteStartA].type = BlockType.ChangeDelete;
              }
            }
            for (int i = 0; i < dblock.InsertCountB && dblock.InsertStartB + i < newBlocks.Count; i++) {
              newBlocks[i + dblock.InsertStartB].type = BlockType.ChangeAdd;
            }
              }
        }
예제 #6
0
 private void ClickSave(object sender, RoutedEventArgs e)
 {
     string text = mergedText.Text;
       newBlock = new LineBlock(SentenceFilter.SplitLines(text), BlockType.Edited);
       Close();
 }