private void Update(XDrawPagesSupplier dps)
        {
            var shapeList = new List <OoShapeObserver>(this.domshapes.Values);

            if (shapeList != null && shapeList.Count > 0)
            {
                foreach (var shapeObs in shapeList)
                {
                    if (shapeObs != null)
                    {
                        shapeObs.Update();
                    }
                }
            }

            List <XDrawPage> dpL = OoDrawUtils.DrawDocGetXDrawPageList(dps);

            Parallel.ForEach(dpL, (drawPage) =>
            {
                if (DrawPageobservers.ContainsKey(drawPage))
                {
                    System.Diagnostics.Debug.WriteLine("[UPDATE] Draw page known");
                    var obs = DrawPageobservers[drawPage];
                    obs.Update();
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("[UPDATE] Draw page NOT known !!!");
                    OoDrawPageObserver dpobs = new OoDrawPageObserver(drawPage, this);
                    RegisterDrawPage(dpobs);
                }
            });
        }
        /// <summary>
        /// Registers a new shape.
        /// </summary>
        /// <param name="shape">The dom shape.</param>
        /// <returns>a registered <see cref="OoShapeObserver"/> for this shape</returns>
        internal OoShapeObserver RegisterNewShape(XShape shape, OoDrawPageObserver pObs = null)
        {
            OoShapeObserver sobs = null;

            if (shape != null)
            {
                // get the page to this shape
                var page = OoDrawUtils.GetPageForShape(shape);
                if (page != null)
                {
                    if (pObs == null || !page.Equals(pObs.DrawPage))
                    {
                        pObs = GetRegisteredPageObserver(page);
                    }

                    if (pObs != null)
                    {
                        sobs = OoShapeObserverFactory.BuildShapeObserver(shape, pObs); // new OoShapeObserver(shape, pObs);
                        RegisterUniqueShape(sobs);
                    }
                }
            }

            return(sobs);
        }
        /// <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>
 /// Registers a new shape.
 /// </summary>
 /// <param name="shape">The dom shape [XShape].</param>
 /// <param name="pObs">The page the shape is registered on.</param>
 /// <returns>
 /// a registered <see cref="OoShapeObserver" /> for this shape
 /// </returns>
 public OoShapeObserver RegisterNewShape(Object shape, OoDrawPageObserver pObs = null)
 {
     if (shape is XShape)
     {
         return(RegisterNewShape(shape as XShape, pObs));
     }
     return(null);
 }
 /// <summary>
 /// Registers a new draw page observer.
 /// </summary>
 /// <param name="dpobs">The dpobs.</param>
 internal void RegisterDrawPage(OoDrawPageObserver dpobs)
 {
     if (dpobs != null && dpobs.DrawPage != null)
     {
         Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE] Register new DrawPage");
         DrawPageobservers[dpobs.DrawPage] = dpobs;
         // DrawPages.Add(dpobs);
         dpobs.ObserverDisposing += new EventHandler(dpobs_ObserverDisposing);
     }
 }
 /// <summary>
 /// Gets the last shape of document.
 /// </summary>
 /// <param name="doc">The doc.</param>
 /// <param name="pages">The pages.</param>
 /// <returns></returns>
 public static OoShapeObserver GetLastShapeOfDocument(OoAccessibleDocWnd doc, OoDrawPageObserver pages = null)
 {
     if (doc != null)
     {
         if (pages == null) { pages = doc.GetActivePage(); }
         if (pages != null && doc.DocumentComponent != null && doc.DocumentComponent.ChildCount > 0)
         {
             // a page doesn't have children in the accessible tree --> damn
             // so we have to go through the shape structure
             return pages.GetLastChild();
         }
         else
         {
             Logger.Instance.Log(LogPriority.DEBUG, "AccDomWalker", "The document to walk through seems to have no child shapes");
         }
     }
     return null;
 }
 /// <summary>
 /// Determine if the shapes is already registered.
 /// </summary>
 /// <param name="shape">The shape.</param>
 /// <returns><c>true</c> if the shape is allready known otherwise <c>false</c> </returns>
 public bool ShapeAlreadyRegistered(XShape shape, OoDrawPageObserver page = null)
 {
     if (shape != null)
     {
         if (domshapes.ContainsKey(shape))
         {
             OoShapeObserver sobs = domshapes[shape];
             if (sobs != null)
             {
                 if (sobs.Shape == shape)
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
        /// <summary>
        /// Gets the registered page observer to the DOM page object.
        /// </summary>
        /// <param name="dp">The DOM draw page.</param>
        /// <returns>The already registered page observer or register a new one and return it.</returns>
        internal OoDrawPageObserver GetRegisteredPageObserver(XDrawPage dp)
        {
            OoDrawPageObserver dpobs = null;

            if (dp != null)
            {
                if (DrawPageobservers.ContainsKey(dp))
                {
                    dpobs = DrawPageobservers[dp];
                }
                else
                {
                    dpobs = new OoDrawPageObserver(dp, this);
                    RegisterDrawPage(dpobs);
                }
            }
            return(dpobs);
        }
        /// <summary>
        /// Get a registered shape observer.
        /// </summary>
        /// <param name="shape">The shape.</param>
        /// <returns>the already registered shape observer to the shape or <c>null</c></returns>
        internal OoShapeObserver GetRegisteredShapeObserver(XShape shape, OoDrawPageObserver page)
        {
            if (domshapes.ContainsKey(shape))
            {
                OoShapeObserver sobs = domshapes[shape];
                if (sobs != null && sobs.Shape == shape)
                {
                    return(sobs);
                }
            }

            String          name = OoUtils.GetStringProperty(shape, "Name");
            OoShapeObserver sObs = getRegisteredShapeObserver(name);

            if (sObs == null)
            {
                if (page == null)
                {
                    XDrawPage pageShape = OoDrawUtils.GetPageForShape(shape);
                    if (pageShape == null)
                    {
                        Logger.Instance.Log(LogPriority.DEBUG, this, "[EROR] Can't get page to requested NEW shape");
                        page = this.DocWnd.GetActivePage();
                    }
                    else
                    {
                        page = GetRegisteredPageObserver(pageShape as XDrawPage);
                    }
                }

                if (page != null)
                {
                    sObs = OoShapeObserverFactory.BuildShapeObserver(shape, page); //new OoShapeObserver(shape, page);
                    RegisterUniqueShape(sObs);
                }
            }

            if (sObs != null && sObs.Shape != shape)
            {
                sObs = RegisterNewShape(shape, page);
            }

            return(sObs);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OoShapeObserver"/> class.
        /// </summary>
        /// <param name="s">The XShape to observe.</param>
        /// <param name="page">The observer for the page the shape is located on.</param>
        /// <param name="parent">The observer for the parent shape.</param>
        public OoShapeObserver(XShape s, OoDrawPageObserver page, OoShapeObserver parent)
            : base()
        {
            Shape = s;
            Page = page;
            Parent = parent;
            if (Shape != null)
            {
                //if (IsGroup)
                //{
                //    util.Debug.GetAllInterfacesOfObject(Shape);
                //}

                if (Page != null && Page.PagesObserver != null) Page.PagesObserver.RegisterUniqueShape(this);

                handleChildren();
                registerListeners();

            }

            registerShapeOnPageShapeList();
        }
        void dpobs_ObserverDisposing(object sender, EventArgs e)
        {
            OoDrawPageObserver dpobs = sender as OoDrawPageObserver;

            if (dpobs != null)
            {
                //DrawPages.

                foreach (var item in DrawPageobservers)
                {
                    if (item.Value == dpobs)
                    {
                        OoDrawPageObserver trash;
                        DrawPageobservers.TryRemove(item.Key, out trash);
                        Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE] DrawPage removed");
                    }

                    if (!HasDrawPages())
                    {
                        Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE] Last page disposed");
                    }
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OoShapeObserver"/> class.
        /// </summary>
        /// <param name="s">The XShape to observe.</param>
        /// <param name="page">The observer for the page the shape is located on.</param>
        /// <param name="parent">The observer for the parent shape.</param>
        public OoShapeObserver(XShape s, OoDrawPageObserver page, OoShapeObserver parent)
            : base()
        {
            Shape  = s;
            Page   = page;
            Parent = parent;
            if (Shape != null)
            {
                //if (IsGroup)
                //{
                //    util.Debug.GetAllInterfacesOfObject(Shape);
                //}

                if (Page != null && Page.PagesObserver != null)
                {
                    Page.PagesObserver.RegisterUniqueShape(this);
                }

                handleChildren();
                registerListeners();
            }

            registerShapeOnPageShapeList();
        }
        private void Update(XDrawPagesSupplier dps)
        {
            List<XDrawPage> dpL = OoDrawUtils.DrawDocGetXDrawPageList(dps);

            Parallel.ForEach(dpL, (drawPage) =>
            {
                if (DrawPageobservers.ContainsKey(drawPage))
                {
                    System.Diagnostics.Debug.WriteLine("[UPDATE] Draw page known");
                    var obs = DrawPageobservers[drawPage];
                    obs.Update();
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("[UPDATE] Draw page NOT known !!!");
                    OoDrawPageObserver dpobs = new OoDrawPageObserver(drawPage, this);
                    RegisterDrawPage(dpobs);
                }
            });
        }
 /// <summary>
 /// Determine if the shapes is already registered.
 /// </summary>
 /// <param name="shape">The shape.</param>
 /// <returns><c>true</c> if the shape is allready known otherwise <c>false</c> </returns>
 public bool ShapeAlreadyRegistered(XShape shape, OoDrawPageObserver page = null)
 {
     if (shape != null)
     {
         if (domshapes.ContainsKey(shape))
         {
             OoShapeObserver sobs = domshapes[shape];
             if (sobs != null)
             {
                 if (sobs.Shape == shape) return true;
             }
         }
     }
     return false;
 }
 /// <summary>
 /// Gets the registered page observer to the DOM page object.
 /// </summary>
 /// <param name="dp">The DOM draw page.</param>
 /// <returns>The already registered page observer or register a new one and return it.</returns>
 internal OoDrawPageObserver GetRegisteredPageObserver(XDrawPage dp)
 {
     OoDrawPageObserver dpobs = null;
     if (dp != null)
     {
         if (DrawPageobservers.ContainsKey(dp))
         {
             dpobs = DrawPageobservers[dp];
         }
         else
         {
             dpobs = new OoDrawPageObserver(dp, this);
             RegisterDrawPage(dpobs);
         }
     }
     return dpobs;
 }
 /// <summary>
 /// Registers a new draw page observer.
 /// </summary>
 /// <param name="dpobs">The dpobs.</param>
 internal void RegisterDrawPage(OoDrawPageObserver dpobs)
 {
     if (dpobs != null && dpobs.DrawPage != null)
     {
         Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE] Register new DrawPage");
         DrawPageobservers[dpobs.DrawPage] = dpobs;
         // DrawPages.Add(dpobs);
         dpobs.ObserverDisposing += new EventHandler(dpobs_ObserverDisposing);
     }
 }
        /// <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>
        /// Get a registered shape observer.
        /// </summary>
        /// <param name="shape">The shape.</param>
        /// <returns>the already registerd shape observer to the shape or <c>null</c></returns>
        internal OoShapeObserver GetRegisteredShapeObserver(XShape shape, OoDrawPageObserver page)
        {
            if (domshapes.ContainsKey(shape))
            {
                OoShapeObserver sobs = domshapes[shape];
                if (sobs != null && sobs.Shape == shape)
                {
                    return sobs;
                }
            }

            String name = OoUtils.GetStringProperty(shape, "Name");
            OoShapeObserver sObs = getRegisteredShapeObserver(name);
            if (sObs == null)
            {
                if (page == null)
                {
                    XDrawPage pageShape = OoDrawUtils.GetPageForShape(shape);
                    if (pageShape == null)
                    {
                        Logger.Instance.Log(LogPriority.DEBUG, this, "[EROR] Can't get page to requested NEW shape");
                        page = this.DocWnd.GetActivePage();
                    }
                    else
                    {
                        page = GetRegisteredPageObserver(pageShape as XDrawPage);
                    }
                }

                if (page != null)
                {
                    sObs = new OoShapeObserver(shape, page);
                    RegisterUniqueShape(sObs);
                }
            }

            if (sObs != null && sObs.Shape != shape)
            {
                sObs = RegisterNewShape(shape, page);
            }

            return sObs;
        }
        ///// <summary>
        ///// a list of observers for the children - the order must not corresponding to the order in the DOM
        ///// </summary>
        //public ConcurrentBag<OoShapeObserver> Children = new ConcurrentBag<OoShapeObserver>();


        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="OoShapeObserver"/> class.
        /// </summary>
        /// <param name="s">The XShape to observe.</param>
        /// <param name="page">The observer for the page the shape is located on.</param>
        public OoShapeObserver(XShape s, OoDrawPageObserver page) : this(s, page, null) { }
        /// <summary>
        /// Registers a new shape.
        /// </summary>
        /// <param name="shape">The dom shape.</param>
        /// <returns>a registered <see cref="OoShapeObserver"/> for this shape</returns>
        internal OoShapeObserver RegisterNewShape(XShape shape, OoDrawPageObserver pObs = null)
        {
            OoShapeObserver sobs = null;

            if (shape != null)
            {
                // get the page to this shape
                var page = OoDrawUtils.GetPageForShape(shape);
                if (page != null)
                {
                    if(pObs == null || !page.Equals(pObs.DrawPage)) 
                        pObs = GetRegisteredPageObserver(page);

                    if (pObs != null)
                    {
                        sobs = new OoShapeObserver(shape, pObs);
                        RegisterUniqueShape(sobs);
                    }
                }
            }

            return sobs;
        }
        ///// <summary>
        ///// a list of observers for the children - the order must not corresponding to the order in the DOM
        ///// </summary>
        //public ConcurrentBag<OoShapeObserver> Children = new ConcurrentBag<OoShapeObserver>();


        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="OoShapeObserver"/> class.
        /// </summary>
        /// <param name="s">The XShape to observe.</param>
        /// <param name="page">The observer for the page the shape is located on.</param>
        public OoShapeObserver(XShape s, OoDrawPageObserver page) : this(s, page, 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>
        /// Return the observer of the current active page.
        /// </summary>
        /// <returns></returns>
        private OoDrawPageObserver getActivePageObserver()
        {
            // if this is hanging or called multiple times
            int tries = 0;
            while (_runing && tries++ < 10) { Thread.Sleep(10); }
            if (_runing) { return _lastPageObs; }

            _runing = true;
            OoDrawPageObserver pageObs = null;
            try
            {
                if (DrawPagesObs != null && DrawPagesObs.HasDrawPages()
                    && DrawPageSupplier != null && DrawPageSupplier is XModel2
                    )
                {
                    var dps = DrawPagesObs.GetDrawPages();
                    if (dps.Count > 1) // if only one page is known - take it
                    {
                        // get the controller of the Draw application
                        XController contr = Controller as XController;

                        int pid = getCurrentActivePageId(contr);

                        // find the OoDrawPageObserver for the correct page number
                        if (pid > 0)
                        {
                            foreach (var page in dps)
                            {
                                if (page != null && page.DrawPage != null)
                                {
                                    int pNum = util.OoUtils.GetIntProperty(page.DrawPage, "Number");
                                    if (pNum == pid)
                                    {
                                        pageObs = page;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        pageObs = dps.Count > 0 ? dps[0] : null;
                    }
                }

                _lastPageObs = pageObs;
                return pageObs;
            }
            finally
            {
                _runing = false;
            }
        }