[Libreoffice-commits] core.git: Branch 'feature/drawinglayercore2' - 107 commits - accessibility/inc accessibility/Library_acc.mk accessibility/source basegfx/source basic/qa basic/source bridges/source chart2/inc chart2/source comphelper/qa comphelper/source compilerplugins/clang config_host/config_oauth2.h.in cui/source desktop/qa desktop/source dictionaries editeng/inc editeng/source extensions/source extensions/uiconfig external/libcmis filter/source formula/source framework/source helpcontent2 i18npool/qa i18npool/source include/avmedia include/basegfx include/comphelper include/editeng include/formula include/framework include/LibreOfficeKit include/o3tl include/osl include/sfx2 include/svl include/svtools include/svx include/toolkit include/tools include/uno include/unotools include/vcl include/xmloff offapi/com officecfg/registry reportdesign/source sal/cppunittester sal/Executable_cppunittester.mk sal/osl sc/inc sc/qa sc/source sdext/source sd/qa sd/source sfx2/Library_sfx.mk sfx2/sdi sf x2/source solenv/vs sot/source svl/source svtools/source svx/source sw/inc sw/qa sw/sdi sw/source testtools/com testtools/source toolkit/inc toolkit/source tools/qa tools/source translations ucb/source unotools/source vcl/inc vcl/jsdialog vcl/qt5 vcl/source vcl/unx writerfilter/source xmlsecurity/source

Rafael Lima (via logerrit) logerrit at kemper.freedesktop.org
Fri Jul 30 14:02:09 UTC 2021


Rebased ref, commits from common ancestor:
commit 350f994d43660b75bfd21990edabdb1c8adb839e
Author:     Rafael Lima <rafael.palma.lima at gmail.com>
AuthorDate: Fri Jul 30 15:53:01 2021 +0200
Commit:     Gerrit Code Review <gerrit at gerrit.libreoffice.org>
CommitDate: Fri Jul 30 15:53:01 2021 +0200

    Update git submodules
    
    * Update helpcontent2 from branch 'master'
      to 1951014d9e7c5270904789c2964d35fca8487134
      - Rewrite SF_Services with Python support focusing user scripts only
    
        Change-Id: Ib3748c3fbe43e25e3a9aa895519f08ec3b11b953
        Reviewed-on: https://gerrit.libreoffice.org/c/help/+/119612
        Tested-by: Jenkins
        Reviewed-by: Jean-Pierre Ledure <jp at ledure.be>

diff --git a/helpcontent2 b/helpcontent2
index 4a07d8d492c5..1951014d9e7c 160000
--- a/helpcontent2
+++ b/helpcontent2
@@ -1 +1 @@
-Subproject commit 4a07d8d492c50f0e2db3200790f92e9e18bb5144
+Subproject commit 1951014d9e7c5270904789c2964d35fca8487134
commit 66fceca24ee0fccd03f23afc689d82c794a2d57e
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Fri Jul 30 14:29:27 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Jul 30 15:23:52 2021 +0200

    osl::Mutex->std::mutex in FmXDisposeListener
    
    Change-Id: I213499d4c707194c516cafe2ee323e61566cac71
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119706
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/include/svx/fmtools.hxx b/include/svx/fmtools.hxx
index 1ead9069b4f0..869023f06f7f 100644
--- a/include/svx/fmtools.hxx
+++ b/include/svx/fmtools.hxx
@@ -31,6 +31,7 @@
 #include <rtl/ref.hxx>
 #include <cppuhelper/implbase.hxx>
 #include <o3tl/sorted_vector.hxx>
+#include <mutex>
 
 namespace com::sun::star::awt { class XWindow; }
 namespace com::sun::star::beans { class XPropertySet; }
@@ -132,7 +133,7 @@ class SAL_WARN_UNUSED FmXDisposeListener
     friend class FmXDisposeMultiplexer;
 
     rtl::Reference<FmXDisposeMultiplexer> m_pAdapter;
-    osl::Mutex   m_aMutex;
+    std::mutex   m_aMutex;
 
 public:
     virtual ~FmXDisposeListener();
diff --git a/svx/source/form/fmtools.cxx b/svx/source/form/fmtools.cxx
index e9f641309d0b..e8e0a5e1a328 100644
--- a/svx/source/form/fmtools.cxx
+++ b/svx/source/form/fmtools.cxx
@@ -235,7 +235,7 @@ FmXDisposeListener::~FmXDisposeListener()
 
 void FmXDisposeListener::setAdapter(FmXDisposeMultiplexer* pAdapter)
 {
-    ::osl::MutexGuard aGuard(m_aMutex);
+    std::lock_guard aGuard(m_aMutex);
     m_pAdapter = pAdapter;
 }
 
commit 7b5922eb666e5f153060468b271d99510adb422e
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Fri Jul 30 10:10:55 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Jul 30 14:07:43 2021 +0200

    osl::Mutex->std::mutex in DispatchHelper
    
    Change-Id: I6443f604f7f5cacc4b3d67bb6dab07706c82a9a7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119700
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/framework/source/services/dispatchhelper.cxx b/framework/source/services/dispatchhelper.cxx
index 380eab11ec67..cfa4a8a2bbe1 100644
--- a/framework/source/services/dispatchhelper.cxx
+++ b/framework/source/services/dispatchhelper.cxx
@@ -53,6 +53,7 @@ css::uno::Sequence<OUString> SAL_CALL DispatchHelper::getSupportedServiceNames()
 */
 DispatchHelper::DispatchHelper(const css::uno::Reference<css::uno::XComponentContext>& xContext)
     : m_xContext(xContext)
+    , m_aBlockFlag(false)
 {
 }
 
@@ -91,11 +92,12 @@ css::uno::Any SAL_CALL DispatchHelper::executeDispatch(
     }
 
     // parse given URL
+    css::uno::Reference<css::util::XURLTransformer> xParser;
     /* SAFE { */
-    osl::ClearableMutexGuard aReadLock(m_mutex);
-    css::uno::Reference<css::util::XURLTransformer> xParser
-        = css::util::URLTransformer::create(m_xContext);
-    aReadLock.clear();
+    {
+        std::lock_guard aReadLock(m_mutex);
+        xParser = css::util::URLTransformer::create(m_xContext);
+    }
     /* } SAFE */
 
     css::util::URL aURL;
@@ -148,16 +150,18 @@ DispatchHelper::executeDispatch(const css::uno::Reference<css::frame::XDispatch>
                                                                                css::uno::UNO_QUERY);
             /* SAFE { */
             {
-                osl::MutexGuard aWriteLock(m_mutex);
+                std::lock_guard aWriteLock(m_mutex);
                 m_xBroadcaster = xNotifyDispatch;
-                m_aBlock.reset();
+                m_aBlockFlag = false;
             }
             /* } SAFE */
 
             // dispatch it and wait for a notification
             // TODO/MBA: waiting in main thread?!
             xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener);
