/// <summary>
        /// Performs the command on the given block.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="block">The block to perform the action on.</param>
        /// <param name="project">The project that contains the current state.</param>
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // Save the previous text so we can undo it.
            previousText = block.Text;

            // Figure out what the new text string would be.
            int textIndex = new CharacterPosition(TextIndex).GetCharacterIndex(
                block.Text);
            string newText = block.Text.Insert(textIndex, Text);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // After we insert text, we need to give the immediate editor plugins a
            // chance to made any alterations to the output.
            block.Project.Plugins.ProcessImmediateEdits(
                context, block, textIndex + Text.Length);

            // Set the new position in the buffer.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, textIndex + Text.Length);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Performs the command on the given block.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="block">The block to perform the action on.</param>
        /// <param name="project">The project that contains the current state.</param>
        protected override void Do(
            BlockCommandContext context,
            Block block)
        {
            // Save the previous text so we can undo it.
            previousText = block.Text;

            // Figure out what the new text string would be.
            int textIndex = new CharacterPosition(TextIndex).GetCharacterIndex(
                block.Text);
            string newText = block.Text.Insert(textIndex, Text);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // After we insert text, we need to give the immediate editor plugins a
            // chance to made any alterations to the output.
            block.Project.Plugins.ProcessImmediateEdits(
                context, block, textIndex + Text.Length);

            // Set the new position in the buffer.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, textIndex + Text.Length);
            }
        }
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            // Revert the block type.
            block.SetBlockType(previousBlockType);
        }
Ejemplo n.º 4
0
        protected override void Do(
            BlockCommandContext context,
            Block block)
        {
            // Save the previous text so we can restore it.
            previousText     = block.Text;
            originalPosition = context.Position;

            // Figure out what the new text string would be.
            startIndex = BlockPosition.TextIndex.GetCharacterIndex(
                block.Text, End, WordSearchDirection.Left);
            int endIndex = End.GetCharacterIndex(
                block.Text, TextIndex, WordSearchDirection.Right);

            int    firstIndex = Math.Min(startIndex, endIndex);
            int    lastIndex  = Math.Max(startIndex, endIndex);
            string newText    = block.Text.Remove(firstIndex, lastIndex - firstIndex);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // Set the position after the next text.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, startIndex);
            }
        }
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // Save the previous text so we can restore it.
            previousText = block.Text;
            originalPosition = context.Position;

            // Figure out what the new text string would be.
            startIndex = BlockPosition.TextIndex.GetCharacterIndex(
                block.Text, End, WordSearchDirection.Left);
            int endIndex = End.GetCharacterIndex(
                block.Text, TextIndex, WordSearchDirection.Right);

            int firstIndex = Math.Min(startIndex, endIndex);
            int lastIndex = Math.Max(startIndex, endIndex);
            string newText = block.Text.Remove(firstIndex, lastIndex - firstIndex);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // Set the position after the next text.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, startIndex);
            }
        }
        public override void Undo(BlockCommandContext context)
        {
            // If we have a block key, we use that first.
            ProjectBlockCollection blocks = context.Blocks;

            if (UseBlockKey)
            {
                Block block;

                using (
                    blocks.AcquireBlockLock(
                        RequestLock.Write, RequestLock.Write, BlockKey, out block))
                {
                    Undo(context, block);
                }
            }
            else
            {
                Block block;

                using (
                    blocks.AcquireBlockLock(
                        RequestLock.Write, RequestLock.Write, (int) Line, out block))
                {
                    Undo(context, block);
                }
            }
        }
        public override void Undo(BlockCommandContext context)
        {
            // If we have a block key, we use that first.
            ProjectBlockCollection blocks = context.Blocks;

            if (UseBlockKey)
            {
                Block block;

                using (
                    blocks.AcquireBlockLock(
                        RequestLock.Write, RequestLock.Write, BlockKey, out block))
                {
                    Undo(context, block);
                }
            }
            else
            {
                Block block;

                using (
                    blocks.AcquireBlockLock(
                        RequestLock.Write, RequestLock.Write, (int)Line, out block))
                {
                    Undo(context, block);
                }
            }
        }
