Beispiel #1
0
        /// <summary>
        /// Converts the gPath to a path of typed tokens
        /// </summary>
        /// <returns>A path of typed tokens</returns>
        public string toString()
        {
            string path = m_type + ":" + m_name;

            if (m_varId != null && m_varId != "")
            {
                path += "[" + m_varId + "=" + m_Nth + "]";
            }
            else
            {
                path += "[" + m_Nth + "]";
            }
            if (m_child != null)
            {
                path += @"/" + m_child.toString();
            }
            return(path);
        }
		/// <summary>
		/// The search is almost breadth-first:
		/// The first step in the path has an unknown sibling index and its role is not 'value'.
		/// If this ah has children of the step type, they are searched until all the
		/// subsequent steps find matching ah's. This search substitutes its own visitor
		/// that records the successful path ah's. Upon success, a sibling index is assigned to
		/// the variable named in the step, the non-terminal subpath ah's are exposed
		/// to the caller's visitor in turn and this method returns the last ah on the path.
		/// Subpath steps are searched for depending on their content.
		/// </summary>
		/// <param name="path">The path to search. Each step in the path contains an
		/// Accessibility name and Accessibility role of the matching gui object.</param>
		/// <param name="visitor">null or the object providing methods that are called when steps are found.</param>
		/// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched
		/// window.</returns>
		private AccessibilityHelper SearchPathForIndex(GuiPath path, IPathVisitor visitor)
		{
			Log log = Log.getOnly();
			log.writeElt("head");
			log.writeElt("SearchPathForIndex");
			log.writeAttr("from", this.Role + ":" + this.Name);
			log.writeAttr("to", path.toString());
			log.endElt();
			if (ChildCount <= 0)
			{
				if (visitor != null) visitor.notFound(path);
				return null;
			}
			AccessibilityHelper ah = null;
			int nnum = 0;
			int index = 0;
			string parentName = null;
			if (path.Prev != null) parentName = path.Prev.Name;
			foreach (AccessibilityHelper child in this)
			{
				if (child == null) continue;
				log.writeElt("SearchPathForIndex");
				log.writeAttr("child", (++nnum));
				log.writeAttr("path", ah.Role + ":" + ah.Name);
				// not supposed to be a value!
				if (path.Next != null && path.Next.Role == AccessibleRole.Alert)
					log.writeAttr("bad-value", ah.Value);
				log.endElt();
				if (MatchNameAndRole(path.Name, path.Role, child))
				{ // this is a candidate for matching the path
					++index; // the first one is 1
					if (path.Next != null)
					{  // This method won't allow for caller's visitors on candidate nodes until proved needed
						TrackingVisitor tv = new TrackingVisitor(); // tv may need to open sub menus
						if (tv != null) tv.visitNode(child); // add child to node list to visit later if this is the right path
						ah = ValueOrChild(path.Next, child, tv);
						if (ah != null)
						{   // the subpath was matched to the end
							if (path.VarId != null && path.VarId != "")
							{  // Create and execute a variable to record the index
					//			Var var = new Var();
					//			var.Id = path.VarId;
					//			var.Set = System.Convert.ToString(index); // 1 based count
					//			var.Execute(); // puts the var in the TestState hash
								// don't set path.Nth = index since it might change if the path is used again
							}
							// let the caller's visitor tend to all the path ah's
							if (visitor != null)
							{
								if (tv != null) tv.StepDownPath(visitor);
							}
							log.endElt(); // end head element
							return ah;
						}
					}
				}
				else if (parentName != null && child.Role == AccessibleRole.Client && child.Name == parentName)
				{ // try the client instead
					ah = child.SearchPathForIndex(path, visitor);
					if (ah != null)
					{
						log.endElt(); // end head element
						return ah; // found it
					}
				}
			}
			if (visitor != null) visitor.notFound(path);
			log.endElt(); // end head element
			return null;
		}
		/// <summary>
		/// Searches the path depth-first.
		/// Nth is not used - if it were, it could get a sibling, ancestor or child.
		/// </summary>
		/// <param name="path">The path to search. Each step in the path contains an
		/// Accessibility name and Accessibility role of the matching gui object.</param>
		/// <param name="visitor">null or the object providing methods that are called when steps are found.</param>
		/// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched
		/// window.</returns>
		private AccessibilityHelper SearchPathByDepth(GuiPath path, IPathVisitor visitor)
		{
			Log log = Log.getOnly();
			log.writeElt("SearchPathByDepth");
			log.writeAttr("from", this.Role + ":" + this.Name);
			log.writeAttr("to", path.toString());
			log.endElt();

			if (ChildCount <= 0)
			{
				if (visitor != null) visitor.notFound(path);
				return null;
			}
			AccessibilityHelper ah = null;
			// try the client first if there is one, but don't visit it
			AccessibilityHelper client = FindClient();
			if (client != null) ah = client.SearchPathByDepth(path, visitor);
			if (ah != null)
			{
				log.endElt(); // end head element
				return ah;
			}

			// Rats!! It wasn't below the client, the caller wants some system widget or something
			foreach (AccessibilityHelper child in this)
			{
				if (child == null || child.Equals(client))
					continue;
				// does this object match?
				// treat name == "" and child.Name == null as a match
				// Note: a null string shows as "" in the debugger!
				log.writeElt("head");
				log.writeElt("SearchPathByDepth");
				log.writeAttr("path", path.toString());
				log.writeAttr("child", child.Role + ":" + child.Name);
				log.endElt();
				if (MatchNameAndRole(path.Name, path.Role, child))
				{
					if (path.Next != null)
					{
						if (visitor != null) visitor.visitNode(child); // allow processing of this ah by caller
						log.endElt(); // end head element
						return ValueOrChild(path.Next, child, visitor);
					}
				}
				// if not a "real" object, a child takes on it's parent's
				// attributes, so it appears to have the same # of children.
				// The first child is always the first child, so you get
				// infinite recursion on it if you don't check "realness".
				if (child.m_fRealAccessibleObject && child.ChildCount > 0)
				{
					// look through the child objects
					ah = child.SearchPathByDepth(path, visitor);
					if (ah != null)
					{
						if (path.Next != null)
						{
							if (visitor != null) visitor.visitNode(ah); // allow processing of this ah by caller
							log.endElt(); // end head element
							return ValueOrChild(path.Next, ah, visitor);
						}
						log.endElt(); // end head element
						return ah;
					}
				}
			}
			if (visitor != null) visitor.notFound(path);
			log.endElt(); // end head element
			return null;
		}
		/// <summary>
		/// The search is almost breadth-first:
		/// The first step in the path is searched breath-first.
		/// Subsequent path steps are searched for depending on their content.
		/// The Accessibility helper representing the step is returned it is found and is the last step.
		/// Otherwise, the search continues with the next path step or if not found, null is returned.
		/// If the first step is found, the visitor is applied before continuing to the next step.
		/// </summary>
		/// <param name="path">The path to search. Each step in the path contains an
		/// Accessibility name and Accessibility role of the matching gui object.</param>
		/// <param name="visitor">null or the object providing methods that are called when steps are found.</param>
		/// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched
		/// window.</returns>
		private AccessibilityHelper SearchPathByBreadth(GuiPath path, IPathVisitor visitor)
		{
			if (ChildCount <= 0 || path.Nth <= 0)
			{
				if (visitor != null) visitor.notFound(path);
				return null;
			}
			int place = path.Nth;
			Log log = Log.getOnly();
			log.writeElt("SearchPathByBreadth");
			log.writeAttr("from", this.Role + ":" + this.Name);
			log.writeAttr("to", path.toString());
			log.endElt();
			ArrayList lists = new ArrayList(); // list of child lists
			ArrayList nodes = MakeChildList(this);
			lists.Add(nodes);
			// Examine the first node in the list, dropping it after examination
			// and adding its children to the end if prudent.
			log.writeElt("head");
			int lnum = 0;
			while (lists.Count > 0)
			{
				int count = 0; // reset match count
				nodes = (ArrayList)lists[0];
				int nnum = 0; ++lnum;
				while (nodes.Count > 0)
				{
					AccessibilityHelper ah = (AccessibilityHelper)nodes[0];
					log.writeElt("SearchPathByBreadth");
					log.writeAttr("child", lnum + ":" + (++nnum));
					log.writeAttr("path", ah.Role + ":" + ah.Name);
					if (path.Next != null && path.Next.Role == AccessibleRole.Alert)
						log.writeAttr("value", ah.Value);
					log.endElt();

					if (MatchNameAndRole(path.Name, path.Role, ah))
					{ // this is the only way to return
						if (++count >= place)
						{ // Found this step, keep stepping along the path
							if (path.Next != null)
							{
								if (visitor != null) visitor.visitNode(ah); // allow processing of this ah by caller
								ah = ValueOrChild(path.Next, ah, visitor);
							}
							log.endElt(); // end head element
							return ah;
						}
					}
					if (ah.m_fRealAccessibleObject && ah.ChildCount > 0)
						lists.Add(MakeChildList(ah));
					nodes.RemoveAt(0); // when 0 is removed, all indices slide down 1
				}
				lists.RemoveAt(0); // when 0 is removed, all indices slide down 1
			}
			if (visitor != null) visitor.notFound(path);
			log.endElt(); // end head element
			return null;
		}