internal static void _OnApplyProperty(TextEditor This, DependencyProperty formattingProperty, object propertyValue, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection))
            {
                return;
            }

            // Check whether the property is known
            if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty))
            {
                Invariant.Assert(false, "The property '" + formattingProperty.Name + "' is unknown to TextEditor");
                return;
            }

            TextSelection selection = (TextSelection)This.Selection;

            if (TextSchema.IsStructuralCharacterProperty(formattingProperty) &&
                !TextRangeEdit.CanApplyStructuralInlineProperty(selection.Start, selection.End))
            {
                // Ignore structural commands fires in inappropriate context.
                return;
            }

            TextEditorTyping._FlushPendingInputItems(This);

            // Forget previously suggested horizontal position
            TextEditorSelection._ClearSuggestedX(This);

            // Break merged typing sequence
            TextEditorTyping._BreakTypingSequence(This);

            // Apply property
            selection.ApplyPropertyValue(formattingProperty, propertyValue, applyToParagraphs, propertyValueAction);
        }
Пример #2
0
        /// <summary>
        /// Applies a formatting property to this TextRange.
        /// </summary>
        /// <param name="formattingProperty">
        /// Property to apply.
        /// </param>
        /// <param name="value">
        /// Specifies a value for the property.
        /// </param>
        /// <param name="applyToParagraphs">
        /// This parameter is used to resolve the ambiguity for overlapping inherited properties 
        /// that apply to both inline and paragraph elements.
        /// </param>
        /// <param name="propertyValueAction">
        /// Specifies how to apply the given value - use it for setting,
        /// for increasing or for decreasing existing values.
        /// This parameter must have PropertyValueAction.SetValue for all properties that
        /// cannot be incremented or decremented by their type.
        /// </param>
        internal void ApplyPropertyValue(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            Invariant.Assert(this.HasConcreteTextContainer, "Can't apply property to non-TextContainer range!");

            if (formattingProperty == null)
            {
                throw new ArgumentNullException("formattingProperty");
            }

            if (!TextSchema.IsCharacterProperty(formattingProperty) &&
                !TextSchema.IsParagraphProperty(formattingProperty))
            {
                #pragma warning suppress 6506 // formattingProperty is obviously not null
                throw new ArgumentException(SR.Get(SRID.TextEditorPropertyIsNotApplicableForTextFormatting, formattingProperty.Name));
            }

            // Convert property value from a string to object if needed
            if ((value is string) && formattingProperty.PropertyType != typeof(string))
            {
                System.ComponentModel.TypeConverter typeConverter = System.ComponentModel.TypeDescriptor.GetConverter(formattingProperty.PropertyType);
                Invariant.Assert(typeConverter != null);
                value = typeConverter.ConvertFromString((string)value);
            }

            // Check if the value is appropriate for the property
            if (!formattingProperty.IsValidValue(value) &&
                !(formattingProperty.PropertyType == typeof(Thickness) && (value is Thickness)))
            {
                // We exclude checking thcickness values because we have special treatment for negative values
                // in TextRangeEdit.SetParagraphProperty - negative values mean: "leave the value as is".
                throw new ArgumentException(SR.Get(SRID.TextEditorTypeOfParameterIsNotAppropriateForFormattingProperty, value == null ? "null" : value.GetType().Name, formattingProperty.Name), "value");
            }

            // Check propertyValueAction validity
            if (propertyValueAction != PropertyValueAction.SetValue &&
                propertyValueAction != PropertyValueAction.IncreaseByAbsoluteValue &&
                propertyValueAction != PropertyValueAction.DecreaseByAbsoluteValue &&
                propertyValueAction != PropertyValueAction.IncreaseByPercentageValue &&
                propertyValueAction != PropertyValueAction.DecreaseByPercentageValue)
            {
                throw new ArgumentException(SR.Get(SRID.TextRange_InvalidParameterValue), "propertyValueAction");
            }
            // Check if propertyValueAction is applicable to this property
            if (propertyValueAction != PropertyValueAction.SetValue &&
                !TextSchema.IsPropertyIncremental(formattingProperty))
            {
                throw new ArgumentException(SR.Get(SRID.TextRange_PropertyCannotBeIncrementedOrDecremented, formattingProperty.Name), "propertyValueAction");
            }

            ApplyPropertyToTextVirtual(formattingProperty, value, applyToParagraphs, propertyValueAction);
        }