-            m_aBlock.wait(); // wait for result
+
+            std::unique_lock aWriteLock(m_mutex);
+            m_aBlock.wait(aWriteLock, [this] { return m_aBlockFlag; }); // wait for result
         }
         else
         {
@@ -180,9 +184,10 @@ DispatchHelper::executeDispatch(const css::uno::Reference<css::frame::XDispatch>
  */
 void SAL_CALL DispatchHelper::dispatchFinished(const css::frame::DispatchResultEvent& aResult)
 {
-    osl::MutexGuard g(m_mutex);
+    std::lock_guard g(m_mutex);
     m_aResult <<= aResult;
-    m_aBlock.set();
+    m_aBlockFlag = true;
+    m_aBlock.notify_one();
     m_xBroadcaster.clear();
 }
 
@@ -193,9 +198,10 @@ void SAL_CALL DispatchHelper::dispatchFinished(const css::frame::DispatchResultE
  */
 void SAL_CALL DispatchHelper::disposing(const css::lang::EventObject&)
 {
-    osl::MutexGuard g(m_mutex);
+    std::lock_guard g(m_mutex);
     m_aResult.clear();
-    m_aBlock.set();
+    m_aBlockFlag = true;
+    m_aBlock.notify_one();
     m_xBroadcaster.clear();
 }
 }
diff --git a/include/framework/dispatchhelper.hxx b/include/framework/dispatchhelper.hxx
index f362f30ab633..ca7e2b2ccf12 100644
--- a/include/framework/dispatchhelper.hxx
+++ b/include/framework/dispatchhelper.hxx
@@ -28,7 +28,8 @@
 
 #include <cppuhelper/implbase.hxx>
 #include <framework/fwkdllapi.h>
-#include <osl/conditn.hxx>
+#include <condition_variable>
+#include <mutex>
 
 namespace com::sun::star::lang
 {
@@ -57,17 +58,15 @@ class UNLESS_MERGELIBS(FWK_DLLPUBLIC) DispatchHelper final
     : public ::cppu::WeakImplHelper<css::lang::XServiceInfo, css::frame::XDispatchHelper,
                                     css::frame::XDispatchResultListener>
 {
-    // member
-
-private:
-    osl::Mutex m_mutex;
+    std::mutex m_mutex;
 
     /** global uno service manager.
             Can be used to create own needed services. */
     css::uno::Reference<css::uno::XComponentContext> m_xContext;
 
     /** used to wait for asynchronous listener callbacks. */
-    ::osl::Condition m_aBlock;
+    std::condition_variable m_aBlock;
+    bool m_aBlockFlag;
 
     css::uno::Any m_aResult;
 
commit 74f4a1796f94477d459c71d0a0aaa8f4a430e208
Author:     Gopi Krishna Menon <gopi.menon at collabora.com>
AuthorDate: Thu Jul 29 15:21:13 2021 +0530
Commit:     Tor Lillqvist <tml at collabora.com>
CommitDate: Fri Jul 30 13:07:49 2021 +0200

    Fix Nesting Level Bug in ProfileZone
    
    Moves the profile zone global nesting variable into the source from header and makes it threadlocal
    
    Change-Id: I97751f5c532d8e0e36adb7d9d383bd88f752953f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119662
    Tested-by: Jenkins
    Reviewed-by: Tor Lillqvist <tml at collabora.com>

diff --git a/comphelper/source/misc/traceevent.cxx b/comphelper/source/misc/traceevent.cxx
index c379bbb97f7e..8b1a9c09427a 100644
--- a/comphelper/source/misc/traceevent.cxx
+++ b/comphelper/source/misc/traceevent.cxx
@@ -29,7 +29,8 @@ std::size_t TraceEvent::s_nBufferSize = 0;
 void (*TraceEvent::s_pBufferFullCallback)() = nullptr;
 
 int AsyncEvent::s_nIdCounter = 0;
-int ProfileZone::s_nNesting = 0;
+
+static thread_local int nProfileZoneNesting = 0; // Level of Nested Profile Zones
 
 namespace
 {
@@ -134,6 +135,10 @@ void ProfileZone::addRecording()
                              + OUString::number(osl_getThreadIdentifier(nullptr)) + "},");
 }
 
+int ProfileZone::getNestingLevel() { return nProfileZoneNesting; }
+
+void ProfileZone::setNestingLevel(int nNestingLevel) { nProfileZoneNesting = nNestingLevel; }
+
 } // namespace comphelper
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/profilezone.hxx b/include/comphelper/profilezone.hxx
index b96b26baffc1..71f9fa30b6dc 100644
--- a/include/comphelper/profilezone.hxx
+++ b/include/comphelper/profilezone.hxx
@@ -22,13 +22,14 @@ namespace comphelper
 {
 class COMPHELPER_DLLPUBLIC ProfileZone : public NamedEvent
 {
-    static int s_nNesting; // level of nested zones.
-
     long long m_nCreateTime;
     int m_nNesting;
 
     void addRecording();
 
+    static void setNestingLevel(int nNestingLevel);
+    static int getNestingLevel();
+
     ProfileZone(const char* sName, const OUString& sArgs)
         : NamedEvent(sName, sArgs)
         , m_nNesting(-1)
@@ -37,7 +38,8 @@ class COMPHELPER_DLLPUBLIC ProfileZone : public NamedEvent
         {
             m_nCreateTime = getNow();
 
-            m_nNesting = s_nNesting++;
+            m_nNesting = getNestingLevel();
+            setNestingLevel(getNestingLevel() + 1);
         }
         else
             m_nCreateTime = 0;
@@ -65,9 +67,9 @@ public:
     {
         if (m_nCreateTime > 0)
         {
-            s_nNesting--;
+            setNestingLevel(getNestingLevel() - 1);
 
-            if (m_nNesting != s_nNesting)
+            if (m_nNesting != getNestingLevel())
             {
                 SAL_WARN("comphelper.traceevent", "Incorrect ProfileZone nesting for " << m_sName);
             }
commit 172f589471edcac9a4974132a3145b721942879a
Author:     Anshu <anshukhare50 at gmail.com>
AuthorDate: Sat Jun 26 08:34:06 2021 +0530
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri Jul 30 12:14:24 2021 +0200

    tdf#38194 related: introduce StylesList control
    
    Change-Id: I31202c213e034ab96f28e16d1f6a59b52f47507d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117918
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk
index fff97d011a02..39b5438c65a2 100644
--- a/sfx2/Library_sfx.mk
+++ b/sfx2/Library_sfx.mk
@@ -203,6 +203,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
     sfx2/source/dialog/styledlg \
     sfx2/source/dialog/tabdlg \
     sfx2/source/dialog/templdlg \
+    sfx2/source/dialog/StyleList \
     sfx2/source/dialog/titledockwin \
     sfx2/source/dialog/tplcitem \
     sfx2/source/dialog/tplpitem \
diff --git a/sfx2/source/dialog/StyleList.cxx b/sfx2/source/dialog/StyleList.cxx
new file mode 100644
index 000000000000..8525c620b2dd
--- /dev/null
+++ b/sfx2/source/dialog/StyleList.cxx
@@ -0,0 +1,1814 @@
+/* -*- 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 .
+ */
+
+#include <memory>
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <vcl/commandevent.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/event.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/style.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <officecfg/Office/Common.hxx>
+
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/templdlg.hxx>
+#include <templdgi.hxx>
+#include <tplcitem.hxx>
+#include <sfx2/styfitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/newstyle.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <sfx2/sfxresid.hxx>
+
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/strings.hrc>
+#include <sfx2/docfac.hxx>
+#include <sfx2/module.hxx>
+#include <helpids.h>
+#include <sfx2/viewfrm.hxx>
+
+#include <comphelper/string.hxx>
+
+#include <sfx2/StyleManager.hxx>
+#include <sfx2/StylePreviewRenderer.hxx>
+
+#include <StyleList.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/menu.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::frame;
+using namespace css::uno;
+
+// Constructor
+
+StyleList::StyleList(weld::Builder* pBuilder, std::optional<SfxStyleFamilies> xFamilies,
+                     SfxBindings* pBindings, SfxCommonTemplateDialog_Impl* Parent,
+                     SfxModule* Module, weld::Container* pC, OString treeviewname,
+                     OString flatviewname)
+    : m_bHierarchical(false)
+    , m_bAllowReParentDrop(false)
+    , m_bNewByExampleDisabled(false)
+    , m_bDontUpdate(false)
+    , m_bTreeDrag(true)
+    , m_bCanEdit(false)
+    , m_bCanHide(true)
+    , m_bCanShow(false)
+    , m_bCanNew(true)
+    , m_bUpdateFamily(false)
+    , m_bCanDel(false)
+    , m_bBindingUpdate(true)
+    , m_pStyleSheetPool(nullptr)
+    , m_nActFilter(0)
+    , m_xFmtLb(pBuilder->weld_tree_view(flatviewname))
+    , m_xTreeBox(pBuilder->weld_tree_view(treeviewname))
+    , m_xStyleFamilies(xFamilies)
+    , m_nActFamily(0xffff)
+    , m_nAppFilter(SfxStyleSearchBits::Auto)
+    , m_pParentDialog(Parent)
+    , m_pBindings(pBindings)
+    , m_Module(Module)
+    , m_nModifier(0)
+    , m_pContainer(pC)
+{
+    m_xFmtLb->set_help_id(HID_TEMPLATE_FMT);
+}
+
+// Destructor
+
+StyleList::~StyleList() {}
+
+// Called in the destructor of Dialog
+// Cleans up the StyleList individual components while closing the application
+IMPL_LINK_NOARG(StyleList, Cleanup, void*, void)
+{
+    if (m_pStyleSheetPool)
+        EndListening(*m_pStyleSheetPool);
+    m_pStyleSheetPool = nullptr;
+    m_xTreeView1DropTargetHelper.reset();
+    m_xTreeView2DropTargetHelper.reset();
+    m_xTreeBox.reset();
+    m_xFmtLb.reset();
+    pIdle.reset();
+}
+
+void StyleList::CreateContextMenu()
+{
+    if (m_bBindingUpdate)
+    {
+        m_pBindings->Invalidate(SID_STYLE_NEW, true);
+        m_pBindings->Update(SID_STYLE_NEW);
+        m_bBindingUpdate = false;
+    }
+    mxMenu.reset();
+    mxMenuBuilder.reset(Application::CreateBuilder(nullptr, "sfx/ui/stylecontextmenu.ui"));
+    mxMenu = mxMenuBuilder->weld_menu("menu");
+    mxMenu->set_sensitive("edit", m_bCanEdit);
+    mxMenu->set_sensitive("delete", m_bCanDel);
+    mxMenu->set_sensitive("new", m_bCanNew);
+    mxMenu->set_sensitive("hide", m_bCanHide);
+    mxMenu->set_sensitive("show", m_bCanShow);
+
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    if (pItem && pItem->GetFamily() == SfxStyleFamily::Table) //tdf#101648, no ui for this yet
+    {
+        mxMenu->set_sensitive("edit", false);
+        mxMenu->set_sensitive("new", false);
+    }
+    if (pItem && pItem->GetFamily() == SfxStyleFamily::Pseudo)
+    {
+        const OUString aTemplName(GetSelectedEntry());
+        if (aTemplName == "No List")
+        {
+            mxMenu->set_sensitive("edit", false);
+            mxMenu->set_sensitive("new", false);
+            mxMenu->set_sensitive("hide", false);
+        }
+    }
+}
+
+IMPL_LINK_NOARG(StyleList, ReadResource, void*, size_t)
+{
+    // Read global user resource
+    for (auto& i : m_pFamilyState)
+        i.reset();
+
+    SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
+    m_pCurObjShell = pViewFrame->GetObjectShell();
+    m_Module = m_pCurObjShell ? m_pCurObjShell->GetModule() : nullptr;
+    if (m_Module)
+        m_xStyleFamilies = m_Module->CreateStyleFamilies();
+    if (!m_xStyleFamilies)
+        m_xStyleFamilies.emplace();
+
+    m_nActFilter = 0xffff;
+    // Assigning value to Dialog's nActFilter so that both nActFilters are in sync
+    m_pParentDialog->SetFilterByIndex(m_nActFilter);
+    if (m_pCurObjShell)
+    {
+        m_nActFilter = static_cast<sal_uInt16>(m_aLoadFactoryStyleFilter.Call(m_pCurObjShell));
+        // Assigning value to Dialog's nActFilter so that both nActFilters are in sync
+        m_pParentDialog->SetFilterByIndex(m_nActFilter);
+        if (0xffff == m_nActFilter)
+        {
+            m_nActFilter = m_pCurObjShell->GetAutoStyleFilterIndex();
+            m_pParentDialog->SetFilterByIndex(m_nActFilter);
+        }
+    }
+    size_t nCount = m_xStyleFamilies->size();
+    m_pBindings->ENTERREGISTRATIONS();
+
+    size_t i;
+    for (i = 0; i < nCount; ++i)
+    {
+        sal_uInt16 nSlot = 0;
+        switch (m_xStyleFamilies->at(i).GetFamily())
+        {
+            case SfxStyleFamily::Char:
+                nSlot = SID_STYLE_FAMILY1;
+                break;
+            case SfxStyleFamily::Para:
+                nSlot = SID_STYLE_FAMILY2;
+                break;
+            case SfxStyleFamily::Frame:
+                nSlot = SID_STYLE_FAMILY3;
+                break;
+            case SfxStyleFamily::Page:
+                nSlot = SID_STYLE_FAMILY4;
+                break;
+            case SfxStyleFamily::Pseudo:
+                nSlot = SID_STYLE_FAMILY5;
+                break;
+            case SfxStyleFamily::Table:
+                nSlot = SID_STYLE_FAMILY6;
+                break;
+            default:
+                OSL_FAIL("unknown StyleFamily");
+                break;
+        }
+        pBoundItems[i].reset(new SfxTemplateControllerItem(nSlot, *m_pParentDialog, *m_pBindings));
+    }
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_WATERCAN, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_NEW_BY_EXAMPLE, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_UPDATE_BY_EXAMPLE, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_NEW, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_DRAGHIERARCHIE, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_EDIT, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_DELETE, *m_pParentDialog, *m_pBindings));
+    pBoundItems[i++].reset(
+        new SfxTemplateControllerItem(SID_STYLE_FAMILY, *m_pParentDialog, *m_pBindings));
+    m_pBindings->LEAVEREGISTRATIONS();
+
+    for (; i < COUNT_BOUND_FUNC; ++i)
+        pBoundItems[i] = nullptr;
+
+    StartListening(*m_pBindings);
+
+    for (i = SID_STYLE_FAMILY1; i <= SID_STYLE_FAMILY4; i++)
+        m_pBindings->Update(i);
+
+    return nCount;
+}
+
+void StyleList::EnableNewByExample(bool newByExampleDisabled)
+{
+    m_bNewByExampleDisabled = newByExampleDisabled;
+}
+
+class TreeViewDropTarget final : public DropTargetHelper
+{
+private:
+    StyleList& m_rParent;
+
+public:
+    TreeViewDropTarget(StyleList& rStyleList, weld::TreeView& rTreeView)
+        : DropTargetHelper(rTreeView.get_drop_target())
+        , m_rParent(rStyleList)
+    {
+    }
+
+    virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
+    {
+        return m_rParent.AcceptDrop(rEvt, *this);
+    }
+
+    virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
+    {
+        return m_rParent.ExecuteDrop(rEvt);
+    }
+};
+
+IMPL_LINK(StyleList, FilterSelect, sal_uInt16, mActFilter, void)
+{
+    m_nActFilter = mActFilter;
+    SfxObjectShell* const pDocShell = m_aSaveSelection.Call(nullptr);
+    SfxStyleSheetBasePool* pOldStyleSheetPool = m_pStyleSheetPool;
+    m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
+    if (pOldStyleSheetPool != m_pStyleSheetPool)
+    {
+        if (pOldStyleSheetPool)
+            EndListening(*pOldStyleSheetPool);
+        if (m_pStyleSheetPool)
+            StartListening(*m_pStyleSheetPool);
+    }
+}
+
+IMPL_LINK(StyleList, SetFamily, sal_uInt16, nId, void)
+{
+    if (m_nActFamily != 0xFFFF)
+        m_pParentDialog->CheckItem(OString::number(m_nActFamily), false);
+    m_nActFamily = nId;
+    if (nId != 0xFFFF)
+    {
+        m_bUpdateFamily = true;
+    }
+}
+
+void StyleList::InvalidateBindings()
+{
+    m_pBindings->Invalidate(SID_STYLE_NEW_BY_EXAMPLE, true);
+    m_pBindings->Update(SID_STYLE_NEW_BY_EXAMPLE);
+    m_pBindings->Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE, true);
+    m_pBindings->Update(SID_STYLE_UPDATE_BY_EXAMPLE);
+    m_pBindings->Invalidate(SID_STYLE_WATERCAN, true);
+    m_pBindings->Update(SID_STYLE_WATERCAN);
+    m_pBindings->Invalidate(SID_STYLE_NEW, true);
+    m_pBindings->Update(SID_STYLE_NEW);
+    m_pBindings->Invalidate(SID_STYLE_DRAGHIERARCHIE, true);
+    m_pBindings->Update(SID_STYLE_DRAGHIERARCHIE);
+}
+
+void StyleList::Initialize()
+{
+    m_pBindings->Invalidate(SID_STYLE_FAMILY);
+    m_pBindings->Update(SID_STYLE_FAMILY);
+
+    m_xFmtLb->connect_row_activated(LINK(this, StyleList, TreeListApplyHdl));
+    m_xFmtLb->connect_mouse_press(LINK(this, StyleList, MousePressHdl));
+    m_xFmtLb->connect_query_tooltip(LINK(this, StyleList, QueryTooltipHdl));
+    m_xFmtLb->connect_changed(LINK(this, StyleList, FmtSelectHdl));
+    m_xFmtLb->connect_popup_menu(LINK(this, StyleList, PopupFlatMenuHdl));
+    m_xFmtLb->connect_key_press(LINK(this, StyleList, KeyInputHdl));
+    m_xFmtLb->set_selection_mode(SelectionMode::Multiple);
+    m_xTreeBox->connect_changed(LINK(this, StyleList, FmtSelectHdl));
+    m_xTreeBox->connect_row_activated(LINK(this, StyleList, TreeListApplyHdl));
+    m_xTreeBox->connect_mouse_press(LINK(this, StyleList, MousePressHdl));
+    m_xTreeBox->connect_query_tooltip(LINK(this, StyleList, QueryTooltipHdl));
+    m_xTreeBox->connect_popup_menu(LINK(this, StyleList, PopupTreeMenuHdl));
+    m_xTreeBox->connect_key_press(LINK(this, StyleList, KeyInputHdl));
+    m_xTreeBox->connect_drag_begin(LINK(this, StyleList, DragBeginHdl));
+    m_xTreeView1DropTargetHelper.reset(new TreeViewDropTarget(*this, *m_xFmtLb));
+    m_xTreeView2DropTargetHelper.reset(new TreeViewDropTarget(*this, *m_xTreeBox));
+
+    m_pParentDialog->connect_stylelist_read_resource(LINK(this, StyleList, ReadResource));
+    m_pParentDialog->connect_stylelist_clear(LINK(this, StyleList, Clear));
+    m_pParentDialog->connect_stylelist_cleanup(LINK(this, StyleList, Cleanup));
+    m_pParentDialog->connect_stylelist_execute_drop(LINK(this, StyleList, ExecuteDrop));
+    m_pParentDialog->connect_stylelist_execute_new_menu(
+        LINK(this, StyleList, NewMenuExecuteAction));
+    m_pParentDialog->connect_stylelist_for_watercan(LINK(this, StyleList, IsSafeForWaterCan));
+    m_pParentDialog->connect_stylelist_has_selected_style(LINK(this, StyleList, HasSelectedStyle));
+    m_pParentDialog->connect_stylelist_update_styles(LINK(this, StyleList, UpdateStyles));
+    m_pParentDialog->connect_stylelist_update_family(LINK(this, StyleList, UpdateFamily));
+    m_pParentDialog->connect_stylelist_update_style_dependents(
+        LINK(this, StyleList, UpdateStyleDependents));
+    m_pParentDialog->connect_stylelist_enable_tree_drag(LINK(this, StyleList, EnableTreeDrag));
+    m_pParentDialog->connect_stylelist_filter_select(LINK(this, StyleList, FilterSelect));
+    m_pParentDialog->connect_stylelist_enable_delete(LINK(this, StyleList, EnableDelete));
+    m_pParentDialog->connect_stylelist_set_water_can_state(LINK(this, StyleList, SetWaterCanState));
+    m_pParentDialog->connect_family_select(LINK(this, StyleList, FamilySelect));
+    m_pParentDialog->connect_set_family(LINK(this, StyleList, SetFamily));
+
+    int nTreeHeight = m_xFmtLb->get_height_rows(8);
+    m_xFmtLb->set_size_request(-1, nTreeHeight);
+    m_xTreeBox->set_size_request(-1, nTreeHeight);
+
+    m_xFmtLb->connect_custom_get_size(LINK(this, StyleList, CustomGetSizeHdl));
+    m_xFmtLb->connect_custom_render(LINK(this, StyleList, CustomRenderHdl));
+    m_xTreeBox->connect_custom_get_size(LINK(this, StyleList, CustomGetSizeHdl));
+    m_xTreeBox->connect_custom_render(LINK(this, StyleList, CustomRenderHdl));
+    bool bCustomPreview = officecfg::Office::Common::StylesAndFormatting::Preview::get();
+    m_xFmtLb->set_column_custom_renderer(0, bCustomPreview);
+    m_xTreeBox->set_column_custom_renderer(0, bCustomPreview);
+
+    m_xFmtLb->set_visible(!m_bHierarchical);
+    m_xTreeBox->set_visible(m_bHierarchical);
+    Update();
+}
+
+IMPL_LINK_NOARG(StyleList, UpdateFamily, void*, void)
+{
+    m_bUpdateFamily = false;
+
+    SfxDispatcher* pDispat = m_pBindings->GetDispatcher_Impl();
+    SfxViewFrame* pViewFrame = pDispat->GetFrame();
+    SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
+
+    SfxStyleSheetBasePool* pOldStyleSheetPool = m_pStyleSheetPool;
+    m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
+    if (pOldStyleSheetPool != m_pStyleSheetPool)
+    {
+        if (pOldStyleSheetPool)
+            EndListening(*pOldStyleSheetPool);
+        if (m_pStyleSheetPool)
+            StartListening(*m_pStyleSheetPool);
+    }
+
+    m_bTreeDrag = true;
+    m_bCanNew = m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1;
+    m_pParentDialog->EnableNew(m_bCanNew);
+    m_bTreeDrag = true;
+    if (m_pStyleSheetPool)
+    {
+        if (!m_xTreeBox->get_visible())
+            UpdateStyles(StyleFlags::UpdateFamily | StyleFlags::UpdateFamilyList);
+        else
+        {
+            UpdateStyles(StyleFlags::UpdateFamily);
+            FillTreeBox(GetActualFamily());
+        }
+    }
+
+    InvalidateBindings();
+}
+
+bool StyleList::EnableExecute()
+{
+    return m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1;
+}
+
+void StyleList::connect_LoadFactoryStyleFilter(const Link<SfxObjectShell const*, sal_Int32>& rLink)
+{
+    m_aLoadFactoryStyleFilter = rLink;
+}
+
+void StyleList::connect_SaveSelection(const Link<void*, SfxObjectShell*> rLink)
+{
+    m_aSaveSelection = rLink;
+}
+
+void StyleList::connect_UpdateStyleDependents(const Link<void*, void> rLink)
+{
+    m_aUpdateStyleDependents = rLink;
+}
+
+/** Drop is enabled as long as it is allowed to create a new style by example, i.e. to
+    create a style out of the current selection.
+*/
+sal_Int8 StyleList::AcceptDrop(const AcceptDropEvent& rEvt, const DropTargetHelper& rHelper)
+{
+    if (rHelper.IsDropFormatSupported(SotClipboardFormatId::OBJECTDESCRIPTOR))
+    {
+        // special case: page styles are allowed to create new styles by example
+        // but not allowed to be created by drag and drop
+        if (GetActualFamily() == SfxStyleFamily::Page || m_bNewByExampleDisabled)
+            return DND_ACTION_NONE;
+        else
+            return DND_ACTION_COPY;
+    }
+    // to enable the autoscroll when we're close to the edges
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    pTreeView->get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
+    return DND_ACTION_MOVE;
+}
+
+// handles drop of content in treeview when creating a new style
+IMPL_LINK(StyleList, ExecuteDrop, const ExecuteDropEvent&, rEvt, sal_Int8)
+{
+    SfxObjectShell* pDocShell = m_pCurObjShell;
+    if (pDocShell)
+    {
+        TransferableDataHelper aHelper(rEvt.maDropEvent.Transferable);
+        sal_uInt32 nFormatCount = aHelper.GetFormatCount();
+
+        sal_Int8 nRet = DND_ACTION_NONE;
+
+        bool bFormatFound = false;
+
+        for (sal_uInt32 i = 0; i < nFormatCount; ++i)
+        {
+            SotClipboardFormatId nId = aHelper.GetFormat(i);
+            TransferableObjectDescriptor aDesc;
+
+            if (aHelper.GetTransferableObjectDescriptor(nId, aDesc))
+            {
+                if (aDesc.maClassName == pDocShell->GetFactory().GetClassId())
+                {
+                    Application::PostUserEvent(
+                        LINK(m_pParentDialog, SfxCommonTemplateDialog_Impl, OnAsyncExecuteDrop));
+
+                    bFormatFound = true;
+                    nRet = rEvt.mnAction;
+                    break;
+                }
+            }
+        }
+
+        if (bFormatFound)
+            return nRet;
+    }
+
+    if (!m_xTreeBox->get_visible())
+        return DND_ACTION_NONE;
+
+    if (!m_bAllowReParentDrop)
+        return DND_ACTION_NONE;
+
+    // otherwise if we're dragging with the treeview to set a new parent of the dragged style
+    weld::TreeView* pSource = m_xTreeBox->get_drag_source();
+    // only dragging within the same widget allowed
+    if (!pSource || pSource != m_xTreeBox.get())
+        return DND_ACTION_NONE;
+
+    std::unique_ptr<weld::TreeIter> xSource(m_xTreeBox->make_iterator());
+    if (!m_xTreeBox->get_selected(xSource.get()))
+        return DND_ACTION_NONE;
+
+    std::unique_ptr<weld::TreeIter> xTarget(m_xTreeBox->make_iterator());
+    if (!m_xTreeBox->get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
+    {
+        // if nothing under the mouse, use the last row
+        int nChildren = m_xTreeBox->n_children();
+        if (!nChildren)
+            return DND_ACTION_NONE;
+        if (!m_xTreeBox->get_iter_first(*xTarget)
+            || !m_xTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
+            return DND_ACTION_NONE;
+        while (m_xTreeBox->get_row_expanded(*xTarget))
+        {
+            nChildren = m_xTreeBox->iter_n_children(*xTarget);
+            if (!m_xTreeBox->iter_children(*xTarget)
+                || !m_xTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
+                return DND_ACTION_NONE;
+        }
+    }
+    OUString aTargetStyle = m_xTreeBox->get_text(*xTarget);
+    DropHdl(m_xTreeBox->get_text(*xSource), aTargetStyle);
+    m_xTreeBox->unset_drag_dest_row();
+    FillTreeBox(GetActualFamily());
+    m_pParentDialog->SelectStyle(aTargetStyle, false, *this);
+    return DND_ACTION_NONE;
+}
+
+IMPL_LINK_NOARG(StyleList, NewMenuExecuteAction, void*, void)
+{
+    if (m_pStyleSheetPool && m_nActFamily != 0xffff)
+    {
+        const SfxStyleFamily eFam = GetFamilyItem()->GetFamily();
+        const SfxStyleFamilyItem* pItem = GetFamilyItem();
+        SfxStyleSearchBits nFilter(SfxStyleSearchBits::Auto);
+        if (pItem && m_nActFilter != 0xffff)
+            nFilter = pItem->GetFilterList()[m_nActFilter].nFlags;
+        if (nFilter == SfxStyleSearchBits::Auto) // automatic
+            nFilter = m_nAppFilter;
+
+        // why? : FloatingWindow must not be parent of a modal dialog
+        SfxNewStyleDlg aDlg(m_pContainer, *m_pStyleSheetPool, eFam);
+        auto nResult = aDlg.run();
+        if (nResult == RET_OK)
+        {
+            const OUString aTemplName(aDlg.GetName());
+            m_pParentDialog->Execute_Impl(SID_STYLE_NEW_BY_EXAMPLE, aTemplName, "",
+                                          static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()),
+                                          *this, nFilter);
+            m_aUpdateFamily.Call(*this);
+        }
+    }
+}
+
+void StyleList::DropHdl(const OUString& rStyle, const OUString& rParent)
+{
+    m_bDontUpdate = true;
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    const SfxStyleFamily eFam = pItem->GetFamily();
+    m_pStyleSheetPool->SetParent(eFam, rStyle, rParent);
+    m_bDontUpdate = false;
+}
+
+void StyleList::PrepareMenu(const Point& rPos)
+{
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    std::unique_ptr<weld::TreeIter> xIter(pTreeView->make_iterator());
+    if (pTreeView->get_dest_row_at_pos(rPos, xIter.get(), false) && !pTreeView->is_selected(*xIter))
+    {
+        pTreeView->unselect_all();
+        pTreeView->set_cursor(*xIter);
+        pTreeView->select(*xIter);
+    }
+    FmtSelectHdl(*pTreeView);
+}
+
+/** Internal structure for the establishment of the hierarchical view */
+namespace
+{
+class StyleTree_Impl;
+}
+
+typedef std::vector<std::unique_ptr<StyleTree_Impl>> StyleTreeArr_Impl;
+
+namespace
+{
+class StyleTree_Impl
+{
+private:
+    OUString aName;
+    OUString aParent;
+    StyleTreeArr_Impl pChildren;
+
+public:
+    bool HasParent() const { return !aParent.isEmpty(); }
+
+    StyleTree_Impl(const OUString& rName, const OUString& rParent)
+        : aName(rName)
+        , aParent(rParent)
+        , pChildren(0)
+    {
+    }
+
+    const OUString& getName() const { return aName; }
+    const OUString& getParent() const { return aParent; }
+    StyleTreeArr_Impl& getChildren() { return pChildren; }
+};
+}
+
+static void MakeTree_Impl(StyleTreeArr_Impl& rArr, const OUString& aUIName)
+{
+    const comphelper::string::NaturalStringSorter aSorter(
+        ::comphelper::getProcessComponentContext(),
+        Application::GetSettings().GetLanguageTag().getLocale());
+
+    std::unordered_map<OUString, StyleTree_Impl*> styleFinder;
+    styleFinder.reserve(rArr.size());
+    for (const auto& pEntry : rArr)
+    {
+        styleFinder.emplace(pEntry->getName(), pEntry.get());
+    }
+
+    // Arrange all under their Parents
+    for (auto& pEntry : rArr)
+    {
+        if (!pEntry->HasParent())
+            continue;
+        auto it = styleFinder.find(pEntry->getParent());
+        if (it != styleFinder.end())
+        {
+            StyleTree_Impl* pCmp = it->second;
+            // Insert child entries sorted
+            auto iPos = std::lower_bound(
+                pCmp->getChildren().begin(), pCmp->getChildren().end(), pEntry,
+                [&aSorter](std::unique_ptr<StyleTree_Impl> const& pEntry1,
+                           std::unique_ptr<StyleTree_Impl> const& pEntry2) {
+                    return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0;
+                });
+            pCmp->getChildren().insert(iPos, std::move(pEntry));
+        }
+    }
+
+    // Only keep tree roots in rArr, child elements can be accessed through the hierarchy
+    rArr.erase(
+        std::remove_if(rArr.begin(), rArr.end(),
+                       [](std::unique_ptr<StyleTree_Impl> const& pEntry) { return !pEntry; }),
+        rArr.end());
+
+    // tdf#91106 sort top level styles
+    std::sort(rArr.begin(), rArr.end());
+    std::sort(rArr.begin(), rArr.end(),
+              [&aSorter, &aUIName](std::unique_ptr<StyleTree_Impl> const& pEntry1,
+                                   std::unique_ptr<StyleTree_Impl> const& pEntry2) {
+                  if (pEntry2->getName() == aUIName)
+                      return false;
+                  if (pEntry1->getName() == aUIName)
+                      return true; // default always first
+                  return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0;
+              });
+}
+
+static bool IsExpanded_Impl(const std::vector<OUString>& rEntries, std::u16string_view rStr)
+{
+    for (const auto& rEntry : rEntries)
+    {
+        if (rEntry == rStr)
+            return true;
+    }
+    return false;
+}
+
+static void FillBox_Impl(weld::TreeView& rBox, StyleTree_Impl* pEntry,
+                         const std::vector<OUString>& rEntries, SfxStyleFamily eStyleFamily,
+                         const weld::TreeIter* pParent)
+{
+    std::unique_ptr<weld::TreeIter> xResult = rBox.make_iterator();
+    const OUString& rName = pEntry->getName();
+    rBox.insert(pParent, -1, &rName, &rName, nullptr, nullptr, false, xResult.get());
+
+    for (size_t i = 0; i < pEntry->getChildren().size(); ++i)
+        FillBox_Impl(rBox, pEntry->getChildren()[i].get(), rEntries, eStyleFamily, xResult.get());
+}
+
+namespace SfxTemplate
+{
+// converts from SFX_STYLE_FAMILY Ids to 1-6
+static sal_uInt16 SfxFamilyIdToNId(SfxStyleFamily nFamily)
+{
+    switch (nFamily)
+    {
+        case SfxStyleFamily::Char:
+            return 1;
+        case SfxStyleFamily::Para:
+            return 2;
+        case SfxStyleFamily::Frame:
+            return 3;
+        case SfxStyleFamily::Page:
+            return 4;
+        case SfxStyleFamily::Pseudo:
+            return 5;
+        case SfxStyleFamily::Table:
+            return 6;
+        default:
+            return 0xffff;
+    }
+}
+// converts from 1-6 to SFX_STYLE_FAMILY Ids
+static SfxStyleFamily NIdToSfxFamilyId(sal_uInt16 nId)
+{
+    switch (nId)
+    {
+        case 1:
+            return SfxStyleFamily::Char;
+        case 2:
+            return SfxStyleFamily::Para;
+        case 3:
+            return SfxStyleFamily::Frame;
+        case 4:
+            return SfxStyleFamily::Page;
+        case 5:
+            return SfxStyleFamily::Pseudo;
+        case 6:
+            return SfxStyleFamily::Table;
+        default:
+            return SfxStyleFamily::All;
+    }
+}
+}
+
+sal_uInt16 StyleList::StyleNrToInfoOffset(sal_uInt16 nId)
+{
+    const SfxStyleFamilyItem& rItem = m_xStyleFamilies->at(nId);
+    return SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily()) - 1;
+}
+
+// Helper function: Access to the current family item
+const SfxStyleFamilyItem* StyleList::GetFamilyItem() const
+{
+    const size_t nCount = m_xStyleFamilies->size();
+    for (size_t i = 0; i < nCount; ++i)
+    {
+        const SfxStyleFamilyItem& rItem = m_xStyleFamilies->at(i);
+        sal_uInt16 nId = SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily());
+        if (nId == m_nActFamily)
+            return &rItem;
+    }
+    return nullptr;
+}
+
+void StyleList::GetSelectedStyle() const
+{
+    const OUString aTemplName(GetSelectedEntry());
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
+}
+
+// Used to get the current selected entry in visible treeview
+OUString StyleList::GetSelectedEntry() const
+{
+    OUString aRet;
+    if (m_xTreeBox->get_visible())
+        aRet = m_xTreeBox->get_selected_text();
+    else
+        aRet = m_xFmtLb->get_selected_text();
+    return aRet;
+}
+
+/**
+ * Is it safe to show the water-can / fill icon. If we've a
+ * hierarchical widget - we have only single select, otherwise
+ * we need to check if we have a multi-selection. We either have
+ * a m_xTreeBox showing or an m_xFmtLb (which we hide when not shown)
+ */
+IMPL_LINK_NOARG(StyleList, IsSafeForWaterCan, void*, bool)
+{
+    if (m_xTreeBox->get_visible())
+        return m_xTreeBox->get_selected_index() != -1;
+    else
+        return m_xFmtLb->count_selected_rows() == 1;
+}
+
+IMPL_LINK(StyleList, SetWaterCanState, const SfxBoolItem*, pItem, void)
+{
+    size_t nCount = m_xStyleFamilies->size();
+    m_pBindings->EnterRegistrations();
+    for (size_t n = 0; n < nCount; n++)
+    {
+        SfxControllerItem* pCItem = pBoundItems[n].get();
+        bool bChecked = pItem && pItem->GetValue();
+        if (pCItem->IsBound() == bChecked)
+        {
+            if (!bChecked)
+                pCItem->ReBind();
+            else
+                pCItem->UnBind();
+        }
+    }
+    m_pBindings->LeaveRegistrations();
+}
+
+IMPL_LINK(StyleList, FamilySelect, sal_uInt16, nEntry, void)
+{
+    m_nActFamily = nEntry;
+    SfxDispatcher* pDispat = m_pBindings->GetDispatcher_Impl();
+    SfxUInt16Item const aItem(SID_STYLE_FAMILY,
+                              static_cast<sal_uInt16>(SfxTemplate::NIdToSfxFamilyId(nEntry)));
+    pDispat->ExecuteList(SID_STYLE_FAMILY, SfxCallMode::SYNCHRON, { &aItem });
+    m_pBindings->Invalidate(SID_STYLE_FAMILY);
+    m_pBindings->Update(SID_STYLE_FAMILY);
+    m_aUpdateFamily.Call(*this);
+}
+
+// It selects the style in treeview
+// bIsCallBack is true for the selected style. For eg. if "Addressee" is selected in
+// styles, bIsCallBack will be true for it.
+void StyleList::SelectStyle(const OUString& rStr, bool bIsCallback)
+{
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    if (!pItem)
+        return;
+    const SfxStyleFamily eFam = pItem->GetFamily();
+    SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(rStr, eFam);
+    if (pStyle)
+    {
+        bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
+        m_pParentDialog->EnableEdit(bReadWrite);
+        m_pParentDialog->EnableHide(bReadWrite && !pStyle->IsHidden() && !pStyle->IsUsed());
+        m_pParentDialog->EnableShow(bReadWrite && pStyle->IsHidden());
+    }
+    else
+    {
+        m_pParentDialog->EnableEdit(false);
+        m_pParentDialog->EnableHide(false);
+        m_pParentDialog->EnableShow(false);
+    }
+
+    if (!bIsCallback)
+    {
+        if (m_xTreeBox->get_visible())
+        {
+            if (!rStr.isEmpty())
+            {
+                std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
+                bool bEntry = m_xTreeBox->get_iter_first(*xEntry);
+                while (bEntry)
+                {
+                    if (m_xTreeBox->get_text(*xEntry) == rStr)
+                    {
+                        m_xTreeBox->scroll_to_row(*xEntry);
+                        m_xTreeBox->select(*xEntry);
+                        break;
+                    }
+                    bEntry = m_xTreeBox->iter_next(*xEntry);
+                }
+            }
+            else if (eFam == SfxStyleFamily::Pseudo)
+            {
+                std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
+                if (m_xTreeBox->get_iter_first(*xEntry))
+                {
+                    m_xTreeBox->scroll_to_row(*xEntry);
+                    m_xTreeBox->select(*xEntry);
+                }
+            }
+            else
+                m_xTreeBox->unselect_all();
+        }
+        else
+        {
+            bool bSelect = !rStr.isEmpty();
+            if (bSelect)
+            {
+                std::unique_ptr<weld::TreeIter> xEntry = m_xFmtLb->make_iterator();
+                bool bEntry = m_xFmtLb->get_iter_first(*xEntry);
+                while (bEntry && m_xFmtLb->get_text(*xEntry) != rStr)
+                    bEntry = m_xFmtLb->iter_next(*xEntry);
+                if (!bEntry)
+                    bSelect = false;
+                else
+                {
+                    if (!m_xFmtLb->is_selected(*xEntry))
+                    {
+                        m_xFmtLb->unselect_all();
+                        m_xFmtLb->scroll_to_row(*xEntry);
+                        m_xFmtLb->select(*xEntry);
+                    }
+                }
+            }
+
+            if (!bSelect)
+            {
+                m_xFmtLb->unselect_all();
+                m_pParentDialog->EnableEdit(false);
+                m_pParentDialog->EnableHide(false);
+                m_pParentDialog->EnableShow(false);
+            }
+        }
+    }
+}
+
+static void MakeExpanded_Impl(const weld::TreeView& rBox, std::vector<OUString>& rEntries)
+{
+    std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
+    if (rBox.get_iter_first(*xEntry))
+    {
+        do
+        {
+            if (rBox.get_row_expanded(*xEntry))
+                rEntries.push_back(rBox.get_text(*xEntry));
+        } while (rBox.iter_next(*xEntry));
+    }
+}
+
+IMPL_LINK(StyleList, EnableTreeDrag, bool, m_bEnable, void)
+{
+    if (m_pStyleSheetPool)
+    {
+        const SfxStyleFamilyItem* pItem = GetFamilyItem();
+        SfxStyleSheetBase* pStyle = pItem ? m_pStyleSheetPool->First(pItem->GetFamily()) : nullptr;
+        m_bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && m_bEnable;
+    }
+    m_bTreeDrag = m_bEnable;
+    m_pParentDialog->SetEnableDrag(m_bTreeDrag);
+}
+
+// Fill the treeview
+
+void StyleList::FillTreeBox(SfxStyleFamily eFam)
+{
+    assert(m_xTreeBox && "FillTreeBox() without treebox");
+    if (!m_pStyleSheetPool || m_nActFamily == 0xffff)
+        return;
+
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    if (!pItem)
+        return;
+
+    StyleTreeArr_Impl aArr;
+    SfxStyleSheetBase* pStyle = m_pStyleSheetPool->First(eFam, SfxStyleSearchBits::AllVisible);
+
+    m_bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && m_bTreeDrag;
+
+    while (pStyle)
+    {
+        StyleTree_Impl* pNew = new StyleTree_Impl(pStyle->GetName(), pStyle->GetParent());
+        aArr.emplace_back(pNew);
+        pStyle = m_pStyleSheetPool->Next();
+    }
+    OUString aUIName = getDefaultStyleName(eFam);
+    MakeTree_Impl(aArr, aUIName);
+    std::vector<OUString> aEntries;
+    MakeExpanded_Impl(*m_xTreeBox, aEntries);
+    m_xTreeBox->freeze();
+    m_xTreeBox->clear();
+    const sal_uInt16 nCount = aArr.size();
+
+    for (sal_uInt16 i = 0; i < nCount; ++i)
+    {
+        FillBox_Impl(*m_xTreeBox, aArr[i].get(), aEntries, eFam, nullptr);
+        aArr[i].reset();
+    }
+
+    m_pParentDialog->EnableItem("watercan", false);
+
+    SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
+
+    m_xTreeBox->thaw();
+
+    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
+    bool bEntry = m_xTreeBox->get_iter_first(*xEntry);
+    if (bEntry && nCount)
+        m_xTreeBox->expand_row(*xEntry);
+
+    while (bEntry)
+    {
+        if (IsExpanded_Impl(aEntries, m_xTreeBox->get_text(*xEntry)))
+            m_xTreeBox->expand_row(*xEntry);
+        bEntry = m_xTreeBox->iter_next(*xEntry);
+    }
+
+    OUString aStyle;
+    if (pState) // Select current entry
+        aStyle = pState->GetStyleName();
+    m_pParentDialog->SelectStyle(aStyle, false, *this);
+    EnableDelete(nullptr);
+}
+
+static OUString lcl_GetStyleFamilyName(SfxStyleFamily nFamily)
+{
+    if (nFamily == SfxStyleFamily::Char)
+        return "CharacterStyles";
+    if (nFamily == SfxStyleFamily::Para)
+        return "ParagraphStyles";
+    if (nFamily == SfxStyleFamily::Page)
+        return "PageStyles";
+    if (nFamily == SfxStyleFamily::Table)
+        return "TableStyles";
+    if (nFamily == SfxStyleFamily::Pseudo)
+        return "NumberingStyles";
+    return OUString();
+}
+
+OUString StyleList::getDefaultStyleName(const SfxStyleFamily eFam)
+{
+    OUString sDefaultStyle;
+    OUString aFamilyName = lcl_GetStyleFamilyName(eFam);
+    if (aFamilyName == "TableStyles")
+        sDefaultStyle = "Default Style";
+    else if (aFamilyName == "NumberingStyles")
+        sDefaultStyle = "No List";
+    else
+        sDefaultStyle = "Standard";
+    uno::Reference<style::XStyleFamiliesSupplier> xModel(m_pCurObjShell->GetModel(),
+                                                         uno::UNO_QUERY);
+    OUString aUIName;
+    try
+    {
+        uno::Reference<container::XNameAccess> xStyles;
+        uno::Reference<container::XNameAccess> xCont = xModel->getStyleFamilies();
+        xCont->getByName(aFamilyName) >>= xStyles;
+        uno::Reference<beans::XPropertySet> xInfo;
+        xStyles->getByName(sDefaultStyle) >>= xInfo;
+        xInfo->getPropertyValue("DisplayName") >>= aUIName;
+    }
+    catch (const uno::Exception&)
+    {
+    }
+    return aUIName;
+}
+
+SfxStyleFamily StyleList::GetActualFamily() const
+{
+    const SfxStyleFamilyItem* pFamilyItem = GetFamilyItem();
+    if (!pFamilyItem || m_nActFamily == 0xffff)
+        return SfxStyleFamily::Para;
+    else
+        return pFamilyItem->GetFamily();
+}
+
+IMPL_LINK_NOARG(StyleList, HasSelectedStyle, void*, bool)
+{
+    return m_xTreeBox->get_visible() ? m_xTreeBox->get_selected_index() != -1
+                                     : m_xFmtLb->count_selected_rows() != 0;
+}
+
+IMPL_LINK_NOARG(StyleList, UpdateStyleDependents, void*, void)
+{
+    // Trigger Help PI. Only when the watercan is on
+    if (m_nActFamily != 0xffff && m_pParentDialog->IsCheckedItem("watercan") &&
+        // only if that region is allowed
+        nullptr != m_pFamilyState[m_nActFamily - 1]
+        && (m_xTreeBox || m_xFmtLb->count_selected_rows() <= 1))
+    {
+        m_pParentDialog->Execute_Impl(SID_STYLE_WATERCAN, "", "", 0, *this);
+        m_pParentDialog->Execute_Impl(SID_STYLE_WATERCAN, GetSelectedEntry(), "",
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
+    }
+}
+
+// Comes into action when the current style is changed
+IMPL_LINK(StyleList, UpdateStyles, StyleFlags, nFlags, void)
+{
+    OSL_ENSURE(nFlags != StyleFlags::NONE, "nothing to do");
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    if (!pItem)
+    {
+        // Is the case for the template catalog
+        const size_t nFamilyCount = m_xStyleFamilies->size();
+        size_t n;
+        for (n = 0; n < nFamilyCount; n++)
+            if (m_pFamilyState[StyleNrToInfoOffset(n)])
+                break;
+        if (n == nFamilyCount)
+            // It happens sometimes, God knows why
+            return;
+        m_nAppFilter = m_pFamilyState[StyleNrToInfoOffset(n)]->GetValue();
+        m_pParentDialog->SetApplicationFilter(m_nAppFilter);
+        m_pParentDialog->FamilySelect(StyleNrToInfoOffset(n) + 1);
+        pItem = GetFamilyItem();
+    }
+
+    const SfxStyleFamily eFam = pItem->GetFamily();
+
+    SfxStyleSearchBits nFilter(m_nActFilter < pItem->GetFilterList().size()
+                                   ? pItem->GetFilterList()[m_nActFilter].nFlags
+                                   : SfxStyleSearchBits::Auto);
+    if (nFilter == SfxStyleSearchBits::Auto) // automatic
+        nFilter = m_nAppFilter;
+
+    OSL_ENSURE(m_pStyleSheetPool, "no StyleSheetPool");
+    if (!m_pStyleSheetPool)
+        return;
+
+    pItem = GetFamilyItem();
+
+    m_aUpdateStyles.Call(nFlags);
+
+    SfxStyleSheetBase* pStyle = m_pStyleSheetPool->First(eFam, nFilter);
+
+    std::unique_ptr<weld::TreeIter> xEntry = m_xFmtLb->make_iterator();
+    bool bEntry = m_xFmtLb->get_iter_first(*xEntry);
+    std::vector<OUString> aStrings;
+
+    comphelper::string::NaturalStringSorter aSorter(
+        ::comphelper::getProcessComponentContext(),
+        Application::GetSettings().GetLanguageTag().getLocale());
+
+    while (pStyle)
+    {
+        aStrings.push_back(pStyle->GetName());
+        pStyle = m_pStyleSheetPool->Next();
+    }
+    OUString aUIName = getDefaultStyleName(eFam);
+
+    // Paradoxically, with a list and non-Latin style names,
+    // sorting twice is faster than sorting once.
+    // The first sort has a cheap comparator, and gets the list into mostly-sorted order.
+    // Then the second sort needs to call its (much more expensive) comparator less often.
+    std::sort(aStrings.begin(), aStrings.end());
+    std::sort(aStrings.begin(), aStrings.end(),
+              [&aSorter, &aUIName](const OUString& rLHS, const OUString& rRHS) {
+                  if (rRHS == aUIName)
+                      return false;
+                  if (rLHS == aUIName)
+                      return true; // default always first
+                  return aSorter.compare(rLHS, rRHS) < 0;
+              });
+
+    size_t nCount = aStrings.size();
+    size_t nPos = 0;
+    while (nPos < nCount && bEntry && aStrings[nPos] == m_xFmtLb->get_text(*xEntry))
+    {
+        ++nPos;
+        bEntry = m_xFmtLb->iter_next(*xEntry);
+    }
+
+    if (nPos < nCount || bEntry)
+    {
+        // Fills the display box
+        m_xFmtLb->freeze();
+        m_xFmtLb->clear();
+
+        for (nPos = 0; nPos < nCount; ++nPos)
+            m_xFmtLb->append(aStrings[nPos], aStrings[nPos]);
+
+        m_xFmtLb->thaw();
+    }
+    // Selects the current style if any
+    SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
+    OUString aStyle;
+    if (pState)
+        aStyle = pState->GetStyleName();
+    m_pParentDialog->SelectStyle(aStyle, false, *this);
+    EnableDelete(nullptr);
+}
+
+void StyleList::SetFamilyState(sal_uInt16 nSlotId, const SfxTemplateItem* pItem)
+{
+    sal_uInt16 nIdx = nSlotId - SID_STYLE_FAMILY_START;
+    m_pFamilyState[nIdx].reset();
+    if (pItem)
+        m_pFamilyState[nIdx].reset(new SfxTemplateItem(*pItem));
+    m_bUpdateFamily = true;
+}
+
+void StyleList::SetHierarchical()
+{
+    m_bHierarchical = true;
+    const OUString aSelectEntry(GetSelectedEntry());
+    m_xFmtLb->hide();
+    FillTreeBox(GetActualFamily());
+    m_pParentDialog->SelectStyle(aSelectEntry, false, *this);
+    m_xTreeBox->show();
+}
+
+void StyleList::SetFilterControlsHandle()
+{
+    m_xTreeBox->hide();
+    m_xFmtLb->show();
+    m_bHierarchical = false;
+}
+
+// Handler for the New-Buttons
+void StyleList::NewHdl()
+{
+    if (m_nActFamily == 0xffff
+        || !(m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1))
+        return;
+
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    const SfxStyleFamily eFam = pItem->GetFamily();
+    SfxStyleSearchBits nMask(SfxStyleSearchBits::Auto);
+    if (m_nActFilter != 0xffff)
+        nMask = pItem->GetFilterList()[m_nActFilter].nFlags;
+    if (nMask == SfxStyleSearchBits::Auto) // automatic
+        nMask = m_nAppFilter;
+
+    m_pParentDialog->Execute_Impl(SID_STYLE_NEW, "", GetSelectedEntry(),
+                                  static_cast<sal_uInt16>(eFam), *this, nMask);
+}
+
+// Handler for the edit-Buttons
+void StyleList::EditHdl()
+{
+    if (m_nActFamily != 0xffff && HasSelectedStyle(nullptr))
+    {
+        sal_uInt16 nFilter = m_nActFilter;
+        OUString aTemplName(GetSelectedEntry());
+        GetSelectedStyle(); // -Wall required??
+        m_pParentDialog->Execute_Impl(SID_STYLE_EDIT, aTemplName, OUString(),
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this,
+                                      SfxStyleSearchBits::Auto, &nFilter);
+    }
+}
+
+// Handler for the Delete-Buttons
+void StyleList::DeleteHdl()
+{
+    if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
+        return;
+
+    bool bUsedStyle = false; // one of the selected styles are used in the document?
+
+    std::vector<std::unique_ptr<weld::TreeIter>> aList;
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+
+    OUStringBuffer aMsg;
+    aMsg.append(SfxResId(STR_DELETE_STYLE_USED) + SfxResId(STR_DELETE_STYLE));
+
+    pTreeView->selected_foreach(
+        [this, pTreeView, pItem, &aList, &bUsedStyle, &aMsg](weld::TreeIter& rEntry) {
+            aList.emplace_back(pTreeView->make_iterator(&rEntry));
+            // check the style is used or not
+            const OUString aTemplName(pTreeView->get_text(rEntry));
+
+            SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
+
+            if (pStyle->IsUsed()) // pStyle is in use in the document?
+            {
+                if (bUsedStyle) // add a separator for the second and later styles
+                    aMsg.append(", ");
+                aMsg.append(aTemplName);
+                bUsedStyle = true;
+            }
+
+            return false;
+        });
+
+    bool aApproved = false;
+
+    // we only want to show the dialog once and if we want to delete a style in use (UX-advice)
+    if (bUsedStyle)
+    {
+        std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
+            pTreeView, VclMessageType::Question, VclButtonsType::YesNo, aMsg.makeStringAndClear()));
+        aApproved = xBox->run() == RET_YES;
+    }
+
+    // if there are no used styles selected or the user approved the changes
+    if (bUsedStyle && !aApproved)
+        return;
+
+    for (auto const& elem : aList)
+    {
+        const OUString aTemplName(pTreeView->get_text(*elem));
+        m_bDontUpdate = true; // To prevent the Treelistbox to shut down while deleting
+        m_pParentDialog->Execute_Impl(SID_STYLE_DELETE, aTemplName, OUString(),
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
+
+        if (m_xTreeBox->get_visible())
+        {
+            weld::RemoveParentKeepChildren(*m_xTreeBox, *elem);
+            m_bDontUpdate = false;
+        }
+    }
+    m_bDontUpdate = false; // if everything is deleted set m_bDontUpdate back to false
+    UpdateStyles(StyleFlags::UpdateFamilyList); // and force-update the list
+}
+
+void StyleList::HideHdl()
+{
+    if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
+        return;
+
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry) {
+        OUString aTemplName = pTreeView->get_text(rEntry);
+
+        m_pParentDialog->Execute_Impl(SID_STYLE_HIDE, aTemplName, OUString(),
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
+
+        return false;
+    });
+}
+
+void StyleList::ShowHdl()
+{
+    if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
+        return;
+
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry) {
+        OUString aTemplName = pTreeView->get_text(rEntry);
+
+        m_pParentDialog->Execute_Impl(SID_STYLE_SHOW, aTemplName, OUString(),
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
+
+        return false;
+    });
+}
+
+IMPL_LINK_NOARG(StyleList, EnableDelete, void*, void)
+{
+    bool bEnableDelete(false);
+    if (m_nActFamily != 0xffff && HasSelectedStyle(nullptr))
+    {
+        OSL_ENSURE(m_pStyleSheetPool, "No StyleSheetPool");
+        const OUString aTemplName(GetSelectedEntry());
+        const SfxStyleFamilyItem* pItem = GetFamilyItem();
+        const SfxStyleFamily eFam = pItem->GetFamily();
+        SfxStyleSearchBits nFilter = SfxStyleSearchBits::Auto;
+        if (pItem->GetFilterList().size() > m_nActFilter)
+            nFilter = pItem->GetFilterList()[m_nActFilter].nFlags;
+        if (nFilter == SfxStyleSearchBits::Auto) // automatic
+            nFilter = m_nAppFilter;
+        const SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(
+            aTemplName, eFam, m_xTreeBox->get_visible() ? SfxStyleSearchBits::All : nFilter);
+
+        OSL_ENSURE(pStyle, "Style not found");
+        if (pStyle && pStyle->IsUserDefined())
+        {
+            if (pStyle->HasClearParentSupport() || !pStyle->IsUsed())
+            {
+                bEnableDelete = true;
+            }
+            else if (pStyle->GetFamily() == SfxStyleFamily::Page)
+            {
+                // Hack to allow Calc page styles to be deleted,
+                // remove when IsUsed is fixed for Calc page styles.
+                SfxViewFrame* pFrame = m_pCurObjShell->GetFrame();
+                if (pFrame)
+                {
+                    uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
+                    if (vcl::CommandInfoProvider::GetModuleIdentifier(xFrame)
+                        == "com.sun.star.sheet.SpreadsheetDocument")
+                    {
+                        bEnableDelete = true;
+                    }
+                }
+            }
+        }
+    }
+    m_pParentDialog->EnableDel(bEnableDelete);
+}
+
+IMPL_LINK_NOARG(StyleList, Clear, void*, void)
+{
+    m_xStyleFamilies.reset();
+    for (auto& i : m_pFamilyState)
+        i.reset();
+    m_pCurObjShell = nullptr;
+    for (auto& i : pBoundItems)
+        i.reset();
+}
+
+void StyleList::ShowMenu(const CommandEvent& rCEvt)
+{
+    CreateContextMenu();
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    OString sCommand(
+        mxMenu->popup_at_rect(pTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
+    MenuSelect(sCommand);
+}
+
+void StyleList::MenuSelect(const OString& rIdent)
+{
+    sLastItemIdent = rIdent;
+    if (sLastItemIdent.isEmpty())
+        return;
+    Application::PostUserEvent(LINK(this, StyleList, MenuSelectAsyncHdl)); /***check this****/
+}
+
+void StyleList::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+    const SfxHintId nId = rHint.GetId();
+
+    switch (nId)
+    {
+        case SfxHintId::UpdateDone:
+        {
+            SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
+            SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
+            if (m_pParentDialog->GetNotifyUpdate()
+                && (!m_pParentDialog->IsCheckedItem("watercan")
+                    || (pDocShell && pDocShell->GetStyleSheetPool() != m_pStyleSheetPool)))
+            {
+                m_pParentDialog->SetNotifyupdate(false);
+                Update();
+            }
+            else if (m_bUpdateFamily)
+            {
+                m_aUpdateFamily.Call(*this);
+            }
+
+            if (m_pStyleSheetPool)
+            {
+                OUString aStr = GetSelectedEntry();
+                if (!aStr.isEmpty())
+                {
+                    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+                    if (!pItem)
+                        break;
+                    const SfxStyleFamily eFam = pItem->GetFamily();
+                    SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aStr, eFam);
+                    if (pStyle)
+                    {
+                        bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
+                        m_pParentDialog->EnableEdit(bReadWrite);
+                        m_pParentDialog->EnableHide(bReadWrite && !pStyle->IsUsed()
+                                                    && !pStyle->IsHidden());
+                        m_pParentDialog->EnableShow(bReadWrite && pStyle->IsHidden());
+                    }
+                    else
+                    {
+                        m_pParentDialog->EnableEdit(false);
+                        m_pParentDialog->EnableHide(false);
+                        m_pParentDialog->EnableShow(false);
+                    }
+                }
+            }
+            break;
+        }
+
+        // Necessary if switching between documents and in both documents
+        // the same template is used. Do not immediately call Update_Impl,
+        // for the case that one of the documents is an internal InPlaceObject!
+        case SfxHintId::DocChanged:
+            m_pParentDialog->SetNotifyupdate(true);
+            break;
+        case SfxHintId::Dying:
+        {
+            EndListening(*m_pStyleSheetPool);
+            m_pStyleSheetPool = nullptr;
+            break;
+        }
+        default:
+            break;
+    }
+
+    // Do not set timer when the stylesheet pool is in the box, because it is
+    // possible that a new one is registered after the timer is up -
+    // works bad in UpdateStyles_Impl ()!
+
+    if (!m_bDontUpdate && nId != SfxHintId::Dying
+        && (dynamic_cast<const SfxStyleSheetPoolHint*>(&rHint)
+            || dynamic_cast<const SfxStyleSheetHint*>(&rHint)
+            || dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint)
+            || nId == SfxHintId::StyleSheetModified))
+    {
+        if (!pIdle)
+        {
+            pIdle.reset(new Idle("SfxCommonTemplate"));
+            pIdle->SetPriority(TaskPriority::LOWEST);
+            pIdle->SetInvokeHandler(LINK(this, StyleList, TimeOut));
+        }
+        pIdle->Start();
+    }
+}
+
+IMPL_LINK_NOARG(StyleList, TimeOut, Timer*, void)
+{
+    if (!m_bDontUpdate)
+    {
+        m_bDontUpdate = true;
+        if (!m_xTreeBox->get_visible())
+            UpdateStyles(StyleFlags::UpdateFamilyList);
+        else
+        {
+            FillTreeBox(GetActualFamily());
+            SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
+            if (pState)
+            {
+                m_pParentDialog->SelectStyle(pState->GetStyleName(), false, *this);
+                EnableDelete(nullptr);
+            }
+        }
+        m_bDontUpdate = false;
+        pIdle.reset();
+    }
+    else
+        pIdle->Start();
+}
+
+IMPL_LINK_NOARG(StyleList, MenuSelectAsyncHdl, void*, void)
+{
+    if (sLastItemIdent == "new")
+        NewHdl();
+    else if (sLastItemIdent == "edit")
+        EditHdl();
+    else if (sLastItemIdent == "delete")
+        DeleteHdl();
+    else if (sLastItemIdent == "hide")
+        HideHdl();
+    else if (sLastItemIdent == "show")
+        ShowHdl();
+}
+
+// Double-click on a style sheet in the ListBox is applied.
+IMPL_LINK(StyleList, DragBeginHdl, bool&, rUnsetDragIcon, bool)
+{
+    rUnsetDragIcon = false;
+    // Allow normal processing. only if bAllowReParentDrop is true
+    return !m_bAllowReParentDrop;
+}
+
+IMPL_LINK(StyleList, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+    bool bRet = false;
+    const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
+    if (m_bCanDel && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_DELETE)
+    {
+        DeleteHdl();
+        bRet = true;
+    }
+    return bRet;
+}
+
+IMPL_LINK(StyleList, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
+{
+    weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
+    const OUString aTemplName(pTreeView->get_text(rEntry));
+    OUString sQuickHelpText(aTemplName);
+
+    const SfxStyleFamilyItem* pItem = GetFamilyItem();
+    if (!pItem)
+        return sQuickHelpText;
+    SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
+
+    if (pStyle && pStyle->IsUsed()) // pStyle is in use in the document?
+    {
+        OUString sUsedBy;
+        if (pStyle->GetFamily() == SfxStyleFamily::Pseudo)
+            sUsedBy = pStyle->GetUsedBy();
+
+        if (!sUsedBy.isEmpty())
+        {
+            const sal_Int32 nMaxLen = 80;
+            if (sUsedBy.getLength() > nMaxLen)
+            {
+                sUsedBy = OUString::Concat(sUsedBy.subView(0, nMaxLen)) + "...";
+            }
+
+            OUString aMessage = SfxResId(STR_STYLEUSEDBY);
+            aMessage = aMessage.replaceFirst("%STYLELIST", sUsedBy);
+            sQuickHelpText = aTemplName + " " + aMessage;
+        }
+    }
+
+    return sQuickHelpText;
+}
+
+IMPL_LINK(StyleList, CustomRenderHdl, weld::TreeView::render_args, aPayload, void)
+{
+    vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
+    const ::tools::Rectangle& rRect = std::get<1>(aPayload);
+    ::tools::Rectangle aRect(
+        rRect.TopLeft(),
+        Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), rRect.GetHeight()));
+    bool bSelected = std::get<2>(aPayload);
+    const OUString& rId = std::get<3>(aPayload);
+
+    rRenderContext.Push(PushFlags::TEXTCOLOR);
+    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+    if (bSelected)
+        rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
+    else
+        rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
+
+    bool bSuccess = false;
+
+    SfxObjectShell* pShell = SfxObjectShell::Current();
+    sfx2::StyleManager* pStyleManager = pShell ? pShell->GetStyleManager() : nullptr;
+
+    if (pStyleManager)
+    {
+        const SfxStyleFamilyItem* pItem = GetFamilyItem();
+        SfxStyleSheetBase* pStyleSheet = pStyleManager->Search(rId, pItem->GetFamily());
+
+        if (pStyleSheet)
+        {
+            rRenderContext.Push(PushFlags::ALL);
+            sal_Int32 nSize = aRect.GetHeight();
+            std::unique_ptr<sfx2::StylePreviewRenderer> pStylePreviewRenderer(
+                pStyleManager->CreateStylePreviewRenderer(rRenderContext, pStyleSheet, nSize));
+            bSuccess = pStylePreviewRenderer->recalculate() && pStylePreviewRenderer->render(aRect);
+            rRenderContext.Pop();
+        }
+    }
+
+    if (!bSuccess)
+        rRenderContext.DrawText(aRect, rId, DrawTextFlags::Left | DrawTextFlags::VCenter);
+
+    rRenderContext.Pop();
+}
+
+// Selection of a template during the Watercan-Status
+IMPL_LINK(StyleList, FmtSelectHdl, weld::TreeView&, rListBox, void)
+{
+    std::unique_ptr<weld::TreeIter> xHdlEntry = rListBox.make_iterator();
+    if (!rListBox.get_cursor(xHdlEntry.get()))
+        return;
+
+    if (rListBox.is_selected(*xHdlEntry))
+        m_aUpdateStyleDependents.Call(nullptr);
+
+    m_pParentDialog->SelectStyle(rListBox.get_text(*xHdlEntry), true, *this);
+}
+
+IMPL_LINK_NOARG(StyleList, TreeListApplyHdl, weld::TreeView&, bool)
+{
+    // only if that region is allowed
+    if (m_nActFamily != 0xffff && nullptr != m_pFamilyState[m_nActFamily - 1]
+        && !GetSelectedEntry().isEmpty())
+    {
+        m_pParentDialog->Execute_Impl(SID_STYLE_APPLY, GetSelectedEntry(), OUString(),
+                                      static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this,
+                                      SfxStyleSearchBits::Auto, nullptr, &m_nModifier);
+    }
+    // After selecting a focused item if possible again on the app window
+    if (dynamic_cast<const SfxTemplateDialog_Impl*>(m_pParentDialog) != nullptr)
+    {
+        SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
+        SfxViewShell* pVu = pViewFrame->GetViewShell();
+        vcl::Window* pAppWin = pVu ? pVu->GetWindow() : nullptr;
+        if (pAppWin)
+            pAppWin->GrabFocus();
+    }
+
+    return true;
+}
+
+IMPL_LINK(StyleList, MousePressHdl, const MouseEvent&, rMEvt, bool)
+{
+    m_nModifier = rMEvt.GetModifier();
+    return false;
+}
+
+// Notice from SfxBindings that the update is completed. Pushes out the update
+// of the display.
+void StyleList::Update()
+{
+    bool bDocChanged = false;
+    SfxStyleSheetBasePool* pNewPool = nullptr;
+    SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
+    SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
+    if (pDocShell)
+        pNewPool = pDocShell->GetStyleSheetPool();
+
+    if (pNewPool != m_pStyleSheetPool && pDocShell)
+    {
+        SfxModule* pNewModule = pDocShell->GetModule();
+        if (pNewModule && pNewModule != m_Module)
+        {
+            m_aClearResource.Call(nullptr);
+            m_aReadResource.Call(*this);
+        }
+        if (m_pStyleSheetPool)
+        {
+            EndListening(*m_pStyleSheetPool);
+            m_pStyleSheetPool = nullptr;
+        }
+
+        if (pNewPool)
+        {
+            StartListening(*pNewPool);
+            m_pStyleSheetPool = pNewPool;
+            bDocChanged = true;
+        }
+    }
+
+    if (m_bUpdateFamily)
+        m_aUpdateFamily.Call(*this);
+
+    sal_uInt16 i;
+    for (i = 0; i < MAX_FAMILIES; ++i)
+        if (m_pFamilyState[i])
+            break;
+    if (i == MAX_FAMILIES || !pNewPool)
+        // nothing is allowed
+        return;
+
+    SfxTemplateItem* pItem = nullptr;
+    // current region not within the allowed region or default
+    if (m_nActFamily == 0xffff || nullptr == (pItem = m_pFamilyState[m_nActFamily - 1].get()))
+    {
+        m_pParentDialog->CheckItem(OString::number(m_nActFamily), false);
+        const size_t nFamilyCount = m_xStyleFamilies->size();
+        size_t n;
+        for (n = 0; n < nFamilyCount; n++)
+            if (m_pFamilyState[StyleNrToInfoOffset(n)])
+                break;
+
+        std::unique_ptr<SfxTemplateItem>& pNewItem = m_pFamilyState[StyleNrToInfoOffset(n)];
+        m_nAppFilter = pNewItem->GetValue();
+        m_pParentDialog->SetApplicationFilter(m_nAppFilter);
+        m_pParentDialog->FamilySelect(StyleNrToInfoOffset(n) + 1);
+        pItem = pNewItem.get();
+    }
+    else if (bDocChanged)
+    {
+        // other DocShell -> all new
+        m_pParentDialog->CheckItem(OString::number(m_nActFamily));
+        m_nActFilter = static_cast<sal_uInt16>(m_aLoadFactoryStyleFilter.Call(pDocShell));
+        m_pParentDialog->SetFilterByIndex(m_nActFilter);
+        if (0xffff == m_nActFilter)
+        {
+            m_nActFilter = pDocShell->GetAutoStyleFilterIndex();
+            m_pParentDialog->SetFilterByIndex(m_nActFilter);
+        }
+
+        m_nAppFilter = pItem->GetValue();
+        m_pParentDialog->SetApplicationFilter(m_nAppFilter);
+        if (!m_xTreeBox->get_visible())
+        {
+            UpdateStyles(StyleFlags::UpdateFamilyList);
+        }
+        else
+            FillTreeBox(GetActualFamily());
+    }
+    else
+    {
+        // other filters for automatic
+        m_pParentDialog->CheckItem(OString::number(m_nActFamily));
+        const SfxStyleFamilyItem* pStyleItem = GetFamilyItem();
+        if (pStyleItem
+            && SfxStyleSearchBits::Auto == pStyleItem->GetFilterList()[m_nActFilter].nFlags
+            && m_nAppFilter != pItem->GetValue())
+        {
+            m_nAppFilter = pItem->GetValue();
+            m_pParentDialog->SetApplicationFilter(m_nAppFilter);
+            if (!m_xTreeBox->get_visible())
+                UpdateStyles(StyleFlags::UpdateFamilyList);
+            else
+                FillTreeBox(GetActualFamily());
+        }
+        else
+        {
+            m_nAppFilter = pItem->GetValue();
+            m_pParentDialog->SetApplicationFilter(m_nAppFilter);
+        }
+    }
+    const OUString aStyle(pItem->GetStyleName());
+    m_pParentDialog->SelectStyle(aStyle, false, *this);
+    EnableDelete(nullptr);
+    m_pParentDialog->EnableNew(m_bCanNew);
+}
+
+void StyleList::EnablePreview(bool bCustomPreview)
+{
+    m_xFmtLb->clear();
+    m_xFmtLb->set_column_custom_renderer(0, bCustomPreview);
+    m_xTreeBox->clear();
+    m_xTreeBox->set_column_custom_renderer(0, bCustomPreview);
+}
+
+const SfxStyleFamilyItem& StyleList::GetFamilyItemByIndex(size_t i) const
+{
+    return m_xStyleFamilies->at(i);
+}
+
+IMPL_STATIC_LINK(StyleList, CustomGetSizeHdl, weld::TreeView::get_size_args, aPayload, Size)
+{
+    vcl::RenderContext& rRenderContext = aPayload.first;
+    return Size(42, 32 * rRenderContext.GetDPIScaleFactor());
+}
+
+IMPL_LINK(StyleList, PopupFlatMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+    if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+        return false;
+
+    PrepareMenu(rCEvt.GetMousePosPixel());
+
+    if (m_xFmtLb->count_selected_rows() <= 0)
+    {
+        m_pParentDialog->EnableEdit(false);
+        m_pParentDialog->EnableDel(false);
+    }
+
+    ShowMenu(rCEvt);
+
+    return true;
+}
+
+IMPL_LINK(StyleList, PopupTreeMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+    if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+        return false;
+
+    PrepareMenu(rCEvt.GetMousePosPixel());
+
+    ShowMenu(rCEvt);
+
+    return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/dialog/templdlg.cxx b/sfx2/source/dialog/templdlg.cxx
index 8951cfb71cbf..ae0d646abc75 100644
--- a/sfx2/source/dialog/templdlg.cxx
+++ b/sfx2/source/dialog/templdlg.cxx
@@ -110,415 +110,87 @@ private:
     DeletionWatcher *const m_pPrevious; /// let's add more epicycles!
 };
 
