// ======================================== // 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(); } }
// ======================================== // method // ======================================== public override void Execute() { var color = _colorProvider(_target.GetInlineAt(_range.Offset)); _command = new ApplyCommandCommand( _target, _range, flow => new SetColorOfFlowCommand(flow, color) ); _command.Execute(); }
// ======================================== // 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; } }
// ======================================== // 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); } } }
// ======================================== // 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); }