Пример #3
0
        // Worker for ApplyProperty; enables extensibility for TextSelection
        internal virtual void ApplyPropertyToTextVirtual(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            TextRangeBase.BeginChange(this);
            try
            {
                for (int i = 0; i < _textSegments.Count; i++)
                {
                    TextSegment textSegment = _textSegments[i];

                    if (formattingProperty == FrameworkElement.FlowDirectionProperty)
                    {
                        // FlowDirection is an overlapping inheritable property that needs special handling. 
                        // We apply it as a paragraph property when:
                        //  1. applyToParagraphs = true or
                        //  2. range is empty or
                        //  3. range crossed paragraph boundary
                        // Otherwise, apply as inline property.
                        if (applyToParagraphs || this.IsEmpty || TextRangeBase.IsParagraphBoundaryCrossed(this))
                        {
                            TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                        }
                        else
                        {
                            TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                        }
                    }
                    else if (TextSchema.IsCharacterProperty(formattingProperty))
                    {
                        TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                    }
                    else if (TextSchema.IsParagraphProperty(formattingProperty))
                    {
                        // We must check for paragraph properties after character ones,
                        // to account for overlapping inheritable properties.

                        // Thinkness properties (Margin, Padding, BorderThickness) have special treatment
                        // in SetParagraphProperty method: it swaps Left and Right values for paragraphs
                        // with RightToLeft flow direction. So we need to set them appropriatly -
                        // depending on the FlowDirection of the first paragraph.
                        if (formattingProperty.PropertyType == typeof(Thickness) &&
                            (FlowDirection)textSegment.Start.GetValue(Paragraph.FlowDirectionProperty) == FlowDirection.RightToLeft)
                        {
                            value = new Thickness(
                                ((Thickness)value).Right, ((Thickness)value).Top, ((Thickness)value).Left, ((Thickness)value).Bottom);
                        }
                        TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                    }
                }
            }
            finally
            {
                TextRangeBase.EndChange(this);
            }
        }
Пример #4
0
        internal static void _OnApplyProperty(TextEditor This, DependencyProperty formattingProperty, object propertyValue, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection))
            {
                return;
            }

            // Check whether the property is known
            if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty))
            {
                Invariant.Assert(false, "The property '" + formattingProperty.Name + "' is unknown to TextEditor");
                return;
            }

            TextSelection selection = (TextSelection)This.Selection;

            if (TextSchema.IsStructuralCharacterProperty(formattingProperty) &&
                !TextRangeEdit.CanApplyStructuralInlineProperty(selection.Start, selection.End))
            {
                // Ignore structural commands fires in inappropriate context.
                return;
            }

            TextEditorTyping._FlushPendingInputItems(This);

            // Forget previously suggested horizontal position
            TextEditorSelection._ClearSuggestedX(This);

            // Break merged typing sequence
            TextEditorTyping._BreakTypingSequence(This);

            // Apply property
            selection.ApplyPropertyValue(formattingProperty, propertyValue, applyToParagraphs, propertyValueAction);
        }
