private OoShapeObserver searchRegisteredShapeByAccessible(String accName, XAccessible acc) { List <String> names = new List <String>(); foreach (KeyValuePair <String, OoShapeObserver> shapeKeyValuePair in shapes) { OoShapeObserver _so = shapeKeyValuePair.Value; if (_so != null && !_so.Disposed) { if (_so.AcccessibleCounterpart != null) { if (_so.AcccessibleCounterpart.Equals(acc)) { return(_so); } } else { if (AccCorrespondsToShapeObserver(acc, _so)) { return(_so); } } } } return(null); }
/// <summary> /// Registers a new draw window. /// </summary> /// <param name="source">The source.</param> /// <param name="dw">The dw.</param> private void registerNewDrawWindow(XAccessible source, Object dw) { if (source != null && dw != null && !dw.Equals(false)) { Logger.Instance.Log(LogPriority.DEBUG, this, "Draw window check: '" + OoAccessibility.GetAccessibleName(source)); if (getCorrespondingAccessibleDocForXaccessible(source) == null) { Logger.Instance.Log(LogPriority.DEBUG, this, "Register new Draw window: '" + OoAccessibility.GetAccessibleName(source)); OoAccessibleDocWnd doc = new OoAccessibleDocWnd(source, dw as XAccessible); drawWnds[source] = doc; // add main window to list if (doc.Document != null) { drawDocs[source] = doc; } if (doc.DocumentWindow != null) { drawDocWnds[doc.DocumentWindow] = doc; } //drawPgSuppl.Clear(); //drawPgSuppl.AddRange(OoDrawUtils.GetDrawPageSuppliers(OO.GetDesktop())); //TODO: call the observers addListeners(doc); fireDrawWindowOpendEvent(doc); } } }
void addNewShape(XAccessible acc) { if (acc != null) { foreach (var item in DrawPageobservers) { item.Value.Update(); } } }
/// <summary> /// find the corresponding accessible counterpart object for this page in the accessible tree /// </summary> private void setAccessibleCounterpart() { String name = OoUtils.GetStringProperty(DrawPage, "LinkDisplayName"); name = "PageShape: " + name; //TODO: find a more general way XAccessible accCounter = OoAccessibility.GetAccessibleChildWithName(name, PagesObserver.Document.AccComp as unoidl.com.sun.star.accessibility.XAccessibleContext); if (accCounter != null) { AcccessibleCounterpart = accCounter; } }
/// <summary> /// try to gets the corresponding accessible doc for XAccessible. /// </summary> /// <param name="key">The key.</param> /// <returns></returns> private OoAccessibleDocWnd getCorrespondingAccessibleDocForXaccessible(XAccessible key) { OoAccessibleDocWnd doc = null; if (key != null) { if (!drawDocs.TryGetValue(key, out doc) || doc == null) { if (!drawWnds.TryGetValue(key, out doc) || doc == null) { drawDocWnds.TryGetValue(key, out doc); } } } return(doc); }
/// <summary> /// Returns the Accessible child that is rendered under the given point. /// The test point's coordinates are defined relative to the coordinate system /// of the object. That means that when the object is an opaque rectangle then /// both the points (0,0) and (with-1,height-1) would yield a true value. /// </summary> /// <param name="p"> /// Coordinates of the test point for which to find the Accessible child. The /// origin of the coordinate system is the upper left corner of the object's /// bounding box as returned by the getBounds. The scale of the coordinate /// system is identical to that of the screen coordinate system. /// </param> /// <returns> /// If there is one child which is rendered so that its bounding box contains /// the test point then a reference to that object is returned. If there is /// more than one child which satisfies that condition then a reference to /// that one is returned that is painted on top of the others. If no there /// is no child which is rendered at the test point an empty reference is /// returned. /// </returns> public XAccessible GetAccessibleFromPoint(System.Drawing.Point p) { XAccessible result = null; if (this.AccComp != null) { TimeLimitExecutor.WaitForExecuteWithTimeLimit(500, () => { try { result = this.AccComp.getAccessibleAtPoint(new unoidl.com.sun.star.awt.Point(p.X, p.Y)); } catch { } }, "GetAccessibleATPoint"); } return(result); }
internal void UpdateObserverLists(OoShapeObserver obs) { String name = obs.Name; XShape shape = obs.Shape; XAccessible acc = obs.AcccessibleCounterpart; XAccessibleContext cont = acc != null?acc.getAccessibleContext() : null; //TODO: maybe do this softer?! try { shapes[name] = obs; } catch (Exception) { } if (cont != null) { try { accshapes[cont] = obs; } catch (Exception) { } } else { // search for a relation? } try { domshapes[shape] = obs; } catch (Exception) { } }
/// <summary> /// Gets the accessible role of the XAccessible obj if possible. /// </summary> /// <param name="obj">The obj.</param> /// <returns>AccessibleRole or AccessibleRole.UNKNOWN</returns> public static AccessibleRole GetAccessibleRole(XAccessible obj) { AccessibleRole r = AccessibleRole.UNKNOWN; if (obj != null) { TimeLimitExecutor.WaitForExecuteWithTimeLimit(400, () => { try { r = GetAccessibleRole(obj.getAccessibleContext()); } catch (unoidl.com.sun.star.lang.DisposedException) { r = AccessibleRole.DISPOSED; } catch (ThreadAbortException) { } catch (ThreadInterruptedException) { } catch { r = AccessibleRole.INVALID; } }, ""); } return AccessibleRole.UNKNOWN; }
/// <summary> /// Check if the accessible object is corresponding to the given shape observer. /// </summary> /// <param name="acc">The accessible object to test.</param> /// <param name="sObs">The shape observer to test.</param> /// <returns><c>true</c> if the acc is related to changes in the observer. If this is true, /// the AccessibleCounterpart field of the OoShapeObserver is updated as well</returns> internal static bool AccCorrespondsToShapeObserver(XAccessible acc, OoShapeObserver sObs) { bool result = false; if (acc != null && sObs != null) { String hash = sObs.GetHashCode().ToString() + "_"; if (sObs.IsText) { // use description string oldDescription = sObs.Description; sObs.Description = hash + oldDescription; if (OoAccessibility.GetAccessibleDesc(acc).StartsWith(hash)) { result = true; } sObs.Description = oldDescription; } else { // use name string oldName = sObs.Name; sObs.Name = hash + oldName; if (OoAccessibility.GetAccessibleName(acc).StartsWith(hash)) { result = true; } sObs.Name = oldName; } } if (result) { sObs.AcccessibleCounterpart = acc; } return(result); }
/// <summary> /// Gets the name of the accessible child with. /// </summary> /// <param name="name">The name.</param> /// <param name="haystack">The haystack.</param> /// <returns>The first found XAccessible with a partly equal name or NULL</returns> public static XAccessible GetAccessibleChildWithName(String name, XAccessible haystack) { if (haystack != null && !String.IsNullOrWhiteSpace(name)) { if (haystack is XAccessibleContext) return GetAccessibleChildWithName(name, haystack as XAccessibleContext); else return GetAccessibleChildWithName(name, haystack.getAccessibleContext()); } return null; }
/// <summary> /// Try to gets all selected child elements. /// </summary> /// <param name="parent">The parent.</param> /// <returns>A list of elements that have the AccessibleStateType.SELECTED = 23</returns> public static List<XAccessible> GetSelectedChildObjects(XAccessible parent) { List<XAccessible> selections = new List<XAccessible>(); if (parent != null) { XAccessibleContext context = parent.getAccessibleContext(); if (context != null) { if (HasAccessibleState(parent, AccessibleStateType.SELECTED)) { selections.Add(parent); //TODO: check type (context or XAccessible) } else { if (context.getAccessibleChildCount() > 0) { for (int i = 0; i < context.getAccessibleChildCount(); i++) { selections.AddRange(GetSelectedChildObjects(context.getAccessibleChild(i))); } } } } } return selections; }
/// <summary> /// Determines whether the the specified element contains accessible state (Must not be right!!). /// </summary> /// <param name="obj">The element to test.</param> /// <param name="state">The AccessibleStateType to test for.</param> /// <returns> /// <c>true</c> if [contains accessible state]; otherwise, <c>false</c>. /// </returns> public static bool ContainsAccessibleState(XAccessible obj, AccessibleStateType state) { if (obj != null) { XAccessibleContext context = obj.getAccessibleContext(); if (context != null) { var states = context.getAccessibleStateSet(); if (states != null) { return states.contains((short)state); ; } } } return false; }
/// <summary> /// Try to gets the root pane parent from the element. /// </summary> /// <param name="element">The element.</param> /// <returns>the XAccessible parent with role <c>AccessibleRole.ROOT_PANE</c> or <c>null</c></returns> public static XAccessible GetRootPaneFromElement(XAccessible element) { //XAccessible root = null; if (element != null) { XAccessibleContext cnt = element.getAccessibleContext(); XAccessible parent = cnt.getAccessibleParent(); int trys = 0; while (cnt != null && parent != null && !element.Equals(parent) ) { // only for debug var role = GetAccessibleRole(cnt); if (!role.Equals(AccessibleRole.UNKNOWN)) { trys = 0; element = parent; if (element != null) cnt = element.getAccessibleContext(); else cnt = null; var role2 = GetAccessibleRole(cnt); if (role2.Equals(AccessibleRole.ROOT_PANE)) { return element; } } else { if (++trys > 5) break; Thread.Sleep(100); } } Logger.Instance.Log(LogPriority.DEBUG, "OoAccessibility", "Can't get root pane - loop break"); } return null; }
/// <summary> /// Determines whether [has accessible state] [the specified obj]. /// </summary> /// <param name="obj">The obj.</param> /// <param name="state">The state.</param> /// <returns> /// <c>true</c> if [has accessible state] [the specified obj]; otherwise, <c>false</c>. /// </returns> public static bool HasAccessibleState(XAccessible obj, AccessibleStateType state) { if (obj != null) { try { XAccessibleContext context = obj.getAccessibleContext(); if (context != null) { var states = context.getAccessibleStateSet(); if (states != null) { bool contains = states.contains((short)state); if (contains) { short[] stateArray = states.getStates(); bool exists = Array.Exists(stateArray, delegate(short s) { return s.Equals((short)state); } ); contains = exists; } return contains; } } } catch (DisposedException) { } } return false; }
/// <summary> /// Determines whether the window [is a draw element]. /// </summary> /// <param name="obj">The obj.</param> /// <returns>False or the DOCUMENT</returns> public static object IsDrawWindowParentPart(XAccessible obj) { if (obj != null) { //check if object is com.sun.star.drawing.AccessibleDrawDocumentView if (OoUtils.ElementSupportsService(obj, OO.Services.DRAWING_ACCESSIBLE_DOC)) { return obj; } // cannot have any children windows if (!(obj is XVclContainer)) return false; AccessibleRole role = AccessibleRole.UNKNOWN; XAccessibleContext cont = obj is XAccessibleContext ? obj as XAccessibleContext : obj.getAccessibleContext(); // if you cannot obtain the context than the other stuff // will run into trouble - so break! if (cont == null) return false; //// try to check for drawing window by comparing children with existing drawing controller windows //try //{ // // get libre office desktop // unoidl.com.sun.star.frame.XDesktop desktop = OO.GetDesktop(OO.GetMultiComponentFactory(OO.GetContext()), OO.GetContext()); // if (desktop != null) // { // // iterate desktop components // unoidl.com.sun.star.container.XEnumeration desktopComponentsEnumeration = desktop.getComponents().createEnumeration(); // while (desktopComponentsEnumeration.hasMoreElements()) // { // object comp = desktopComponentsEnumeration.nextElement().Value; // if (comp != null && comp is XDrawPagesSupplier) // { // XDrawPagesSupplier drawPageSuppliesModel = (XDrawPagesSupplier)comp; // // check only desktop components that is are drawPagesSuppliers (these are models too) // if (drawPageSuppliesModel != null && OoUtils.ElementSupportsService(drawPageSuppliesModel, "com.sun.star.drawing.DrawingDocument") && drawPageSuppliesModel is unoidl.com.sun.star.frame.XModel) // { // // get the draw page components controller and check if its supporting the Service DrawingDocumentDrawView // unoidl.com.sun.star.frame.XController currentController = ((unoidl.com.sun.star.frame.XModel)drawPageSuppliesModel).getCurrentController(); // if (currentController != null && OoUtils.ElementSupportsService(currentController, "com.sun.star.drawing.DrawingDocumentDrawView")) // { // // get the component window // XWindow currentControllerComponentWindow = (XWindow)currentController.getFrame().getComponentWindow(); // // get its rectangle // Rectangle currentRect = (Rectangle)currentControllerComponentWindow.getPosSize(); // // search sources children for visible children if one matches the rectangle which indicates a match // if (obj is XVclContainer) // { // XWindow[] sourceChildWindows = ((XVclContainer)obj).getWindows(); // foreach (XWindow sourceChildWindow in sourceChildWindows) // { // Rectangle sourceChildRect = (Rectangle)sourceChildWindow.getPosSize(); // System.Diagnostics.Debug.WriteLine("Source Child Rect: " + sourceChildRect.X + ", " + sourceChildRect.Y + " " + sourceChildRect.Width + " x " + sourceChildRect.Height); // if (((XWindow2)sourceChildWindow).isVisible() && // ((XWindow2)currentControllerComponentWindow).isVisible() && // ((XWindow2)sourceChildWindow).hasFocus() == ((XWindow2)currentControllerComponentWindow).hasFocus() && // sourceChildRect.X == currentRect.X && // sourceChildRect.Y == currentRect.Y && // sourceChildRect.Width == currentRect.Width && // sourceChildRect.Height == currentRect.Height // ) // { // //System.Diagnostics.Debug.WriteLine("match rects"); // //return currentController; // } // } // } // } // } // } // } // } //} //catch (Exception ex) //{ //} int ccount = 0; try { // fast check to search further or stop // if top window and the accessible name ends with a "- OpenOffice Draw" if (obj is XWindow2 && ((XWindow2)obj).isVisible()) { ccount = cont.getAccessibleChildCount(); // don't go to deep -- if the element has no children // then it is not the document or a valid container for a document if (ccount < 1) return false; } else { return false; } // stop if obj is not a window or is invisible if (denieObjectBecauseOfServiceCheck(cont)) return false; int trys = 0; while (role == AccessibleRole.UNKNOWN && (trys++ <= 2)) { if (trys > 1) Thread.Sleep(5 * trys); role = GetAccessibleRole(cont); } // if role is a surrounding container type, search for the draw doc children if (role.Equals(AccessibleRole.PANEL) || role.Equals(AccessibleRole.SCROLL_PANE) || role.Equals(AccessibleRole.ROOT_PANE) || role.Equals(AccessibleRole.SPLIT_PANE) || role.Equals(AccessibleRole.STATUS_BAR) || role.Equals(AccessibleRole.UNKNOWN) // FIXME: see this as a bad hack - remove this if possible ) { if (cont != null) { for (int i = 0; i < ccount; i++) { try { XAccessible child = cont.getAccessibleChild(i); if (child != null) { Object result = IsDrawWindowParentPart(child); if (!(result is bool)) { return result; } else continue; } } catch { return false; } } } } } catch { } } return false; }
/// <summary> /// Gets all children and sub children under the accessible object. /// </summary> /// <param name="parent">The parent.</param> /// <returns>list of all available accessible children and sub children under this node</returns> public static List<XAccessible> GetAllChildrenOfAccessibleObject(XAccessible parent) { List<XAccessible> children = new List<XAccessible>(); if (parent != null) { XAccessibleContext context = parent.getAccessibleContext(); if (context != null) { if (context.getAccessibleChildCount() > 0) { for (int i = 0; i < context.getAccessibleChildCount(); i++) { try { var child = context.getAccessibleChild(i); if (child != null) { children.Add(child); children.AddRange(GetAllChildrenOfAccessibleObject(child)); } } catch (Exception ex) { Logger.Instance.Log(LogPriority.DEBUG, "can't get all childen from XAccessible", ex); } } } } } return children; }
/// <summary> /// Try to get the parent page. /// </summary> /// <param name="acc">The acc.</param> /// <returns></returns> public static XAccessible GetParentPage(XAccessible acc) { if (acc != null) { XAccessibleContext accCont = acc.getAccessibleContext(); if (accCont != null) { AccessibleRole role = GetAccessibleRole(accCont); if (role == AccessibleRole.PAGE) return accCont as XAccessible; else if ( role == AccessibleRole.WINDOW || role == AccessibleRole.DOCUMENT || role == AccessibleRole.ROOT_PANE || role == AccessibleRole.MENU_BAR ) return null; else { XAccessible parent = GetParent(acc); if (parent != null && !parent.Equals(acc) && !parent.Equals(accCont)) { return GetParentPage(parent); } } } } return null; }
/// <summary> /// Check if the accessible object is corresponding to the given shape observer. /// </summary> /// <param name="acc">The accessible object to test.</param> /// <param name="sObs">The shape observer to test.</param> /// <returns><c>true</c> if the acc is related to changes in the observer. If this is true, /// the AccessibleCounterpart field of the OoShapeObserver is updated as well</returns> internal static bool AccCorrespondsToShapeObserver(XAccessible acc, OoShapeObserver sObs) { bool result = false; if (acc != null && sObs != null) { String hash = sObs.GetHashCode().ToString() + "_"; if (sObs.IsText) { // use description string oldDescription = sObs.Description; sObs.Description = hash + oldDescription; if (OoAccessibility.GetAccessibleDesc(acc).StartsWith(hash)) { result = true; } sObs.Description = oldDescription; } else { // use name string oldName = sObs.Name; sObs.Name = hash + oldName; if (OoAccessibility.GetAccessibleName(acc).StartsWith(hash)) { result = true; } sObs.Name = oldName; } } if (result) { sObs.AcccessibleCounterpart = acc; } return result; }
private OoShapeObserver searchRegisteredShapeByAccessible(String accName, XAccessible acc) { List<String> names = new List<String>(); foreach (KeyValuePair<String, OoShapeObserver> shapeKeyValuePair in shapes) { OoShapeObserver _so = shapeKeyValuePair.Value; if(_so != null && !_so.Disposed) { if (_so.AcccessibleCounterpart != null) { if (_so.AcccessibleCounterpart.Equals(acc)) { return _so; } } else { if (AccCorrespondsToShapeObserver(acc, _so)) { return _so; } } } } return null; }
/// <summary> /// try to gets the corresponding accessible doc for XAccessible. /// </summary> /// <param name="key">The key.</param> /// <returns></returns> private OoAccessibleDocWnd getCorrespondingAccessibleDocForXaccessible(XAccessible key) { OoAccessibleDocWnd doc = null; if (key != null) { if (!drawDocs.TryGetValue(key, out doc) || doc == null) { if (!drawWnds.TryGetValue(key, out doc) || doc == null) { drawDocWnds.TryGetValue(key, out doc); } } } return doc; }
private void setDocumentAndDocumentWindow(XAccessible doc) { if (doc == null) { doc = OoAccessibility.IsDrawWindow(MainWindow) as XAccessible; } if (doc != null && doc is XAccessibleContext) { var par = ((XAccessibleContext)doc).getAccessibleParent(); while (par != null && !(par is XWindow2)) { ((XAccessibleContext)par).getAccessibleParent(); } DocumentWindow = par as XAccessible; } else { DocumentWindow = null; } //Document Window Events addWindowListeners(DocumentWindow); //Document Events addDocumentListeners(Document); }
/// <summary> /// Initializes a new instance of the <see cref="OoAccessibleDocWnd"/> struct. /// </summary> /// <param name="mainWnd">The main window (top Window).</param> /// <param name="doc">The DOCUMENT (role) object.</param> public OoAccessibleDocWnd(XAccessible mainWnd, XAccessible doc) { registerToEventForwarder(); DrawPageSupplier = null; Whnd = IntPtr.Zero; MainWindow = mainWnd; Document = doc; setDocumentAndDocumentWindow(doc); if (MainWindow != null) { Whnd = OoUtils.GetWindowHandle(MainWindow as XSystemDependentWindowPeer); } // Main Window Events addWindowListeners(MainWindow); Task t = new Task( () => { int trys = 0; while (!getXDrawPageSupplier() && ++trys < 10) { Thread.Sleep(1000); } //addSelectionListener(DrawPageSupplier); } ); t.Start(); }
/// <summary> /// Returns the parent of the element. /// </summary> /// <param name="element">The element.</param> /// <returns>The parent XAccessible or <c>null</c></returns> public static XAccessible GetParent(XAccessible element) { if (element != null) { XAccessibleContext cont = element.getAccessibleContext(); if (cont != null) { XAccessible parent = cont.getAccessibleParent(); if (!parent.Equals(element)) return element; } } return null; }
/// <summary> /// Gets the accessible description. /// </summary> /// <param name="obj">The obj.</param> /// <returns></returns> public static String GetAccessibleDesc(XAccessible obj) { return obj != null ? GetAccessibleDesc(obj.getAccessibleContext()) : String.Empty; }
/// <summary> /// Determines whether the window [is a draw element]. /// This function works only for determining if the main window of the DRAW application is sent to this function e.g. through a top window event. /// If you want to check if any other element could bee the parent of an DRAW document us the <see cref="IsDrawWindowParentPart"/> function (mutch slower). /// </summary> /// <param name="obj">The obj.</param> /// <returns><c>False</c> or the DOCUMENT</returns> public static object IsDrawWindow(XAccessible obj) { //util.Debug.GetAllServicesOfObject(obj); //util.Debug.GetAllProperties(obj); //util.Debug.GetAllInterfacesOfObject(obj); if (!(obj is XSystemDependentWindowPeer)) return false; return IsDrawWindowParentPart(obj); }
/// <summary> /// Prints some accessible infos into the Debug Output. /// </summary> /// <param name="obj">The obj.</param> public static String PrintAccessibleInfos(XAccessible obj, bool printStates = false) { if (obj != null) { XAccessibleContext accessibleContext = obj.getAccessibleContext(); return PrintAccessibleInfos(accessibleContext, printStates); } return String.Empty; }
private void renewRegistrationOfShape(String key, String newKey, OoShapeObserver _so, XAccessible acc) { OoShapeObserver _trash; shapes.TryRemove(key, out _trash); if (!shapes.ContainsKey(newKey)) { shapes[newKey] = _so; } else { //TODO: renew the name to a unique one? Logger.Instance.Log(LogPriority.IMPORTANT, this, "Shape with name '" + newKey + "' already registered. Cannot add this shape to list of Shapes"); } }