private void ExecutePaste(ExecutedRoutedEventArgs e) { var bytes = (byte[])Clipboard.GetData(DataFormats.Serializable); var br = new ByteRange(CaretOffset, bytes); var cmd = new AddBulkTextCommand(this, br, OverwriteMode); _commandManager.AddCommand(cmd); }
public void Insert(ByteRange change) { // find first affected range var ranges = _dataRanges.Values; DataRange dr = null; int i = 0; for (; i < ranges.Count; i++) { dr = ranges[i]; if (dr.Range.Contains(change.Start)) { break; } } if (i == ranges.Count) { // just add the change Debug.Assert(change.Start == Size); _dataRanges.Add(change.Start, change); var oldSize = Size; Size = change.End + 1; OnSizeChanged(oldSize); } else { // split current var left = dr.GetSubRange(Range.FromStartToEnd(dr.Start, change.Start - 1)); var right = dr.GetSubRange(Range.FromStartToEnd(change.Start, dr.End)); _dataRanges.Remove(dr.Start); i--; //shift the rightmost ranges in reverse order to prevent accidental overlap ranges = _dataRanges.Values; for (int j = ranges.Count - 1; j > i; --j) { dr = ranges[j]; _dataRanges.Remove(dr.Start); dr.Shift(change.Count); _dataRanges.Add(dr.Start, dr); } if (!left.Range.IsEmpty) { _dataRanges.Add(left.Start, left); } if (!right.Range.IsEmpty) { right.Shift(change.Count); _dataRanges.Add(right.Start, right); } // finally, insert the change _dataRanges.Add(change.Start, change); Size += change.Count; OnSizeChanged(Size - change.Count); } }
public void Overwrite(ByteRange change) { DataRange dr; if (_dataRanges.TryGetValue(change.Start, out dr) && change.Count == dr.Count) { // just replace _dataRanges.Remove(change.Start); _dataRanges.Add(change.Start, change); return; } var ranges = _dataRanges.Values; int index = -1; for (int i = 0; i < ranges.Count; i++) { dr = ranges[i]; // are we off the grid? if (change.End < dr.Start) { break; } // skip ranges eariler than the change if (change.Start > dr.End) { continue; } if (index < 0) { index = i; } if (change.Range.ContainsEntirely(dr.Range)) { // range can be removed _dataRanges.RemoveAt(i); i--; continue; } } if (index < 0) { return; } if (index >= ranges.Count) { // add at the end _dataRanges.Add(change.Start, change); var oldSize = Size; Size = change.End + 1; OnSizeChanged(oldSize); return; } dr = ranges[index]; // some non trivial intersection var isec = change.Range.GetIntersection(dr.Range); var left = dr.GetSubRange(Range.FromStartToEnd(dr.Start, change.Start - 1)); var right = dr.GetSubRange(Range.FromStartToEnd(change.End + 1, dr.End)); var next = index < ranges.Count - 1 ? ranges[index + 1] : null; _dataRanges.RemoveAt(index); if (!left.Range.IsEmpty) { _dataRanges.Add(left.Start, left); } _dataRanges.Add(change.Start, change); if (change.End >= Size) { var oldSize = Size; Size = change.End + 1; OnSizeChanged(oldSize); } if (!right.Range.IsEmpty) { _dataRanges.Add(right.Start, right); } if (next != null) { // check next range for overlap var isec2 = change.Range.GetIntersection(next.Range); if (!isec2.IsEmpty) { right = next.GetSubRange(Range.FromStartToEnd(change.End + 1, next.End)); _dataRanges.Remove(next.Start); if (!right.IsEmpty) { _dataRanges.Add(right.Start, right); } } } }