Пример #5
0
        // Helper for SetParagraphProperty -- applies given property value to passed block element. 
        private static void SetPropertyOnParagraphOrBlockUIContainer(DependencyObject parent, Block block, DependencyProperty property, object value, PropertyValueAction propertyValueAction)
        { 
            // Get the parent flow direction
            FlowDirection parentFlowDirection;

            if (parent != null) 
            {
                parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty); 
            } 
            else
            { 
                parentFlowDirection = (FlowDirection)FrameworkElement.FlowDirectionProperty.GetDefaultValue(typeof(FrameworkElement));
            }

            // Some of paragraph operations depend on its flow direction, so get it first. 
            FlowDirection flowDirection = (FlowDirection)block.GetValue(Block.FlowDirectionProperty);
 
            // Inspect a property value for this paragraph 
            object currentValue = block.GetValue(property);
            object newValue = value; 

            // If we're setting a structural property on a Paragraph, we need to preserve
            // the current value on its children.
            PreserveBlockContentStructuralProperty(block, property, currentValue, value); 

            if (property.PropertyType == typeof(Thickness)) 
            { 
                // For Margin, Padding, Border - apply the following logic:
                Invariant.Assert(currentValue is Thickness, "Expecting the currentValue to be of Thinkness type"); 
                Invariant.Assert(newValue is Thickness, "Expecting the newValue to be of Thinkness type");

                newValue = ComputeNewThicknessValue((Thickness)currentValue, (Thickness)newValue, parentFlowDirection, flowDirection, propertyValueAction);
            } 
            else if (property == Paragraph.TextAlignmentProperty)
            { 
                Invariant.Assert(value is TextAlignment, "Expecting TextAlignment as a value of a Paragraph.TextAlignmentProperty"); 

                // TextAlignment must be reverted for RightToLeft flow direction 
                newValue = ComputeNewTextAlignmentValue((TextAlignment)value, flowDirection);

                // For BlockUIContainer text alignment must be translated into
                // HorizontalAlignment of the child embedded object. 
                if (block is BlockUIContainer)
                { 
                    UIElement embeddedElement = ((BlockUIContainer)block).Child; 
                    if (embeddedElement != null)
                    { 
                        HorizontalAlignment horizontalAlignment = GetHorizontalAlignmentFromTextAlignment((TextAlignment)newValue);

                        // Create an undo unit for property change on embedded framework element.
                        UIElementPropertyUndoUnit.Add(block.TextContainer, embeddedElement, FrameworkElement.HorizontalAlignmentProperty, horizontalAlignment); 
                        embeddedElement.SetValue(FrameworkElement.HorizontalAlignmentProperty, horizontalAlignment);
                    } 
                } 
            }
            else if (currentValue is double) 
            {
                newValue = GetNewDoubleValue(property, (double)currentValue, (double)newValue, propertyValueAction);
            }
 
            SetPropertyValue(block, property, currentValue, newValue);
 
            if (property == Block.FlowDirectionProperty) 
            {
                // For flow direction command, we also swap Left and Right margins of the paragraph. 
                // This ensures indentation is mirrored correctly.
                SwapBlockLeftAndRightMargins(block);
            }
        } 
Пример #6
0
        // Worker for SetParagraphProperty, iterates over Blocks recursively. 
        private static void SetParagraphPropertyWorker(TextPointer start, TextPointer end, DependencyProperty property, object value, PropertyValueAction propertyValueAction) 
        {
            Block block = GetNextBlock(start, end); 

            while (block != null)
            {
                if (TextSchema.IsParagraphOrBlockUIContainer(block.GetType())) 
                {
                    // Get the parent to check the parent FlowDirection with current 
                    DependencyObject parent = start.TextContainer.Parent; 

                    SetPropertyOnParagraphOrBlockUIContainer(parent, block, property, value, propertyValueAction); 

                    // Go to paragraph/BUIC end position, normalize forward
                    start = block.ElementEnd.GetPositionAtOffset(0, LogicalDirection.Forward);
                } 
                else if (block is List)
                { 
                    // Apply property value to content first, recursively, since 
                    // (potentially) setting FlowDirection on the parent List will
                    // affect child elements. 
                    TextPointer contentStart = block.ContentStart.GetPositionAtOffset(0, LogicalDirection.Forward); // Normalize forward;
                    contentStart = contentStart.GetNextContextPosition(LogicalDirection.Forward); // Leave scope of initial List.
                    TextPointer contentEnd = block.ContentEnd;
                    SetParagraphPropertyWorker(contentStart, contentEnd, property, value, propertyValueAction); 

                    // Special cases for applying paragraph properties to Lists 
                    if (property == Block.FlowDirectionProperty) 
                    {
                        // Set FlowDirection property on List 
                        SetPropertyValue(block, property, /*currentValue:*/block.GetValue(property), /*newValue:*/value);

                        // For flow direction command, we also swap Left and Right margins of the list.
                        // This ensures indentation is mirrored correctly. 
                        SwapBlockLeftAndRightMargins(block);
                    } 
 
                    // Go to end position, normalize forward.
                    start = block.ElementEnd.GetPositionAtOffset(0, LogicalDirection.Forward); 
                }

                block = GetNextBlock(start, end);
            } 
        }
