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

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

            if (charIndexInInline == 0)
            {
                /// inlineの最初の文字を指している場合,inlineの直前に挿入する
                var line  = inline.Parent as LineSegment;
                var index = line._Inlines.IndexOf(inline);
                _commands.Add(new InsertInlineToLineSegmentCommand(line, _inserted, index));
            }
            else
            {
                /// inlineの最初文字でない場合,inlineを分割して間に挿入する
                var line        = inline.Parent as LineSegment;
                var inlineClone = inline.Clone() as Inline;
                var index       = line._Inlines.IndexOf(inline);
                _commands.Add(new RemoveStringFromInlineCommand(inline, charIndexInInline));
                _commands.Add(new RemoveStringFromInlineCommand(inlineClone, 0, charIndexInInline));
                _commands.Add(new InsertInlineToLineSegmentCommand(line, _inserted, index + 1));
                _commands.Add(new InsertInlineToLineSegmentCommand(line, inlineClone, index + 2));
            }

            foreach (var cmd in _commands)
            {
                cmd.Execute();
            }
        }
Ejemplo n.º 2
0
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            var color = _colorProvider(_target.GetInlineAt(_range.Offset));

            _command = new ApplyCommandCommand(
                _target,
                _range,
                flow => new SetColorOfFlowCommand(flow, color)
                );
            _command.Execute();
        }
Ejemplo n.º 3
0
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            var font = _fontProvider(_target.GetInlineAt(_range.Offset));

            _command = new ApplyCommandCommand(
                _target,
                _range,
                (flow) => new SetFontOfFlowCommand(flow, font)
                );
            _command.Execute();
        }
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            _command    = null;
            _isExecuted = false;

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

            if (charIndexInInline != 0)
            {
                _command = new SplitInlineCommand(inline, charIndexInInline);
                _command.Execute();
                _isExecuted = true;
            }
        }
Ejemplo n.º 5
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);
                }
            }
        }
