Ejemplo n.º 1
0
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            _commands.Clear();

            if (_length == 1)
            {
                /// 削除する長さが1のとき

                int inlineOffset, charIndexInInline;
                var inline = _target.GetInlineAt(_index, out charIndexInInline, out inlineOffset);

                if (inline.IsLineEndCharacter)
                {
                    var line = inline.Parent as LineSegment;

                    if (inline is LineBreak)
                    {
                        /// line breakならlineをマージ
                        var nextLine = line.NextSibling as LineSegment;
                        var cmd      = new MergeLineSegmentsCommand(line, nextLine);
                        cmd.Execute();
                        _commands.Add(cmd);
                    }
                    else if (inline is BlockBreak)
                    {
                        /// block breakならblockをマージ
                        var block = line.Parent as Block;
                        if (block.HasNextSibling)
                        {
                            var nextBlock     = block.NextSibling as Block;
                            var lastLine      = block.LineSegments.Last();
                            var nextFirstLine = nextBlock.LineSegments.First();

                            var mbcmd = new MergeBlocksCommand(block, nextBlock);
                            mbcmd.Execute();
                            _commands.Add(mbcmd);

                            var mlcmd = new MergeLineSegmentsCommand(lastLine, nextFirstLine);
                            mlcmd.Execute();
                            _commands.Add(mlcmd);
                        }
                    }
                }
                else
                {
                    if (inline.Length == 1)
                    {
                        var line = inline.Parent as LineSegment;
                        var cmd  = new RemoveInlineFromLineSegmentCommand(line, inline);
                        cmd.Execute();
                        _commands.Add(cmd);
                    }
                    else
                    {
                        var cmd = new RemoveStringFromInlineCommand(inline, charIndexInInline, 1);
                        cmd.Execute();
                        _commands.Add(cmd);
                    }
                }
            }
            else if (_length > 1)
            {
                var range = new Range(_index, _length);

                /// rangeの最初と最後でblockを分ける
                var endInline = _target.GetInlineAt(range.End);
                var endcmd    = new EnsureBlockBreakCommand(_target, range.End + 1);
                endcmd.Execute();
                _commands.Add(endcmd);
                range = endcmd.IsExecuted && !endInline.IsLineEndCharacter?
                        new Range(_index, _length + 1):
                        range;

                var prevInline = range.Offset > 0? _target.GetInlineAt(range.Offset - 1): null;
                var startcmd   = new EnsureBlockBreakCommand(_target, range.Offset);
                startcmd.Execute();
                _commands.Add(startcmd);
                range = startcmd.IsExecuted && !prevInline.IsLineEndCharacter?
                        new Range(range.Offset + 1, range.Length):
                        range;

                /// 範囲内のblockをすべて削除
                var removeds = new List <Block>();
                foreach (var block in _target.Blocks)
                {
                    var blockRange = _target.GetRange(block);
                    if (range.Contains(blockRange))
                    {
                        removeds.Add(block);
                    }
                }

                foreach (var block in removeds)
                {
                    var cmd = new RemoveBlockFromStyledTextCommand(_target, block);
                    cmd.Execute();
                    _commands.Add(cmd);
                }

                /// rangeの最初でblockを分けた場合はmergeしておく
                if (startcmd.IsExecuted && !prevInline.IsLineEndCharacter)
                {
                    /// 直前のinlineがLineBreakではなかったならば
                    /// blockをつないでlineもつなげる
                    /// (BlockBreakをLineBreakにして,さらにLineBreakを削除)

                    var block         = _target.GetBlockAt(_index);
                    var nextBlock     = block.NextSibling as Block;
                    var lastLine      = block.LineSegments.Last();
                    var nextFirstLine = nextBlock.LineSegments.First();

                    var mbcmd = new MergeBlocksCommand(block, nextBlock);
                    mbcmd.Execute();
                    _commands.Add(mbcmd);

                    var mlcmd = new MergeLineSegmentsCommand(lastLine, nextFirstLine);
                    mlcmd.Execute();
                    _commands.Add(mlcmd);
                }
                else if (startcmd.IsExecuted && prevInline.IsLineEndCharacter)
                {
                    /// 直前のinlineがLineBreakだったならば
                    /// blockをつなぐ
                    /// (BlockBreakをLineBreakにするだけ)

                    var block     = _target.GetBlockAt(_index - 1);
                    var nextBlock = block.NextSibling as Block;

                    var mbcmd = new MergeBlocksCommand(block, nextBlock);
                    mbcmd.Execute();
                    _commands.Add(mbcmd);
                }
            }
        }