示例#1
0
        /// <summary>
        ///     Replaces text.
        /// </summary>
        /// <param name="offset">The starting offset of the text to be replaced.</param>
        /// <param name="length">The length of the text to be replaced.</param>
        /// <param name="text">The new text.</param>
        /// <param name="offsetChangeMap">
        ///     The offsetChangeMap determines how offsets inside the old text are mapped to the new text.
        ///     This affects how the anchors and segments inside the replaced region behave.
        ///     If you pass null (the default when using one of the other overloads), the offsets are changed as
        ///     in OffsetChangeMappingType.Normal mode.
        ///     If you pass OffsetChangeMap.Empty, then everything will stay in its old place
        ///     (OffsetChangeMappingType.CharacterReplace mode).
        ///     The offsetChangeMap must be a valid 'explanation' for the document change. See
        ///     <see cref="OffsetChangeMap.IsValidForDocumentChange" />.
        ///     Passing an OffsetChangeMap to the Replace method will automatically freeze it to ensure the thread safety of the
        ///     resulting
        ///     DocumentChangeEventArgs instance.
        /// </param>
        public void Replace(int offset, int length, ITextSource text, OffsetChangeMap offsetChangeMap)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            text = text.CreateSnapshot();
            if (offsetChangeMap != null)
            {
                offsetChangeMap.Freeze();
            }

            // Ensure that all changes take place inside an update group.
            // Will also take care of throwing an exception if inDocumentChanging is set.
            BeginUpdate();
            try
            {
                // protect document change against corruption by other changes inside the event handlers
                inDocumentChanging = true;
                try
                {
                    // The range verification must wait until after the BeginUpdate() call because the document
                    // might be modified inside the UpdateStarted event.
                    ThrowIfRangeInvalid(offset, length);

                    DoReplace(offset, length, text, offsetChangeMap);
                }
                finally
                {
                    inDocumentChanging = false;
                }
            }
            finally
            {
                EndUpdate();
            }
        }
示例#2
0
        /// <summary>
        ///     Replaces text.
        /// </summary>
        /// <param name="offset">The starting offset of the text to be replaced.</param>
        /// <param name="length">The length of the text to be replaced.</param>
        /// <param name="text">The new text.</param>
        /// <param name="offsetChangeMappingType">
        ///     The offsetChangeMappingType determines how offsets inside the old text are mapped to the new text.
        ///     This affects how the anchors and segments inside the replaced region behave.
        /// </param>
        public void Replace(int offset, int length, ITextSource text, OffsetChangeMappingType offsetChangeMappingType)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            // Please see OffsetChangeMappingType XML comments for details on how these modes work.
            switch (offsetChangeMappingType)
            {
            case OffsetChangeMappingType.Normal:
                Replace(offset, length, text, null);
                break;

            case OffsetChangeMappingType.KeepAnchorBeforeInsertion:
                Replace(offset, length, text, OffsetChangeMap.FromSingleElement(
                            new OffsetChangeMapEntry(offset, length, text.TextLength, false, true)));
                break;

            case OffsetChangeMappingType.RemoveAndInsert:
                if (length == 0 || text.TextLength == 0)
                {
                    // only insertion or only removal?
                    // OffsetChangeMappingType doesn't matter, just use Normal.
                    Replace(offset, length, text, null);
                }
                else
                {
                    var map = new OffsetChangeMap(2);
                    map.Add(new OffsetChangeMapEntry(offset, length, 0));
                    map.Add(new OffsetChangeMapEntry(offset, 0, text.TextLength));
                    map.Freeze();
                    Replace(offset, length, text, map);
                }
                break;

            case OffsetChangeMappingType.CharacterReplace:
                if (length == 0 || text.TextLength == 0)
                {
                    // only insertion or only removal?
                    // OffsetChangeMappingType doesn't matter, just use Normal.
                    Replace(offset, length, text, null);
                }
                else if (text.TextLength > length)
                {
                    // look at OffsetChangeMappingType.CharacterReplace XML comments on why we need to replace
                    // the last character
                    var entry = new OffsetChangeMapEntry(offset + length - 1, 1, 1 + text.TextLength - length);
                    Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
                }
                else if (text.TextLength < length)
                {
                    var entry = new OffsetChangeMapEntry(offset + text.TextLength, length - text.TextLength, 0, true, false);
                    Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
                }
                else
                {
                    Replace(offset, length, text, OffsetChangeMap.Empty);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("offsetChangeMappingType", offsetChangeMappingType, "Invalid enum value");
            }
        }