Ejemplo n.º 8
0
        protected override void Do(
            BlockCommandContext context,
            Block block)
        {
            // Pull out some common elements we'll need.
            ProjectBlockCollection blocks = block.Blocks;
            int blockIndex = blocks.IndexOf(block) + 1;

            // Because of how block keys work, the ID is unique very time so we have
            // to update our inverse operation.
            addedBlocks.Clear();

            // Go through and create each block at a time, adding it to the inverse
            // command as we create them.
            for (int count = 0;
                 count < Count;
                 count++)
            {
                // Create and insert a new block into the system.
                var newBlock = new Block(blocks);
                blocks.Insert(blockIndex, newBlock);

                // Keep track of the block so we can remove them later.
                addedBlocks.Add(newBlock);

                // Update the position.
                if (UpdateTextPosition.HasFlag(DoTypes.Do))
                {
                    context.Position = new BlockPosition(newBlock.BlockKey, 0);
                }
            }
        }
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // Pull out some common elements we'll need.
            ProjectBlockCollection blocks = block.Blocks;
            int blockIndex = blocks.IndexOf(block) + 1;

            // Because of how block keys work, the ID is unique very time so we have
            // to update our inverse operation.
            addedBlocks.Clear();

            // Go through and create each block at a time, adding it to the inverse
            // command as we create them.
            for (int count = 0;
                count < Count;
                count++)
            {
                // Create and insert a new block into the system.
                var newBlock = new Block(blocks);
                blocks.Insert(blockIndex, newBlock);

                // Keep track of the block so we can remove them later.
                addedBlocks.Add(newBlock);

                // Update the position.
                if (UpdateTextPosition.HasFlag(DoTypes.Do))
                {
                    context.Position = new BlockPosition(newBlock.BlockKey, 0);
                }
            }
        }
        public void TestUndoRedoCommand()
        {
            // Arrange
            var project = new Project();
            var context = new BlockCommandContext(project);
            ProjectBlockCollection blocks = project.Blocks;
            Block block = blocks[0];
            int blockVersion = block.Version;
            BlockKey blockKey = block.BlockKey;

            var command = new SetTextCommand(blockKey, "Testing 123");
            project.Commands.Do(command, context);

            project.Commands.Undo(context);

            // Act
            project.Commands.Redo(context);

            // Assert
            Assert.AreEqual(1, blocks.Count);
            Assert.AreEqual(
                new BlockPosition(blocks[0], "Testing 123".Length),
                project.Commands.LastPosition);

            const int index = 0;
            Assert.AreEqual("Testing 123", blocks[index].Text);
            Assert.AreEqual(blockVersion + 3, blocks[index].Version);
        }
        public void TestUndoCommand()
        {
            // Arrange
            var project = new Project();
            var context = new BlockCommandContext(project);
            ProjectBlockCollection blocks = project.Blocks;
            Block block = blocks[0];
            using (block.AcquireBlockLock(RequestLock.Write))
            {
                block.SetText("Testing 123");
            }
            BlockKey blockKey = block.BlockKey;

            var command = new InsertAfterBlockCommand(blockKey, 1);
            project.Commands.Do(command, context);

            // Act
            project.Commands.Undo(context);

            // Assert
            Assert.AreEqual(1, blocks.Count);
            Assert.AreEqual(
                new BlockPosition(blocks[0], "Testing 123".Length),
                project.Commands.LastPosition);

            const int index = 0;
            Assert.AreEqual("Testing 123", blocks[index].Text);
        }
 protected override void Undo(
     BlockCommandContext context,
     Block block)
 {
     // Revert the block type.
     block.SetBlockType(previousBlockType);
 }
        public void TestUndoCommand()
        {
            // Arrange
            var project = new Project();
            var context = new BlockCommandContext(project);
            ProjectBlockCollection blocks = project.Blocks;
            Block block = blocks[0];
            using (block.AcquireBlockLock(RequestLock.Write))
            {
                block.SetText("abcd");
            }
            int blockVersion = block.Version;
            BlockKey blockKey = block.BlockKey;

            var command = new InsertTextCommand(new BlockPosition(blockKey, 2), "YES");
            project.Commands.Do(command, context);

            // Act
            project.Commands.Undo(context);

            // Assert
            Assert.AreEqual(1, blocks.Count);
            Assert.AreEqual(
                new BlockPosition(blocks[0], 2), project.Commands.LastPosition);

            const int index = 0;
            Assert.AreEqual("abcd", blocks[index].Text);
            Assert.AreEqual(blockVersion + 2, blocks[index].Version);
        }
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            block.SetText(previousText);
            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockKey, previousText.Length);
            }
        }
 protected override void Undo(
     BlockCommandContext context,
     Block block)
 {
     block.SetText(previousText);
     if (UpdateTextPosition.HasFlag(DoTypes.Undo))
     {
         context.Position = new BlockPosition(BlockKey, previousText.Length);
     }
 }
