Beispiel #1
0
        public void ExpandToEnclosingUnit(TextUnit unit)
        {
            switch (unit)
            {
            case TextUnit.Character:
                // This does nothing
                break;

            case TextUnit.Format:
                // Textbox doesn't support Format
                break;

            case TextUnit.Word:
                normalizer.WordNormalize();
                break;

            case TextUnit.Line:
                normalizer.LineNormalize();
                break;

            case TextUnit.Paragraph:
                normalizer.ParagraphNormalize();
                break;

            case TextUnit.Page:
            // Textbox doesn't support Page
            case TextUnit.Document:
                normalizer.DocumentNormalize();
                break;
            }
        }
        /// <summary>
        /// Expands the text range to the specified TextUnit.
        /// </summary>
        /// <param name="control">The UI Automation element</param>
        /// <param name="unit">The textual unit.</param>
        internal static void ExpandToEnclosingUnit(AutomationElement control, TextUnit unit)
        {
            TextPattern pat = (TextPattern)CommonUIAPatternHelpers.CheckPatternSupport(TextPattern.Pattern, control);

            TextPatternRange[] selection = pat.GetSelection();
            selection[0].ExpandToEnclosingUnit(unit);
        }
Beispiel #3
0
    public void LoadUnit(TextUnit TU)
    {
        if (!TU)
        {
            return;
        }
        if (GetCurrentUnit())
        {
            GetCurrentUnit().OnEnd();
        }

        TU.OnLoad();
        NextActive   = false;
        ChoiceActive = false;
        CurrentUnit  = TU;
        NextUnit     = TU.GetNextUnit();
        CurrentDelay = TU.GetDelay();
        PastUnits.Add(TU);

        if (TU.UType == UnitType.Player)
        {
            PlayerUnit = TU;
        }
        else
        {
            AIUnit     = TU;
            PlayerUnit = null;
        }

        foreach (TextRenderer TR in Renderers)
        {
            TR.Update();
        }
    }
Beispiel #4
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            var layer = r.GetLayerGraphics("hi_res_overlay");

            layer.Clear(Color.FromArgb(31, 24, 51));

            System.Drawing.Size layerSize = layer.GetSize();

            var logo = r.SpriteManager["logo"];

            System.Drawing.Size logoSize = r.GraphicsContext.GetSize(logo);
            logoSize.Width  *= 4;
            logoSize.Height *= 4;

            layer.Draw(logo, new System.Drawing.Rectangle(layerSize.Width / 2 - logoSize.Width / 2, layerSize.Height / 2 - logoSize.Height / 2, logoSize.Width, logoSize.Height));

            if (Delay <= 0)
            {
                TextUnit text = new TextUnit(new Sprite("x_icons", new Rectangle(0, -4, 9 * 4, 9 * 4), new Rectangle(0, 0, 9, 9))
                {
                    Modifiers = Sprite.Mod_InputType
                }, " Start", Color.FromArgb(182, 203, 207));

                System.Drawing.Size textSize = text.GetSize(4);
                text.Render(r, layer, new Point(layerSize.Width / 2 - textSize.Width / 2, layerSize.Height / 2 + logoSize.Height / 2 + 32), 4);
            }
        }
Beispiel #5
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            if (!ModalVisible)
            {
                return;
            }

            var layer = r.GetLayerGraphics("hi_res_overlay");

            System.Drawing.Rectangle sidebar = new System.Drawing.Rectangle(EditorRendering.SidebarX, 0, EditorRendering.SidebarWidth, 720);

            layer.FillRect(sidebar, Color.FromArgb(45, 45, 48));
            layer.FillRect(new System.Drawing.Rectangle(sidebar.X + EditorRendering.SidebarMargin, sidebar.Y + EditorRendering.SidebarMargin, sidebar.Width - 2 * EditorRendering.SidebarMargin, sidebar.Height - 2 * EditorRendering.SidebarMargin), Color.FromArgb(37, 37, 38));

            int x = EditorRendering.SidebarX + 2 * EditorRendering.SidebarMargin;
            int y = EditorRendering.SidebarMargin + 4;

            new TextUnit(EditorMenuSystem.CogIcon, new[] { "Top", "Right", "Bottom", "Left" }[FaceIndex] +" Face").Render(r, layer, new Point(x, y), 2);
            y += 20;

            layer.FillRect(new System.Drawing.Rectangle(x - 2 * EditorRendering.SidebarMargin, y, EditorRendering.SidebarWidth - 2 * EditorRendering.SidebarMargin, 3), Color.FromArgb(45, 45, 48));
            y += 8;

            int index = 0;

            foreach (IMemberSummary member in Members)
            {
                TextUnit label = member.Label;
                label.Color = SelectedPropertyIndex == index ? Color.CornflowerBlue : Color.White;
                label.Render(r, layer, new Point(x + 8, y), 2);
                y += 24;
                index++;
            }
        }
        public void IsCultureSupported_ReturnsCorrectValue()
        {
            TextUnit unit = new TextUnit("key", invariantCultureTexts);

            Assert.IsFalse(unit.IsCultureSupported(frFR));
            Assert.IsTrue(unit.IsCultureSupported(CultureInfo.InvariantCulture));
        }
        public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
        {
            Log("{0}.MoveEndpointByUnit({1}, {2}, {3})", ID, endpoint, unit, count);
            int offset = GetEndpoint(endpoint);

            switch (unit)
            {
            case TextUnit.Character:
                offset = MoveOffset(offset, CaretPositioningMode.Normal, count);
                break;

            case TextUnit.Format:
            case TextUnit.Word:
                offset = MoveOffset(offset, CaretPositioningMode.WordStart, count);
                break;

            case TextUnit.Line:
            case TextUnit.Paragraph:
                int line    = doc.GetLineByOffset(offset).LineNumber;
                int newLine = Math.Max(1, Math.Min(doc.LineCount, line + count));
                offset = doc.GetLineByNumber(newLine).Offset;
                break;

            case TextUnit.Document:
                offset = count < 0 ? 0 : doc.TextLength;
                break;
            }
            SetEndpoint(endpoint, offset);
            return(count);
        }
Beispiel #8
0
                public void ExpandToEnclosingUnit(TextUnit unit)
                {
                    var document  = _control.Document;
                    int endOffset = _selection.EndOffset;

                    switch (unit)
                    {
                    case TextUnit.Character:
                    case TextUnit.Line:
                    case TextUnit.Paragraph:
                    case TextUnit.Word:
                        endOffset = FindOffset(endOffset, unit, true);

                        _selection = new DefaultSelection(
                            document,
                            _selection.StartPosition,
                            document.OffsetToPosition(endOffset)
                            );
                        break;

                    case TextUnit.Document:
                        _selection = new DefaultSelection(
                            document,
                            document.OffsetToPosition(0),
                            document.OffsetToPosition(document.TextLength)
                            );
                        break;
                    }
                }
        public void OverloadedToString_ReturnsCorrectValue()
        {
            TextUnit unit = new TextUnit("key", twoCultureTexts);

            Assert.IsTrue(unit.ToString(CultureInfo.InvariantCulture) == HelloWorld);
            Assert.IsTrue(unit.ToString(frFR) == HelloWorldFr);
        }
Beispiel #10
0
        public int Move(TextUnit unit, int count)
        {
            switch (unit)
            {
            case TextUnit.Character:
            {
                var previousStart = this.Position;
                this.Position    = Math.Max(0, Math.Min(this.editor.TextLength - 1, this.Position + count));
                this.EndPosition = this.Position + 1;
                return(this.Position - previousStart);
            }

            case TextUnit.Line:
            {
                var previous = this.editor.LineFromPosition(this.Position);
                var newIndex = Math.Max(0, Math.Min(this.editor.Lines.Count - 1, previous + count));
                var newLine  = this.editor.Lines[newIndex];
                this.Position    = newLine.Position;
                this.EndPosition = newLine.EndPosition - 1;
                return(newIndex - previous);
            }

            default:
                throw new NotImplementedException();
            }
        }
Beispiel #11
0
 // check an unit argument to see if it is valid.
 void ValidateUnitArgument(TextUnit unit, string name)
 {
     if (unit < TextUnit.Character || unit > TextUnit.Document)
     {
         Misc.ThrowInvalidArgument(name);
     }
 }
Beispiel #12
0
        protected override IList <TextUnit> SplitUnit(TextUnit textUnit)
        {
            var foundIndex = FindLocInStr(textUnit.Text, _splitItems, out var foundItem);

            if (textUnit.CanSplit == false || foundIndex == -1)
            {
                return(new List <TextUnit> {
                    textUnit
                });
            }

            var retList       = new List <TextUnit>();
            var firstPart     = textUnit.Text.Substring(0, foundIndex);
            var lastPartStart = foundIndex + foundItem.Length;
            var lastPart      = textUnit.Text.Substring(lastPartStart, textUnit.Text.Length - lastPartStart);

            if (!string.IsNullOrEmpty(firstPart))
            {
                retList.AddRange(SplitUnit(TextUnit.CreateUnit(firstPart)));
            }
            retList.Add(TextUnit.CreateUnit(foundItem, false));
            if (!string.IsNullOrEmpty(lastPart))
            {
                retList.AddRange(SplitUnit(TextUnit.CreateUnit(lastPart)));
            }

            return(retList);
        }