Пример #7
0
        /// <summary>
        /// Applies formatting properties for whole block elements. 
        /// </summary>
        /// <param name="start">
        /// a position within first block in sequence
        /// </param> 
        /// <param name="end">
        /// a positionn within last block in sequence 
        /// </param> 
        /// <param name="property">
        /// property changed on blocks 
        /// </param>
        /// <param name="value">
        /// value for the property
        /// </param> 
        /// <param name="propertyValueAction">
        /// Specifies how to use the value - as absolute, as increment or a decrement. 
        /// </param> 
        internal static void SetParagraphProperty(TextPointer start, TextPointer end, DependencyProperty property, object value, PropertyValueAction propertyValueAction)
        { 
            Invariant.Assert(start != null, "null check: start");
            Invariant.Assert(end != null, "null check: end");
            Invariant.Assert(start.CompareTo(end) <= 0, "expecting: start <= end");
            Invariant.Assert(property != null, "null check: property"); 

            // Exclude last opening tag to avoid affecting a paragraph following the selection 
            end = (TextPointer)TextRangeEdit.GetAdjustedRangeEnd(start, end); 

            // Expand start pointer to the beginning of the first paragraph/blockuicontainer 
            Block startParagraphOrBlockUIContainer = start.ParagraphOrBlockUIContainer;
            if (startParagraphOrBlockUIContainer != null)
            {
                start = startParagraphOrBlockUIContainer.ContentStart; 
            }
 
            // Applying FlowDirection requires splitting all containing lists on the range boundaries 
            // because the property is applied to whole List element (to affect bullet appearence)
            if (property == Block.FlowDirectionProperty) 
            {
                // Split any boundary lists if needed.
                // We want to maintain the invariant that all lists and paragraphs within a list, have the same FlowDirection value.
                // If paragraph FlowDirection command requests a different value of FlowDirection on parts of a list, 
                // we split the list to maintain this invariant.
                if (!TextRangeEditLists.SplitListsForFlowDirectionChange(start, end, value)) 
                { 
                    // If lists at start and end cannot be split successfully, we cannot apply FlowDirection property to the paragraph content.
                    return; 
                }

                // And expand range start to the beginning of the containing list
                ListItem listItem = start.GetListAncestor(); 
                if (listItem != null && listItem.List != null)
                { 
                    start = listItem.List.ElementStart; 
                }
            } 

            // Walk all paragraphs in the affected segment. For FlowDirection property, also walk lists.
            SetParagraphPropertyWorker(start, end, property, value, propertyValueAction);
        } 
 // Token: 0x06003AFE RID: 15102 RVA: 0x0010A744 File Offset: 0x00108944
 internal virtual void ApplyPropertyToTextVirtual(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction)
 {
     TextRangeBase.BeginChange(this);
     try
     {
         for (int i = 0; i < this._textSegments.Count; i++)
         {
             TextSegment textSegment = this._textSegments[i];
             if (formattingProperty == FrameworkElement.FlowDirectionProperty)
             {
                 if (applyToParagraphs || this.IsEmpty || TextRangeBase.IsParagraphBoundaryCrossed(this))
                 {
                     TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                 }
                 else
                 {
                     TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
                 }
             }
             else if (TextSchema.IsCharacterProperty(formattingProperty))
             {
                 TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
             }
             else if (TextSchema.IsParagraphProperty(formattingProperty))
             {
                 if (formattingProperty.PropertyType == typeof(Thickness) && (FlowDirection)textSegment.Start.GetValue(Block.FlowDirectionProperty) == FlowDirection.RightToLeft)
                 {
                     value = new Thickness(((Thickness)value).Right, ((Thickness)value).Top, ((Thickness)value).Left, ((Thickness)value).Bottom);
                 }
                 TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction);
             }
         }
     }
     finally
     {
         TextRangeBase.EndChange(this);
     }
 }