Ejemplo n.º 16
0
        protected override void Undo(
            BlockCommandContext context,
            Block block)
        {
            block.SetText(previousText);

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = originalPosition;
            }
        }
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            previousText = block.Text;
            block.SetText(Text);

            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, Text.Length);
            }
        }
        protected override void Do(
            BlockCommandContext context,
            Block block)
        {
            previousText = block.Text;
            block.SetText(Text);

            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, Text.Length);
            }
        }
Ejemplo n.º 19
0
        protected override void Undo(
            BlockCommandContext context,
            Block block)
        {
            block.SetText(previousText);

            // Set the new cursor position.
            int textIndex = BlockPosition.TextIndex.GetCharacterIndex(previousText);

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockPosition.BlockKey, textIndex);
            }
        }
Ejemplo n.º 20
0
        protected override void Undo(
            BlockCommandContext context,
            Block block)
        {
            foreach (Block addedBlock in addedBlocks)
            {
                context.Blocks.Remove(addedBlock);
            }

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockKey, block.Text.Length);
            }
        }
        public void Undo(BlockCommandContext context)
        {
            // We need a write lock since we are making changes to the collection itself.
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                context.Blocks.Remove(Block);

                // Set the position after the command.
                if (UpdateTextPosition.HasFlag(DoTypes.Undo) &&
                    previousPosition.HasValue)
                {
                    context.Position = previousPosition.Value;
                }
            }
        }