Beispiel #13
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            var layer = r.GetLayerGraphics("hud");

            layer.Draw(r.SpriteManager["menu_bg"], new System.Drawing.Rectangle(new Point(0, 0), layer.GetSize()));

            r.GetLayerGraphics("hi_res_overlay").Draw(r.SpriteManager["logo"], new System.Drawing.Rectangle(648, 128, 480, 152));

            int destY = 100;
            int index = 0;

            foreach (string label in OptionLabels)
            {
                TextUnit text;
                if (index == SelectedIndex)
                {
                    text = new TextUnit(new Sprite("gui", new EntityComponentSystem.Util.Rectangle(0, 0, 8, 8), new EntityComponentSystem.Util.Rectangle(0, 0, 8, 8)), label, Color.Coral);
                }
                else
                {
                    text = new TextUnit(label, Color.White);
                }
                text.Render(r, layer, new Point(8, destY));
                destY += 12;
                index++;
            }
        }
Beispiel #14
0
        /// <summary>
        /// Moves the range the specified number of units in the text.  Note that the text is not altered.  Instead the
        /// range spans a different part of the text.
        /// If the range is degenerate, this method tries to move the insertion point count units.  If the range is nondegenerate
        /// and count is greater than zero, this method collapses the range at its end point, moves the resulting range forward
        /// to a unit boundary (if it is not already at one), and then tries to move count - 1 units forward. If the range is
        /// nondegenerate and count is less than zero, this method collapses the range at the starting point, moves the resulting
        /// range backward to a unit boundary (if it isn't already at one), and then tries to move |count| - 1 units backward.
        /// Thus, in both cases, collapsing a nondegenerate range, whether or not moving to the start or end of the unit following
        /// the collapse, counts as a unit.
        /// </summary>
        /// <param name="unit">The textual unit for moving.</param>
        /// <param name="count">The number of units to move.  A positive count moves the range forward.
        /// A negative count moves backward. A count of 0 has no effect.</param>
        /// <returns>The number of units actually moved, which can be less than the number requested if
        /// moving the range runs into the beginning or end of the document.</returns>
        public int Move(TextUnit unit, int count)
        {
            ValidateUnitArgument(unit, "unit");
            // note: we could optimize the case of count==0 and just return 0.

            return(UiaCoreApi.TextRange_Move(_hTextRange, unit, count));
        }
        public static TextUnit GetMacro(TextUnit father, string macroName, string fileData, string macroData)
        {
            switch (macroName)
            {
            case "#if":
                return(new IfConstruction(father, fileData, macroData));

            case "#foreach":
                return(new ForeachConstruction(father, fileData, macroData));

            case "#else":
                return(new ElseConstruction(fileData));

            case "#elseif":
                return(new ElseIfConstruction(fileData, macroData));

            case "#set":
                return(new SetMacros(father, fileData, macroData));

            case "#include":
                return(new IncludeConstruction(father, fileData, macroData));

            case "#parse":
                return(new ParseConstruction(father, fileData, macroData));
            }
            throw new ArgumentException("There's no such macros in predefined macroses");
        }
Beispiel #16
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            if (!ModalActive)
            {
                return;
            }

            var layer = r.GetLayerGraphics("hi_res_overlay");

            if (Label != null)
            {
                TextUnit label = new TextUnit(Label);
                label.Render(r, layer, new Point(80 - 18, 500 - 18 - 30 - 30), 3);
            }

            TextUnit textDisplay = new TextUnit(Display);

            layer.FillRect(new System.Drawing.Rectangle(80 - 18, 500 - 18 - 30 - 7, 40 * 13 - 4, 36 - 3), Color.FromArgb(27, 27, 28));
            textDisplay.Render(r, layer, new Point(80 - 18 + 4, 500 - 18 - 30), 3);

            if (CaretBlinkingProgress <= CaretBlinkingPeriod / 2)
            {
                int caretX = 80 - 18 + new TextUnit(Display.Substring(0, CaretIndex)).GetSize(3).Width + 6;
                layer.FillRect(new System.Drawing.Rectangle(caretX, 500 - 18 - 30, 2, 24), Color.White);
            }

            foreach (GUIButton button in Pad)
            {
                button.Render(r, layer, new Vector2D(80, 500));
            }
        }
Beispiel #17
0
        /// <summary>
        /// Moves one endpoint of the range the specified number of units in the text.
        /// If the endpoint being moved crosses the other endpoint then the other endpoint
        /// is moved along too resulting in a degenerate range and ensuring the correct ordering
        /// of the endpoints. (i.e. always Start&lt;=End)
        /// </summary>
        /// <param name="endpoint">The endpoint to move.</param>
        /// <param name="unit">The textual unit for moving.</param>
        /// <param name="count">The number of units to move.  A positive count moves the endpoint forward.
        /// A negative count moves backward. A count of 0 has no effect.</param>
        /// <returns>The number of units actually moved, which can be less than the number requested if
        /// moving the endpoint runs into the beginning or end of the document.</returns>
        public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
        {
            ValidateEndpointArgument(endpoint, "endpoint");
            ValidateUnitArgument(unit, "unit");

            return(UiaCoreApi.TextRange_MoveEndpointByUnit(_hTextRange, endpoint, unit, count));
        }
Beispiel #18
0
        public static int CountTextUnit(TextUnit tu, TextPatternRange rangeToCount)
        {
            ValidateArgumentNonNull(rangeToCount, "rangeToCount argument cannot be null");  // Sanity check

            TextPatternRange clone = rangeToCount.Clone();

            int count = clone.MoveEndpointByUnit(TextPatternRangeEndpoint.Start, tu, Int32.MaxValue);

            // Provider / Text Unit specific offsets
            switch (typeOfProvider)
            {
            case "win32":
            case "winform":
            {
                // This is to correct the fact that our line count will skip the last line if it
                // DOES NOT have a trailing \r, \n or \r\n
                if (tu == TextUnit.Line)
                {
                    string            text    = rangeToCount.GetText(-1);
                    AutomationElement element = rangeToCount.GetEnclosingElement();
                    if (IsTrailingCRLF(element, text) == 0)
                    {
                        count++;
                    }
                }
            }
            break;

            case "wpf":
                break;
            }

            return(count);
        }
        public void OverloadedToString_NotSupportedCulture_ThrowsKeyNotFoundException()
        {
            TextUnit unit = new TextUnit("key", invariantCultureTexts);

            CultureInfo impossibleCultureInfo = CultureInfo.GetCultureInfo("sq"); // Albanian !

            unit.ToString(impossibleCultureInfo);
        }
 public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
 {
     try {
         return(range.MoveEndpointByUnit(endpoint, unit, count));
     } catch (Exception ex) {
         throw DbusExceptionTranslator.Translate(ex);
     }
 }
 public int Move(TextUnit unit, int count)
 {
     try {
         return(range.Move(unit, count));
     } catch (Exception ex) {
         throw DbusExceptionTranslator.Translate(ex);
     }
 }
        private object Move(object arg)
        {
            object[] args  = (object[])arg;
            TextUnit unit  = (TextUnit)args[0];
            int      count = (int)args[1];

            return(_iface.Move(unit, count));
        }
 public void ExpandToEnclosingUnit(TextUnit unit)
 {
     try {
         range.ExpandToEnclosingUnit(unit);
     } catch (Exception ex) {
         throw DbusExceptionTranslator.Translate(ex);
     }
 }
        private object ExpandToEnclosingUnit(object arg)
        {
            object[] args = (object[])arg;
            TextUnit unit = (TextUnit)args[0];

            _iface.ExpandToEnclosingUnit(unit);
            return(null);
        }
        private object MoveEndpointByUnit(object arg)
        {
            object[] args = (object[])arg;
            TextPatternRangeEndpoint endpoint = (TextPatternRangeEndpoint)args[0];
            TextUnit unit  = (TextUnit)args[1];
            int      count = (int)args[2];

            return(_iface.MoveEndpointByUnit(endpoint, unit, count));
        }
Beispiel #26
0
        public int Move(TextUnit unit, int count)
        {
            int result = MoveEndpointByUnit(
                TextPatternRangeEndpoint.Start, unit, count);

            MoveEndpointByUnit(
                TextPatternRangeEndpoint.End, unit, 1);
            return(result);
        }