Пример #9
0
        // Helper to calculate new value of Run.FontSize property when PropertyValueAction is increment/decrement. 
        private static double GetNewFontSizeValue(double currentValue, double value, PropertyValueAction propertyValueAction)
        { 
            double newValue = value;

            // Calculate the new value as increment/decrement from the current value
            if (propertyValueAction == PropertyValueAction.IncreaseByAbsoluteValue) 
            {
                newValue = currentValue + value; 
            } 
            else if (propertyValueAction == PropertyValueAction.DecreaseByAbsoluteValue)
            { 
                newValue = currentValue - value;
            }

            // Check limiting boundaries 
            if (newValue < TextEditorCharacters.OneFontPoint)
            { 
                newValue = TextEditorCharacters.OneFontPoint; 
            }
            else if (newValue > TextEditorCharacters.MaxFontPoint) 
            {
                newValue = TextEditorCharacters.MaxFontPoint;
            }
 
            return newValue;
        } 
Пример #10
0
        // Helper to set non-structural Inline property to a range between start and end positions.
        private static void SetNonStructuralInlineProperty(TextPointer start, TextPointer end, DependencyProperty formattingProperty, object value, PropertyValueAction propertyValueAction) 
        { 
            // Split formatting elements at range boundaries
            start = SplitFormattingElements(start, /*keepEmptyFormatting:*/false, /*preserveStructuralFormatting*/true, /*limitingAncestor*/null); 
            end = SplitFormattingElements(end, /*keepEmptyFormatting:*/false, /*preserveStructuralFormatting*/true, /*limitingAncestor*/null);

            Run run = TextRangeEdit.GetNextRun(start, end);
 
            while (run != null)
            { 
                object currentValue = run.GetValue(formattingProperty); 
                object newValue = value;
 
                if (propertyValueAction != PropertyValueAction.SetValue)
                {
                    Invariant.Assert(formattingProperty == TextElement.FontSizeProperty, "Only FontSize can be incremented/decremented among character properties");
                    newValue = GetNewFontSizeValue((double)currentValue, (double)value, propertyValueAction); 
                }
 
                // Set new property value 
                SetPropertyValue(run, formattingProperty, currentValue, newValue);
 
                // Remember a position after the current run for the following processing.
                // Normalize forward since Run.ElementEnd has backward gravity.
                TextPointer nextRunPosition = run.ElementEnd.GetPositionAtOffset(0, LogicalDirection.Forward);
 
                if (TextPointerBase.IsAtPotentialRunPosition(run))
                { 
                    // If current run was an implicit run, we move to the next context position after its element end. 
                    // This is safe because by definition of IsAtPotentialRunPosition predicate,
                    // our current run can never have an adjacent run element or 
                    // another adjacent potential run position.
                    nextRunPosition = nextRunPosition.GetNextContextPosition(LogicalDirection.Forward);
                }
 
                // Merge this run with the previous one.
                // Note that this can affect text structure even after this run. 
                MergeFormattingInlines(run.ContentStart); 

                // Find the next Run to process 
                run = TextRangeEdit.GetNextRun(nextRunPosition, end);
            }

            MergeFormattingInlines(end); 
        }