Ejemplo n.º 22
0
        public void Do(BlockCommandContext context)
        {
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                // We need the index of the block so we can restore it back into
                // its place.
                Block block = context.Blocks[blockKey];
                removedBlockIndex = context.Blocks.IndexOf(blockKey);
                removedBlock      = block;

                // Delete the block from the list.
                context.Blocks.Remove(block);

                // If we have no more blocks, then we need to ensure we have a minimum
                // number of blocks.
                addedBlankBlock = null;

                if (!IgnoreMinimumLines &&
                    context.Blocks.Count == 0)
                {
                    // Create a new placeholder block, which is blank.
                    addedBlankBlock = new Block(
                        context.Blocks, block.Project.BlockTypes.Paragraph);

                    context.Blocks.Add(addedBlankBlock);

                    if (UpdateTextPosition.HasFlag(DoTypes.Do))
                    {
                        context.Position = new BlockPosition(addedBlankBlock.BlockKey, 0);
                    }
                }
                else if (!IgnoreMinimumLines)
                {
                    // We have to figure out where the cursor would be after this operation.
                    // Ideally, this would be the block in the current position, but if this
                    // is the last line, then use that.
                    if (UpdateTextPosition.HasFlag(DoTypes.Do))
                    {
                        context.Position =
                            new BlockPosition(
                                removedBlockIndex < context.Blocks.Count
                                                                        ? context.Blocks[removedBlockIndex].BlockKey
                                                                        : context.Blocks[removedBlockIndex - 1].BlockKey,
                                0);
                    }
                }
            }
        }
        public void Do(BlockCommandContext context)
        {
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                // We need the index of the block so we can restore it back into
                // its place.
                Block block = context.Blocks[blockKey];
                removedBlockIndex = context.Blocks.IndexOf(blockKey);
                removedBlock = block;

                // Delete the block from the list.
                context.Blocks.Remove(block);

                // If we have no more blocks, then we need to ensure we have a minimum
                // number of blocks.
                addedBlankBlock = null;

                if (!IgnoreMinimumLines
                    && context.Blocks.Count == 0)
                {
                    // Create a new placeholder block, which is blank.
                    addedBlankBlock = new Block(
                        context.Blocks, block.Project.BlockTypes.Paragraph);

                    context.Blocks.Add(addedBlankBlock);

                    if (UpdateTextPosition.HasFlag(DoTypes.Do))
                    {
                        context.Position = new BlockPosition(addedBlankBlock.BlockKey, 0);
                    }
                }
                else if (!IgnoreMinimumLines)
                {
                    // We have to figure out where the cursor would be after this operation.
                    // Ideally, this would be the block in the current position, but if this
                    // is the last line, then use that.
                    if (UpdateTextPosition.HasFlag(DoTypes.Do))
                    {
                        context.Position =
                            new BlockPosition(
                                removedBlockIndex < context.Blocks.Count
                                    ? context.Blocks[removedBlockIndex].BlockKey
                                    : context.Blocks[removedBlockIndex - 1].BlockKey,
                                0);
                    }
                }
            }
        }
        protected override void Do(
            BlockCommandContext context,
            Block block)
        {
            // We need to keep track of the previous block type so we can change
            // it back with Undo.
            previousBlockType = block.BlockType;

            // Set the block type.
            block.SetBlockType(BlockType);

            // Save the position from this command.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, 0);
            }
        }
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // We need to keep track of the previous block type so we can change
            // it back with Undo.
            previousBlockType = block.BlockType;

            // Set the block type.
            block.SetBlockType(BlockType);

            // Save the position from this command.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, 0);
            }
        }
        public void Undo(BlockCommandContext context)
        {
            // Delete all the added blocks first.
            foreach (Block block in addedBlocks)
            {
                context.Blocks.Remove(block);
            }

            // Restore the text from the first line.
            insertFirstCommand.Undo(context);
            deleteFirstCommand.Undo(context);

            // Update the last position to where we started.
            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = BlockPosition;
            }
        }
        public void ProcessImmediateEdits(
			BlockCommandContext context,
			Block block,
			int textIndex)
        {
            // Get the plugin settings from the project.
            ImmediateBlockTypesSettings settings = Settings;

            // Grab the substring from the beginning to the index and compare that
            // in the dictionary.
            string text = block.Text.Substring(0, textIndex);

            if (!settings.Replacements.ContainsKey(text))
            {
                // We want to fail as fast as possible.
                return;
            }

            // If the block type is already set to the same name, skip it.
            string blockTypeName = settings.Replacements[text];
            BlockType blockType = Project.BlockTypes[blockTypeName];

            if (block.BlockType == blockType)
            {
                return;
            }

            // Perform the substitution with a replace operation and a block change
            // operation.
            var replaceCommand =
                new ReplaceTextCommand(
                    new BlockPosition(block.BlockKey, 0), textIndex, string.Empty);
            var changeCommand = new ChangeBlockTypeCommand(block.BlockKey, blockType);

            // Create a composite command that binds everything together.
            var compositeCommand = new CompositeCommand<BlockCommandContext>(true, false);

            compositeCommand.Commands.Add(replaceCommand);
            compositeCommand.Commands.Add(changeCommand);

            // Add the command to the deferred execution so the command could
            // be properly handled via the undo/redo management.
            block.Project.Commands.DeferDo(compositeCommand);
        }
        public void Do(BlockCommandContext context)
        {
            // We need a write lock since we are making changes to the collection itself.
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                if (UpdateTextPosition.HasFlag(DoTypes.Undo))
                {
                    previousPosition = context.Position;
                }

                context.Blocks.Insert(BlockIndex, Block);

                // Set the position after the command.
                if (UpdateTextPosition.HasFlag(DoTypes.Do))
                {
                    context.Position = new BlockPosition(
                        Block.BlockKey, CharacterPosition.Begin);
                }
            }
        }
        public void Undo(BlockCommandContext context)
        {
            // Since we're making chanegs to the list, we need a write lock.
            ProjectBlockCollection blocks = context.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Go through all the blocks in the project.
                foreach (Block block in blocks)
                {
                    if (Changes.ContainsKey(block.BlockKey))
                    {
                        // Revert the type of this block.
                        BlockType blockType = previousBlockTypes[block.BlockKey];

                        block.SetBlockType(blockType);
                    }
                }
            }
        }
        public void Do(BlockCommandContext context)
        {
            // We need a write lock since we are making changes to the collection itself.
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                if (UpdateTextPosition.HasFlag(DoTypes.Undo))
                {
                    previousPosition = context.Position;
                }

                context.Blocks.Insert(BlockIndex, Block);

                // Set the position after the command.
                if (UpdateTextPosition.HasFlag(DoTypes.Do))
                {
                    context.Position = new BlockPosition(
                        Block.BlockKey, CharacterPosition.Begin);
                }
            }
        }