Beispiel #27
0
        /// <summary>
        /// Rewrites the cloneable collection in method call.
        /// </summary>
        protected void RewriteCloneableCollectionInMethodCall()
        {
            if (this.Parent.Machine == null || this.Parent.State == null ||
                !(this.Parent.Machine.FunctionDeclarations.Any(val => val.Identifier.TextUnit.Text.
                                                               Equals(this.RewrittenStmtTokens[this.Index].TextUnit.Text))))
            {
                return;
            }

            this.Index++;
            this.SkipWhiteSpaceTokens();

            int counter = 0;

            while (this.Index < this.RewrittenStmtTokens.Count)
            {
                if (this.RewrittenStmtTokens[this.Index].Type == TokenType.LeftParenthesis)
                {
                    counter++;
                }
                else if (this.RewrittenStmtTokens[this.Index].Type == TokenType.RightParenthesis)
                {
                    counter--;
                }

                if (counter == 0)
                {
                    break;
                }

                if (this.Parent.Machine.FieldDeclarations.Any(val => val.Identifier.TextUnit.Text.Equals(
                                                                  this.RewrittenStmtTokens[this.Index].TextUnit.Text)))
                {
                    var field = this.Parent.Machine.FieldDeclarations.Find(val =>
                                                                           val.Identifier.TextUnit.Text.Equals(this.RewrittenStmtTokens[this.Index].
                                                                                                               TextUnit.Text)) as PFieldDeclaration;
                    if (field.Type.Type != PType.Tuple &&
                        field.Type.Type != PType.Seq &&
                        field.Type.Type != PType.Map)
                    {
                        return;
                    }

                    var textUnit = new TextUnit("(", this.RewrittenStmtTokens[this.Index].TextUnit.Line);
                    this.RewrittenStmtTokens.Insert(this.Index, new Token(textUnit));
                    this.Index++;

                    this.RewriteMemberIdentifier();

                    var cloneStr = ".Clone() as " + field.Type.GetRewrittenText() + ")";
                    textUnit = new TextUnit(cloneStr, this.RewrittenStmtTokens[this.Index].TextUnit.Line);
                    this.RewrittenStmtTokens.Insert(this.Index + 1, new Token(textUnit));
                }

                this.Index++;
            }
        }
        public int Move(TextUnit unit, int count)
        {
            Log("{0}.Move({1}, {2})", ID, unit, count);
            int movedCount = MoveEndpointByUnit(TextPatternRangeEndpoint.Start, unit, count);

            segment = new SimpleSegment(segment.Offset, 0);             // Collapse to empty range
            ExpandToEnclosingUnit(unit);
            return(movedCount);
        }
Beispiel #29
0
        internal static int Win32CountTextUnit(TextUnit textUnit, TextPatternRange rangeToCount)
        {
            AutomationElement element    = null;
            string            actualText = "";

            ValidateArgumentNonNull(rangeToCount, "rangeToCount argument cannot be null");  // Sanity check

            // Get text
            try
            {
                actualText = rangeToCount.GetText(-1);
                element    = rangeToCount.GetEnclosingElement();
                if (element == null)
                {
                    throw new InvalidOperationException("Null automation element incorrectly returned by TextPatternRange.GetEnclosingElement() in Win32CountTextUnit()");
                }
            }
            catch (Exception exception)
            {
                if (IsCriticalException(exception))
                {
                    throw;
                }

                throw new InvalidOperationException("Unable to call TextPatternRange.GetText() in Win32CountTextUnit()", exception);
            }

            // Count text units and assign to array element
            switch (textUnit)
            {
            case TextUnit.Character:
                return(actualText.Length);

            case TextUnit.Format:
                return(CountTextUnit(TextUnit.Format, rangeToCount));

            case TextUnit.Word:
                return(CountTextUnit(TextUnit.Word, rangeToCount));

            case TextUnit.Line:
                return(Win32CountLines(element));

            case TextUnit.Paragraph:
                return(CountParagraphs(actualText));

            case TextUnit.Page:
                return(1);

            case TextUnit.Document:
                return(1);

            default:
                throw new ArgumentException("CountTextUnits() does not support " + textUnit.ToString());
            }
        }
Beispiel #30
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            if (!ModalActive)
            {
                return;
            }
            if (Dirty)
            {
                bool negative = Display.StartsWith("-");
                if (negative)
                {
                    Display = Display.Substring(1);
                }

                if (Display.Length == 0)
                {
                    Display  = "0";
                    negative = false;
                }

                int i;
                for (i = 0; i < Display.Length; i++)
                {
                    if (Display[i] == '0' && i + 1 < Display.Length && Display[i + 1] != '.')
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                Display = (negative ? "-" : "") + Display.Substring(i);

                Dirty = false;
            }

            var layer = r.GetLayerGraphics("hi_res_overlay");

            if (Label != null)
            {
                TextUnit label = new TextUnit(Label);
                label.Render(r, layer, new Point(80 - 18, 500 - 18 - 30 - 30), 3);
            }

            TextUnit numberDisplay = new TextUnit(Display);

            layer.FillRect(new System.Drawing.Rectangle(80 - 18, 500 - 18 - 30 - 7, 40 * 3 - 4, 36 - 3), Color.FromArgb(27, 27, 28));
            numberDisplay.Render(r, layer, new Point(80 - 18 + 4, 500 - 18 - 30), 3);

            foreach (GUIButton button in Pad)
            {
                button.Render(r, layer, new Vector2D(80, 500));
            }
        }
Beispiel #31
0
        void ITextRangeProvider.ExpandToEnclosingUnit(TextUnit unit)
        {
            Misc.SetFocus(_pattern._hwnd);

            switch (unit)
            {
                case TextUnit.Format:
                    {
                        // take the minimum of expanding by character and paragraph formatting.
                        ITextRange charRange = _range.GetDuplicate();
                        charRange.Expand(TomUnit.tomCharFormat);

                        ITextRange paraRange = _range.GetDuplicate();
                        paraRange.Expand(TomUnit.tomParaFormat);

                        _range.SetRange(Math.Max(charRange.Start, paraRange.Start), Math.Min(charRange.End, paraRange.End));
                    }
                    break;

                default:
                    _range.Expand(TomUnitFromTextUnit(unit, "unit"));
                    break;
            }
        }
Beispiel #32
0
 public int Move(TextUnit unit, int count)
 {
     return 0;
 }
        int ITextRangeProvider.Move(TextUnit unit, int count)
        {
            Misc.SetFocus(_provider._hwnd);

            // positive count means move forward.  negative count means move backwards.
            int moved = 0;
            if (count > 0)
            {
                // If the range is non-degenerate then we need to collapse the range.
                // (See the discussion of Count for ITextRange::Move)
                if (!IsDegenerate)
                {
                    // If the count is greater than zero, collapse the range at its end point
                    Start = End;
                }

                // move the degenerate range forward by the number of units
                int m;
                int start = Start;
                Start = MoveEndpointForward(Start, unit, count, out m);
                // if the start did not change then no move was done.
                if (start != Start)
                {
                    moved = m;
                }
            }
            else if (count < 0)
            {
                // If the range is non-degenerate then we need to collapse the range.
                if (!IsDegenerate)
                {
                    // If the count is less than zero, collapse the range at the starting point
                    End = Start;
                }

                // move the degenerate range backward by the number of units
                int m;
                int end = End;
                End = MoveEndpointBackward(End, unit, count, out m);
                // if the end did not change then no move was done.
                if (end != End)
                {
                    moved = m;
                }
            }
            else
            {
                // moving zero of any unit has no effect.
                moved = 0;
            }

            return moved;
        }
 public int Move(TextUnit unit, int count)
 {
     Log("{0}.Move({1}, {2})", ID, unit, count);
     int movedCount = MoveEndpointByUnit(TextPatternRangeEndpoint.Start, unit, count);
     segment = new SimpleSegment(segment.Offset, 0); // Collapse to empty range
     ExpandToEnclosingUnit(unit);
     return movedCount;
 }
Beispiel #35
0
 //-------------------------------------------------------------------
 // Identify supported TextUnits in Win32
 //-------------------------------------------------------------------
 internal static TextUnit win32_IdentifySupportedTextUnits(AutomationElement element, TextUnit targetUnit)
 {
     return TextLibraryCount.win32_IdentifySupportedTextUnits(element, targetUnit);
 }
Beispiel #36
0
 /// -------------------------------------------------------------------
 /// <summary>
 /// Count a single TextUnit
 /// </summary>
 /// -------------------------------------------------------------------
 internal static int Win32CountTextUnit(TextUnit textUnit, TextPatternRange rangeToCount)
 {
     return Win32CountTextUnit(textUnit, rangeToCount);
 }
Beispiel #37
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="unit">TextUnit</param>
 /// <param name="type">TokenType</param>
 public Token(TextUnit unit, TokenType type)
 {
     this.TextUnit = unit;
     this.Text = unit.Text;
     this.Type = type;
 }
