svx/inc/shapecollection.hxx                      |   74 +++++++++++++++++++++++
 svx/source/accessibility/ChildrenManagerImpl.cxx |   18 +++--
 svx/source/unodraw/unoshcol.cxx                  |   52 +---------------
 3 files changed, 90 insertions(+), 54 deletions(-)

New commits:
commit cef0b4c187a669896706799967def4a9aecf2126
Author:     Noel Grandin <[email protected]>
AuthorDate: Thu May 4 12:43:25 2023 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Thu May 4 15:04:59 2023 +0200

    speed up dealing with large shape selections
    
    cuts the time spent waiting when changing large selections by 90%
    
    Change-Id: I558b5b28449d0cc6b1d3b5e9e4cf455a4b37016a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151360
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/svx/inc/shapecollection.hxx b/svx/inc/shapecollection.hxx
new file mode 100644
index 000000000000..67610f056763
--- /dev/null
+++ b/svx/inc/shapecollection.hxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <cppuhelper/implbase3.hxx>
+#include <comphelper/interfacecontainer4.hxx>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <mutex>
+#include <vector>
+
+class SvxShapeCollection
+    : public cppu::WeakAggImplHelper3<css::drawing::XShapes, 
css::lang::XServiceInfo,
+                                      css::lang::XComponent>
+{
+private:
+    std::mutex m_aMutex;
+    std::vector<css::uno::Reference<css::drawing::XShape>> maShapeContainer;
+    comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> 
maEventListeners;
+    bool bDisposed = false;
+    bool bInDispose = false;
+
+public:
+    SvxShapeCollection() noexcept;
+
+    // XInterface
+    virtual void SAL_CALL release() noexcept override;
+
+    // XComponent
+    virtual void SAL_CALL dispose() override;
+    virtual void SAL_CALL
+    addEventListener(const css::uno::Reference<css::lang::XEventListener>& 
aListener) override;
+    virtual void SAL_CALL
+    removeEventListener(const css::uno::Reference<css::lang::XEventListener>& 
aListener) override;
+
+    // XIndexAccess
+    virtual sal_Int32 SAL_CALL getCount() override;
+    virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override;
+
+    // XElementAccess
+    virtual css::uno::Type SAL_CALL getElementType() override;
+    virtual sal_Bool SAL_CALL hasElements() override;
+
+    // XShapes
+    virtual void SAL_CALL add(const css::uno::Reference<css::drawing::XShape>& 
xShape) override;
+    virtual void SAL_CALL remove(const 
css::uno::Reference<css::drawing::XShape>& xShape) override;
+
+    // XServiceInfo
+    virtual OUString SAL_CALL getImplementationName() override;
+    virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
+    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() 
override;
+
+    void getAllShapes(std::vector<css::uno::Reference<css::drawing::XShape>>& 
rShapes) const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/accessibility/ChildrenManagerImpl.cxx 
b/svx/source/accessibility/ChildrenManagerImpl.cxx
index 8a54822796ee..2926087060d3 100644
--- a/svx/source/accessibility/ChildrenManagerImpl.cxx
+++ b/svx/source/accessibility/ChildrenManagerImpl.cxx
@@ -40,11 +40,11 @@
 #include <com/sun/star/container/XChild.hpp>
 #include <comphelper/types.hxx>
 #include <o3tl/safeint.hxx>
-#include <o3tl/sorted_vector.hxx>
 #include <rtl/ustring.hxx>
 #include <tools/debug.hxx>
 #include <svx/SvxShapeTypes.hxx>
 #include <vcl/window.hxx>
+#include <shapecollection.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::accessibility;
@@ -861,16 +861,22 @@ void ChildrenManagerImpl::UpdateSelection()
         }
 
         // tdf#139220 to quickly find if a given drawing::XShape is selected