Пример #11
0
        // ..................................................................... 
        //
        // Paragraph Editing Commands 
        //
        // .....................................................................

        /// <summary> 
        /// Increments/decrements paragraph leading maring property.
        /// For LeftToRight paragraphs a leading maring is the left marinng, 
        /// for RightToLeft paragraphs it is the right maring. 
        /// </summary>
        /// <param name="range"></param> 
        /// <param name="increment"></param>
        /// <param name="propertyValueAction">
        /// Must be one of IncreaseValue or DecreaseValue.
        /// </param> 
        internal static void IncrementParagraphLeadingMargin(TextRange range, double increment, PropertyValueAction propertyValueAction)
        { 
            Invariant.Assert(increment >= 0); 
            Invariant.Assert(propertyValueAction != PropertyValueAction.SetValue);
 
            if (increment == 0)
            {
                // Nothing to do. Just return.
                return; 
            }
 
            // Note that SetParagraphProperty method will swap Left and Right margins for RightToLeft paragraphs. 
            // Note that -1 values for Thickness axis means leaving its value as is.
            Thickness thickness = new Thickness(increment, -1, -1, -1); 

            // Apply paragraph margin property
            TextRangeEdit.SetParagraphProperty(range.Start, range.End, Block.MarginProperty, thickness, propertyValueAction);
        } 
Пример #12
0
        // Applies newValue to the currentValue according to a propertyValueAction -
        // increments or just sets it. 
        private static double NewValue(double currentValue, double newValue, PropertyValueAction propertyValueAction) 
        {
            if (double.IsNaN(newValue)) 
            {
                return newValue;
            }
 
            if (double.IsNaN(currentValue))
            { 
                currentValue = 0.0; 
            }
 
            newValue =
                propertyValueAction == PropertyValueAction.IncreaseByAbsoluteValue ? currentValue + newValue :
                propertyValueAction == PropertyValueAction.DecreaseByAbsoluteValue ? currentValue - newValue :
                propertyValueAction == PropertyValueAction.IncreaseByPercentageValue ? currentValue * (1.0 + newValue / 100) : 
                propertyValueAction == PropertyValueAction.DecreaseByPercentageValue ? currentValue * (1.0 - newValue / 100) :
                newValue; 
 
            return newValue;
        } 
Пример #13
0
 /// <summary> 
 /// Calculates valid value for specified DP, current and new (desired) value, 
 /// and <see cref="PropertyValueAction"/>.
 /// The value is made to adhere editor's acceptable range of values for given property. 
 /// If the value is invalid, then closest valid bound of the range is returned.
 /// </summary>
 /// <param name="property"></param>
 /// <param name="currentValue"></param> 
 /// <param name="newValue"></param>
 /// <param name="propertyValueAction"></param> 
 /// <returns>new value</returns> 
 private static double GetNewDoubleValue(DependencyProperty property, double currentValue, double newValue, PropertyValueAction propertyValueAction)
 { 
     double outValue = NewValue(currentValue, newValue, propertyValueAction);
     return DoublePropertyBounds.GetClosestValidValue(property, outValue);
 }