Beispiel #38
0
        /// <summary>
        /// Moves one endpoint of the range the specified number of units in the text.
        /// If the endpoint being moved crosses the other endpoint then the other endpoint
        /// is moved along too resulting in a degenerate range and ensuring the correct ordering
        /// of the endpoints. (i.e. always Start&lt;=End)
        /// </summary>
        /// <param name="endpoint">The endpoint to move.</param>
        /// <param name="unit">The textual unit for moving.</param>
        /// <param name="count">The number of units to move.  A positive count moves the endpoint forward.  
        /// A negative count moves backward. A count of 0 has no effect.</param>
        /// <returns>The number of units actually moved, which can be less than the number requested if 
        /// moving the endpoint runs into the beginning or end of the document.</returns>
        int ITextRangeProvider.MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
        {
            Normalize();

            int movedCount = 0;
            if (count != 0)
            {
                // Move endpoint by number of units.
                bool start = (endpoint == TextPatternRangeEndpoint.Start);
                ITextPointer positionRef = start ? _start : _end;
                ITextPointer position = positionRef.CreatePointer();
                if (MoveToUnitBoundary(position, start, count < 0 ? LogicalDirection.Backward : LogicalDirection.Forward, unit))
                {
                    movedCount = (count > 0) ? 1 : -1;
                }
                if (count != movedCount)
                {
                    movedCount += MovePositionByUnits(position, unit, count - movedCount);
                }

                // If endpoint has been moved at least by one unit, snap it to TextUnit boundary,
                // because movement done by MovePositionByUnits does not guarantee position snapping.
                if ((count > 0 && position.CompareTo(positionRef) > 0) || 
                    (count < 0 && position.CompareTo(positionRef) < 0) ||
                    (position.CompareTo(positionRef) == 0 && position.LogicalDirection != positionRef.LogicalDirection))
                {
                    if (start)
                    {
                        _start = position;
                    }
                    else
                    {
                        _end = position;
                    }
                    if (unit != TextUnit.Page)
                    {
                        ExpandToEnclosingUnit(unit, start, !start);
                    }
                    // If endpoint has been moved, but 'movedCount' is 0, it means that we snapped to neariest
                    // unit boundary. Treat this situation as actual move.
                    if (movedCount == 0)
                    {
                        movedCount = (count > 0) ? 1 : -1;
                    }
                }
                // Ensure the correct ordering of the endpoint.
                if (_start.CompareTo(_end) > 0)
                {
                    if (start)
                    {
                        _end = _start.CreatePointer();
                    }
                    else
                    {
                        _start = _end.CreatePointer();
                    }
                }
            }
            return movedCount;
        }
Beispiel #39
0
 public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
 {
     return 0;
 }