Ejemplo n.º 6
0
        // ========================================
        // method
        // ========================================
        public override void Execute()
        {
            _command = null;

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

            if (inline.IsLineEndCharacter || inline.IsAnchorCharacter)
            {
                /// _indexのinlineがControlCharならば

                if (_target.HasPrevInline(inline))
                {
                    /// 文頭でなければ

                    var prev = _target.GetPrevInline(inline);
                    if (prev.IsLineEndCharacter || prev.IsAnchorCharacter)
                    {
                        /// inlineの前がControlCharacterなら直前にrunを追加
                        var parent = inline.Parent as LineSegment;
                        var index  = parent._Inlines.IndexOf(inline);

                        var newRun = new Run(_text);
                        if (prev.IsLineEndCharacter && prev.HasPrevSibling)
                        {
                            /// inlineの前のLineEndCharacterの前に
                            /// ControlCharacterでないinlineがあればtransfer

                            var para           = parent.Parent as Paragraph;
                            var pp             = prev.PrevSibling as Inline;
                            var ppLine         = pp.Parent;
                            var ppPara         = ppLine == null ? null : ppLine.Parent as Paragraph;
                            var ppParaIsNormal = ppPara != null && ppPara.ParagraphKind == ParagraphKind.Normal;
                            var ppParaIsEqual  = ppPara != null && ppPara.ParagraphKind == para.ParagraphKind;
                            if (pp != null && !pp.IsLineEndCharacter && !pp.IsAnchorCharacter && ppParaIsNormal && ppParaIsEqual)
                            {
                                var ppRun = pp as Run;
                                if (ppRun != null)
                                {
                                    /// Linkは写さない
                                    ppRun.TransferWithoutLink(newRun);
                                }
                                else
                                {
                                    pp.Transfer(newRun);
                                }
                            }
                            else if (para.ParagraphKind != ParagraphKind.Normal)
                            {
                                newRun.Font = _target.GetDefaultFont(para.ParagraphKind);
                            }
                        }
                        _command = new InsertInlineToLineSegmentCommand(parent, newRun, index);
                    }
                    else
                    {
                        var run = prev as Run;
                        if (run != null && run.HasLink)
                        {
                            /// prevにlinkが設定されている場合はlinkを引き継がないように直前にrunを追加
                            var parent = inline.Parent as LineSegment;
                            var index  = parent._Inlines.IndexOf(inline);
                            var newRun = new Run(_text);
                            run.TransferWithoutLink(newRun);
                            _command = new InsertInlineToLineSegmentCommand(parent, newRun, index);
                        }
                        else
                        {
                            _command = new AppendStringToInlineCommand(prev, _text);
                        }
                    }
                }
                else
                {
                    /// 文頭の場合prevがないので挿入しておく
                    var first  = _target.Blocks.First();
                    var newRun = new Run(_text);
                    _target.Transfer(newRun);
                    _command = new InsertInlineBeforeToBlockCommand(first, newRun);
                }
            }
            else
            {
                /// _indexのinlineがControlCharでなければ

                if (_index == inlineOffset)
                {
                    /// inlineの最初の文字を指している場合,

                    /// StyledText中で一番最初のinlineだったり,
                    /// ControlCharacter直後のinlineの場合はinlineにInsert,
                    /// そうでなければ直前のinlineにAppend
                    if (_target.HasPrevInline(inline))
                    {
                        var prev = _target.GetPrevInline(inline);
                        if (prev.IsLineEndCharacter || prev.IsAnchorCharacter)
                        {
                            _command = new InsertStringToInlineCommand(inline, _text, charIndexInInline);
                        }
                        else
                        {
                            var run = prev as Run;
                            if (run != null && run.HasLink)
                            {
                                /// prevにlinkが設定されている場合はlinkを引き継がないように直前にrunを追加
                                var parent = inline.Parent as LineSegment;
                                var index  = parent._Inlines.IndexOf(inline);
                                var newRun = new Run(_text);
                                run.TransferWithoutLink(newRun);
                                _command = new InsertInlineToLineSegmentCommand(parent, newRun, index);
                            }
                            else
                            {
                                _command = new AppendStringToInlineCommand(prev, _text);
                            }
                        }
                    }
                    else
                    {
                        var run = inline as Run;
                        if (run != null && run.HasLink)
                        {
                            /// inlineにlinkを設定されている場合はlinkにならないように直前にrunを挿入
                            var parent = inline.Parent as LineSegment;
                            var index  = parent._Inlines.IndexOf(inline);
                            var newRun = new Run(_text);
                            run.TransferWithoutLink(newRun);
                            _command = new InsertInlineToLineSegmentCommand(parent, newRun, index);
                        }
                        else
                        {
                            /// inlineにlinkが設定されていなければそのまま文字列をinsert
                            _command = new InsertStringToInlineCommand(inline, _text, charIndexInInline);
                        }
                    }
                }
                else
                {
                    /// inlineの最初でなければ普通にInsert
                    _command = new InsertStringToInlineCommand(inline, _text, charIndexInInline);
                }
            }

            _command.Execute();
        }
        private int InsertFlows(IEnumerable <Flow> flows)
        {
            _commands = new List <ICommand>();
            {
                var cmd = new EnsureInlineBreakCommand(_target, _index);
                cmd.Execute();
                _commands.Add(cmd);
            }

            var firstBlock = _target.GetBlockAt(_index);
            var bIndex     = _target._Blocks.IndexOf(firstBlock);
            var cIndex     = _index;

            foreach (var flow in flows)
            {
                if (flow is Block)
                {
                    var block = flow as Block;

                    int charIndexInLine, lineSegOffset;
                    _target.GetLineSegmentAt(cIndex, out charIndexInLine, out lineSegOffset);

                    if (charIndexInLine == 0)
                    {
                        /// Line中でなければそのまま挿入
                        var cmd = new InsertBlockToStyledTextCommand(_target, block, bIndex);
                        cmd.Execute();
                        _commands.Add(cmd);
                        cIndex += flow.Length;
                    }
                    else
                    {
                        /// Line中ならInlineだけ挿入
                        foreach (var line in block.LineSegments)
                        {
                            foreach (var inline in line.Inlines)
                            {
                                if (inline.IsLineEndCharacter)
                                {
                                    if (inline is BlockBreak)
                                    {
                                        var cmd = new InsertBlockBreakCommand(_target, cIndex);
                                        cmd.Execute();
                                        _commands.Add(cmd);
                                    }
                                    else if (inline is LineBreak)
                                    {
                                        var cmd = new InsertLineBreakCommand(_target, cIndex);
                                        cmd.Execute();
                                        _commands.Add(cmd);
                                    }
                                }
                                else
                                {
                                    var clone = inline.CloneDeeply() as Inline;
                                    var cmd   = new InsertInlineCommand(_target, cIndex, clone);
                                    cmd.Execute();
                                    _commands.Add(cmd);
                                }
                                cIndex += inline.Length;
                            }
                        }
                    }
                    ++bIndex;
                }
                else if (flow is Inline)
                {
                    var inline = flow as Inline;
                    if (inline.IsLineEndCharacter)
                    {
                        if (inline is BlockBreak)
                        {
                            var cmd = new InsertBlockBreakCommand(_target, cIndex);
                            cmd.Execute();
                            _commands.Add(cmd);
                            ++bIndex;
                        }
                        else if (inline is LineBreak)
                        {
                            var cmd = new InsertLineBreakCommand(_target, cIndex);
                            cmd.Execute();
                            _commands.Add(cmd);
                        }
                    }
                    else
                    {
                        var clone = inline.CloneDeeply() as Inline;
                        var cmd   = new InsertInlineCommand(_target, cIndex, clone);
                        cmd.Execute();
                        _commands.Add(cmd);
                    }
                    cIndex += flow.Length;
                }
            }

            /// 最初のinlineがmergeできるならmerge
            var firstInline = _target.GetInlineAt(_index);

            if (_target.HasPrevInline(firstInline))
            {
                var prev = _target.GetPrevInline(firstInline);
                if (prev.CanMerge(firstInline))
                {
                    var cmd = new MergeInlineCommand(prev, firstInline);
                    cmd.Execute();
                    _commands.Add(cmd);
                }
            }

            /// 最後のinlineがmergeできるならmerge
            var lastInline = _target.GetInlineAt(cIndex - 1);

            if (_target.HasNextInline(lastInline))
            {
                var next = _target.GetNextInline(lastInline);
                if (lastInline.CanMerge(next))
                {
                    var cmd = new MergeInlineCommand(lastInline, next);
                    cmd.Execute();
                    _commands.Add(cmd);
                }
            }

            return(cIndex);
        }