Ejemplo n.º 31
0
        public void Undo(BlockCommandContext context)
        {
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                // Insert in the old block.
                context.Blocks.Insert(removedBlockIndex, removedBlock);

                // Set the last text position.
                if (UpdateTextPosition.HasFlag(DoTypes.Undo))
                {
                    context.Position = new BlockPosition(blockKey, removedBlock.Text.Length);
                }

                // Remove the blank block, if we added one.
                if (addedBlankBlock != null)
                {
                    context.Blocks.Remove(addedBlankBlock);
                    addedBlankBlock = null;
                }
            }
        }
        public void Do(BlockCommandContext context)
        {
            // Since we're making chanegs to the list, we need a write lock.
            ProjectBlockCollection blocks = context.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Clear out the undo list since we'll be rebuilding it.
                previousBlockTypes.Clear();

                // Go through all the blocks in the project.
                foreach (Block block in blocks)
                {
                    if (Changes.ContainsKey(block.BlockKey))
                    {
                        BlockType blockType = Changes[block.BlockKey];
                        BlockType existingType = block.BlockType;

                        previousBlockTypes[block.BlockKey] = existingType;
                        block.SetBlockType(blockType);
                    }
                }
            }
        }
        public void Do(BlockCommandContext context)
        {
            // Since we're making chanegs to the list, we need a write lock.
            ProjectBlockCollection blocks = context.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Clear out the undo list since we'll be rebuilding it.
                previousBlockTypes.Clear();

                // Go through all the blocks in the project.
                foreach (Block block in blocks)
                {
                    if (Changes.ContainsKey(block.BlockKey))
                    {
                        BlockType blockType    = Changes[block.BlockKey];
                        BlockType existingType = block.BlockType;

                        previousBlockTypes[block.BlockKey] = existingType;
                        block.SetBlockType(blockType);
                    }
                }
            }
        }
        /// <summary>
        /// Creates a project with a set number of lines and gives them a state that
        /// can easily be tested for.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="blocks">The block collection in the project.</param>
        /// <param name="blockTypes">The block types supervisor for the project.</param>
        /// <param name="commands">The commands supervisor for the project.</param>
        /// <param name="lineCount">The number of blocks to insert into the projects.</param>
        protected void SetupMultilineTest(
			out BlockCommandContext context,
			out ProjectBlockCollection blocks,
			out BlockTypeSupervisor blockTypes,
			out BlockCommandSupervisor commands,
			int lineCount = 4)
        {
            // Everything is based on the project.
            var project = new Project();

            context = new BlockCommandContext(project);
            blocks = project.Blocks;
            commands = project.Commands;
            blockTypes = project.BlockTypes;

            // Insert the bulk of the lines.
            InsertLines(project, lineCount);

            // Go through and set up the block types for these elements.
            project.Blocks[0].SetBlockType(blockTypes.Chapter);

            for (int index = 1;
                index < project.Blocks.Count;
                index++)
            {
                project.Blocks[index].SetBlockType(blockTypes.Scene);
            }
        }
 public abstract void Undo(BlockCommandContext context);
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            foreach (Block addedBlock in addedBlocks)
            {
                context.Blocks.Remove(addedBlock);
            }

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockKey, block.Text.Length);
            }
        }
 public void Redo(BlockCommandContext state)
 {
     Do(state);
 }
        public void Do(BlockCommandContext context)
        {
            // We have to clear the undo buffer every time because we'll be creating
            // new blocks.
            addedBlocks.Clear();

            // Start by breaking apart the lines on the newline.
            string[] lines = Text.Split('\n');

            // Make changes to the first line by creating a command, adding it to the
            // list of commands we need an inverse for, and then performing it.
            Block  block         = context.Blocks[BlockPosition.BlockKey];
            string remainingText = block.Text.Substring((int)BlockPosition.TextIndex);

            deleteFirstCommand = new DeleteTextCommand(BlockPosition, block.Text.Length);
            insertFirstCommand = new InsertTextCommand(BlockPosition, lines[0]);

            deleteFirstCommand.Do(context);
            insertFirstCommand.Do(context);

            // Update the final lines text with the remains of the first line.
            int lastLineLength = lines[lines.Length - 1].Length;

            lines[lines.Length - 1] += remainingText;

            // For the remaining lines, we need to insert each one in turn.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = BlockPosition.Empty;
            }

            if (lines.Length > 1)
            {
                // Go through all the lines in reverse order to insert them.
                int firstBlockIndex = context.Blocks.IndexOf(block);

                for (int i = lines.Length - 1;
                     i > 0;
                     i--)
                {
                    // Insert the line and set its text value.
                    var newBlock = new Block(context.Blocks);

                    addedBlocks.Add(newBlock);

                    using (newBlock.AcquireBlockLock(RequestLock.Write))
                    {
                        newBlock.SetText(lines[i]);
                    }

                    context.Blocks.Insert(firstBlockIndex + 1, newBlock);

                    // Update the last position as we go.
                    if (context.Position == BlockPosition.Empty)
                    {
                        if (UpdateTextPosition.HasFlag(DoTypes.Do))
                        {
                            context.Position = new BlockPosition(
                                newBlock.BlockKey, (CharacterPosition)lastLineLength);
                        }
                    }
                }
            }
        }
        public void ProcessImmediateEdits(
			BlockCommandContext context,
			Block block,
			int textIndex)
        {
            // If we aren't optimized, we have to pull the settings back in from the
            // project settings and optimize them.
            if (!optimizedSubstitions)
            {
                RetrieveSettings();
            }

            // Pull out the edit text and add a leading space to simplify the
            // "whole word" substitutions.
            string editText = block.Text.Substring(0, textIndex);

            if (editText.Length - 1 < 0)
            {
                return;
            }

            // Figure out if we're at a word break.
            char finalCharacter = editText[editText.Length - 1];
            bool isWordBreak = char.IsPunctuation(finalCharacter)
                || char.IsWhiteSpace(finalCharacter);

            // Go through the substitution elements and look for each one.
            foreach (RegisteredSubstitution substitution in Substitutions)
            {
                // If we are doing whole word searches, then we don't bother if
                // the final character isn't a word break or if it isn't a word
                // break before it.
                ReplaceTextCommand command;
                int searchLength = substitution.Search.Length;
                int startSearchIndex = editText.Length - searchLength;

                // If we are going to be searching before the string, then this
                // search term will never be valid.
                if (startSearchIndex < 0)
                {
                    continue;
                }

                // Do the search based on the whole word or suffix search.
                if (substitution.IsWholeWord)
                {
                    // Check to see if we have a valid search term.
                    if (!isWordBreak)
                    {
                        continue;
                    }

                    if (startSearchIndex > 0
                        && char.IsPunctuation(editText[startSearchIndex - 1]))
                    {
                        continue;
                    }

                    if (startSearchIndex - 1 < 0)
                    {
                        continue;
                    }

                    // Make sure the string we're looking at actually is the same.
                    string editSubstring = editText.Substring(
                        startSearchIndex - 1, substitution.Search.Length);

                    if (editSubstring != substitution.Search)
                    {
                        // The words don't match.
                        continue;
                    }

                    // Perform the substitution with a replace operation.
                    command =
                        new ReplaceTextCommand(
                            new BlockPosition(block.BlockKey, startSearchIndex - 1),
                            searchLength + 1,
                            substitution.Replacement + finalCharacter);
                }
                else
                {
                    // Perform a straight comparison search.
                    if (!editText.EndsWith(substitution.Search))
                    {
                        continue;
                    }

                    // Figure out the replace operation.
                    command =
                        new ReplaceTextCommand(
                            new BlockPosition(block.BlockKey, startSearchIndex),
                            searchLength,
                            substitution.Replacement);
                }

                // Add the command to the deferred execution so the command could
                // be properly handled via the undo/redo management.
                block.Project.Commands.DeferDo(command);
            }
        }
        public void Do(BlockCommandContext context)
        {
            // We have to clear the undo buffer every time because we'll be creating
            // new blocks.
            addedBlocks.Clear();

            // Start by breaking apart the lines on the newline.
            string[] lines = Text.Split('\n');

            // Make changes to the first line by creating a command, adding it to the
            // list of commands we need an inverse for, and then performing it.
            Block block = context.Blocks[BlockPosition.BlockKey];
            string remainingText = block.Text.Substring((int) BlockPosition.TextIndex);
            deleteFirstCommand = new DeleteTextCommand(BlockPosition, block.Text.Length);
            insertFirstCommand = new InsertTextCommand(BlockPosition, lines[0]);

            deleteFirstCommand.Do(context);
            insertFirstCommand.Do(context);

            // Update the final lines text with the remains of the first line.
            int lastLineLength = lines[lines.Length - 1].Length;
            lines[lines.Length - 1] += remainingText;

            // For the remaining lines, we need to insert each one in turn.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = BlockPosition.Empty;
            }

            if (lines.Length > 1)
            {
                // Go through all the lines in reverse order to insert them.
                int firstBlockIndex = context.Blocks.IndexOf(block);

                for (int i = lines.Length - 1;
                    i > 0;
                    i--)
                {
                    // Insert the line and set its text value.
                    var newBlock = new Block(context.Blocks);

                    addedBlocks.Add(newBlock);

                    using (newBlock.AcquireBlockLock(RequestLock.Write))
                    {
                        newBlock.SetText(lines[i]);
                    }

                    context.Blocks.Insert(firstBlockIndex + 1, newBlock);

                    // Update the last position as we go.
                    if (context.Position == BlockPosition.Empty)
                    {
                        if (UpdateTextPosition.HasFlag(DoTypes.Do))
                        {
                            context.Position = new BlockPosition(
                                newBlock.BlockKey, (CharacterPosition) lastLineLength);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Called when the context menu is being populated.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The event arguments.</param>
        private void OnPopulateContextMenu(
			object sender,
			PopulateContextMenuArgs args)
        {
            // Remove the existing items from the list.
            var menuItems = new HashSet<Widget>(args.Menu.Children);

            foreach (Widget menuItem in menuItems)
            {
                args.Menu.Remove(menuItem);
            }

            // We need a read lock on both the collection and the specific block
            // for the given line index.
            TextPosition position = editorView.Caret.Position;
            int blockIndex =
                position.LinePosition.GetLineIndex(editorView.LineBuffer.LineCount);
            int characterIndex = position.GetCharacterIndex(editorView.LineBuffer);
            Block block;

            var context = new BlockCommandContext(project);

            using (blocks.AcquireBlockLock(RequestLock.Read, blockIndex, out block))
            {
                // Figure out if we have any spans for this position.
                if (!block.TextSpans.Contains(characterIndex))
                {
                    // Nothing to add, so we can stop processing.
                    return;
                }

                // Gather up all the text spans for the current position in the line.
                var textSpans = new List<TextSpan>();

                textSpans.AddRange(block.TextSpans.GetAll(characterIndex));

                // Gather up the menu items for this point.
                bool firstItem = true;

                foreach (TextSpan textSpan in textSpans)
                {
                    IList<IEditorAction> actions = textSpan.Controller.GetEditorActions(
                        block, textSpan);

                    foreach (IEditorAction action in actions)
                    {
                        // Create a menu item and hook up events.
                        IEditorAction doAction = action;

                        var menuItem = new MenuItem(action.DisplayName);

                        menuItem.Activated += delegate
                        {
                            doAction.Do(context);
                            RaiseLineChanged(new LineChangedArgs(blockIndex));
                        };

                        // If this is the first item, then make the initial
                        // selection to avoid scrolling.
                        if (firstItem)
                        {
                            menuItem.Select();
                        }

                        firstItem = false;

                        // Add the item to the popup menu.
                        args.Menu.Add(menuItem);
                    }
                }
            }
        }
        /// <summary>
        /// Configures the environment to load the plugin manager and verify we
        /// have access to our plugin and projectPlugin.
        /// </summary>
        private void SetupPlugin(
			out BlockCommandContext context,
			out ProjectBlockCollection blocks,
			out BlockCommandSupervisor commands,
			out PluginSupervisor plugins,
			out SpellEngineSpellingProjectPlugin projectPlugin)
        {
            // Start getting us a simple plugin manager.
            var spelling = new SpellingFrameworkPlugin();
            var nhunspell = new HunspellSpellingPlugin();
            var pluginManager = new PluginManager(spelling, nhunspell);

            PluginManager.Instance = pluginManager;

            // Create a project and pull out the useful properties we'll use to
            // make changes.
            var project = new Project();

            context = new BlockCommandContext(project);
            blocks = project.Blocks;
            commands = project.Commands;
            plugins = project.Plugins;

            // Load in the immediate correction editor.
            if (!plugins.Add("Spelling Framework"))
            {
                // We couldn't load it for some reason.
                throw new ApplicationException("Cannot load 'Spelling' plugin.");
            }

            if (!plugins.Add("NHunspell"))
            {
                // We couldn't load it for some reason.
                throw new ApplicationException("Cannot load 'NHunspell' plugin.");
            }

            // Pull out the projectPlugin for the correction and cast it (since we know
            // what type it is).
            ProjectPluginController pluginController = plugins.Controllers[1];
            projectPlugin =
                (SpellEngineSpellingProjectPlugin) pluginController.ProjectPlugin;
        }
Ejemplo n.º 43
0
 public void Redo(BlockCommandContext state)
 {
     Do(state);
 }
Ejemplo n.º 44
0
 public abstract void Undo(BlockCommandContext context);
Ejemplo n.º 45
0
 protected abstract void Undo(
     BlockCommandContext context,
     Block block);
        public override LineBufferOperationResults InsertLines(
			int lineIndex,
			int count)
        {
            var composite = new CompositeCommand<BlockCommandContext>(true, false);

            using (project.Blocks.AcquireLock(RequestLock.Write))
            {
                for (int i = 0;
                    i < count;
                    i++)
                {
                    var block = new Block(project.Blocks);
                    var command = new InsertIndexedBlockCommand(lineIndex, block);
                    composite.Commands.Add(command);
                }

                var context = new BlockCommandContext(project);
                project.Commands.Do(composite, context);

                return GetOperationResults();
            }
        }
        public void Undo(BlockCommandContext context)
        {
            using (context.Blocks.AcquireLock(RequestLock.Write))
            {
                // Insert in the old block.
                context.Blocks.Insert(removedBlockIndex, removedBlock);

                // Set the last text position.
                if (UpdateTextPosition.HasFlag(DoTypes.Undo))
                {
                    context.Position = new BlockPosition(blockKey, removedBlock.Text.Length);
                }

                // Remove the blank block, if we added one.
                if (addedBlankBlock != null)
                {
                    context.Blocks.Remove(addedBlankBlock);
                    addedBlankBlock = null;
                }
            }
        }
        public override LineBufferOperationResults InsertText(
			int lineIndex,
			int characterIndex,
			string text)
        {
            using (project.Blocks.AcquireLock(RequestLock.Write))
            {
                Block block = project.Blocks[lineIndex];
                var position = new BlockPosition(block.BlockKey, characterIndex);
                var command = new InsertTextCommand(position, text);
                var context = new BlockCommandContext(project);
                project.Commands.Do(command, context);

                return GetOperationResults();
            }
        }
 public void Redo(BlockCommandContext context)
 {
     Do(context);
 }
        public override LineBufferOperationResults DeleteLines(
			int lineIndex,
			int count)
        {
            using (project.Blocks.AcquireLock(RequestLock.Write))
            {
                Block block = project.Blocks[lineIndex];
                var command = new DeleteBlockCommand(block.BlockKey);
                var context = new BlockCommandContext(project);
                project.Commands.Do(command, context);

                return GetOperationResults();
            }
        }
		/// <summary>
		/// Checks for immediate edits on a block. This is intended to be a blocking
		/// editing that will always happen within a write lock.
		/// </summary>
		/// <param name="context">The context of the edit just performed.</param>
		/// <param name="block">The block associated with the current changes.</param>
		/// <param name="textIndex">Index of the text inside the block.</param>
		public void ProcessImmediateEdits(
			BlockCommandContext context,
			Block block,
			int textIndex)
		{
			foreach (
				IImmediateEditorProjectPlugin immediateBlockEditor in ImmediateEditors)
			{
				immediateBlockEditor.ProcessImmediateEdits(context, block, textIndex);
			}
		}
 public void Redo(BlockCommandContext context)
 {
     Do(context);
 }
        protected abstract void Undo(
			BlockCommandContext context,
			Block block);