Beispiel #40
0
        /// <summary>
        /// Moves the position to the closes unit boundary.
        /// </summary>
        private bool MoveToUnitBoundary(ITextPointer position, bool isStart, LogicalDirection direction, TextUnit unit)
        {
            bool moved = false;
            ITextView textView;
            switch (unit)
            {
                case TextUnit.Character:
                    if (!TextPointerBase.IsAtInsertionPosition(position))
                    {
                        if (TextPointerBase.MoveToNextInsertionPosition(position, direction))
                        {
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Word:
                    if (!IsAtWordBoundary(position))
                    {
                        if (MoveToNextWordBoundary(position, direction))
                        {
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Format:
                    // Formatting changes can be introduced by elements. Hence it is fair to 
                    // assume that formatting boundaries are defined by non-text context.
                    while (position.GetPointerContext(direction) == TextPointerContext.Text)
                    {
                        if (position.MoveToNextContextPosition(direction))
                        {
                            moved = true;
                        }
                    }
                    // Make sure we end with text on the right, so that later ExpandToEnclosingUnit calls
                    // do the right thing.
                    if (moved && direction == LogicalDirection.Forward)
                    {
                        while (true)
                        {
                            TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward);

                            if (context != TextPointerContext.ElementStart && context != TextPointerContext.ElementEnd)
                                break;

                            position.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                    break;

                case TextUnit.Line:
                    // Positions are snapped to closest line boundaries. But since line information
                    // is based on the layout, positions are not changed, if:
                    // a) they are not currently in the view, or
                    // b) containing line cannot be found.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        TextSegment lineRange = textView.GetLineRange(position);
                        if (!lineRange.IsNull)
                        {
                            double newSuggestedX;
                            int linesMoved = 0;

                            if (direction == LogicalDirection.Forward)
                            {
                                ITextPointer nextLineStart = null;

                                if (isStart)
                                {
                                    nextLineStart = textView.GetPositionAtNextLine(lineRange.End, Double.NaN, 1, out newSuggestedX, out linesMoved);
                                }

                                if (linesMoved != 0)
                                {
                                    lineRange = textView.GetLineRange(nextLineStart);
                                    nextLineStart = lineRange.Start;
                                }
                                else
                                {
                                    nextLineStart = lineRange.End;
                                }
                                nextLineStart = GetInsertionPosition(nextLineStart, LogicalDirection.Forward);

                                if (position.CompareTo(nextLineStart) != 0)
                                {
                                    position.MoveToPosition(nextLineStart);
                                    position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                                    moved = true;
                                }
                            }
                            else
                            {
                                ITextPointer previousLineEnd = null;

                                if (!isStart)
                                {
                                    previousLineEnd = textView.GetPositionAtNextLine(lineRange.Start, Double.NaN, -1, out newSuggestedX, out linesMoved);
                                }

                                if (linesMoved != 0)
                                {
                                    lineRange = textView.GetLineRange(previousLineEnd);
                                    previousLineEnd = lineRange.End;
                                }
                                else
                                {
                                    previousLineEnd = lineRange.Start;
                                }
                                previousLineEnd = GetInsertionPosition(previousLineEnd, LogicalDirection.Backward);

                                if (position.CompareTo(previousLineEnd) != 0)
                                {
                                    position.MoveToPosition(previousLineEnd);
                                    position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    // Utilize TextRange logic to determine paragraph boundaries.
                    ITextRange textRange = new TextRange(position, position);
                    TextRangeBase.SelectParagraph(textRange, position);

                    if (direction == LogicalDirection.Forward)
                    {
                        ITextPointer nextParagraphStart = textRange.End;

                        if (isStart)
                        {
                            nextParagraphStart = nextParagraphStart.CreatePointer();
                            if (nextParagraphStart.MoveToNextInsertionPosition(LogicalDirection.Forward))
                            {
                                TextRangeBase.SelectParagraph(textRange, nextParagraphStart);
                                nextParagraphStart = textRange.Start;
                            }
                        }

                        if (position.CompareTo(nextParagraphStart) != 0)
                        {
                            position.MoveToPosition(nextParagraphStart);
                            position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                            moved = true;
                        }
                    }
                    else
                    {
                        ITextPointer previousParagraphEnd = textRange.Start;

                        if (!isStart)
                        {
                            previousParagraphEnd = previousParagraphEnd.CreatePointer();
                            if (previousParagraphEnd.MoveToNextInsertionPosition(LogicalDirection.Backward))
                            {
                                TextRangeBase.SelectParagraph(textRange, previousParagraphEnd);
                                previousParagraphEnd = textRange.End;
                            }
                        }

                        if (position.CompareTo(previousParagraphEnd) != 0)
                        {
                            position.MoveToPosition(previousParagraphEnd);
                            position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Page:
                    // Positions are snapped to nearest page boundaries. But since page information
                    // is based on the layout, positions are not changed, if they are not currently in the view.
                    // We need to consider 2 types of scenarios: single page and multi-page.
                    // In case of multi-page scenario, first need to find a page associated with the position.
                    // If page is found, move the start position to the beginning of the first range of that page
                    // and move the end position to the end of the last range of that page.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        ITextView pageTextView = textView;
                        if (textView is MultiPageTextView)
                        {
                            // This is "multi page" case. Find page associated with the start position.
                            pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position);
                        }
                        ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;

                        if (textSegments != null && textSegments.Count > 0)
                        {
                            //When comparing, we need to take into account if the pointer is not right at 
                            //the end of the page (or beginning) because of normalization
                            
                            if (direction == LogicalDirection.Forward)
                            {
                                while (position.CompareTo(textSegments[textSegments.Count - 1].End) != 0)
                                {
                                    if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.ElementEnd)
                                    {
                                        position.MoveToPosition(textSegments[textSegments.Count - 1].End);
                                        moved = true;
                                        break;
                                    }
                                    Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Forward));
                                }
                                MoveToInsertionPosition(position, LogicalDirection.Forward);
                            }
                            else
                            {
                                while (position.CompareTo(textSegments[0].Start) != 0)
                                {
                                    if (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.ElementStart)
                                    {
                                        position.MoveToPosition(textSegments[0].Start);
                                        moved = true;
                                        break;
                                    }
                                    Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Backward));
                                }
                                MoveToInsertionPosition(position, LogicalDirection.Backward);
                                
                            }
                        }
                    }
                    break;

                case TextUnit.Document:
                    if (direction == LogicalDirection.Forward)
                    {
                        if (position.CompareTo(GetInsertionPosition(position.TextContainer.End, LogicalDirection.Backward)) != 0)
                        {
                            position.MoveToPosition(position.TextContainer.End);
                            moved = true;
                        }
                    }
                    else
                    {
                        if (position.CompareTo(GetInsertionPosition(position.TextContainer.Start, LogicalDirection.Forward)) != 0)
                        {
                            position.MoveToPosition(position.TextContainer.Start);
                            moved = true;
                        }
                    }
                    break;

                default:
                    // Unknown unit
                    break;
            }
            return moved;
        }
Beispiel #41
0
        /// <summary>
        /// Re-positions the given position by an integral number of text units, but it does
        /// not guarantee that position is snapped to TextUnit boundary.
        /// This method assumes that input position is already snapped to appropriate TextUnit boundary.
        /// </summary>
        /// <param name="position">The position to move</param>
        /// <param name="unit">Text units to step by</param>
        /// <param name="count">Number of units to step over. Also specifies the direction of moving: 
        /// forward if positive, backward otherwise</param>
        /// <returns>The actual number of units the position was moved over</returns>
        private int MovePositionByUnits(ITextPointer position, TextUnit unit, int count)
        {
            ITextView textView;
            int moved = 0;
            int absCount = (count == int.MinValue) ? int.MaxValue : Math.Abs(count);
            LogicalDirection direction = (count > 0) ? LogicalDirection.Forward : LogicalDirection.Backward;

            // This method assumes that position is already snapped to appropriate TextUnit.

            switch (unit)
            {
                case TextUnit.Character:
                    while (moved < absCount)
                    {
                        if (!TextPointerBase.MoveToNextInsertionPosition(position, direction))
                        {
                            break;
                        }
                        moved++;
                    }
                    break;

                case TextUnit.Word:
                    while (moved < absCount)
                    {
                        if (!MoveToNextWordBoundary(position, direction))
                        {
                            break;
                        }
                        moved++;
                    }
                    break;

                case TextUnit.Format:
                    // Formatting changes can be introduced by elements. Hence it is fair to 
                    // assume that formatting boundaries are defined by non-text context.
                    while (moved < absCount)
                    {
                        ITextPointer positionOrig = position.CreatePointer();

                        // First skip all text in given direction.
                        while (position.GetPointerContext(direction) == TextPointerContext.Text)
                        {
                            if (!position.MoveToNextContextPosition(direction))
                            {
                                break;
                            }
                        }
                        // Move to next context
                        if (!position.MoveToNextContextPosition(direction))
                        {
                            break;
                        }
                        // Skip all formatting elements and position the pointer next to text.
                        while (position.GetPointerContext(direction) != TextPointerContext.Text)
                        {
                            if (!position.MoveToNextContextPosition(direction))
                            {
                                break;
                            }
                        }
                        // If moving backwards, position the pointer at the beginning of formatting range.
                        if (direction == LogicalDirection.Backward)
                        {
                            while (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text)
                            {
                                if (!position.MoveToNextContextPosition(LogicalDirection.Backward))
                                {
                                    break;
                                }
                            }
                        }
                        if (position.GetPointerContext(direction) != TextPointerContext.None)
                        {
                            moved++;
                        }
                        else
                        {
                            position.MoveToPosition(positionOrig);
                            break;
                        }
                    }

                    // Adjust logical direction to point to the following text (forward or backward movement).
                    // If we don't do this, we'll normalize in the wrong direction and get stuck in a loop
                    // if caller tries to advance again.
                    position.SetLogicalDirection(LogicalDirection.Forward);

                    break;

                case TextUnit.Line:
                    // Position is snapped to nearest line boundary. But since line information
                    // is based on the layout, position is not changed, if:
                    // a) it is not currently in the view, or
                    // b) containing line cannot be found.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        // ITextPointer.MoveToLineBoundary can't handle Table row end positions.
                        // Mimic TextEditor's caret navigation code and move into the preceding
                        // TableCell.
                        if (TextPointerBase.IsAtRowEnd(position))
                        {
                            position.MoveToNextInsertionPosition(LogicalDirection.Backward);
                        }

                        moved = position.MoveToLineBoundary(count);
                        
                        MoveToInsertionPosition(position, LogicalDirection.Forward);

                        if (moved < 0)
                        {
                            moved = -moved; // Will be reversed below.
                        }
                    }
                    break; 

                case TextUnit.Paragraph:
                    // Utilize TextRange logic to determine paragraph boundaries.
                    ITextRange paragraphRange = new TextRange(position, position);
                    paragraphRange.SelectParagraph(position);
                    while (moved < absCount)
                    {
                        position.MoveToPosition(direction == LogicalDirection.Forward ? paragraphRange.End : paragraphRange.Start);
                        if (!position.MoveToNextInsertionPosition(direction))
                        {
                            break;
                        }
                        moved++;
                        paragraphRange.SelectParagraph(position);
                        position.MoveToPosition(paragraphRange.Start); // Position it always at the beginning of the paragraph.
                    }
                    break;

                case TextUnit.Page:
                    // But since page information is based on the layout, position is not changed, if:
                    // a) it is not currently in the view, or
                    // b) containing page cannot be found.
                    // Page movement is possible only in multi-page scenario.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        if (textView is MultiPageTextView)
                        {
                            // Get embedded page ITextView for given position.
                            ITextView pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position);
                            ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;
                            while (moved < absCount)
                            {
                                if (textSegments == null || textSegments.Count == 0)
                                {
                                    break;
                                }
                                // Move the position to appropriate edge.
                                if (direction == LogicalDirection.Backward)
                                {
                                    position.MoveToPosition(textSegments[0].Start);
                                    MoveToInsertionPosition(position, LogicalDirection.Backward);
                                }
                                else
                                {
                                    position.MoveToPosition(textSegments[textSegments.Count - 1].End);
                                    MoveToInsertionPosition(position, LogicalDirection.Forward);
                                }
                                // Try to move the position to the next page.
                                ITextPointer positionTemp = position.CreatePointer();
                                if (!positionTemp.MoveToNextInsertionPosition(direction))
                                {
                                    break;
                                }
                                else
                                {
                                    // MoveToNextInsertionPosition may return 'true' and move the position
                                    // in oposite direction.
                                    if (direction == LogicalDirection.Forward)
                                    {
                                        if (positionTemp.CompareTo(position) <= 0)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (positionTemp.CompareTo(position) >= 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                                // Get embedded page ITextView for given position.
                                if (!textView.Contains(positionTemp))
                                {
                                    break;
                                }
                                pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(positionTemp);
                                textSegments = pageTextView.TextSegments;
                                moved++;
                            }
                        }
                    }
                    break;

                case TextUnit.Document:
                    // This method assumes that position is already snapped to appropriate TextUnit.
                    break;
            }

            return (direction == LogicalDirection.Forward) ? moved : -moved;
        }
Beispiel #42
0
 public void ExpandToEnclosingUnit(TextUnit unit)
 {
     try
     {
         this._range.ExpandToEnclosingUnit((UIAutomationClient.TextUnit)unit);
     }
     catch (System.Runtime.InteropServices.COMException e)
     {
         Exception newEx; if (Utility.ConvertException(e, out newEx)) { throw newEx; } else { throw; }
     }
 }
        int ITextRangeProvider.MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
        {
            Misc.SetFocus(_provider._hwnd);

            // positive count means move forward.  negative count means move backwards.
            int moved = 0;
            bool moveStart = endpoint == TextPatternRangeEndpoint.Start;
            int start = Start;
            int end = End;
            if (count > 0)
            {
                if (moveStart)
                {
                    Start = MoveEndpointForward(Start, unit, count, out moved);

                    // if the start did not change then no move was done.
                    if (start == Start)
                    {
                        moved = 0;
                    }
                }
                else
                {
                    End = MoveEndpointForward(End, unit, count, out moved);

                    // if the end did not change then no move was done.
                    if (end == End)
                    {
                        moved = 0;
                    }
                }
            }
            else if (count < 0)
            {
                if (moveStart)
                {
                    Start = MoveEndpointBackward(Start, unit, count, out moved);

                    // if the start did not change then no move was done.
                    if (start == Start)
                    {
                        moved = 0;
                    }
                }
                else
                {
                    End = MoveEndpointBackward(End, unit, count, out moved);

                    // if the end did not change then no move was done.
                    if (end == End)
                    {
                        moved = 0;
                    }
                }
            }
            else
            {
                // moving zero of any unit has no effect.
                moved = 0;
            }

            return moved;
        }
        // moves an endpoint forward a certain number of units.
        // the endpoint is just an index into the text so it could represent either
        // the endpoint.
        private int MoveEndpointForward(int index, TextUnit unit, int count, out int moved)
        {
            switch (unit)
            {
                case TextUnit.Character:
                    {
                        int limit = _provider.GetTextLength() ;
                        ValidateEndpoints();

                        moved = Math.Min(count, limit - index);
                        index = index + moved;

                        index = index > limit ? limit : index;
                    }
                    break;

                case TextUnit.Word:
                    {
                        string text = _provider.GetText();
                        ValidateEndpoints();

#if WCP_NLS_ENABLED
                    // use the same word breaker as Avalon Text.
                    WordBreaker breaker = new WordBreaker();
                    TextContainer container = new TextContainer(text);
                    TextNavigator navigator = new TextNavigator(index, container);

                    // move forward one word break for each count
                    for (moved = 0; moved < count && index < text.Length; moved++)
                    {
                        if (!breaker.MoveToNextWordBreak(navigator))
                            break;
                    }

                    index = navigator.Position;
#else
                        for (moved = 0; moved < count && index < text.Length; moved++)
                        {
                            for (index++; !AtWordBoundary(text, index); index++) ;
                        }
#endif
                    }
                    break;

                case TextUnit.Line:
                    {
                        // figure out what line we are on.  if we are in the middle of a line and
                        // are moving left then we'll round up to the next line so that we move
                        // to the beginning of the current line.
                        int line = _provider.LineFromChar(index);

                        // limit the number of lines moved to the number of lines available to move
                        // Note lineMax is always >= 1.
                        int lineMax = _provider.GetLineCount();
                        moved = Math.Min(count, lineMax - line - 1);

                        if (moved > 0)
                        {
                            // move the endpoint to the beginning of the destination line.
                            index = _provider.LineIndex(line + moved);
                        }
                        else if (moved == 0 && lineMax == 1)
                        {
                            // There is only one line so get the text length as endpoint
                            index = _provider.GetTextLength();
                            moved = 1;
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    {
                        // just like moving words but we look for paragraph boundaries instead of 
                        // word boundaries.
                        string text = _provider.GetText();
                        ValidateEndpoints();

                        for (moved = 0; moved < count && index < text.Length; moved++)
                        {
                            for (index++; !AtParagraphBoundary(text, index); index++) ;
                        }
                    }
                    break;

                case TextUnit.Format:
                case TextUnit.Page:
                case TextUnit.Document:
                    {
                        // since edit controls are plain text moving one uniform format unit will
                        // take us all the way to the end of the document, just like
                        // "pages" and document.
                        int limit = _provider.GetTextLength();
                        ValidateEndpoints();

                        // we'll move 1 format unit if we aren't already at the end of the
                        // document.  Otherwise, we won't move at all.
                        moved = index < limit ? 1 : 0;
                        index = limit;
                    }
                    break;

                default:
                    throw new System.ComponentModel.InvalidEnumArgumentException("unit", (int)unit, typeof(TextUnit));
            }

            return index;
        }
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        /// <param name="parentNode">Node</param>
        internal void Visit(StateDeclaration parentNode)
        {
            if (parentNode.Machine.IsMonitor)
            {
                throw new ParsingException("Monitors cannot \"defer\".",
                    new List<TokenType>());
            }

            base.TokenStream.Index++;
            base.TokenStream.SkipWhiteSpaceAndCommentTokens();

            var nameVisitor = new NameVisitor(base.TokenStream);

            // Consumes multiple generic event names.
            var eventIdentifiers =
                nameVisitor.ConsumeMultipleNames(TokenType.EventIdentifier,
                tt => nameVisitor.ConsumeGenericEventName(tt));

            var resolvedEventIdentifiers = new Dictionary<Token, List<Token>>();
            foreach (var eventIdentifier in eventIdentifiers)
            {
                if (eventIdentifier.Count == 1)
                {
                    // We don't want to collapse halt and default
                    // events to event identifiers.
                    resolvedEventIdentifiers.Add(eventIdentifier[0], eventIdentifier);
                }
                else
                {
                    var identifierBuilder = new StringBuilder();
                    foreach (var token in eventIdentifier)
                    {
                        identifierBuilder.Append(token.TextUnit.Text);
                    }

                    TextUnit textUnit = new TextUnit(identifierBuilder.ToString(),
                        eventIdentifier[0].TextUnit.Line);
                    resolvedEventIdentifiers.Add(new Token(textUnit, TokenType.EventIdentifier),
                        eventIdentifier);
                }
            }

            foreach (var kvp in resolvedEventIdentifiers)
            {
                if (!parentNode.AddDeferredEvent(kvp.Key, kvp.Value))
                {
                    throw new ParsingException("Unexpected defer declaration.",
                        new List<TokenType>());
                }
            }

            if (!base.TokenStream.Done &&
                base.TokenStream.Peek().Type == TokenType.Identifier)
            {
                throw new ParsingException("Expected \",\".",
                    new List<TokenType>
                {
                    TokenType.Comma
                });
            }

            if (!base.TokenStream.Done &&
                (base.TokenStream.Peek().Type == TokenType.LeftAngleBracket ||
                base.TokenStream.Peek().Type == TokenType.RightAngleBracket))
            {
                throw new ParsingException("Invalid generic expression.",
                    new List<TokenType> { });
            }

            if (base.TokenStream.Done ||
                base.TokenStream.Peek().Type != TokenType.Semicolon)
            {
                throw new ParsingException("Expected \";\".",
                    new List<TokenType>
                {
                    TokenType.Semicolon
                });
            }
        }
Beispiel #46
0
        /// <summary>
        /// Expands the range to an integral number of enclosing units.  If the range is already an
        /// integral number of the specified units then it remains unchanged.
        /// </summary>
        private void ExpandToEnclosingUnit(TextUnit unit, bool expandStart, bool expandEnd)
        {
            ITextView textView;
            switch (unit)
            {
                case TextUnit.Character:
                    if (expandStart && !TextPointerBase.IsAtInsertionPosition(_start))
                    {
                        TextPointerBase.MoveToNextInsertionPosition(_start, LogicalDirection.Backward);
                    }
                    if (expandEnd && !TextPointerBase.IsAtInsertionPosition(_end))
                    {
                        TextPointerBase.MoveToNextInsertionPosition(_end, LogicalDirection.Forward);
                    }
                    break;

                case TextUnit.Word:
                    if (expandStart && !IsAtWordBoundary(_start))
                    {
                        MoveToNextWordBoundary(_start, LogicalDirection.Backward);
                    }
                    if (expandEnd && !IsAtWordBoundary(_end))
                    {
                        MoveToNextWordBoundary(_end, LogicalDirection.Forward);
                    }
                    break;

                case TextUnit.Format:
                    // Formatting changes can be introduced by elements. Hence it is fair to 
                    // assume that formatting boundaries are defined by non-text context.

                    if (expandStart)
                    {
                        TextPointerContext forwardContext = _start.GetPointerContext(LogicalDirection.Forward);
                        while (true)
                        {
                            TextPointerContext backwardContext = _start.GetPointerContext(LogicalDirection.Backward);

                            if (backwardContext == TextPointerContext.None)
                                break;
                            if (forwardContext == TextPointerContext.Text && backwardContext != TextPointerContext.Text)
                                break;

                            forwardContext = backwardContext;
                            _start.MoveToNextContextPosition(LogicalDirection.Backward);
                        }
                    }

                    if (expandEnd)
                    {
                        TextPointerContext backwardContext = _end.GetPointerContext(LogicalDirection.Backward);
                        while (true)
                        {
                            TextPointerContext forwardContext = _end.GetPointerContext(LogicalDirection.Forward);

                            if (forwardContext == TextPointerContext.None)
                                break;
                            if (forwardContext == TextPointerContext.Text && backwardContext != TextPointerContext.Text)
                                break;

                            backwardContext = forwardContext;
                            _end.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }

                    // Set LogicalDirection to prevent end points from crossing a formatting
                    // boundary when normalized.
                    _start.SetLogicalDirection(LogicalDirection.Forward);
                    _end.SetLogicalDirection(LogicalDirection.Forward);
                    break;

                case TextUnit.Line:
                    // Positions are snapped to closest line boundaries. But since line information
                    // is based on the layout, positions are not changed, if:
                    // a) they are not currently in the view, or
                    // b) containing line cannot be found.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid)
                    {
                        bool snapEndPosition = true;
                        if (expandStart && textView.Contains(_start))
                        {
                            TextSegment lineRange = textView.GetLineRange(_start);
                            if (!lineRange.IsNull)
                            {
                                // Move start position to the beginning of containing line.
                                if (_start.CompareTo(lineRange.Start) != 0)
                                {
                                    _start = lineRange.Start.CreatePointer();
                                }
                                // If this line contains also end position, move it to the
                                // end of this line.
                                if (lineRange.Contains(_end))
                                {
                                    snapEndPosition = false;
                                    if (_end.CompareTo(lineRange.End) != 0)
                                    {
                                        _end = lineRange.End.CreatePointer();
                                    }
                                }
                            }
                        }
                        if (expandEnd && snapEndPosition && textView.Contains(_end))
                        {
                            TextSegment lineRange = textView.GetLineRange(_end);
                            if (!lineRange.IsNull)
                            {
                                // Move end position to the end of containing line.
                                if (_end.CompareTo(lineRange.End) != 0)
                                {
                                    _end = lineRange.End.CreatePointer();
                                }
                            }
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    // Utilize TextRange logic to determine paragraph boundaries.
                    ITextRange textRange = new TextRange(_start, _end);
                    TextRangeBase.SelectParagraph(textRange, _start);
                    if (expandStart && _start.CompareTo(textRange.Start) != 0)
                    {
                        _start = textRange.Start.CreatePointer();
                    }
                    if (expandEnd)
                    {
                        if (!textRange.Contains(_end))
                        {
                            TextRangeBase.SelectParagraph(textRange, _end);
                        }
                        if (_end.CompareTo(textRange.End) != 0)
                        {
                            _end = textRange.End.CreatePointer();
                        }
                    }
                    break;

                case TextUnit.Page:
                    // Positions are snapped to nearest page boundaries. But since page information
                    // is based on the layout, positions are not changed, if they are not currently in the view.
                    // We need to consider 2 types of scenarios: single page and multi-page.
                    // In case of multi-page scenario, first need to find a page associated with the position.
                    // If page is found, move the start position to the beginning of the first range of that page
                    // and move the end position to the end of the last range of that page.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid)
                    {
                        if (expandStart && textView.Contains(_start))
                        {
                            ITextView pageTextView = textView;
                            if (textView is MultiPageTextView)
                            {
                                // This is "multi page" case. Find page associated with the start position.
                                pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(_start);
                            }
                            ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;
                            if (textSegments != null && textSegments.Count > 0)
                            {
                                if (_start.CompareTo(textSegments[0].Start) != 0)
                                {
                                    _start = textSegments[0].Start.CreatePointer();
                                }
                            }
                        }
                        if (expandEnd && textView.Contains(_end))
                        {
                            ITextView pageTextView = textView;
                            if (textView is MultiPageTextView)
                            {
                                // This is "multi page" case. Find page associated with the start position.
                                pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(_end);
                            }
                            ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;
                            if (textSegments != null && textSegments.Count > 0)
                            {
                                if (_end.CompareTo(textSegments[textSegments.Count - 1].End) != 0)
                                {
                                    _end = textSegments[textSegments.Count - 1].End.CreatePointer();
                                }
                            }
                        }
                    }
                    break;

                case TextUnit.Document:
                    if (expandStart && _start.CompareTo(_start.TextContainer.Start) != 0)
                    {
                        _start = _start.TextContainer.Start.CreatePointer();
                    }
                    if (expandEnd && _end.CompareTo(_start.TextContainer.End) != 0)
                    {
                        _end = _start.TextContainer.End.CreatePointer();
                    }
                    break;

                default:
                    // Unknown unit
                    break;
            }
        }
Beispiel #47
0
		public void ExpandToEnclosingUnit (TextUnit unit)
		{
			int newStartOffset, newEndOffset;
			int dummy;
			switch (unit) {
			case TextUnit.Format:
				text.GetAttributeRun (startOffset, out newStartOffset, out newEndOffset, false);
				break;
			case TextUnit.Word:
				WordNormalize ();
				return;
			case TextUnit.Paragraph:
				ParagraphNormalize ();
				return;
			case TextUnit.Page:
				// Not currently supported; treat as Document
			case TextUnit.Document:
				StartOffset = 0;
				EndOffset = text.CharacterCount;
				return;
			default:
				text.GetTextAtOffset (startOffset,
					GetAtkBoundaryType (unit, false),
					out newStartOffset,
					out dummy);
				text.GetTextAtOffset (endOffset - 1,
					GetAtkBoundaryType (unit, false),
					out dummy,
					out newEndOffset);
				break;
			}
			if (newStartOffset < startOffset)
				StartOffset = newStartOffset;
			if (newEndOffset > endOffset)
				EndOffset = newEndOffset;
		}
Beispiel #48
0
		public int Move (TextUnit unit, int count)
		{
			int result = MoveEndpointByUnit (
				TextPatternRangeEndpoint.Start, unit, count);
			MoveEndpointByUnit (
				TextPatternRangeEndpoint.End, unit, 1);
			return result;
		}
Beispiel #49
0
 /// <summary>
 /// Constructor. By default the type of the token is None.
 /// </summary>
 /// <param name="unit">TextUnit</param>
 public Token(TextUnit unit)
 {
     this.TextUnit = unit;
     this.Text = unit.Text;
     this.Type = TokenType.None;
 }
Beispiel #50
0
		public int MoveEndpointByUnit (TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
		{
			if (count == 0)
				return 0;
			switch (unit) {
			case TextUnit.Format:
				Log.Debug ("AtspiUiaSource: Moving by unit "
					+ unit + " not supported.");
				return 0;
			case TextUnit.Word:
				if (endpoint == TextPatternRangeEndpoint.Start)
					return WordMoveStartPoint (count);
				else
					return WordMoveEndPoint (count);
			case TextUnit.Page:
			case TextUnit.Document:
				if (endpoint == TextPatternRangeEndpoint.Start) {
					if (count < 0) {
						if (startOffset <= 0)
							return 0;
						StartOffset = 0;
						return -1;
					} else {
						int characterCount = text.CharacterCount;
						if (startOffset >= characterCount)
							return 0;
						StartOffset = characterCount;
						return 1;
					}
				} else {
					if (count < 0) {
						if (endOffset <= 0)
							return 0;
						EndOffset = 0;
						return -1;
					} else {
						int characterCount = text.CharacterCount;
						if (endOffset >= characterCount)
							return 0;
						EndOffset = characterCount;
						return 1;
					}
				}
			case TextUnit.Paragraph:
				if (endpoint == TextPatternRangeEndpoint.Start)
					return ParagraphMoveStartPoint (count);
				else
					return ParagraphMoveEndPoint (count);
			default:
				int offset = (endpoint == TextPatternRangeEndpoint.Start
					? startOffset
					: endOffset - 1);
				int newStartOffset = offset;
				int newEndOffset = offset;
				int ret = 0;
				BoundaryType boundary = GetAtkBoundaryType (unit, count > 0);
				while (count != 0) {
					int oldStartOffset = newStartOffset;
					int oldEndOffset = newEndOffset;
					if (count < 0) {
						text.GetTextBeforeOffset (oldStartOffset, boundary, out newStartOffset, out newEndOffset);
						if (newStartOffset == oldStartOffset &&
							newEndOffset == oldEndOffset)
							break;
						count++;
						ret--;
					} else {
						text.GetTextAfterOffset (oldStartOffset, boundary, out newStartOffset, out newEndOffset);
						if (newStartOffset == oldStartOffset &&
							newEndOffset == oldEndOffset)
							break;
						count--;
						ret++;
					}
				}
				if (endpoint == TextPatternRangeEndpoint.Start)
					StartOffset = newStartOffset;
				else
					EndOffset = newEndOffset;
				return ret;
			}
		}
Beispiel #51
0
 public static int CountTextUnit(TextUnit tu, TextPatternRange rangeToCount)
 {
     return TextLibraryCount.CountTextUnit(tu, rangeToCount);
 }
Beispiel #52
0
		private BoundaryType GetAtkBoundaryType (TextUnit unit, bool end)
		{
			switch (unit) {
			case TextUnit.Character:
				return BoundaryType.Char;
			case TextUnit.Word:
				return (end?
					BoundaryType.WordEnd:
					BoundaryType.WordStart);
			case TextUnit.Line:
				return (end?
					BoundaryType.LineEnd:
					BoundaryType.LineStart);
			default:
				throw new Exception ("GetAtkBoundaryType called with unsupported TextUnit " + unit);
			}
		}
Beispiel #53
0
 /// -------------------------------------------------------------------
 /// <summary>
 /// Identifies supported text units. Some units will map upwards
 /// TextUnit.Page, for example, maps up to a Document for all 
 /// controls/providers except Word/Office
 /// </summary>
 /// -------------------------------------------------------------------
 public static void IdentifySupportedTextUnits(AutomationElement element, ref TextUnit[] supportedTextUnits)
 {
     TextLibraryCount.IdentifySupportedTextUnits(element, ref supportedTextUnits);
 }
            public SummarizationInformationContainer()
            {
                TextUnit = new TextUnit
                {
                    RawValue = TextUnitText,
                    FormattedValue = TextUnitText,
                    Stem = TextUnitText
                };

                ScoredTextUnits = new List<TextUnitScore>
                {
                    new TextUnitScore {Score = 15, ScoredTextUnit = TextUnit},
                    new TextUnitScore {Score = 30, ScoredTextUnit = TextUnit}
                };

                Sentence = new Sentence
                {
                    OriginalSentence = SentenceText,
                    OriginalSentenceIndex = 0,
                    TextUnits = new List<TextUnit>
                    {
                        TextUnit
                    }
                };

                ScoredSentences = new List<SentenceScore>
                {
                    new SentenceScore {Score = 10, ScoredSentence = Sentence},
                    new SentenceScore {Score = 20, ScoredSentence = Sentence}
                };
            }
 public void ExpandToEnclosingUnit(TextUnit unit)
 {
     Log("{0}.ExpandToEnclosingUnit({1})", ID, unit);
     switch (unit) {
         case TextUnit.Character:
             ExpandToEnclosingUnit(CaretPositioningMode.Normal);
             break;
         case TextUnit.Format:
         case TextUnit.Word:
             ExpandToEnclosingUnit(CaretPositioningMode.WordStartOrSymbol);
             break;
         case TextUnit.Line:
         case TextUnit.Paragraph:
             segment = doc.GetLineByOffset(segment.Offset);
             break;
         case TextUnit.Document:
             segment = new AnchorSegment(doc, 0, doc.TextLength);
             break;
     }
 }
Beispiel #56
0
        public void ExpandToEnclosingUnit(TextUnit unit)
        {

        }
 public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
 {
     Log("{0}.MoveEndpointByUnit({1}, {2}, {3})", ID, endpoint, unit, count);
     int offset = GetEndpoint(endpoint);
     switch (unit) {
         case TextUnit.Character:
             offset = MoveOffset(offset, CaretPositioningMode.Normal, count);
             break;
         case TextUnit.Format:
         case TextUnit.Word:
             offset = MoveOffset(offset, CaretPositioningMode.WordStart, count);
             break;
         case TextUnit.Line:
         case TextUnit.Paragraph:
             int line = doc.GetLineByOffset(offset).LineNumber;
             int newLine = Math.Max(1, Math.Min(doc.LineCount, line + count));
             offset = doc.GetLineByNumber(newLine).Offset;
             break;
         case TextUnit.Document:
             offset = count < 0 ? 0 : doc.TextLength;
             break;
     }
     SetEndpoint(endpoint, offset);
     return count;
 }
Beispiel #58
0
 public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
 {
     try
     {
         return this._range.MoveEndpointByUnit(
             (UIAutomationClient.TextPatternRangeEndpoint)endpoint,
             (UIAutomationClient.TextUnit)unit,
             count);
     }
     catch (System.Runtime.InteropServices.COMException e)
     {
         Exception newEx; if (Utility.ConvertException(e, out newEx)) { throw newEx; } else { throw; }
     }
 }
        void ITextRangeProvider.ExpandToEnclosingUnit(TextUnit unit)
        {
            Misc.SetFocus(_provider._hwnd);

            switch (unit)
            {
                case TextUnit.Character:
                    // if it is a degenerate range then expand it to be one character.
                    // otherwise, leave it as it is.
                    if (Start == End)
                    {
                        int moved;
                        End = MoveEndpointForward(End, TextUnit.Character, 1, out moved);
                    }
                    break;

                case TextUnit.Word:
                    {
                        // this works same as paragraph except we look for word boundaries instead of paragraph boundaries.

                        // get the text so we can figure out where the boundaries are
                        string text = _provider.GetText();
                        ValidateEndpoints();

#if WCP_NLS_ENABLED
                        // use the same word breaker that Avalon Text uses.
                        WordBreaker breaker = new WordBreaker();
                        TextContainer container = new TextContainer(text);
                        // if the starting point of the range is not already at a word break
                        // then move it backwards to the nearest word break.
                        TextNavigator startNavigator = new TextNavigator(Start, container);
                        if (!breaker.IsAtWordBreak(startNavigator))
                        {
                            breaker.MoveToPreviousWordBreak(startNavigator);
                            Start = startNavigator.Position;
                        }

                        // if the range is degenerate or the ending point of the range is not already at a word break 
                        // then move it forwards to the nearest word break.
                        TextNavigator endNavigator = new TextNavigator(End, container);
                        if (Start==End || !breaker.IsAtWordBreak(endNavigator))
                        {
                            breaker.MoveToNextWordBreak(endNavigator);
                            End = endNavigator.Position;
                        }
#else
                        // move start left until we reach a word boundary.
                        for (; !AtWordBoundary(text, Start); Start--) ;

                        // move end right until we reach word boundary (different from Start).
                        End = Math.Min(Math.Max(End, Start + 1), text.Length);
                        for (; !AtWordBoundary(text, End); End++) ;
#endif
                    }
                    break;

                case TextUnit.Line:
                    {
                        if (_provider.GetLineCount() != 1)
                        {
                            int startLine = _provider.LineFromChar(Start);
                            int endLine = _provider.LineFromChar(End);

                            MoveTo(_provider.LineIndex(startLine), _provider.LineIndex(endLine + 1));
                        }
                        else
                        {
                            MoveTo(0, _provider.GetTextLength());
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    { 
                        // this works same as paragraph except we look for word boundaries instead of paragraph boundaries.

                        // get the text so we can figure out where the boundaries are
                        string text = _provider.GetText();
                        ValidateEndpoints();

                        // move start left until we reach a paragraph boundary.
                        for (; !AtParagraphBoundary(text, Start); Start--);

                        // move end right until we reach a paragraph boundary (different from Start).
                        End = Math.Min(Math.Max(End, Start + 1), text.Length);
                        for (; !AtParagraphBoundary(text, End); End++);
                    } 
                    break;

                case TextUnit.Format:
                case TextUnit.Page:
                case TextUnit.Document:
                    MoveTo(0, _provider.GetTextLength());
                    break;

                //break;
                default:
                    throw new System.ComponentModel.InvalidEnumArgumentException("unit", (int)unit, typeof(TextUnit));
            }
        }
        // moves an endpoint backward a certain number of units.
        // the endpoint is just an index into the text so it could represent either
        // the endpoint.
        private int MoveEndpointBackward(int index, TextUnit unit, int count, out int moved)
        {
            switch (unit)
            {
                case TextUnit.Character:
                    {
                        int limit = _provider.GetTextLength();
                        ValidateEndpoints();

                        int oneBasedIndex = index + 1;

                        moved = Math.Max(count, -oneBasedIndex);
                        index = index + moved;

                        index = index < 0 ? 0 : index;
                    }
                    break;

                case TextUnit.Word:
                    {
                        string text = _provider.GetText();
                        ValidateEndpoints();

#if WCP_NLS_ENABLED
                    // use the same word breaker as Avalon Text.
                    WordBreaker breaker = new WordBreaker();
                    TextContainer container = new TextContainer(text);
                    TextNavigator navigator = new TextNavigator(index, container);

                    // move backward one word break for each count
                    for (moved = 0; moved > count && index > 0; moved--)
                    {
                        if (!breaker.MoveToPreviousWordBreak(navigator))
                            break;
                    }

                    index = navigator.Position;
#else
                        for (moved = 0; moved > count && index > 0; moved--)
                        {
                            for (index--; !AtWordBoundary(text, index); index--) ;
                        }
#endif
                    }
                    break;

                case TextUnit.Line:
                    {
                        // Note count < 0.

                        // Get 1-based line.
                        int line = _provider.LineFromChar(index) + 1;

                        int lineMax = _provider.GetLineCount();

                        // Truncate the count to the number of available lines.
                        int actualCount = Math.Max(count, -line);

                        moved = actualCount;

                        if (actualCount == -line)
                        {
                            // We are moving by the maximum number of possible lines,
                            // so we know the resulting index will be 0.
                            index = 0;

                            // If a line other than the first consists of only "\r\n",
                            // you can move backwards past this line and the position changes,
                            // hence this is counted.  The first line is special, though:
                            // if it is empty, and you move say from the second line back up
                            // to the first, you cannot move further; however if the first line
                            // is nonempty, you can move from the end of the first line to its
                            // beginning!  This latter move is counted, but if the first line
                            // is empty, it is not counted.

                            // Recalculate the value of "moved".
                            // The first line is empty if it consists only of
                            // a line separator sequence.
                            bool firstLineEmpty =
                                ((lineMax > 1 && _provider.LineIndex(1) == _lineSeparator.Length)
                                    || lineMax == 0);
                                
                            if (moved < 0 && firstLineEmpty)
                            {
                                ++moved;
                            }
                        }
                        else // actualCount > -line
                        {
                            // Move the endpoint to the beginning of the following line,
                            // then back by the line separator length to get to the end
                            // of the previous line, since the Edit control has
                            // no method to get the character index of the end
                            // of a line directly.
                            index = _provider.LineIndex(line + actualCount) - _lineSeparator.Length;
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    {
                        // just like moving words but we look for paragraph boundaries instead of 
                        // word boundaries.
                        string text = _provider.GetText();
                        ValidateEndpoints();

                        for (moved = 0; moved > count && index > 0; moved--)
                        {
                            for (index--; !AtParagraphBoundary(text, index); index--) ;
                        }
                    }
                    break;

                case TextUnit.Format:
                case TextUnit.Page:
                case TextUnit.Document:
                    {
                        // since edit controls are plain text moving one uniform format unit will
                        // take us all the way to the beginning of the document, just like
                        // "pages" and document.

                        // we'll move 1 format unit if we aren't already at the beginning of the
                        // document.  Otherwise, we won't move at all.
                        moved = index > 0 ? -1 : 0;
                        index = 0;
                    }
                    break;

                default:
                    throw new System.ComponentModel.InvalidEnumArgumentException("unit", (int)unit, typeof(TextUnit));
            }

            return index;
        }