// Assumes that a range contains a sequence of same-level ListItems. // Converts all these ListItems into Paragraphs and // either adds them to preceding ListItem (as non-bulleted continuation) // or pulls them out of a List if they start in the beginning of a List internal static void ConvertListItemsToParagraphs(TextRange range) { ListItem firstListItem = TextPointerBase.GetListItem(range.Start); ListItem lastListItem = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); // The range must be in a sequence of ListItems belonging to one List wrapper if (firstListItem == null || lastListItem == null || firstListItem.Parent != lastListItem.Parent || !(firstListItem.Parent is List)) { return; } List listToRemove = null; ListItem leadingListItem = firstListItem.PreviousListItem; if (leadingListItem != null) { // We have a leading ListItem, so pull selected items into it leadingListItem.Reposition(leadingListItem.ContentStart, lastListItem.ElementEnd); } else { // We do not have a leading ListItem. So pull selected items out of a list // Cut wrapping list after endListItem if (lastListItem.NextListItem != null) { TextRangeEdit.SplitElement(lastListItem.ElementEnd); } // Set list to remove listToRemove = firstListItem.List; } // Remove ListItems from all selected blocks ListItem listItem = firstListItem; while (listItem != null) { ListItem nextListItem = listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem; // If this is an empty <ListItem></ListItem>, insert an explicit paragraph in it before deleting the list item. if (listItem.ContentStart.CompareTo(listItem.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem.ContentStart); } listItem.Reposition(null, null); listItem = listItem == lastListItem ? null : nextListItem; } // If we have a list to remove, remove it and set its FlowDirection to its children if (listToRemove != null) { FlowDirection flowDirection = (FlowDirection)listToRemove.GetValue(Paragraph.FlowDirectionProperty); listToRemove.Reposition(null, null); TextRangeEdit.SetParagraphProperty(range.Start, range.End, Paragraph.FlowDirectionProperty, flowDirection); } }
// Token: 0x06003B88 RID: 15240 RVA: 0x0010F530 File Offset: 0x0010D730 internal static bool SplitListsForFlowDirectionChange(TextPointer start, TextPointer end, object newFlowDirectionValue) { ListItem listAncestor = start.GetListAncestor(); if (listAncestor != null && listAncestor.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listAncestor.List.GetValue(Block.FlowDirectionProperty))) { while (listAncestor != null && listAncestor.List != null && listAncestor.List.Parent is ListItem) { if (!TextRangeEditLists.UnindentListItems(new TextRange(start, TextRangeEditLists.GetPositionAfterList(listAncestor.List)))) { return(false); } listAncestor = start.GetListAncestor(); } } ListItem listItem = end.GetListAncestor(); if (listItem != null && listItem.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listItem.List.GetValue(Block.FlowDirectionProperty))) { if (listAncestor == null || listAncestor.List == null || listItem.List.ElementEnd.CompareTo(listAncestor.List.ElementEnd) >= 0) { while (listItem != null && listItem.List != null && listItem.List.Parent is ListItem) { if (!TextRangeEditLists.UnindentListItems(new TextRange(listItem.List.ContentStart, TextRangeEditLists.GetPositionAfterList(listItem.List)))) { return(false); } listItem = end.GetListAncestor(); } } } if ((listAncestor = start.GetListAncestor()) != null && listAncestor.PreviousListItem != null && listAncestor.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listAncestor.List.GetValue(Block.FlowDirectionProperty))) { Invariant.Assert(!(listAncestor.List.Parent is ListItem), "startListItem's list must not be nested!"); TextRangeEdit.SplitElement(listAncestor.ElementStart); } if ((listItem = end.GetListAncestor()) != null && listItem.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listItem.List.GetValue(Block.FlowDirectionProperty))) { if (listItem.List.Parent is ListItem) { while (listItem.List != null && listItem.List.Parent is ListItem) { listItem = (ListItem)listItem.List.Parent; } } if (listItem.List != null && listItem.NextListItem != null) { Invariant.Assert(!(listItem.List.Parent is ListItem), "endListItem's list must not be nested!"); TextRangeEdit.SplitElement(listItem.ElementEnd); } } return(true); }
// Token: 0x06003546 RID: 13638 RVA: 0x000F1448 File Offset: 0x000EF648 private TextPointer SplitElement(TextPointer position) { if (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { position = position.GetNextContextPosition(LogicalDirection.Backward); } else if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) { position = position.GetNextContextPosition(LogicalDirection.Forward); } else { position = TextRangeEdit.SplitElement(position); } return(position); }
// Token: 0x06003B82 RID: 15234 RVA: 0x0010EF28 File Offset: 0x0010D128 internal static bool ConvertParagraphsToListItems(TextRange range, TextMarkerStyle markerStyle) { if (range.IsEmpty && TextPointerBase.IsAtPotentialParagraphPosition(range.Start)) { TextPointer textPointer = TextRangeEditTables.EnsureInsertionPosition(range.Start); ((ITextRange)range).Select(textPointer, textPointer); } Block paragraphOrBlockUIContainer = range.Start.ParagraphOrBlockUIContainer; TextPointer textPointer2 = (TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End); Block paragraphOrBlockUIContainer2 = textPointer2.ParagraphOrBlockUIContainer; if (paragraphOrBlockUIContainer == null || paragraphOrBlockUIContainer2 == null || paragraphOrBlockUIContainer.Parent != paragraphOrBlockUIContainer2.Parent || (paragraphOrBlockUIContainer.Parent is ListItem && paragraphOrBlockUIContainer.PreviousBlock == null)) { return(false); } Block block = paragraphOrBlockUIContainer; while (block != paragraphOrBlockUIContainer2 && block != null) { if (block is Table || block is Section) { return(false); } block = block.NextBlock; } ListItem listItem = paragraphOrBlockUIContainer.Parent as ListItem; if (listItem != null) { Block block3; for (Block block2 = paragraphOrBlockUIContainer; block2 != null; block2 = block3) { block3 = ((block2 == paragraphOrBlockUIContainer2) ? null : (block2.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as Block)); Invariant.Assert(block2.Parent is ListItem); TextRangeEdit.SplitElement(block2.ElementStart); } } else { new List { MarkerStyle = markerStyle }.Apply(paragraphOrBlockUIContainer, paragraphOrBlockUIContainer2); } return(true); }
// Token: 0x06003B83 RID: 15235 RVA: 0x0010F058 File Offset: 0x0010D258 internal static void ConvertListItemsToParagraphs(TextRange range) { ListItem listItem = TextPointerBase.GetListItem(range.Start); ListItem listItem2 = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); if (listItem == null || listItem2 == null || listItem.Parent != listItem2.Parent || !(listItem.Parent is List)) { return; } List list = null; ListItem previousListItem = listItem.PreviousListItem; if (previousListItem != null) { previousListItem.Reposition(previousListItem.ContentStart, listItem2.ElementEnd); } else { if (listItem2.NextListItem != null) { TextRangeEdit.SplitElement(listItem2.ElementEnd); } list = listItem.List; } ListItem listItem4; for (ListItem listItem3 = listItem; listItem3 != null; listItem3 = ((listItem3 == listItem2) ? null : listItem4)) { listItem4 = (listItem3.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem); if (listItem3.ContentStart.CompareTo(listItem3.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem3.ContentStart); } listItem3.Reposition(null, null); } if (list != null) { FlowDirection flowDirection = (FlowDirection)list.GetValue(Block.FlowDirectionProperty); list.Reposition(null, null); TextRangeEdit.SetParagraphProperty(range.Start, range.End, Block.FlowDirectionProperty, flowDirection); } }
// Checks if start and end positions are parented by a List. // If so, unindents list items between (start - start's list end) or (end's list start - end) // until they are parented by a top level list. // Then, if needed, splits the list(s) at start and/or end positions. // Returns false if splitting is not successful due to a failing unindent operation on any nested lists. internal static bool SplitListsForFlowDirectionChange(TextPointer start, TextPointer end, object newFlowDirectionValue) { ListItem startListItem = start.GetListAncestor(); // Unindent startListItem's list to prepare for a split, if the List's FlowDirection value is different. if (startListItem != null && startListItem.List != null && // Check for unparented list items !TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ startListItem.List.GetValue(Paragraph.FlowDirectionProperty))) { while (startListItem != null && startListItem.List != null && startListItem.List.Parent is ListItem) { // startListItem is within a nested List. if (!UnindentListItems(new TextRange(start, GetPositionAfterList(startListItem.List)))) { return(false); } startListItem = start.GetListAncestor(); } } ListItem endListItem = end.GetListAncestor(); // Unindent endListItem's list to prepare for a split, if the List's FlowDirection value is different. if (endListItem != null && endListItem.List != null && !TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ endListItem.List.GetValue(Paragraph.FlowDirectionProperty))) { if (startListItem != null && startListItem.List != null && endListItem.List.ElementEnd.CompareTo(startListItem.List.ElementEnd) < 0) { // endListItem's List is contained within startListItem's List. // No need to unindent endListItem. } else { while (endListItem != null && endListItem.List != null && endListItem.List.Parent is ListItem) { // endListItem is within a nested List. if (!UnindentListItems(new TextRange(endListItem.List.ContentStart, GetPositionAfterList(endListItem.List)))) { return(false); } endListItem = end.GetListAncestor(); } } } // Split list(s) at boundary position(s) if // 1. startListItem is not the first list item within its list (or endListItem is not the last one) // and // 2. start/end's parent List's flow direction value is different than the new value being set if ((startListItem = start.GetListAncestor()) != null && startListItem.PreviousListItem != null && startListItem.List != null && // Check for unparented list items (!TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ startListItem.List.GetValue(Paragraph.FlowDirectionProperty)))) { Invariant.Assert(!(startListItem.List.Parent is ListItem), "startListItem's list must not be nested!"); TextRangeEdit.SplitElement(startListItem.ElementStart); } if ((endListItem = end.GetListAncestor()) != null && endListItem.List != null && // Check for unparented list items (!TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ endListItem.List.GetValue(Paragraph.FlowDirectionProperty)))) { // Walk up from endListItem to find the topmost listitem that contains it. if (endListItem.List.Parent is ListItem) { while (endListItem.List != null && endListItem.List.Parent is ListItem) { endListItem = (ListItem)endListItem.List.Parent; } } if (endListItem.List != null && endListItem.NextListItem != null) { Invariant.Assert(!(endListItem.List.Parent is ListItem), "endListItem's list must not be nested!"); TextRangeEdit.SplitElement(endListItem.ElementEnd); } } return(true); }
internal static bool UnindentListItems(TextRange range) { // If listitems in this range cross a list boundary, we cannot unindent them. if (!IsRangeWithinSingleList(range)) { return(false); } ListItem firstListItem = TextPointerBase.GetListItem(range.Start); ListItem lastListItem = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); // At this point it is possible that lastListItem is a child of // firstListItem. // // This is due to a special case in IsRangeWithinSingleList // which allows the input TextRange to cross List boundaries only // in the case where the TextRange ends adjacent to an insertion // position at the same level as the start, e.g.: // // - parent item // - start item (range starts here) // - child item (range ends here) // <start item must not have any siblings> // // Here we check for that special case and ensure that // lastListItem is at the same level as firstListItem. TextElement parent = (TextElement)lastListItem.Parent; while (parent != firstListItem.Parent) { lastListItem = parent as ListItem; parent = (TextElement)parent.Parent; } if (lastListItem == null) { // This can happen if the input is a fragment, a collection // of ListItems not parented by an outer List. return(false); } // Cut wrapping list before startListItem if (firstListItem.PreviousListItem != null) { TextRangeEdit.SplitElement(firstListItem.ElementStart); } // Cut wrapping list after endListItem if (lastListItem.NextListItem != null) { TextRangeEdit.SplitElement(lastListItem.ElementEnd); } // Remove List wrapper from selected items List unindentedList = (List)firstListItem.Parent; // Check whether we have outer ListItem ListItem outerListItem = unindentedList.Parent as ListItem; if (outerListItem != null) { // Selected items belong to a nested list. // So we need to pull them to the level of enclosing ListItem, i.e. cut this ListItem. // In this case we also need to include trailing list into the last of selected items // Remove a wrapping List from selected items unindentedList.Reposition(null, null); // Remember end position of outerListItem to pull any trailing list or other blocks into the last of selected listitems TextPointer outerListItemEnd = outerListItem.ContentEnd; if (outerListItem.ContentStart.CompareTo(firstListItem.ElementStart) == 0) { // There is nothing before first list item; so outer list item would be empty - just delete it outerListItem.Reposition(null, null); } else { // Wrap all stuff preceding firstListItem in outerListItem outerListItem.Reposition(outerListItem.ContentStart, firstListItem.ElementStart); } if (outerListItemEnd.CompareTo(lastListItem.ElementEnd) == 0) { // There are no following siblings to pull into last selected item; do nothing. } else { // Pull trailing items (following siblings to the selected ones) into the last selected item // Remember a position to merge any trailing list after lastListItem TextPointer mergePosition = lastListItem.ContentEnd; // Reposition last selectd ListItem so that it includes trailing list (or other block) as its children lastListItem.Reposition(lastListItem.ContentStart, outerListItemEnd); // Merge any trailing list with a sublist outdented with our listitem MergeLists(mergePosition); } } else { // Selected items are not in nested list. // We need to simply unwrap them and convert to paragraphs TextPointer start = unindentedList.ElementStart; TextPointer end = unindentedList.ElementEnd; // Save the list's FlowDirection value, to apply later to its children. object listFlowDirectionValue = unindentedList.GetValue(Paragraph.FlowDirectionProperty); // Remove a wrapping List from selected items unindentedList.Reposition(null, null); // Remove ListItems from all selected items ListItem listItem = firstListItem; while (listItem != null) { ListItem nextListItem = listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem; // If this is an empty <ListItem></ListItem>, insert an explicit paragraph in it before deleting the list item. if (listItem.ContentStart.CompareTo(listItem.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem.ContentStart); } listItem.Reposition(null, null); listItem = listItem == lastListItem ? null : nextListItem; } // Apply FlowDirection of the list just deleted to all its children. TextRangeEdit.SetParagraphProperty(start, end, Paragraph.FlowDirectionProperty, listFlowDirectionValue); // Merge lists on boundaries MergeLists(start); MergeLists(end); } return(true); }
internal static bool ConvertParagraphsToListItems(TextRange range, TextMarkerStyle markerStyle) { if (range.IsEmpty && TextPointerBase.IsAtPotentialParagraphPosition(range.Start)) { TextPointer insertionPosition = TextRangeEditTables.EnsureInsertionPosition(range.Start); ((ITextRange)range).Select(insertionPosition, insertionPosition); } Block firstBlock = range.Start.ParagraphOrBlockUIContainer; TextPointer end = (TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End); Block lastBlock = end.ParagraphOrBlockUIContainer; // We assume that a range contains a sequence of one-level paragraphs. // Otherwise the operation is disabled. if (firstBlock == null || lastBlock == null || firstBlock.Parent != lastBlock.Parent || firstBlock.Parent is ListItem && firstBlock.PreviousBlock == null) { // Either the paragraphs belong to different scopes or first of them has a bullet already. // We cannot convert them into bulleted lists. return(false); } // Check that all top-level elements of selection are Paragraphs. // We do not apply the command to Tables or Sections. for (Block block = firstBlock; block != lastBlock && block != null; block = block.NextBlock) { if (block is Table || block is Section) { return(false); } } ListItem parentListItem = firstBlock.Parent as ListItem; if (parentListItem != null) { // Paragraphs are inside of ListItem already. // Split a current ListItem before each of selected blocks Block block = firstBlock; while (block != null) { Block nextBlock = block == lastBlock ? null : block.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as Block; Invariant.Assert(block.Parent is ListItem); TextRangeEdit.SplitElement(block.ElementStart); block = nextBlock; } } else { // Create a list around all paragraphs List list = new List(); list.MarkerStyle = markerStyle; list.Apply(firstBlock, lastBlock); // Merge with neighboring lists //MergeLists(list.ElementEnd); // start with End to not loose an instance of "list" during merging with the following list //MergeLists(list.ElementStart); } return(true); }
// Token: 0x06003B85 RID: 15237 RVA: 0x0010F26C File Offset: 0x0010D46C internal static bool UnindentListItems(TextRange range) { if (!TextRangeEditLists.IsRangeWithinSingleList(range)) { return(false); } ListItem listItem = TextPointerBase.GetListItem(range.Start); ListItem listItem2 = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); for (TextElement textElement = (TextElement)listItem2.Parent; textElement != listItem.Parent; textElement = (TextElement)textElement.Parent) { listItem2 = (textElement as ListItem); } if (listItem2 == null) { return(false); } if (listItem.PreviousListItem != null) { TextRangeEdit.SplitElement(listItem.ElementStart); } if (listItem2.NextListItem != null) { TextRangeEdit.SplitElement(listItem2.ElementEnd); } List list = (List)listItem.Parent; ListItem listItem3 = list.Parent as ListItem; if (listItem3 != null) { list.Reposition(null, null); TextPointer contentEnd = listItem3.ContentEnd; if (listItem3.ContentStart.CompareTo(listItem.ElementStart) == 0) { listItem3.Reposition(null, null); } else { listItem3.Reposition(listItem3.ContentStart, listItem.ElementStart); } if (contentEnd.CompareTo(listItem2.ElementEnd) != 0) { TextPointer contentEnd2 = listItem2.ContentEnd; listItem2.Reposition(listItem2.ContentStart, contentEnd); TextRangeEditLists.MergeLists(contentEnd2); } } else { TextPointer elementStart = list.ElementStart; TextPointer elementEnd = list.ElementEnd; object value = list.GetValue(Block.FlowDirectionProperty); list.Reposition(null, null); ListItem listItem5; for (ListItem listItem4 = listItem; listItem4 != null; listItem4 = ((listItem4 == listItem2) ? null : listItem5)) { listItem5 = (listItem4.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem); if (listItem4.ContentStart.CompareTo(listItem4.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem4.ContentStart); } listItem4.Reposition(null, null); } TextRangeEdit.SetParagraphProperty(elementStart, elementEnd, Block.FlowDirectionProperty, value); TextRangeEditLists.MergeLists(elementStart); TextRangeEditLists.MergeLists(elementEnd); } return(true); }