/// <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); } }
/// <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); }
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); } } }
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); } }
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); } }
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); } }
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; } } }
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); } } }
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; }
public void Redo(BlockCommandContext state) { Do(state); }
public abstract void Undo(BlockCommandContext context);
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);