コード例 #1
0
        public void TestUndoRedoCommand()
        {
            // 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 ReplaceTextCommand(
                new BlockPosition(blockKey, 2), 1, "YES");

            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], 5), project.Commands.LastPosition);

            const int index = 0;

            Assert.AreEqual("abYESd", blocks[index].Text);
            Assert.AreEqual(blockVersion + 6, blocks[index].Version);
        }
コード例 #2
0
        private void PerformCommandAction(
            OperationContext context,
            Action <BlockCommandContext> action)
        {
            // Every command needs a full write lock on the blocks.
            using (Project.Blocks.AcquireLock(RequestLock.Write))
            {
                // Create the context for the block commands.
                var blockContext = new BlockCommandContext(Project);

                // Execute the internal command.
                action(blockContext);

                // Set the operation context from the block context.
                if (blockContext.Position.HasValue)
                {
                    // Grab the block position and figure out the index.
                    BlockPosition blockPosition = blockContext.Position.Value;
                    int           blockIndex    = Project.Blocks.IndexOf(blockPosition.BlockKey);

                    var position = new TextPosition(blockIndex, (int)blockPosition.TextIndex);

                    // Set the context results.
                    context.Results = new LineBufferOperationResults(position);
                }
            }
        }
        /// <summary>
        /// Configures the environment to load the plugin manager and verify we
        /// have access to the ImmediateCorrectionPlugin.
        /// </summary>
        private void SetupCorrectionPlugin(
            out BlockCommandContext context,
            out ProjectBlockCollection blocks,
            out BlockCommandSupervisor commands,
            out ImmediateCorrectionProjectPlugin projectPlugin)
        {
            // Start getting us a simple plugin manager.
            var plugin        = new ImmediateCorrectionPlugin();
            var pluginManager = new PluginManager(plugin);

            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;

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

            // Pull out the controller for the correction and cast it (since we know
            // what type it is).
            ProjectPluginController pluginController = project.Plugins.Controllers[0];

            projectPlugin =
                (ImmediateCorrectionProjectPlugin)pluginController.ProjectPlugin;
        }
コード例 #4
0
        public void TestUndoRedoCommand()
        {
            // 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);
            project.Commands.Undo(context);

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

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

            int index = 0;

            Assert.AreEqual("Testing 123", blocks[index].Text);

            index++;
            Assert.AreEqual("", blocks[index].Text);
        }
コード例 #5
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);
        }
コード例 #6
0
        /// <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);
            }
        }
コード例 #7
0
        public ICommand <OperationContext> Undo(OperationContext context)
        {
            // Every command needs a full write lock on the blocks.
            using (Project.Blocks.AcquireLock(RequestLock.Write))
            {
                // Create the context for the block commands.
                var blockContext = new BlockCommandContext(Project);

                // Execute the internal command.
                ICommand <BlockCommandContext> command = Commands.Undo(blockContext);

                // Set the operation context from the block context.
                if (blockContext.Position.HasValue)
                {
                    // Grab the block position and figure out the index.
                    BlockPosition blockPosition = blockContext.Position.Value;
                    int           blockIndex    = Project.Blocks.IndexOf(blockPosition.BlockKey);

                    var position = new TextPosition(blockIndex, (int)blockPosition.TextIndex);

                    // Set the context results.
                    context.Results = new LineBufferOperationResults(position);
                }

                // See if we have a wrapped command, then do the post do.
                var wrapped = command as IWrappedCommand;

                if (wrapped != null)
                {
                    wrapped.PostUndo(context);
                }
            }

            return(null);
        }
コード例 #8
0
 /// <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);
     }
 }
コード例 #9
0
        private void AddToInsensitiveList(
            BlockCommandContext context,
            string word)
        {
            // Update the internal dictionaries.
            CaseInsensitiveDictionary.Add(word.ToLowerInvariant());

            // Clear the spell-checking on the entire document and reparse it.
            Project.Plugins.ClearAnalysis(BlockAnalyzer);
            Project.Plugins.ProcessBlockAnalysis();

            // Make sure the settings are written out.
            WriteSettings();
        }
コード例 #10
0
        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());
            }
        }
コード例 #11
0
        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 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);
        }
コード例 #13
0
        /// <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;
        }
コード例 #14
0
        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());
            }
        }
コード例 #15
0
        public void Do(
            ICommand <OperationContext> command,
            OperationContext context)
        {
            // Every command needs a full write lock on the blocks.
            using (Project.Blocks.AcquireLock(RequestLock.Write))
            {
                // Create the context for the block commands.
                var          blockContext = new BlockCommandContext(Project);
                LinePosition linePosition = context.Position.LinePosition;
                int          lineIndex    = linePosition.GetLineIndex(Project.Blocks.Count);
                Block        currentBlock = Project.Blocks[lineIndex];
                blockContext.Position = new BlockPosition(
                    currentBlock, context.Position.CharacterPosition);

                // Wrap the command with our wrappers.
                IWrappedCommand wrappedCommand = WrapCommand(command, context);

                Project.Commands.Do(wrappedCommand, blockContext);

                // Set the operation context from the block context.
                if (blockContext.Position.HasValue)
                {
                    // Grab the block position and figure out the index.
                    BlockPosition blockPosition = blockContext.Position.Value;
                    int           blockIndex    = Project.Blocks.IndexOf(blockPosition.BlockKey);

                    var position = new TextPosition(blockIndex, (int)blockPosition.TextIndex);

                    // Set the context results.
                    context.Results = new LineBufferOperationResults(position);
                }

                // Make sure we process our wrapped command.
                wrappedCommand.PostDo(context);
            }
        }
        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);
            }
        }
コード例 #17
0
        /// <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);
                    }
                }
            }
        }
コード例 #18
0
 public void Do(BlockCommandContext context)
 {
     command.Do(context);
 }
コード例 #19
0
 public void Redo(BlockCommandContext context)
 {
     command.Redo(context);
 }
コード例 #20
0
 public void Do(BlockCommandContext context)
 {
     Action(context);
 }
コード例 #21
0
 public void Undo(BlockCommandContext context)
 {
     command.Undo(context);
 }