Пример #14
0
        // Helper for SetParagraphProperty
        private static Thickness ComputeNewThicknessValue(Thickness currentThickness, Thickness newThickness,
            FlowDirection parentFlowDirection, FlowDirection flowDirection, PropertyValueAction propertyValueAction) 
        {
            // Negative value for particular axis means "leave it unchanged" 
            double topMargin = newThickness.Top < 0 
                ? currentThickness.Top
                : GetNewDoubleValue(null, currentThickness.Top, newThickness.Top, propertyValueAction); 

            double bottomMargin = newThickness.Bottom < 0
                ? currentThickness.Bottom
                : GetNewDoubleValue(null, currentThickness.Bottom, newThickness.Bottom, propertyValueAction); 

            double leftMargin; 
            double rightMargin; 

            if (parentFlowDirection != flowDirection) 
            {
                // In case of mismatching FlowDirection between parent and current,
                // we apply value.Left to currentValue.Right and vice versa.
                // The caller of the method must account for that and use Left/Right margins appropriately. 
                leftMargin = newThickness.Right < 0
                    ? currentThickness.Left 
                    : GetNewDoubleValue(null, currentThickness.Left, newThickness.Right, propertyValueAction); 

                rightMargin = newThickness.Left < 0 
                    ? currentThickness.Right
                    : GetNewDoubleValue(null, currentThickness.Right, newThickness.Left, propertyValueAction);
            }
            else 
            {
                leftMargin = newThickness.Left < 0 
                    ? currentThickness.Left 
                    : GetNewDoubleValue(null, currentThickness.Left, newThickness.Left, propertyValueAction);
 
                rightMargin = newThickness.Right < 0
                    ? currentThickness.Right
                    : GetNewDoubleValue(null, currentThickness.Right, newThickness.Right, propertyValueAction);
            } 

            return new Thickness(leftMargin, topMargin, rightMargin, bottomMargin); 
        } 
        // Token: 0x06003835 RID: 14389 RVA: 0x000FA980 File Offset: 0x000F8B80
        internal static void _OnApplyProperty(TextEditor This, DependencyProperty formattingProperty, object propertyValue, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection))
            {
                return;
            }
            if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty))
            {
                Invariant.Assert(false, "The property '" + formattingProperty.Name + "' is unknown to TextEditor");
                return;
            }
            TextSelection textSelection = (TextSelection)This.Selection;

            if (TextSchema.IsStructuralCharacterProperty(formattingProperty) && !TextRangeEdit.CanApplyStructuralInlineProperty(textSelection.Start, textSelection.End))
            {
                return;
            }
            TextEditorTyping._FlushPendingInputItems(This);
            TextEditorSelection._ClearSuggestedX(This);
            TextEditorTyping._BreakTypingSequence(This);
            textSelection.ApplyPropertyValue(formattingProperty, propertyValue, applyToParagraphs, propertyValueAction);
        }
Пример #16
0
        /// <summary>
        /// Applies a property value to a selection.
        /// In case of empty selection sets property to springloaded property set.
        /// </summary>
        internal override void ApplyPropertyToTextVirtual(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction)
        {
            if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty))
            {
                return; // Ignore any unknown property
            }

            // Check whether we are in a situation when auto-word formatting must happen
            if (this.IsEmpty && TextSchema.IsCharacterProperty(formattingProperty) &&
                !applyToParagraphs &&
                formattingProperty != FrameworkElement.FlowDirectionProperty) // We dont want to apply flowdirection property to inlines when selection is empty.
            {
                TextSegment autoWordRange = TextRangeBase.GetAutoWord(this);
                if (autoWordRange.IsNull)
                {
                    // This property goes to springload formatting. We should not create undo unit for it.
                    if (_springloadFormatting == null)
                    {
                        _springloadFormatting = new DependencyObject();
                    }

                    _springloadFormatting.SetValue(formattingProperty, value);
                }
                else
                {
                    // TextRange will create undo unit with proper name
                    new TextRange(autoWordRange.Start, autoWordRange.End).ApplyPropertyValue(formattingProperty, value);
                }
            }
            else
            {
                // No word to auto-format. Apply property to a selection.
                // TextRange will create undo unit with proper name
                base.ApplyPropertyToTextVirtual(formattingProperty, value, applyToParagraphs, propertyValueAction);
                this.ClearSpringloadFormatting();
            }
        }
