private static OoAccComponent moveToPrevComponent(OoAccComponent comp) { if (comp != null && comp.IsValid()) { //-------------------------- // try to get the parent OoAccComponent parent = comp.GetParent(); if (parent != null) { int pIndex = comp.IndexInParent; int pcCount = parent.ChildCount; int npIndex = mod(pIndex - 1, pcCount); if (pIndex != npIndex) { // get prev sibling var prevSibling = parent.GetChild(npIndex); if (prevSibling != null) { System.Diagnostics.Debug.WriteLine("[MOVE PREV] ---> return prev sibling: " + prevSibling); return(prevSibling); } } } } return(null); }
/// <summary> /// Gets the OoShapeObserver for an accessible if already registered. /// </summary> /// <param name="accComp">The acc comp to get the observer for.</param> /// <param name="page">The page observer to search the observer in.</param> /// <returns>The related OoShapeObserver if already registered</returns> private static OoShapeObserver getObserverForAccessible(OoAccComponent accComp, OoDrawPageObserver page) { if (accComp != null && accComp.IsValid() && page != null) { var pObs = page.PagesObserver; if (pObs != null) { OoShapeObserver sObs = pObs.GetRegisteredShapeObserver(accComp); if (sObs == null) // shape is not registered { page.Update(); // try to do it better for the next term AudioRenderer.Instance.PlayWaveImmediately(StandardSounds.Error); ////TODO: try to get the parent return(null); } return(sObs); } else { Logger.Instance.Log(LogPriority.DEBUG, "OpenOfficeDrawShapeManipulator", "[ERROR] can't get the pages observer to get a ShapeObserver for the next item"); } } return(null); }
/// <summary> /// Moves to a child element. /// </summary> /// <param name="shape">The parent shape to get the child of.</param> /// <param name="index">The index of the child to get (infinite loop by modulo child count).</param> /// <returns> /// The child shape on the screen if possible otherwise the child in the DOM if possible otherwise <c>null</c> /// </returns> public static OoShapeObserver MoveToChild(OoShapeObserver shape, ref int index) { if (shape != null && shape.IsValid()) { // move thought the Accessible tree because this elements should be visible on the screen and the tree navigation is faster // TODO remove false to use search in accessibility tree again. Currently accessing the page AccessibleShape element during search crashes openoffice! if (false && shape.AccComponent != null && shape.AccComponent.IsValid()) { OoAccComponent comp = shape.AccComponent; while (true) { OoAccComponent child = moveToChildComponent(comp, ref index); if (child != null && child != comp) { if (acceptAsUsableShape(child)) { return(getObserverForAccessible(child, shape.Page)); } else { child = moveToChildComponent(child, ref index); } } break; } } else // go through the dom tree { return(moveToChildShape(shape, ref index)); } } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="OoDrawPagesObserver"/> class. /// </summary> /// <param name="dp">The Draw document.</param> /// <param name="doc">The document related accessibility component.</param> /// <param name="docWnd">The related document accessible window component.</param> public OoDrawPagesObserver(XDrawPagesSupplier dp, OoAccComponent doc, OoAccessibleDocWnd docWnd = null) { this.PagesSupplier = dp; Document = doc; DocWnd = docWnd; // get Zoom and ViewOffset first time if (Controller != null) { if (Controller is XPropertySet) { refreshDrawViewProperties((XPropertySet)(Controller)); } // try to get dpi settings from openoffice XWindow componentWindow = Controller.ComponentWindow; if (componentWindow != null && componentWindow is XDevice) { DeviceInfo deviceInfo = (DeviceInfo)((XDevice)componentWindow).getInfo(); if (deviceInfo != null) { PixelPerMeterX = deviceInfo.PixelPerMeterX; PixelPerMeterY = deviceInfo.PixelPerMeterY; } } } // register for Zoom and ViewOffset updates addVisibleAreaPropertyChangeListener(); if (this.PagesSupplier != null) { List <XDrawPage> dpL = OoDrawUtils.DrawDocGetXDrawPageList(dp); if (PagesSupplier is unoidl.com.sun.star.frame.XTitle) { Title = ((unoidl.com.sun.star.frame.XTitle)PagesSupplier).getTitle(); } Logger.Instance.Log(LogPriority.DEBUG, this, "create DrawPagesObserver for supplier " + dp.GetHashCode() + " width title '" + Title + "' - having " + dpL.Count + " pages"); //FIXME: Do this if the api enable parallel access //Parallel.ForEach(dpL, (drawPage) => //{ // OoDrawPageObserver dpobs = new OoDrawPageObserver(drawPage, this); // DrawPageobservers[drawPage] = dpobs; // DrawPages.Add(dpobs); //}); foreach (var drawPage in dpL) { OoDrawPageObserver dpobs = new OoDrawPageObserver(drawPage, this); RegisterDrawPage(dpobs); } XModifyBroadcaster mdfBc = PagesSupplier as XModifyBroadcaster; if (mdfBc != null) { mdfBc.addModifyListener(eventForwarder); } } }
/// <summary> /// Gets the audio text for the given element and send it immediately to the audio renderer. /// </summary> /// <param name="element">The element to get the text of.</param> /// <param name="additionalText">An additional text, that is put behind the element properties and befor the label (if available).</param> /// <returns>The describing string of the element in the following form: [ROLE] [NAME] (addintionalText)</returns> public static string PlayElementImmediately(OoAccComponent element, string additionalText = "") { String text = GetElementAudioText(element, additionalText); if (!String.IsNullOrWhiteSpace(text)) { audio.PlaySoundImmediately(text); } return(text); }
/// <summary> /// Moves to prev component. /// </summary> /// <param name="comp">The comp.</param> /// <param name="handleChildren">if set to <c>true</c> [handle children].</param> /// <returns></returns> private static OoAccComponent moveDeterministicToPrevComponent(OoAccComponent comp, bool handleChildren = true) { if (comp != null) { //walk through the children and back to the parent //check if has children if (handleChildren && comp.HasChildren) // should have children --> go deeper { //TODO: check if we accept this children - e.g. Text ??? // try get the first child OoAccComponent child = comp.GetChild(comp.ChildCount - 1); if (child != null) { System.Diagnostics.Debug.WriteLine("[MOVE PREV] ---> return child: " + child); return(child); } } // if has no children --> go to prev sibling //-------------------------- // try to get the parent OoAccComponent parent = comp.GetParent(); if (parent != null) { int pIndex = comp.IndexInParent; if (pIndex >= 0) { int pcCount = parent.ChildCount; if (pIndex > 0) // is not the first child { // get prev sibling var prevSibling = parent.GetChild(pIndex - 1); if (prevSibling != null) { System.Diagnostics.Debug.WriteLine("[MOVE PREV] ---> return prev sibling: " + prevSibling); return(prevSibling); } } else // is first element --> go higher { return(moveDeterministicToPrevComponent(parent, false)); } } else { // ERROR - this happens e.g. when the parent object is invalid AudioRenderer.Instance.PlayWaveImmediately(StandardSounds.Error); Logger.Instance.Log(LogPriority.OFTEN, "AccDomWalker", "[ERROR] Index in parent is negative"); } } } return(null); }
private static OoAccComponent moveToChildComponent(OoAccComponent comp, ref int index) { if (comp != null && comp.IsValid() && comp.HasChildren) { try { int childNumber = comp.ChildCount; index = index % childNumber; return(comp.GetChild(index)); } catch { } } return(null); }
/// <summary> /// Moves to the next element. /// </summary> /// <param name="shape">The shape to get the next sibling.</param> /// <returns> /// The next shape on the screen if possible otherwise the next in the DOM if possible otherwise <c>null</c> /// </returns> public static OoShapeObserver MoveToNext(OoShapeObserver shape) { if (shape != null && shape.IsValid()) { // move thought the Accessible tree because this elements should be visible on the screen and the tree navigation is faster // TODO remove false to use search in accessibility tree again. Currently accessing the page AccessibleShape element during search crashes openoffice! if (false && shape.AccComponent != null && shape.AccComponent.IsValid()) { OoAccComponent comp = shape.AccComponent; while (true) { OoAccComponent next = moveToNextComponent(comp); if (next != null && next != comp && next.IsValid()) { if (acceptAsUsableShape(next)) { OoShapeObserver obs = getObserverForAccessible(next, shape.Page); if (obs != null) { return(obs); } else { break; } } else { comp = next; continue; } } break; } } // go through the dom tree { return(moveToNextShape(shape)); } } return(null); }
private static OoAccComponent moveToParentComponent(OoAccComponent comp) { if (comp != null && comp.IsValid()) { try { OoAccComponent parent = comp.GetParent(); if (parent != null && acceptAsUsableShape(parent)) { return(parent); } } catch { } } return(null); }
/// <summary> /// Gets the audio text for the given element. /// </summary> /// <param name="element">The element to get the text of.</param> /// <param name="additionalText">An additional text, that is put behind the element properties</param> /// <returns>A string that should describe the element in the following form: [ROLE] [NAME] (addintionalText)</returns> public static String GetElementAudioText(OoAccComponent element, string additionalText = "") { String result = String.Empty; try { if (element != null) { result += LL.GetTrans("tangram.oomanipulation.element_speaker.audio.element", element.Role.ToString(), element.Name.ToString(), additionalText.ToString()); } } catch (System.Exception ex) { Logger.Instance.Log(LogPriority.DEBUG, "OoElementSpeaker", "[ERROR] Can't play element: " + ex); } return(result); }
/// <summary> /// Try to figure out if the accessible element is usable as interactive Shape /// </summary> /// <param name="element">The element.</param> /// <returns></returns> private static bool acceptAsUsableShape(OoAccComponent element) { if (element != null && element != null) { // check if the child is the paragraph if (element.ServiceNames.Contains(tud.mci.tangram.util.OO.Services.TEXT_ACCESSIBLE_PARAGRAPH)) { return(false); } else { if (element.Name.StartsWith("PageShape: ")) { //TODO: decide if is a proper result return(false); } } } return(element != null); }
/// <summary> /// Gets the shape observer for modification. /// </summary> /// <param name="c">The component to get the corresponding observer to.</param> /// <param name="observed">The observed window / draw document.</param> /// <param name="silent">if set to <c>true</c> no audio feedback about the selection is given.</param> /// <param name="immediatly">if set to <c>true</c> the audio feedback is immediately given and all other audio feedback is aborted.</param> /// <returns>The corresponding observer to the shape in the given Draw document.</returns> public OoShapeObserver GetShapeForModification(OoAccComponent c, OoAccessibleDocWnd observed, bool silent = true, bool immediately = true) { if (observed != null && c.Role != AccessibleRole.INVALID) { //TODO: prepare name: OoShapeObserver shape = observed.GetRegisteredShapeObserver(c); if (shape != null) { return(GetShapeForModification(shape, observed, silent, immediately)); //if (shapeManipulatorFunctionProxy != null && !ImageData.Instance.Active) //{ // OoElementSpeaker.PlayElementImmediately(shape, LL.GetTrans("tangram.lector.oo_observer.selected", String.Empty)); // //audioRenderer.PlaySound("Form kann manipuliert werden"); // shapeManipulatorFunctionProxy.LastSelectedShape = shape; // return shape; //} //else // title+desc dialog handling //{ // ImageData.Instance.NewSelectionHandling(shape); //} } else { // disable the pageShapes if (c.Name.StartsWith("PageShape:")) { return(null); } OoElementSpeaker.PlayElementImmediately(c, LL.GetTrans("tangram.lector.oo_observer.selected")); audioRenderer.PlaySound(LL.GetTrans("tangram.lector.oo_observer.selected_element.locked")); } } return(null); }
/// <summary> /// Gets the registered shape observer. /// </summary> /// <param name="comp">The comp.</param> /// <returns></returns> public OoShapeObserver GetRegisteredShapeObserver(OoAccComponent comp) { return(GetRegisteredShapeObserver(comp.AccCont)); }