private bool SplitParagraph(MultiLineInsertData input, out Action makeSelection) { int index = ItemIndex(input.Selection as InsertionPoint); MakeListItem(index + 1, false); var newItem = List[index + 1]; var sel = input.Selection as InsertionPoint; if (input.TsStrAppendToFirstPara == null || input.TsStrPrependToLastPara == null) { MoveMaterialAfterIpToStart(sel, input.StringAppendToFirstPara, input.StringPrependToLastPara, newItem); } else { MoveMaterialAfterIpToStart(sel, input.TsStrAppendToFirstPara, input.TsStrPrependToLastPara, newItem); } if (input.ParaStyles != null) { if (input.ParaStyles.First() != null) { ApplyParagraphStyle(index, 1, input.ParaStyles.First().Name); } if (input.ParaStyles.Last() != null) { ApplyParagraphStyle(index + 1, 1, input.ParaStyles.Last().Name); } } makeSelection = () => SelectionBuilder.In(Hookup)[index].Offset(0).Install(); return(true); }
/// <summary> /// Insert a new paragraph, after the user types Enter, where the previous selection /// is an insertion point at the end of the paragraph. /// </summary> public virtual bool InsertFollowingParagraph(InsertionPoint ip, out Action makeSelection) { int index = ItemIndex(ip) + 1; MakeListItem(index, false); makeSelection = () => SelectionBuilder.In(Hookup)[index].Offset(0).Install(); return(true); }
public virtual bool InsertFollowingParagraph(RangeSelection range, out Action makeSelection) { int index = ItemIndex(range.Start) + 1; DeleteItems(range.Start.StringPosition, range.End.StringPosition); MakeListItem(index, false); makeSelection = () => SelectionBuilder.In(Hookup)[index].Offset(0).Install(); return(true); }
public bool SplitParagraph(InsertionPoint ip, out Action makeSelection) { int index = ItemIndex(ip); MakeListItem(index + 1, false); var newItem = List[index + 1]; MoveMaterialAfterIpToStart(ip, "", "", newItem); makeSelection = () => SelectionBuilder.In(Hookup)[index + 1].Offset(0).Install(); return(true); }
/// <summary> /// Initializes a new instance of the <see cref="SelectSetup{TSource,TDestination}" /> class. /// </summary> /// <param name="selectionBuilder"> /// The selection builder. /// </param> /// <param name="data"> /// The <see cref="QueryHelperData" /> instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="selectionBuilder" /> is null. /// </exception> public SelectSetup(SelectionBuilder <TSource, TDestination> selectionBuilder, QueryHelperData data) { if (selectionBuilder == null) { throw new ArgumentNullException("selectionBuilder"); } Data = data; Mappings = new Dictionary <string, IProjection>(); ProjectionList = Projections.ProjectionList(); SelectionBuilder = selectionBuilder; }
public void MlsDelete() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles.WithWs(23)); var mock1 = new MockData1(23, 23); mock1.MlSimpleOne = new MultiAccessor(23, 23); mock1.MlSimpleOne.set_String(23, TsStrFactoryClass.Create().MakeString("This is it", 23)); var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.MlSimpleOne, 23)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is ".Length).Install(); var sel = root.Selection as RangeSelection; // This is currently the main test for SelectionBuilder.In(RootBox) and SelectionBuilder.To in TsStrings // This verifies that it makes roughly the right range selection. Assert.That(sel.Anchor.LogicalParaPosition, Is.EqualTo("This ".Length)); Assert.That(sel.DragEnd.LogicalParaPosition, Is.EqualTo("This is ".Length)); Assert.That(sel.CanDelete(), Is.True); root.OnDelete(); ITsString i = mock1.MlSimpleOne.get_String(23); Assert.That(mock1.MlSimpleOne.get_String(23).Text, Is.EqualTo("This it")); var ip = root.Selection as InsertionPoint; Assert.That(ip.LogicalParaPosition, Is.EqualTo("This ".Length)); // Enhance JohnT: if there is any reason to prefer associatePrevious to be true or false, // clamp that and make it so. // A fairly rudimentary check on invalidate, since we elsewhere check general string-edit ops. Assert.That(site.RectsInvalidatedInRoot, Is.Not.Empty); }
/// <summary> /// Replace the text in the range, presumed to extend across more than one paragraph, /// with the supplied text. /// This one serves also for backspace at start of paragraph and delete at end, since /// these can readily be transformed into deleting a range from the end of one para /// to the start of the next. The given range is replace by a simple string. /// Enhance JohnT: it would probably make sense to break this up, more like SplitParagraph, /// into further virtual methods that subclasses could override. But I haven't figured out how yet. /// </summary> public bool InsertString(RangeSelection range, string insert, out Action makeSelection) { makeSelection = () => DoNothing(); // a default. var firstIp = range.Start; var lastIp = range.End; int firstItemIndex = ItemIndex(firstIp); int lastItemIndex = ItemIndex(lastIp); if (firstItemIndex == lastItemIndex) { throw new ArgumentException("Should not need to use ParagraphOps.InsertString for range in same item"); } int startPosition = firstIp.StringPosition; if (!MergeTextAfterSecondIntoFirst(firstIp, lastIp, insert)) { return(false); } DeleteItems(firstItemIndex + 1, lastItemIndex); makeSelection = () => SelectionBuilder.In(Hookup)[firstItemIndex].Offset(startPosition + insert.Length).Install(); return(true); }
public void DragCopyRtf() { var stylesheet = new MockStylesheet(); var styleFirst = stylesheet.AddStyle("first", false); var styleSecond = stylesheet.AddStyle("second", false); var propsTrue = new MockStyleProp <bool>() { Value = true, ValueIsSet = true }; var charInfo = new MockCharStyleInfo(); styleFirst.DefaultCharacterStyleInfo = charInfo; charInfo.Bold = propsTrue; // Todo: make styleSecond have pretty much everything else. var charInfo2 = new MockCharStyleInfo(); styleSecond.DefaultCharacterStyleInfo = charInfo2; charInfo2.FontColor = MakeColorProp(Color.Red); charInfo2.BackColor = MakeColorProp(Color.Yellow); charInfo2.UnderlineColor = MakeColorProp(Color.Green); charInfo2.Italic = propsTrue; charInfo2.FontName = new MockStyleProp <string>() { Value = "Arial", ValueIsSet = true }; var styles = new AssembledStyles(stylesheet); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "This is"; var mock2 = new MockData1(23, 23); mock2.SimpleThree = " the day"; var mock3 = new MockData1(23, 23); mock3.SimpleThree = " that the"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); var wsf = new MockWsf(); engine.WritingSystemFactory = wsf; var wsEngine = wsf.MakeMockEngine(23, "en", engine); factory.SetRenderer(23, engine); root.Builder.Show( Paragraph.Containing( Display.Of(() => mock1.SimpleThree, 23).Style("first"), Display.Of(() => mock2.SimpleThree, 23).Style("second"), Display.Of(() => mock3.SimpleThree, 23).Style("first") )); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is the day that".Length).Install(); int indent = FakeRenderEngine.SimulatedWidth("This "); root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans); root.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(GetStringDropData(site), Is.EqualTo("is the day that")); // The order of the font and colors in the color table is arbitrary. This happens to be what the code does now. For some reason // Color.Green has green only 128. // The order of items in the definition of a style is arbitrary. // We're not doing anything yet for background color. \highlightN can specify background color for a character run, // but it can't be part of a style definition. Assert.That(GetRtfDropData(site), Is.EqualTo( RangeSelection.RtfPrefix + @"{\fonttbl{\f0 MockFont;}{\f1 Arial;}}" + @"{\colortbl ;\red0\green0\blue0;\red255\green255\blue255;\red255\green0\blue0;\red255\green255\blue0;\red0\green128\blue0;}" + @"{\stylesheet{\*\cs1\b\additive first;\*\cs2\i\f1\cf3\ulc5\additive second;}}" + RangeSelection.RtfDataPrefix + @"{\*\cs1\b is}{\*\cs2\i\f1\cf3\ulc5\highlight4 the day}{\*\cs1\b that\par}" + @"}")); // Todo: handle styles that depend on WS // Todo: handle more than two runs // Todo: handle runs where actual formatting differs from style-specified formatting // Todo: handle multiple paragraphs // Todo: handle paragraph styles }
public void BasicDragMove() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "This is the day"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is ".Length).Install(); var dataObj = new DataObject(DataFormats.StringFormat, "is "); int x = FakeRenderEngine.SimulatedWidth("This is the ") + 2; var location = new Point(x, 8); // A drag to where we can drop, allowing both copy and move, no keys held var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Move)); Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere)); var qcdArgs = new QueryContinueDragEventArgs((int)DragDropKeyStates.None, false, DragAction.Drop); root.OnQueryContinueDrag(qcdArgs); Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove)); root.OnDragLeave(); Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove), "DragLeave should not clear InternalMove"); root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(mock1.SimpleThree, Is.EqualTo("This the is day")); Assert.That(root.DragState, Is.EqualTo(WindowDragState.None)); // Now let's drag the 'is' out to another window. SelectionBuilder.In(root).Offset("This the ".Length).To.Offset("This the is ".Length).Install(); qcdArgs = new QueryContinueDragEventArgs((int)DragDropKeyStates.None, false, DragAction.Drop); root.OnQueryContinueDrag(qcdArgs); Assert.That(root.DragState, Is.EqualTo(WindowDragState.None), "We should only set InternalMove if this window is the destination"); Assert.That(mock1.SimpleThree, Is.EqualTo("This the day")); // Check that we can't drag inside our own selection. SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This the".Length).Install(); x = FakeRenderEngine.SimulatedWidth("This t") + 2; location = new Point(x, 8); dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.DragState = WindowDragState.InternalMove; root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None)); Assert.That(mock1.SimpleThree, Is.EqualTo("This the day")); }
public void CombinedParaOperations() { // Set up a simple multi-para layout using the ObjSeq2 and SimpleThree properties of MockData1 AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBoxFdo(styles); var owner = new MockData1(); var p1 = new MockData1(10, 11); var p2 = new MockData1(10, 11); p1.SimpleThree = "Hello World"; p2.SimpleThree = "This is a test"; owner.ObjSeq2.Add(p1); owner.ObjSeq2.Add(p2); var po = new MockReceiveParagraphOperations(); root.Builder.Show(Display.Of(() => owner.ObjSeq2) .Using((builder, para) => builder.AddString(() => para.SimpleThree, 10)) .EditParagraphsUsing(po)); SetupFakeRootSite(root); var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55); root.Layout(layoutInfo); var ip = root.FirstBox.SelectAtEnd(); // Insert at end of paragraph. ip.InsertLineBreak(); Assert.That(owner.ObjSeq2.Count, Is.EqualTo(3)); Assert.That(owner.ObjSeq2[0], Is.EqualTo(p1)); Assert.That(owner.ObjSeq2[2], Is.EqualTo(p2)); var p3 = owner.ObjSeq2[1]; // empty inserted paragraph. ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(root.FirstBox.Next.Next, Is.Not.Null); Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next)); // Insert at start of paragraph. To make it unambiguously the start, give p3 some data, // and since that might eventually destroy the selection, reset it. var rootHookup = ip.Hookup.ParentHookup.ParentHookup; // StringHookup, ItemHookup, Sequence p3.SimpleThree = "First insert"; ip = (InsertionPoint)SelectionBuilder.In(rootHookup)[1].Offset(0).Install(); ip.InsertLineBreak(); Assert.That(owner.ObjSeq2.Count, Is.EqualTo(4)); Assert.That(owner.ObjSeq2[0], Is.EqualTo(p1)); Assert.That(owner.ObjSeq2[2], Is.EqualTo(p3)); Assert.That(owner.ObjSeq2[3], Is.EqualTo(p2)); var p4 = owner.ObjSeq2[1]; // empty inserted paragraph (before p3). Assert.That(root.FirstBox.Next.Next.Next, Is.Not.Null); ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next)); // Split a paragraph. var oldObjects = owner.ObjSeq2.ToArray(); ip = (InsertionPoint)SelectionBuilder.In(rootHookup)[2].Offset("First ".Length).Install(); ip.InsertLineBreak(); Assert.That(owner.ObjSeq2.Count, Is.EqualTo(5)); Assert.That(owner.ObjSeq2[1], Is.EqualTo(oldObjects[1])); Assert.That(owner.ObjSeq2[2], Is.EqualTo(oldObjects[2])); Assert.That(owner.ObjSeq2[4], Is.EqualTo(oldObjects[3])); // insert between 2 and 3 var p5 = owner.ObjSeq2[3]; // inserted paragraph. ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next.Next)); Assert.That(owner.ObjSeq2[2].SimpleThree, Is.EqualTo("First ")); Assert.That(owner.ObjSeq2[3].SimpleThree, Is.EqualTo("insert")); // Combine two paragraphs by backspace at start of line. oldObjects = owner.ObjSeq2.ToArray(); ip.Backspace(); Assert.That(owner.ObjSeq2.Count, Is.EqualTo(4)); Assert.That(owner.ObjSeq2[1], Is.EqualTo(oldObjects[1])); Assert.That(owner.ObjSeq2[2], Is.EqualTo(oldObjects[2])); Assert.That(owner.ObjSeq2[3], Is.EqualTo(oldObjects[4])); // delete item 3 ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo("First ".Length)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next)); Assert.That(owner.ObjSeq2[2].SimpleThree, Is.EqualTo("First insert")); }
public void CombinedParaOperationsFdo() { // Set up a simple multi-para layout using the ObjSeq2 and SimpleThree properties of MockData1 AssembledStyles styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var text = Cache.ServiceLocator.GetInstance <ITextFactory>().Create(); //Cache.LangProject.TextsOC.Add(text); var owner = Cache.ServiceLocator.GetInstance <IStTextFactory>().Create(); text.ContentsOA = owner; IStTxtPara p1 = MakePara(owner, "Hello World"); var p2 = MakePara(owner, "This is a test"); m_actionHandler.EndUndoTask(); // Finish settin up data, we want to control from now on. var po = new StTextParagraphOperations(owner); root.Builder.Show(Display.Of(() => owner.ParagraphsOS).Using((builder, para) => builder.AddString(() => ((IStTxtPara)para).Contents)).EditParagraphsUsing(po)); SetupFakeRootSite(root); var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55); root.Layout(layoutInfo); var ip = root.FirstBox.SelectAtEnd(); // Insert at end of paragraph. m_actionHandler.BeginUndoTask("undo insert line break", "redo insert"); ip.InsertLineBreak(); m_actionHandler.EndUndoTask(); Assert.That(owner.ParagraphsOS.Count, Is.EqualTo(3)); Assert.That(owner.ParagraphsOS[0], Is.EqualTo(p1)); Assert.That(owner.ParagraphsOS[2], Is.EqualTo(p2)); var p3 = (IStTxtPara)owner.ParagraphsOS[1]; // empty inserted paragraph. Assert.That(p3.Contents.Length, Is.EqualTo(0)); Assert.That(p3.Contents.get_WritingSystem(0), Is.EqualTo(Cache.DefaultVernWs)); ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(root.FirstBox.Next.Next, Is.Not.Null); Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next)); // Insert at start of paragraph. To make it unambiguously the start, give p3 some data, // and since that might eventually destroy the selection, reset it. var rootHookup = ip.Hookup.ParentHookup.ParentHookup; // StringHookup, ItemHookup, Sequence UndoableUnitOfWorkHelper.Do("adjust contents", "redo", m_actionHandler, () => p3.Contents = Cache.TsStrFactory.MakeString("First insert", Cache.DefaultVernWs)); ip = (InsertionPoint)SelectionBuilder.In(rootHookup)[1].Offset(0).Install(); m_actionHandler.BeginUndoTask("undo insert line break", "redo insert"); ip.InsertLineBreak(); m_actionHandler.EndUndoTask(); Assert.That(owner.ParagraphsOS.Count, Is.EqualTo(4)); Assert.That(owner.ParagraphsOS[0], Is.EqualTo(p1)); Assert.That(owner.ParagraphsOS[2], Is.EqualTo(p3)); Assert.That(owner.ParagraphsOS[3], Is.EqualTo(p2)); var p4 = (IStTxtPara)owner.ParagraphsOS[1]; // empty inserted paragraph (before p3). Assert.That(root.FirstBox.Next.Next.Next, Is.Not.Null); Assert.That(p4.Contents.get_WritingSystem(0), Is.EqualTo(Cache.DefaultVernWs)); ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next)); // Split a paragraph. var oldObjects = owner.ParagraphsOS.ToArray(); ip = (InsertionPoint)SelectionBuilder.In(rootHookup)[2].Offset("First ".Length).Install(); m_actionHandler.BeginUndoTask("undo insert line break", "redo insert"); ip.InsertLineBreak(); m_actionHandler.EndUndoTask(); Assert.That(owner.ParagraphsOS.Count, Is.EqualTo(5)); Assert.That(owner.ParagraphsOS[1], Is.EqualTo(oldObjects[1])); Assert.That(owner.ParagraphsOS[2], Is.EqualTo(oldObjects[2])); Assert.That(owner.ParagraphsOS[4], Is.EqualTo(oldObjects[3])); // insert between 2 and 3 var p5 = (IStTxtPara)owner.ParagraphsOS[3]; // inserted paragraph. ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo(0)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next.Next)); Assert.That(((IStTxtPara)owner.ParagraphsOS[2]).Contents.Text, Is.EqualTo("First ")); Assert.That(((IStTxtPara)owner.ParagraphsOS[3]).Contents.Text, Is.EqualTo("insert")); // Combine two paragraphs by backspace at start of line. oldObjects = owner.ParagraphsOS.ToArray(); m_actionHandler.BeginUndoTask("undo backspace", "redo backspace"); ip.Backspace(); m_actionHandler.EndUndoTask(); Assert.That(owner.ParagraphsOS.Count, Is.EqualTo(4)); Assert.That(owner.ParagraphsOS[1], Is.EqualTo(oldObjects[1])); Assert.That(owner.ParagraphsOS[2], Is.EqualTo(oldObjects[2])); Assert.That(owner.ParagraphsOS[3], Is.EqualTo(oldObjects[4])); // delete item 3 ((MockSite)root.Site).DoPendingAfterNotificationTasks(); ip = (InsertionPoint)root.Selection; Assert.That(ip.StringPosition, Is.EqualTo("First ".Length)); Assert.That(ip.Para, Is.EqualTo(root.FirstBox.Next.Next)); Assert.That(((IStTxtPara)owner.ParagraphsOS[2]).Contents.Text, Is.EqualTo("First insert")); }