-/** Drop is enabled as long as it is allowed to create a new style by example, i.e. to
-    create a style out of the current selection.
-*/
-sal_Int8 SfxCommonTemplateDialog_Impl::AcceptDrop(const AcceptDropEvent& rEvt, const DropTargetHelper& rHelper)
-{
-    if (rHelper.IsDropFormatSupported(SotClipboardFormatId::OBJECTDESCRIPTOR))
-    {
-        // special case: page styles are allowed to create new styles by example
-        // but not allowed to be created by drag and drop
-        if (GetActualFamily() == SfxStyleFamily::Page || bNewByExampleDisabled)
-            return DND_ACTION_NONE;
-        else
-            return DND_ACTION_COPY;
-    }
-
-    // to enable the autoscroll when we're close to the edges
-    weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
-    pTreeView->get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
-    return DND_ACTION_MOVE;
-}
-
 sal_Int8 SfxCommonTemplateDialog_Impl::ExecuteDrop(const ExecuteDropEvent& rEvt)
 {
     // handle drop of content into the treeview to create a new style
-    SfxObjectShell* pDocShell = GetObjectShell();
-    if (pDocShell)
-    {
-        TransferableDataHelper aHelper(rEvt.maDropEvent.Transferable);
-        sal_uInt32 nFormatCount = aHelper.GetFormatCount();
-
-        sal_Int8 nRet = DND_ACTION_NONE;
-
-        bool bFormatFound = false;
-
-        for ( sal_uInt32 i = 0; i < nFormatCount; ++i )
-        {
-            SotClipboardFormatId nId = aHelper.GetFormat(i);
-            TransferableObjectDescriptor aDesc;
-
-            if ( aHelper.GetTransferableObjectDescriptor( nId, aDesc ) )
-            {
-                if ( aDesc.maClassName == pDocShell->GetFactory().GetClassId() )
-                {
-                    Application::PostUserEvent(LINK(this, SfxCommonTemplateDialog_Impl, OnAsyncExecuteDrop));
-
-                    bFormatFound = true;
-                    nRet =  rEvt.mnAction;
-                    break;
-                }
-            }
-        }
-
-        if (bFormatFound)
-            return nRet;
-    }
-
-    if (!mxTreeBox->get_visible())
-        return DND_ACTION_NONE;
-
-    if (!bAllowReParentDrop)
-        return DND_ACTION_NONE;
-
-    // otherwise if we're dragging with the treeview to set a new parent of the dragged style
-    weld::TreeView* pSource = mxTreeBox->get_drag_source();
-    // only dragging within the same widget allowed
-    if (!pSource || pSource != mxTreeBox.get())
-        return DND_ACTION_NONE;
-
-    std::unique_ptr<weld::TreeIter> xSource(mxTreeBox->make_iterator());
-    if (!mxTreeBox->get_selected(xSource.get()))
-        return DND_ACTION_NONE;
-
-    std::unique_ptr<weld::TreeIter> xTarget(mxTreeBox->make_iterator());
-    if (!mxTreeBox->get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
-    {
-        // if nothing under the mouse, use the last row
-        int nChildren = mxTreeBox->n_children();
-        if (!nChildren)
-            return DND_ACTION_NONE;
-        if (!mxTreeBox->get_iter_first(*xTarget) || !mxTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
-            return DND_ACTION_NONE;
-        while (mxTreeBox->get_row_expanded(*xTarget))
-        {
-            nChildren = mxTreeBox->iter_n_children(*xTarget);
-            if (!mxTreeBox->iter_children(*xTarget) || !mxTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
-                return DND_ACTION_NONE;
-        }
-    }
-    OUString aTargetStyle = mxTreeBox->get_text(*xTarget);
-    DropHdl(mxTreeBox->get_text(*xSource), aTargetStyle);
-    mxTreeBox->unset_drag_dest_row();
-    FillTreeBox();
-    SelectStyle(aTargetStyle, false);
+    m_aStyleListExecuteDrop.Call(rEvt);
     return DND_ACTION_NONE;
 }
 
-IMPL_LINK(SfxCommonTemplateDialog_Impl, DragBeginHdl, bool&, rUnsetDragIcon, bool)
-{
-    rUnsetDragIcon = false;
-    // Allow normal processing. only if bAllowReParentDrop is true
-    return !bAllowReParentDrop;
-}
-
 IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, OnAsyncExecuteDrop, void*, void)
 {
-    ActionSelect("new");
-}
-
-IMPL_LINK(SfxCommonTemplateDialog_Impl, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
-{
-    bool bRet = false;
-    const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
-    if (bCanDel && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_DELETE)
-    {
-        DeleteHdl();
-        bRet =  true;
-    }
-    return bRet;
+    ActionSelect("new", m_aStyleList);
 }
 
-IMPL_LINK(SfxCommonTemplateDialog_Impl, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
+SfxTemplatePanelControl::SfxTemplatePanelControl(SfxBindings* pBindings, weld::Widget* pParent)
+    : PanelLayout(pParent, "TemplatePanel", "sfx/ui/templatepanel.ui")
+    , pImpl(new SfxTemplateDialog_Impl(pBindings, this))
 {
-    weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
-    const OUString aTemplName(pTreeView->get_text(rEntry));
-    OUString sQuickHelpText(aTemplName);
-
-    const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
-    if (!pItem)
-        return sQuickHelpText;
-    SfxStyleSheetBase* pStyle = pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
-
-    if (pStyle && pStyle->IsUsed())  // pStyle is in use in the document?
-    {
-        OUString sUsedBy;
-        if (pStyle->GetFamily() == SfxStyleFamily::Pseudo)
-            sUsedBy = pStyle->GetUsedBy();
-
-        if (!sUsedBy.isEmpty())
-        {
-            const sal_Int32 nMaxLen = 80;
-            if (sUsedBy.getLength() > nMaxLen)
-            {
-                sUsedBy = OUString::Concat(sUsedBy.subView(0, nMaxLen)) + "...";
-            }
-
-            OUString aMessage = SfxResId(STR_STYLEUSEDBY);
-            aMessage = aMessage.replaceFirst("%STYLELIST", sUsedBy);
-            sQuickHelpText = aTemplName + " " + aMessage;
-        }
-    }
-
-    return sQuickHelpText;
+    OSL_ASSERT(pBindings!=nullptr);
 }
 
-IMPL_STATIC_LINK(SfxCommonTemplateDialog_Impl, CustomGetSizeHdl, weld::TreeView::get_size_args, aPayload, Size)
+SfxTemplatePanelControl::~SfxTemplatePanelControl()
 {
-    vcl::RenderContext& rRenderContext = aPayload.first;
-    return Size(42, 32 * rRenderContext.GetDPIScaleFactor());
 }
 
-IMPL_LINK(SfxCommonTemplateDialog_Impl, CustomRenderHdl, weld::TreeView::render_args, aPayload, void)
+namespace SfxTemplate
 {
-    vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
-    const ::tools::Rectangle& rRect = std::get<1>(aPayload);
-    ::tools::Rectangle aRect(rRect.TopLeft(), Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), rRect.GetHeight()));
-    bool bSelected = std::get<2>(aPayload);
-    const OUString& rId = std::get<3>(aPayload);
-
-    rRenderContext.Push(PushFlags::TEXTCOLOR);
-    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
-    if (bSelected)
-        rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
-    else
-        rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
-
-    bool bSuccess = false;
-
-    SfxObjectShell* pShell = SfxObjectShell::Current();
-    sfx2::StyleManager* pStyleManager = pShell ? pShell->GetStyleManager(): nullptr;
-
-    if (pStyleManager)
+    // converts from SFX_STYLE_FAMILY Ids to 1-6
+    static sal_uInt16 SfxFamilyIdToNId(SfxStyleFamily nFamily)
     {
-        const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
-        SfxStyleSheetBase* pStyleSheet = pStyleManager->Search(rId, pItem->GetFamily());
-
-        if (pStyleSheet)
+        switch ( nFamily )
         {
-            rRenderContext.Push(PushFlags::ALL);
-            sal_Int32 nSize = aRect.GetHeight();
-            std::unique_ptr<sfx2::StylePreviewRenderer> pStylePreviewRenderer(
-                pStyleManager->CreateStylePreviewRenderer(rRenderContext, pStyleSheet, nSize));
-            bSuccess = pStylePreviewRenderer->recalculate() && pStylePreviewRenderer->render(aRect);
-            rRenderContext.Pop();
+            case SfxStyleFamily::Char:   return 1;
+            case SfxStyleFamily::Para:   return 2;
+            case SfxStyleFamily::Frame:  return 3;
+            case SfxStyleFamily::Page:   return 4;
+            case SfxStyleFamily::Pseudo: return 5;
+            case SfxStyleFamily::Table:  return 6;
+            default:                     return 0xffff;
         }
     }
-
-    if (!bSuccess)
-        rRenderContext.DrawText(aRect, rId, DrawTextFlags::Left | DrawTextFlags::VCenter);
-
-    rRenderContext.Pop();
 }
 
-IMPL_LINK(SfxCommonTemplateDialog_Impl, PopupFlatMenuHdl, const CommandEvent&, rCEvt, bool)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_execute_drop(
+    const Link<const ExecuteDropEvent&, sal_Int8>& rLink)
 {
-    if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
-        return false;
-
-    PrepareMenu(rCEvt.GetMousePosPixel());
-
-    if (mxFmtLb->count_selected_rows() <= 0)
-    {
-        EnableEdit(false);
-        EnableDel(false);
-    }
-
-    ShowMenu(rCEvt);
-
-    return true;
+    m_aStyleListExecuteDrop = rLink;
 }
 
-void SfxCommonTemplateDialog_Impl::PrepareMenu(const Point& rPos)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_has_selected_style(const Link<void*, bool>& rLink)
 {
-    weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
-    std::unique_ptr<weld::TreeIter> xIter(pTreeView->make_iterator());
-    if (pTreeView->get_dest_row_at_pos(rPos, xIter.get(), false) && !pTreeView->is_selected(*xIter))
-    {
-        pTreeView->unselect_all();
-        pTreeView->set_cursor(*xIter);
-        pTreeView->select(*xIter);
-        FmtSelectHdl(*pTreeView);
-    }
+    m_aStyleListHasSelectedStyle = rLink;
 }
 
-void SfxCommonTemplateDialog_Impl::ShowMenu(const CommandEvent& rCEvt)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_update_style_dependents(const Link<void*, void>& rLink)
 {
-    CreateContextMenu();
-
-    weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
-    OString sCommand(mxMenu->popup_at_rect(pTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
-    MenuSelect(sCommand);
+    m_aStyleListUpdateStyleDependents = rLink;
 }
 
-IMPL_LINK(SfxCommonTemplateDialog_Impl, PopupTreeMenuHdl, const CommandEvent&, rCEvt, bool)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_enable_tree_drag(const Link<bool, void> rLink)
 {
-    if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
-        return false;
-
-    PrepareMenu(rCEvt.GetMousePosPixel());
-
-    ShowMenu(rCEvt);
-
-    return true;
+    m_aStyleListEnableTreeDrag = rLink;
 }
 
-SfxTemplatePanelControl::SfxTemplatePanelControl(SfxBindings* pBindings, weld::Widget* pParent)
-    : PanelLayout(pParent, "TemplatePanel", "sfx/ui/templatepanel.ui")
-    , pImpl(new SfxTemplateDialog_Impl(pBindings, this))
-{
-    OSL_ASSERT(pBindings!=nullptr);
-}
-
-SfxTemplatePanelControl::~SfxTemplatePanelControl()
-{
-}
-
-static void MakeExpanded_Impl(const weld::TreeView& rBox, std::vector<OUString>& rEntries)
-{
-    std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
-    if (rBox.get_iter_first(*xEntry))
-    {
-        do
-        {
-            if (rBox.get_row_expanded(*xEntry))
-                rEntries.push_back(rBox.get_text(*xEntry));
-        } while (rBox.iter_next(*xEntry));
-    }
-}
-
-/** Internal structure for the establishment of the hierarchical view */
-namespace {
-
-class StyleTree_Impl;
-
-}
-
-typedef std::vector<std::unique_ptr<StyleTree_Impl>> StyleTreeArr_Impl;
-
-namespace {
-
-class StyleTree_Impl
-{
-private:
-    OUString aName;
-    OUString aParent;
-    StyleTreeArr_Impl pChildren;
-
-public:
-    bool HasParent() const { return !aParent.isEmpty(); }
-
-    StyleTree_Impl(const OUString &rName, const OUString &rParent):
-        aName(rName), aParent(rParent), pChildren(0) {}
-
-    const OUString& getName() const { return aName; }
-    const OUString& getParent() const { return aParent; }
-    StyleTreeArr_Impl& getChildren() { return pChildren; }
-};
-
-}
-
-static void MakeTree_Impl(StyleTreeArr_Impl& rArr, const OUString& aUIName)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_filter_select(Link<sal_uInt16, void> rLink)
 {
-    const comphelper::string::NaturalStringSorter aSorter(
-        ::comphelper::getProcessComponentContext(),
-        Application::GetSettings().GetLanguageTag().getLocale());
-
-    std::unordered_map<OUString, StyleTree_Impl*> styleFinder;
-    styleFinder.reserve(rArr.size());
-    for (const auto& pEntry : rArr)
-    {
-        styleFinder.emplace(pEntry->getName(), pEntry.get());
-    }
-
-    // Arrange all under their Parents
-    for (auto& pEntry : rArr)
-    {
-        if (!pEntry->HasParent())
-            continue;
-        auto it = styleFinder.find(pEntry->getParent());
-        if (it != styleFinder.end())
-        {
-            StyleTree_Impl* pCmp = it->second;
-            // Insert child entries sorted
-            auto iPos = std::lower_bound(pCmp->getChildren().begin(), pCmp->getChildren().end(), pEntry,
-                [&aSorter](std::unique_ptr<StyleTree_Impl> const & pEntry1, std::unique_ptr<StyleTree_Impl> const & pEntry2) { return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0; });
-            pCmp->getChildren().insert(iPos, std::move(pEntry));
-        }
-    }
-
-    // Only keep tree roots in rArr, child elements can be accessed through the hierarchy
-    rArr.erase(std::remove_if(rArr.begin(), rArr.end(), [](std::unique_ptr<StyleTree_Impl> const & pEntry) { return !pEntry; }), rArr.end());
-
-    // tdf#91106 sort top level styles
-    std::sort(rArr.begin(), rArr.end());
-    std::sort(rArr.begin(), rArr.end(),
-        [&aSorter, &aUIName](std::unique_ptr<StyleTree_Impl> const & pEntry1, std::unique_ptr<StyleTree_Impl> const & pEntry2) {
-            if (pEntry2->getName() == aUIName)
-                return false;
-            if (pEntry1->getName() == aUIName)
-                return true; // default always first
-            return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0;
-        });
+    m_aStyleListFilterSelect = rLink;
 }
 
-static bool IsExpanded_Impl( const std::vector<OUString>& rEntries,
-                             std::u16string_view rStr)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_enable_delete(const Link<void*, void> rLink)
 {
-    for (const auto & rEntry : rEntries)
-    {
-        if (rEntry == rStr)
-            return true;
-    }
-    return false;
+    m_aStyleListEnableDelete = rLink;
 }
 
-static void FillBox_Impl(weld::TreeView& rBox,
-                         StyleTree_Impl* pEntry,
-                         const std::vector<OUString>& rEntries,
-                         SfxStyleFamily eStyleFamily,
-                         const weld::TreeIter* pParent)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_set_water_can_state(
+    const Link<const SfxBoolItem*, void> rLink)
 {
-    std::unique_ptr<weld::TreeIter> xResult = rBox.make_iterator();
-    const OUString& rName = pEntry->getName();
-    rBox.insert(pParent, -1, &rName, &rName, nullptr, nullptr, false, xResult.get());
-
-    for (size_t i = 0; i < pEntry->getChildren().size(); ++i)
-        FillBox_Impl(rBox, pEntry->getChildren()[i].get(), rEntries, eStyleFamily, xResult.get());
+    m_aStyleListSetWaterCanState = rLink;
 }
 
-namespace SfxTemplate
+void SfxCommonTemplateDialog_Impl::connect_family_select(const Link<sal_uInt16, void> rLink)
 {
-    // converts from SFX_STYLE_FAMILY Ids to 1-6
-    static sal_uInt16 SfxFamilyIdToNId(SfxStyleFamily nFamily)
-    {
-        switch ( nFamily )
-        {
-            case SfxStyleFamily::Char:   return 1;
-            case SfxStyleFamily::Para:   return 2;
-            case SfxStyleFamily::Frame:  return 3;
-            case SfxStyleFamily::Page:   return 4;
-            case SfxStyleFamily::Pseudo: return 5;
-            case SfxStyleFamily::Table:  return 6;
-            default:                     return 0xffff;
-        }
-    }
-
-    // converts from 1-6 to SFX_STYLE_FAMILY Ids
-    static SfxStyleFamily NIdToSfxFamilyId(sal_uInt16 nId)
-    {
-        switch (nId)
-        {
-            case 1: return SfxStyleFamily::Char;
-            case 2: return SfxStyleFamily::Para;
-            case 3: return SfxStyleFamily::Frame;
-            case 4: return SfxStyleFamily::Page;
-            case 5: return SfxStyleFamily::Pseudo;
-            case 6: return SfxStyleFamily::Table;
-            default: return SfxStyleFamily::All;
-        }
-    }
+    m_aStyleListFamilySelect = rLink;
 }
 
 // Constructor
@@ -527,49 +199,27 @@ SfxCommonTemplateDialog_Impl::SfxCommonTemplateDialog_Impl(SfxBindings* pB, weld
     : pBindings(pB)
     , mpContainer(pC)
     , pModule(nullptr)
-    , pStyleSheetPool(nullptr)
-    , pCurObjShell(nullptr)
     , xModuleManager(frame::ModuleManager::create(::comphelper::getProcessComponentContext()))
     , m_pDeletionWatcher(nullptr)
-    , mxFmtLb(pBuilder->weld_tree_view("flatview"))
-    , mxTreeBox(pBuilder->weld_tree_view("treeview"))
+    , m_aStyleList(pBuilder, mxStyleFamilies, pB, this, pModule, pC, "treeview", "flatview")
     , mxPreviewCheckbox(pBuilder->weld_check_button("showpreview"))
     , mxFilterLb(pBuilder->weld_combo_box("filter"))
-
     , nActFamily(0xffff)
     , nActFilter(0)
     , nAppFilter(SfxStyleSearchBits::Auto)
-
-    , m_nModifier(0)
-    , bDontUpdate(false)
     , bIsWater(false)
     , bUpdate(false)
     , bUpdateFamily(false)
-    , bCanEdit(false)
-    , bCanDel(false)
-    , bCanNew(true)
-    , bCanHide(true)
-    , bCanShow(false)
     , bWaterDisabled(false)
     , bNewByExampleDisabled(false)
     , bUpdateByExampleDisabled(false)
     , bTreeDrag(true)
-    , bAllowReParentDrop(false)
-    , bHierarchical(false)
     , m_bWantHierarchical(false)
-    , bBindingUpdate(true)
 {
-    mxFmtLb->set_help_id(HID_TEMPLATE_FMT);
     mxFilterLb->set_help_id(HID_TEMPLATE_FILTER);
     mxPreviewCheckbox->set_active(officecfg::Office::Common::StylesAndFormatting::Preview::get());
 }
 
-sal_uInt16 SfxCommonTemplateDialog_Impl::StyleNrToInfoOffset(sal_uInt16 nId)
-{
-    const SfxStyleFamilyItem& rItem = mxStyleFamilies->at( nId );
-    return SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily())-1;
-}
-
 void SfxTemplateDialog_Impl::EnableEdit(bool bEnable)
 {
     SfxCommonTemplateDialog_Impl::EnableEdit( bEnable );
@@ -577,79 +227,10 @@ void SfxTemplateDialog_Impl::EnableEdit(bool bEnable)
         EnableItem("update", bEnable);
 }
 
-void SfxCommonTemplateDialog_Impl::ReadResource()
+IMPL_LINK(SfxCommonTemplateDialog_Impl, ReadResource_Hdl, StyleList&, rStyleList, void)
 {
-    // Read global user resource
-    for (auto & i : pFamilyState)
-        i.reset();
-
-    SfxViewFrame* pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame();
-    pCurObjShell = pViewFrame->GetObjectShell();
-    pModule = pCurObjShell ? pCurObjShell->GetModule() : nullptr;
-    if (pModule)
-        mxStyleFamilies = pModule->CreateStyleFamilies();
-    if (!mxStyleFamilies)
-        mxStyleFamilies.emplace();
-
-    nActFilter = 0xffff;
-    if (pCurObjShell)
-    {
-        nActFilter = static_cast< sal_uInt16 >( LoadFactoryStyleFilter( pCurObjShell ) );
-        if ( 0xffff == nActFilter )
-            nActFilter = pCurObjShell->GetAutoStyleFilterIndex();
-    }
-
-    // Paste in the toolbox
-    // reverse order, since always inserted at the head
-    size_t nCount = mxStyleFamilies->size();
-
-    pBindings->ENTERREGISTRATIONS();
 
-    size_t i;
-    for (i = 0; i < nCount; ++i)
-    {
-        sal_uInt16 nSlot = 0;
-        switch (mxStyleFamilies->at(i).GetFamily())
-        {
-            case SfxStyleFamily::Char:
-                nSlot = SID_STYLE_FAMILY1; break;
-            case SfxStyleFamily::Para:
-                nSlot = SID_STYLE_FAMILY2; break;
-            case SfxStyleFamily::Frame:
-                nSlot = SID_STYLE_FAMILY3; break;
-            case SfxStyleFamily::Page:
-                nSlot = SID_STYLE_FAMILY4; break;
-            case SfxStyleFamily::Pseudo:
-                nSlot = SID_STYLE_FAMILY5; break;
-            case SfxStyleFamily::Table:
-                nSlot = SID_STYLE_FAMILY6; break;
-            default: OSL_FAIL("unknown StyleFamily"); break;
-        }
-        pBoundItems[i].reset(
-            new SfxTemplateControllerItem(nSlot, *this, *pBindings) );
-    }
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_WATERCAN, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_NEW_BY_EXAMPLE, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_UPDATE_BY_EXAMPLE, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_NEW, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_DRAGHIERARCHIE, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_EDIT, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_DELETE, *this, *pBindings) );
-    pBoundItems[i++].reset( new SfxTemplateControllerItem(
-        SID_STYLE_FAMILY, *this, *pBindings) );
-    pBindings->LEAVEREGISTRATIONS();
-
-    for(; i < COUNT_BOUND_FUNC; ++i)
-        pBoundItems[i] = nullptr;
-
-    StartListening(*pBindings);
+    size_t nCount = m_aStyleListReadResource.Call(nullptr);
 
 // Insert in the reverse order of occurrence in the Style Families. This is for
 // the toolbar of the designer. The list box of the catalog respects the
@@ -666,29 +247,16 @@ void SfxCommonTemplateDialog_Impl::ReadResource()
 
     for( ; nCount--; )
     {
-        const SfxStyleFamilyItem &rItem = mxStyleFamilies->at( nCount );
+        const SfxStyleFamilyItem &rItem = rStyleList.GetFamilyItemByIndex( nCount );
         sal_uInt16 nId = SfxTemplate::SfxFamilyIdToNId( rItem.GetFamily() );
         InsertFamilyItem(nId, rItem);
     }
-
-    for ( i = SID_STYLE_FAMILY1; i <= SID_STYLE_FAMILY4; i++ )
-        pBindings->Update(i);
 }
 
-void SfxCommonTemplateDialog_Impl::ClearResource()
+IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, ClearResource_Hdl, void*, void)
 {
     ClearFamilyList();
-    impl_clear();
-}
-
-void SfxCommonTemplateDialog_Impl::impl_clear()
-{
-    mxStyleFamilies.reset();
-    for (auto & i : pFamilyState)
-        i.reset();
-    for (auto & i : pBoundItems)
-        i.reset();
-    pCurObjShell = nullptr;
+    m_aStyleListClear.Call(nullptr);
 }
 
 SfxCommonTemplateDialog_Impl::DeletionWatcher *
@@ -700,392 +268,40 @@ SfxCommonTemplateDialog_Impl::impl_setDeletionWatcher(
     return pRet;
 }
 
-class TreeViewDropTarget final : public DropTargetHelper
-{
-private:
-    SfxCommonTemplateDialog_Impl& m_rParent;
-
-public:
-    TreeViewDropTarget(SfxCommonTemplateDialog_Impl& rDialog, weld::TreeView& rTreeView)
-        : DropTargetHelper(rTreeView.get_drop_target())
-        , m_rParent(rDialog)
-    {
-    }
-
-    virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
-    {
-        return m_rParent.AcceptDrop(rEvt, *this);
-    }
-
-    virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
-    {
-        return m_rParent.ExecuteDrop(rEvt);
-    }
-};
-
 void SfxCommonTemplateDialog_Impl::Initialize()
 {
-    // Read global user resource
-    ReadResource();
-    pBindings->Invalidate( SID_STYLE_FAMILY );
-    pBindings->Update( SID_STYLE_FAMILY );
+    m_aStyleList.connect_ReadResource(LINK(this, SfxCommonTemplateDialog_Impl, ReadResource_Hdl));
+    m_aStyleList.connect_ClearResource(LINK(this, SfxCommonTemplateDialog_Impl, ClearResource_Hdl));
+    m_aStyleList.connect_LoadFactoryStyleFilter(LINK(this, SfxCommonTemplateDialog_Impl, LoadFactoryStyleFilter_Hdl));
+    m_aStyleList.connect_SaveSelection(LINK(this, SfxCommonTemplateDialog_Impl, SaveSelection_Hdl));

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list