public MultiLineInsertData(Selection whereToInsert, string stringToInsert, List<IStyle> styles) { if (stringToInsert == "" || (stringToInsert.IndexOfAny(new[] { '\r', '\n' }) == -1 && !stringToInsert.Contains(@"\par"))) return; ParaStyles = styles; Selection = whereToInsert; int startOfUnprocessedLines = stringToInsert.IndexOfAny(new[] { '\r', '\n' }); int limOfUnprocessedLines = stringToInsert.LastIndexOfAny(new[] { '\r', '\n' }) + 1; int otherStartOfUnprocessedLines = stringToInsert.IndexOf(@"\par"); int otherLimOfUnprocessedLines = stringToInsert.LastIndexOf(@"\par") + 4; startOfUnprocessedLines = Math.Min(startOfUnprocessedLines != -1 ? startOfUnprocessedLines : otherStartOfUnprocessedLines, otherStartOfUnprocessedLines != -1 ? otherStartOfUnprocessedLines : startOfUnprocessedLines); limOfUnprocessedLines = Math.Max(limOfUnprocessedLines, otherLimOfUnprocessedLines); StringAppendToFirstPara = stringToInsert.Substring(0, startOfUnprocessedLines); StringPrependToLastPara = stringToInsert.Substring(limOfUnprocessedLines); if (StringAppendToFirstPara == "\r" || StringAppendToFirstPara == "\n" || StringAppendToFirstPara == @"\par") StringAppendToFirstPara = ""; if (StringPrependToLastPara == "\r" || StringPrependToLastPara == "\n" || StringPrependToLastPara == @"\par") StringPrependToLastPara = ""; limOfUnprocessedLines = BackPastLineBreak(limOfUnprocessedLines, stringToInsert); InsertedStringLines = new List<string>(); while (true) { startOfUnprocessedLines = AdvancePastLineBreak(startOfUnprocessedLines, stringToInsert); if (startOfUnprocessedLines > limOfUnprocessedLines) break; int index = stringToInsert.IndexOfAny(new[] { '\r', '\n' }, startOfUnprocessedLines); if(index == -1) index = stringToInsert.IndexOf(@"\par", startOfUnprocessedLines); string nextString = stringToInsert.Substring(startOfUnprocessedLines, index - startOfUnprocessedLines); nextString = nextString.Trim(new[] { '\r', '\n' }); nextString = nextString.Replace(@"\par", ""); InsertedStringLines.Add(nextString); startOfUnprocessedLines = index; } }
public abstract ISelectionRestoreData RestoreData(Selection dataToSave);
/// <summary> /// The root box handles the overall paint. /// </summary> /// <param name="vg"></param> /// <param name="ptrans"></param> public void Paint(IVwGraphics vg, PaintTransform ptrans) { if (m_layoutCallbacks != null) { // In a state where we can't paint. Arrange for an invalidate AFTER the dangerous operation is over, // so what needs painting eventually does get painted. var bounds = Bounds; bounds.Inflate(10, 10); m_layoutCallbacks.Invalidate(bounds); return; } // First we paint the overall background. This basically covers everything but text. PaintBackground(vg, ptrans); // Then the text. PaintForeground(vg, ptrans); // And finally the selection. if (Selection != null && m_selectionShowing) { if (Selection.IsValid) Selection.Draw(vg, ptrans); else Selection = null; } }
/// <summary> /// Implement dragging to this view. /// </summary> public void OnDragDrop(DragEventArgs drgevent, Point location, IVwGraphics vg, PaintTransform ptrans) { var sel = GetSelectionAt(location, vg, ptrans) as InsertionPoint; if (sel == null) return; var rtf = drgevent.Data.GetData(DataFormats.Rtf); var data = drgevent.Data.GetData(DataFormats.StringFormat); if (data == null) return; var text = data.ToString(); // MS example of GetData does this, though for DataFormats.Text. if (DragState == WindowDragState.InternalMove) { DragState = WindowDragState.None; // We are dragging our own selection. Is it in the same property? var range = (RangeSelection)Selection; // Enhance JohnT: when we can drag a range that isn't all in one property, this needs more work. if (!Selection.IsInsertionPoint) { if (Selection.Contains(sel)) { Selection = sel; return; // Can't drag to inside own selection. } } if (range.End.Hookup == sel.Hookup && range.End.StringPosition < sel.StringPosition) { // Dragging to later in the same property. If we delete first, we will mess up the insert // position. However, a simple solution is to insert first. //Log("Inserted dropped " + text + " before deleted range"); if (rtf == null) sel.InsertText(text); else if (!sel.InsertRtfString(rtf.ToString())) sel.InsertText(text); range.Delete(); return; } // The bit we're moving comes after the place to insert, or they are in separate properties. // We can just go ahead and delete the source first, since we already have a copy of the // text to insert. // Enhance JohnT: do we need to consider a special case where the source and destination are // different occurrences of the same property? //Log("Deleted selection"); range.Delete(); } DragState = WindowDragState.None; //Log("Dropped text: " + text); if (rtf == null) sel.InsertText(text); else if (!sel.InsertRtfString(rtf.ToString())) sel.InsertText(text); }
private void ExtendSelection(Selection sel, bool makeRange) { var dragEnd = sel as InsertionPoint; var oldIP = Selection as InsertionPoint; if (dragEnd.SameLocation(oldIP)) { if (oldIP.AssociatePrevious == dragEnd.AssociatePrevious) return; // otherwise, keep sel, we want to install it because the direction changed. // But don't even think about changing it to a range. } else if (makeRange && Selection != null) { // See if we can make a range selection based on the old anchor and new dragEnd. var start = Selection as InsertionPoint; if (Selection is RangeSelection) { var range = (RangeSelection)Selection; if (range.DragEnd.Para == dragEnd.Para && range.DragEnd.LogicalParaPosition == dragEnd.LogicalParaPosition) return; start = range.Anchor; } if (start != null && !start.SameLocation(dragEnd)) sel = new RangeSelection(start, dragEnd); // If they ARE the same location, replace the range with the new (IP) selection. } if (sel != null) sel.Install(); }
public MultiLineInsertData(Selection whereToInsert, List<ITsString> stringToInsert, List<IStyle> styles) { if (stringToInsert == null || stringToInsert.Count <= 0) return; ParaStyles = styles; Selection = whereToInsert; if(stringToInsert.Count == 1) { ITsString tsString = stringToInsert[0]; int charIndexOfNextRun; int startOfUnprocessedLines = tsString.Text.IndexOfAny(new[] { '\r', '\n' }); int limOfUnprocessedLines = tsString.Text.LastIndexOfAny(new[] { '\r', '\n' }) + 1; int otherStartOfUnprocessedLines = tsString.Text.IndexOf(@"\par"); int otherLimOfUnprocessedLines = tsString.Text.LastIndexOf(@"\par")+1; startOfUnprocessedLines = Math.Min(startOfUnprocessedLines != -1 ? startOfUnprocessedLines : otherStartOfUnprocessedLines, otherStartOfUnprocessedLines != -1 ? otherStartOfUnprocessedLines : startOfUnprocessedLines); limOfUnprocessedLines = Math.Max(limOfUnprocessedLines, otherLimOfUnprocessedLines); TsStrAppendToFirstPara = tsString.Substring(0, startOfUnprocessedLines); if (limOfUnprocessedLines == tsString.Length) TsStrPrependToLastPara = TsStrFactoryClass.Create().EmptyString( tsString.Runs().Reverse().Where(run => run.Props.GetWs() > 0).First().Props.GetWs()); else { TsStrPrependToLastPara = tsString.Substring(limOfUnprocessedLines); if (TsStrPrependToLastPara.Text == "\r" || TsStrPrependToLastPara.Text == "\n" || TsStrPrependToLastPara.Text == @"\par") { var bldr = TsStrPrependToLastPara.GetBldr(); bldr.Replace(0, TsStrPrependToLastPara.Text.Length, "", null); TsStrPrependToLastPara = bldr.GetString(); } } if (TsStrAppendToFirstPara.Text == "\r" || TsStrAppendToFirstPara.Text == "\n" || TsStrAppendToFirstPara.Text == @"\par") { var bldr = TsStrAppendToFirstPara.GetBldr(); bldr.Replace(0, TsStrAppendToFirstPara.Text.Length, "", null); TsStrAppendToFirstPara = bldr.GetString(); } InsertedTsStrLines = new List<ITsString>(); while (true) { startOfUnprocessedLines = AdvancePastLineBreak(startOfUnprocessedLines, tsString.Text); if (startOfUnprocessedLines >= limOfUnprocessedLines) break; int limIndex = tsString.Text.IndexOfAny(new[] { '\r', '\n' }, startOfUnprocessedLines); int otherIndex = tsString.Text.IndexOf(@"\par", startOfUnprocessedLines); limIndex = Math.Min(limIndex != -1 ? limIndex : otherIndex, otherIndex != -1 ? otherIndex : limIndex); string nextString = tsString.Text.Substring(startOfUnprocessedLines, limIndex - startOfUnprocessedLines); nextString = nextString.Trim(new[] { '\r', '\n' }); nextString = nextString.Replace(@"\par", ""); var bldr = TsStrFactoryClass.Create().MakeString(nextString, tsString.get_WritingSystemAt(startOfUnprocessedLines)).GetBldr(); for (int runIndex = tsString.get_RunAt(startOfUnprocessedLines); runIndex < tsString.get_RunAt(limIndex); runIndex++) { int start = tsString.get_MinOfRun(runIndex) - startOfUnprocessedLines; int end = tsString.get_LimOfRun(runIndex) - startOfUnprocessedLines; bldr.Replace(start, end, bldr.Text.Substring(start, end - start), tsString.get_Properties(runIndex)); } InsertedTsStrLines.Add(bldr.GetString()); startOfUnprocessedLines = limIndex; } } else { TsStrAppendToFirstPara = stringToInsert.First(); TsStrPrependToLastPara = stringToInsert.Last(); stringToInsert.Remove(stringToInsert.First()); stringToInsert.Remove(stringToInsert.Last()); InsertedTsStrLines = stringToInsert; } }
private void VerifyRange(Selection sel, ParaBox paraAnchor, string textBeforeAnchor, ParaBox paraEnd, string textBeforeEnd, string label) { Assert.That(sel, Is.TypeOf(typeof(RangeSelection)), label + " should produce range"); var range = (RangeSelection) sel; VerifyIp(range.Anchor, paraAnchor, textBeforeAnchor, range.EndBeforeAnchor, label + " (anchor)"); VerifyIp(range.DragEnd, paraEnd, textBeforeEnd, !range.EndBeforeAnchor, label + " (end)"); }
private void VerifyIp(Selection sel, ParaBox para, string textBefore, bool assocPrev, string label) { Assert.That(sel, Is.TypeOf(typeof(InsertionPoint)), label + " should produce IP"); var ip = (InsertionPoint) sel; Assert.That(ip.Para, Is.EqualTo(para), label + " should be in expected para"); Assert.That(ip.LogicalParaPosition, Is.EqualTo(textBefore.Length), label + " should be at expected position"); Assert.That(ip.AssociatePrevious, Is.EqualTo(assocPrev), label + " should associate correctly"); }
public override ISelectionRestoreData RestoreData(Selection dataToSave) { if (dataToSave.IsInsertionPoint) return new InsertionPointRestoreData((InsertionPoint)dataToSave); return new RangeRestoreData((RangeSelection)dataToSave); }
public override ISelectionRestoreData RestoreData(Selection dataToSave) { throw new NotImplementedException(); }