Пример #17
0
        /// <summary> 
        /// Applies a property to a range between start and end positions.
        /// </summary> 
        /// <param name="start">
        /// TextPointer identifying start of affected range.
        /// </param>
        /// <param name="end"> 
        /// TextPointer identifying end of affected range.
        /// </param> 
        /// <param name="formattingProperty"> 
        /// A dependency property whose value is supposed to applied to a range.
        /// </param> 
        /// <param name="value">
        /// A value for a property to apply.
        /// </param>
        /// <param name="propertyValueAction"> 
        /// Specifies how to use the value - as absolute, as increment or a decrement.
        /// </param> 
        internal static void SetInlineProperty(TextPointer start, TextPointer end, DependencyProperty formattingProperty, object value, PropertyValueAction propertyValueAction) 
        {
            // Check for corner case when we have siple text run with all properties set as requested. 
            // This case is iportant optimization for Backspace-Type scenario, when Springload formatting applies for nothing for 50 properties
            if (start.CompareTo(end) >= 0 ||
                propertyValueAction == PropertyValueAction.SetValue &&
                start.Parent is Run && 
                start.Parent == end.Parent && TextSchema.ValuesAreEqual(start.Parent.GetValue(formattingProperty), value))
            { 
                return; 
            }
 
            // Remove unnecessary spans on range ends - to optimize resulting markup
            RemoveUnnecessarySpans(start);
            RemoveUnnecessarySpans(end);
 
            if (TextSchema.IsStructuralCharacterProperty(formattingProperty))
            { 
                SetStructuralInlineProperty(start, end, formattingProperty, value); 
            }
            else 
            {
                SetNonStructuralInlineProperty(start, end, formattingProperty, value, propertyValueAction);
            }
        } 
 // Token: 0x06003AD7 RID: 15063 RVA: 0x0010A16C File Offset: 0x0010836C
 internal void ApplyPropertyValue(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction)
 {
     Invariant.Assert(this.HasConcreteTextContainer, "Can't apply property to non-TextContainer range!");
     if (formattingProperty == null)
     {
         throw new ArgumentNullException("formattingProperty");
     }
     if (!TextSchema.IsCharacterProperty(formattingProperty) && !TextSchema.IsParagraphProperty(formattingProperty))
     {
         throw new ArgumentException(SR.Get("TextEditorPropertyIsNotApplicableForTextFormatting", new object[]
         {
             formattingProperty.Name
         }));
     }
     if (value is string && formattingProperty.PropertyType != typeof(string))
     {
         TypeConverter converter = TypeDescriptor.GetConverter(formattingProperty.PropertyType);
         Invariant.Assert(converter != null);
         value = converter.ConvertFromString((string)value);
     }
     if (!formattingProperty.IsValidValue(value) && (!(formattingProperty.PropertyType == typeof(Thickness)) || !(value is Thickness)))
     {
         throw new ArgumentException(SR.Get("TextEditorTypeOfParameterIsNotAppropriateForFormattingProperty", new object[]
         {
             (value == null) ? "null" : value.GetType().Name,
             formattingProperty.Name
         }), "value");
     }
     if (propertyValueAction != PropertyValueAction.SetValue && propertyValueAction != PropertyValueAction.IncreaseByAbsoluteValue && propertyValueAction != PropertyValueAction.DecreaseByAbsoluteValue && propertyValueAction != PropertyValueAction.IncreaseByPercentageValue && propertyValueAction != PropertyValueAction.DecreaseByPercentageValue)
     {
         throw new ArgumentException(SR.Get("TextRange_InvalidParameterValue"), "propertyValueAction");
     }
     if (propertyValueAction != PropertyValueAction.SetValue && !TextSchema.IsPropertyIncremental(formattingProperty))
     {
         throw new ArgumentException(SR.Get("TextRange_PropertyCannotBeIncrementedOrDecremented", new object[]
         {
             formattingProperty.Name
         }), "propertyValueAction");
     }
     this.ApplyPropertyToTextVirtual(formattingProperty, value, applyToParagraphs, propertyValueAction);
 }