-        o3tl::sorted_vector<css::uno::Reference<css::drawing::XShape>> 
aSortedSelectedShapes;
+        std::vector<css::uno::Reference<css::drawing::XShape>> 
aSortedSelectedShapes;
         if (!xSelectedShape.is() && xSelectedShapeAccess.is())
         {
             sal_Int32 nCount = xSelectedShapeAccess->getCount();
             aSortedSelectedShapes.reserve(nCount);
-            for (sal_Int32 i = 0; i < nCount; ++i)
+            if (auto pSvxShape = 
dynamic_cast<SvxShapeCollection*>(xSelectedShapeAccess.get()))
             {
-                css::uno::Reference<css::drawing::XShape> 
xShape(xSelectedShapeAccess->getByIndex(i), uno::UNO_QUERY);
-                aSortedSelectedShapes.insert(xShape);
+                pSvxShape->getAllShapes(aSortedSelectedShapes);
             }
+            else
+                for (sal_Int32 i = 0; i < nCount; ++i)
+                {
+                    css::uno::Reference<css::drawing::XShape> 
xShape(xSelectedShapeAccess->getByIndex(i), uno::UNO_QUERY);
+                    aSortedSelectedShapes.push_back(xShape);
+                }
+            std::sort(aSortedSelectedShapes.begin(), 
aSortedSelectedShapes.end());
         }
 
         for (const auto& rChild : maVisibleChildren)
@@ -899,7 +905,7 @@ void ChildrenManagerImpl::UpdateSelection()
                 }
                 else if (!aSortedSelectedShapes.empty())
                 {
-                    if (aSortedSelectedShapes.find(rChild.mxShape) != 
aSortedSelectedShapes.end())
+                    if (std::binary_search(aSortedSelectedShapes.begin(), 
aSortedSelectedShapes.end(), rChild.mxShape))
                     {
                         bShapeIsSelected = true;
                         // In a multi-selection no shape has the focus.
diff --git a/svx/source/unodraw/unoshcol.cxx b/svx/source/unodraw/unoshcol.cxx
index 2c1a75a14a66..c7fadc620147 100644
--- a/svx/source/unodraw/unoshcol.cxx
+++ b/svx/source/unodraw/unoshcol.cxx
@@ -18,63 +18,16 @@
  */
 
 #include <com/sun/star/document/EventObject.hpp>
-#include <com/sun/star/drawing/XShapes.hpp>
 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
-#include <com/sun/star/lang/XComponent.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
 
-#include <cppuhelper/implbase3.hxx>
-#include <comphelper/interfacecontainer4.hxx>
 #include <cppuhelper/supportsservice.hxx>
-#include <mutex>
 #include <osl/diagnose.h>
 #include <sal/log.hxx>
+#include <shapecollection.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
 
-namespace {
-
-class SvxShapeCollection :
-    public cppu::WeakAggImplHelper3<drawing::XShapes, lang::XServiceInfo, 
lang::XComponent>
-{
-private:
-    std::mutex m_aMutex;
-    std::vector<uno::Reference<drawing::XShape>> maShapeContainer;
-    comphelper::OInterfaceContainerHelper4<lang::XEventListener> 
maEventListeners;
-    bool bDisposed = false;
-    bool bInDispose = false;
-
-public:
-    SvxShapeCollection() noexcept;
-
-    // XInterface
-    virtual void SAL_CALL release() noexcept override;
-
-    // XComponent
-    virtual void SAL_CALL dispose() override;
-    virtual void SAL_CALL addEventListener( const css::uno::Reference< 
css::lang::XEventListener >& aListener ) override;
-    virtual void SAL_CALL removeEventListener( const css::uno::Reference< 
css::lang::XEventListener >& aListener ) override;
-
-    // XIndexAccess
-    virtual sal_Int32 SAL_CALL getCount() override ;
-    virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
-
-    // XElementAccess
-    virtual css::uno::Type SAL_CALL getElementType() override;
-    virtual sal_Bool SAL_CALL hasElements() override;
-
-    // XShapes
-    virtual void SAL_CALL add( const css::uno::Reference< css::drawing::XShape 
>& xShape ) override;
-    virtual void SAL_CALL remove( const css::uno::Reference< 
css::drawing::XShape >& xShape ) override;
-
-    // XServiceInfo
-    virtual OUString SAL_CALL getImplementationName() override;
-    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) 
override;
-    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() 
override;
-};
-
 SvxShapeCollection::SvxShapeCollection() noexcept
 {
 }
@@ -245,6 +198,9 @@ uno::Sequence< OUString > SAL_CALL 
SvxShapeCollection::getSupportedServiceNames(
     return { "com.sun.star.drawing.Shapes", 
"com.sun.star.drawing.ShapeCollection" };
 }
 
+void 
SvxShapeCollection::getAllShapes(std::vector<css::uno::Reference<css::drawing::XShape>>&
 rShapes) const
+{
+    rShapes = maShapeContainer;
 }
 
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *

Reply via email to