summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnshu <anshukhare50@gmail.com>2021-06-26 08:34:06 +0530
committerMike Kaganski <mike.kaganski@collabora.com>2021-07-30 12:14:24 +0200
commit172f589471edcac9a4974132a3145b721942879a (patch)
treee0ff8483c2303812c8c146069e1289add28adf3c
parent5c9001acf25bf1795f683fc1a43dc6ec0ba6ced9 (diff)
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@collabora.com>
-rw-r--r--sfx2/Library_sfx.mk1
-rw-r--r--sfx2/source/dialog/StyleList.cxx1814
-rw-r--r--sfx2/source/dialog/templdlg.cxx1722
-rw-r--r--sfx2/source/inc/StyleList.hxx235
-rw-r--r--sfx2/source/inc/templdgi.hxx243
5 files changed, 2327 insertions, 1688 deletions
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))
+void SfxCommonTemplateDialog_Impl::connect_stylelist_filter_select(Link<sal_uInt16, void> rLink)
{
- OSL_ASSERT(pBindings!=nullptr);
+ m_aStyleListFilterSelect = rLink;
}
-SfxTemplatePanelControl::~SfxTemplatePanelControl()
+void SfxCommonTemplateDialog_Impl::connect_stylelist_enable_delete(const Link<void*, void> rLink)
{
+ m_aStyleListEnableDelete = rLink;
}
-static void MakeExpanded_Impl(const weld::TreeView& rBox, std::vector<OUString>& rEntries)
+void SfxCommonTemplateDialog_Impl::connect_stylelist_set_water_can_state(
+ const Link<const SfxBoolItem*, void> rLink)
{
- 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;
-
+ m_aStyleListSetWaterCanState = rLink;
}
-typedef std::vector<std::unique_ptr<StyleTree_Impl>> StyleTreeArr_Impl;
-
-namespace {
-
-class StyleTree_Impl
+void SfxCommonTemplateDialog_Impl::connect_family_select(const Link<sal_uInt16, void> rLink)
{
-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;
- }
- }
+ 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,115 +268,93 @@ SfxCommonTemplateDialog_Impl::impl_setDeletionWatcher(
return pRet;
}
-class TreeViewDropTarget final : public DropTargetHelper
+void SfxCommonTemplateDialog_Impl::Initialize()
{
-private:
- SfxCommonTemplateDialog_Impl& m_rParent;
+ 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));
+ m_aStyleList.connect_UpdateStyleDependents(LINK(this, SfxCommonTemplateDialog_Impl, UpdateStyleDependents_Hdl));
+ m_aStyleList.connect_UpdateFamily(LINK(this, SfxCommonTemplateDialog_Impl, UpdateFamily_Hdl));
+ m_aStyleList.connect_UpdateStyles(LINK(this, SfxCommonTemplateDialog_Impl, UpdateStyles_Hdl));
-public:
- TreeViewDropTarget(SfxCommonTemplateDialog_Impl& rDialog, weld::TreeView& rTreeView)
- : DropTargetHelper(rTreeView.get_drop_target())
- , m_rParent(rDialog)
- {
- }
+ mxFilterLb->connect_changed(LINK(this, SfxCommonTemplateDialog_Impl, FilterSelectHdl));
+ mxPreviewCheckbox->connect_toggled(LINK(this, SfxCommonTemplateDialog_Impl, PreviewHdl));
+ m_aStyleList.Initialize();
+}
- virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
- {
- return m_rParent.AcceptDrop(rEvt, *this);
- }
+IMPL_LINK(SfxCommonTemplateDialog_Impl, UpdateStyles_Hdl, StyleFlags, nFlags, void)
+{
+ const SfxStyleFamilyItem* pItem = m_aStyleList.GetFamilyItem();
+ SfxStyleSearchBits nFilter(nActFilter < pItem->GetFilterList().size()
+ ? pItem->GetFilterList()[nActFilter].nFlags
+ : SfxStyleSearchBits::Auto);
+ if (nFilter == SfxStyleSearchBits::Auto) // automatic
+ nFilter = nAppFilter;
- virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
+ if (nFlags & StyleFlags::UpdateFamily) // Update view type list (Hierarchical, All, etc.
{
- return m_rParent.ExecuteDrop(rEvt);
- }
-};
+ CheckItem(OString::number(nActFamily)); // check Button in Toolbox
-void SfxCommonTemplateDialog_Impl::Initialize()
-{
- // Read global user resource
- ReadResource();
- pBindings->Invalidate( SID_STYLE_FAMILY );
- pBindings->Update( SID_STYLE_FAMILY );
+ mxFilterLb->freeze();
+ mxFilterLb->clear();
- mxFilterLb->connect_changed(LINK(this, SfxCommonTemplateDialog_Impl, FilterSelectHdl));
- mxFmtLb->connect_row_activated(LINK( this, SfxCommonTemplateDialog_Impl, TreeListApplyHdl));
- mxFmtLb->connect_mouse_press(LINK(this, SfxCommonTemplateDialog_Impl, MousePressHdl));
- mxFmtLb->connect_query_tooltip(LINK(this, SfxCommonTemplateDialog_Impl, QueryTooltipHdl));
- mxFmtLb->connect_changed(LINK(this, SfxCommonTemplateDialog_Impl, FmtSelectHdl));
- mxFmtLb->connect_popup_menu(LINK(this, SfxCommonTemplateDialog_Impl, PopupFlatMenuHdl));
- mxFmtLb->connect_key_press(LINK(this, SfxCommonTemplateDialog_Impl, KeyInputHdl));
- mxFmtLb->set_selection_mode(SelectionMode::Multiple);
- mxTreeBox->connect_changed(LINK(this, SfxCommonTemplateDialog_Impl, FmtSelectHdl));
- mxTreeBox->connect_row_activated(LINK( this, SfxCommonTemplateDialog_Impl, TreeListApplyHdl));
- mxTreeBox->connect_mouse_press(LINK(this, SfxCommonTemplateDialog_Impl, MousePressHdl));
- mxTreeBox->connect_query_tooltip(LINK(this, SfxCommonTemplateDialog_Impl, QueryTooltipHdl));
- mxTreeBox->connect_popup_menu(LINK(this, SfxCommonTemplateDialog_Impl, PopupTreeMenuHdl));
- mxTreeBox->connect_key_press(LINK(this, SfxCommonTemplateDialog_Impl, KeyInputHdl));
- mxTreeBox->connect_drag_begin(LINK(this, SfxCommonTemplateDialog_Impl, DragBeginHdl));
- mxPreviewCheckbox->connect_toggled(LINK(this, SfxCommonTemplateDialog_Impl, PreviewHdl));
- m_xTreeView1DropTargetHelper.reset(new TreeViewDropTarget(*this, *mxFmtLb));
- m_xTreeView2DropTargetHelper.reset(new TreeViewDropTarget(*this, *mxTreeBox));
+ //insert hierarchical at the beginning
+ mxFilterLb->append(OUString::number(static_cast<int>(SfxStyleSearchBits::All)),
+ SfxResId(STR_STYLE_FILTER_HIERARCHICAL));
+ const SfxStyleFilter& rFilter = pItem->GetFilterList();
+ for (const SfxFilterTuple& i : rFilter)
+ mxFilterLb->append(OUString::number(static_cast<int>(i.nFlags)), i.aName);
+ mxFilterLb->thaw();
- int nTreeHeight = mxFmtLb->get_height_rows(8);
- mxFmtLb->set_size_request(-1, nTreeHeight);
- mxTreeBox->set_size_request(-1, nTreeHeight);
+ if (nActFilter < mxFilterLb->get_count() - 1)
+ mxFilterLb->set_active(nActFilter + 1);
+ else
+ {
+ nActFilter = 0;
+ m_aStyleList.SetFilterIdx(nActFilter);
+ mxFilterLb->set_active(1);
+ nFilter = (nActFilter < rFilter.size()) ? rFilter[nActFilter].nFlags
+ : SfxStyleSearchBits::Auto;
+ }
- mxFmtLb->connect_custom_get_size(LINK(this, SfxCommonTemplateDialog_Impl, CustomGetSizeHdl));
- mxFmtLb->connect_custom_render(LINK(this, SfxCommonTemplateDialog_Impl, CustomRenderHdl));
- mxTreeBox->connect_custom_get_size(LINK(this, SfxCommonTemplateDialog_Impl, CustomGetSizeHdl));
- mxTreeBox->connect_custom_render(LINK(this, SfxCommonTemplateDialog_Impl, CustomRenderHdl));
- bool bCustomPreview = officecfg::Office::Common::StylesAndFormatting::Preview::get();
- mxFmtLb->set_column_custom_renderer(0, bCustomPreview);
- mxTreeBox->set_column_custom_renderer(0, bCustomPreview);
+ // if the tree view again, select family hierarchy
+ if (m_aStyleList.IsTreeView() || m_bWantHierarchical)
+ {
+ mxFilterLb->set_active_text(SfxResId(STR_STYLE_FILTER_HIERARCHICAL));
+ EnableHierarchical(true, m_aStyleList);
+ }
+ }
+ else
+ {
+ if (nActFilter < mxFilterLb->get_count() - 1)
+ mxFilterLb->set_active(nActFilter + 1);
+ else
+ {
+ nActFilter = 0;
+ m_aStyleList.SetFilterIdx(nActFilter);
+ mxFilterLb->set_active(1);
+ }
+ }
- mxFmtLb->set_visible(!bHierarchical);
- mxTreeBox->set_visible(bHierarchical);
+ if (!(nFlags & StyleFlags::UpdateFamilyList))
+ return;
- Update_Impl();
+ EnableItem("watercan", false);
}
SfxCommonTemplateDialog_Impl::~SfxCommonTemplateDialog_Impl()
{
if ( bIsWater )
- Execute_Impl(SID_STYLE_WATERCAN, "", "", 0);
- impl_clear();
- if ( pStyleSheetPool )
- EndListening(*pStyleSheetPool);
- pStyleSheetPool = nullptr;
- m_xTreeView1DropTargetHelper.reset();
- m_xTreeView2DropTargetHelper.reset();
- mxTreeBox.reset();
- pIdle.reset();
+ Execute_Impl(SID_STYLE_WATERCAN, "", "", 0, m_aStyleList);
+ m_aStyleListClear.Call(nullptr);
+ m_aStyleListCleanup.Call(nullptr);
if ( m_pDeletionWatcher )
m_pDeletionWatcher->signal();
- mxFmtLb.reset();
mxPreviewCheckbox.reset();
mxFilterLb.reset();
}
-// Helper function: Access to the current family item
-const SfxStyleFamilyItem *SfxCommonTemplateDialog_Impl::GetFamilyItem_Impl() const
-{
- const size_t nCount = mxStyleFamilies->size();
- for(size_t i = 0; i < nCount; ++i)
- {
- const SfxStyleFamilyItem &rItem = mxStyleFamilies->at( i );
- sal_uInt16 nId = SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily());
- if(nId == nActFamily)
- return &rItem;
- }
- return nullptr;
-}
-
-void SfxCommonTemplateDialog_Impl::GetSelectedStyle() const
-{
- if (!IsInitialized() || !pStyleSheetPool || !HasSelectedStyle())
- return;
- const OUString aTemplName( GetSelectedEntry() );
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
- pStyleSheetPool->Find( aTemplName, pItem->GetFamily() );
-}
-
/**
* Is it safe to show the water-can / fill icon. If we've a
* hierarchical widget - we have only single select, otherwise
@@ -817,124 +363,25 @@ void SfxCommonTemplateDialog_Impl::GetSelectedStyle() const
*/
bool SfxCommonTemplateDialog_Impl::IsSafeForWaterCan() const
{
- if (mxTreeBox->get_visible())
- return mxTreeBox->get_selected_index() != -1;
- else
- return mxFmtLb->count_selected_rows() == 1;
+ return m_aStyleListWaterCan.Call(nullptr);
}
-void SfxCommonTemplateDialog_Impl::SelectStyle(const OUString &rStr, bool bIsCallback)
+void SfxCommonTemplateDialog_Impl::SelectStyle(const OUString &rStr, bool bIsCallback, StyleList& rStyleList)
{
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
- if ( !pItem )
- return;
- const SfxStyleFamily eFam = pItem->GetFamily();
- SfxStyleSheetBase* pStyle = pStyleSheetPool->Find( rStr, eFam );
- if( pStyle )
- {
- bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
- EnableEdit( bReadWrite );
- EnableHide( bReadWrite && !pStyle->IsHidden( ) && !pStyle->IsUsed( ) );
- EnableShow( bReadWrite && pStyle->IsHidden( ) );
- }
- else
- {
- EnableEdit(false);
- EnableHide(false);
- EnableShow(false);
- }
-
- if (!bIsCallback)
- {
- if (mxTreeBox->get_visible())
- {
- if (!rStr.isEmpty())
- {
- std::unique_ptr<weld::TreeIter> xEntry = mxTreeBox->make_iterator();
- bool bEntry = mxTreeBox->get_iter_first(*xEntry);
- while (bEntry)
- {
- if (mxTreeBox->get_text(*xEntry) == rStr)
- {
- mxTreeBox->scroll_to_row(*xEntry);
- mxTreeBox->select(*xEntry);
- break;
- }
- bEntry = mxTreeBox->iter_next(*xEntry);
- }
- }
- else if (eFam == SfxStyleFamily::Pseudo)
- {
- std::unique_ptr<weld::TreeIter> xEntry = mxTreeBox->make_iterator();
- if (mxTreeBox->get_iter_first(*xEntry))
- {
- mxTreeBox->scroll_to_row(*xEntry);
- mxTreeBox->select(*xEntry);
- }
- }
- else
- mxTreeBox->unselect_all();
- }
- else
- {
- bool bSelect = !rStr.isEmpty();
- if (bSelect)
- {
- std::unique_ptr<weld::TreeIter> xEntry = mxFmtLb->make_iterator();
- bool bEntry = mxFmtLb->get_iter_first(*xEntry);
- while (bEntry && mxFmtLb->get_text(*xEntry) != rStr)
- bEntry = mxFmtLb->iter_next(*xEntry);
- if (!bEntry)
- bSelect = false;
- else
- {
- if (!mxFmtLb->is_selected(*xEntry))
- {
- mxFmtLb->unselect_all();
- mxFmtLb->scroll_to_row(*xEntry);
- mxFmtLb->select(*xEntry);
- }
- }
- }
-
- if (!bSelect)
- {
- mxFmtLb->unselect_all();
- EnableEdit(false);
- EnableHide(false);
- EnableShow(false);
- }
- }
- }
+ rStyleList.SelectStyle(rStr, bIsCallback);
bWaterDisabled = !IsSafeForWaterCan();
if (!bIsCallback)
{
// tdf#134598 call UpdateStyleDependents to update watercan
- UpdateStyleDependents();
+ UpdateStyleDependents_Hdl(nullptr);
}
}
-OUString SfxCommonTemplateDialog_Impl::GetSelectedEntry() const
-{
- OUString aRet;
- if (mxTreeBox->get_visible())
- aRet = mxTreeBox->get_selected_text();
- else
- aRet = mxFmtLb->get_selected_text();
- return aRet;
-}
-
void SfxCommonTemplateDialog_Impl::EnableTreeDrag(bool bEnable)
{
- if (pStyleSheetPool)
- {
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
- SfxStyleSheetBase* pStyle = pItem ? pStyleSheetPool->First(pItem->GetFamily()) : nullptr;
- bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && bEnable;
- }
- bTreeDrag = bEnable;
+ m_aStyleListEnableTreeDrag.Call(bEnable);
}
static OUString lcl_GetStyleFamilyName( SfxStyleFamily nFamily )
@@ -952,7 +399,7 @@ static OUString lcl_GetStyleFamilyName( SfxStyleFamily nFamily )
return OUString();
}
-OUString SfxCommonTemplateDialog_Impl::getDefaultStyleName( const SfxStyleFamily eFam )
+OUString SfxCommonTemplateDialog_Impl::getDefaultStyleName( const SfxStyleFamily eFam, StyleList& rStyleList )
{
OUString sDefaultStyle;
OUString aFamilyName = lcl_GetStyleFamilyName(eFam);
@@ -962,7 +409,7 @@ OUString SfxCommonTemplateDialog_Impl::getDefaultStyleName( const SfxStyleFamily
sDefaultStyle = "No List";
else
sDefaultStyle = "Standard";
- uno::Reference< style::XStyleFamiliesSupplier > xModel(GetObjectShell()->GetModel(), uno::UNO_QUERY);
+ uno::Reference<style::XStyleFamiliesSupplier> xModel(rStyleList.GetObjectShell()->GetModel(), uno::UNO_QUERY);
OUString aUIName;
try
{
@@ -979,210 +426,6 @@ OUString SfxCommonTemplateDialog_Impl::getDefaultStyleName( const SfxStyleFamily
return aUIName;
}
-void SfxCommonTemplateDialog_Impl::FillTreeBox()
-{
- assert(mxTreeBox && "FillTreeBox() without treebox");
- if (!pStyleSheetPool || nActFamily == 0xffff)
- return;
-
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
- if (!pItem)
- return;
- const SfxStyleFamily eFam = pItem->GetFamily();
- StyleTreeArr_Impl aArr;
- SfxStyleSheetBase* pStyle = pStyleSheetPool->First(eFam, SfxStyleSearchBits::AllVisible);
-
- bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && bTreeDrag;
-
- while (pStyle)
- {
- StyleTree_Impl* pNew = new StyleTree_Impl(pStyle->GetName(), pStyle->GetParent());
- aArr.emplace_back(pNew);
- pStyle = pStyleSheetPool->Next();
- }
- OUString aUIName = getDefaultStyleName(eFam);
- MakeTree_Impl(aArr, aUIName);
- std::vector<OUString> aEntries;
- MakeExpanded_Impl(*mxTreeBox, aEntries);
- mxTreeBox->freeze();
- mxTreeBox->clear();
- const sal_uInt16 nCount = aArr.size();
-
- for (sal_uInt16 i = 0; i < nCount; ++i)
- {
- FillBox_Impl(*mxTreeBox, aArr[i].get(), aEntries, eFam, nullptr);
- aArr[i].reset();
- }
-
- EnableItem("watercan", false);
-
- SfxTemplateItem* pState = pFamilyState[nActFamily - 1].get();
-
- mxTreeBox->thaw();
-
- std::unique_ptr<weld::TreeIter> xEntry = mxTreeBox->make_iterator();
- bool bEntry = mxTreeBox->get_iter_first(*xEntry);
- if (bEntry && nCount)
- mxTreeBox->expand_row(*xEntry);
-
- while (bEntry)
- {
- if (IsExpanded_Impl(aEntries, mxTreeBox->get_text(*xEntry)))
- mxTreeBox->expand_row(*xEntry);
- bEntry = mxTreeBox->iter_next(*xEntry);
- }
-
- OUString aStyle;
- if(pState) // Select current entry
- aStyle = pState->GetStyleName();
- SelectStyle(aStyle, false);
- EnableDelete();
-}
-
-bool SfxCommonTemplateDialog_Impl::HasSelectedStyle() const
-{
- return mxTreeBox->get_visible() ? mxTreeBox->get_selected_index() != -1
- : mxFmtLb->count_selected_rows() != 0;
-}
-
-// internal: Refresh the display
-// nFlags: what we should update.
-void SfxCommonTemplateDialog_Impl::UpdateStyles_Impl(StyleFlags nFlags)
-{
- OSL_ENSURE(nFlags != StyleFlags::NONE, "nothing to do");
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- if (!pItem)
- {
- // Is the case for the template catalog
- const size_t nFamilyCount = mxStyleFamilies->size();
- size_t n;
- for( n = 0; n < nFamilyCount; n++ )
- if( pFamilyState[ StyleNrToInfoOffset(n) ] ) break;
- if ( n == nFamilyCount )
- // It happens sometimes, God knows why
- return;
- nAppFilter = pFamilyState[StyleNrToInfoOffset(n)]->GetValue();
- FamilySelect( StyleNrToInfoOffset(n)+1 );
- pItem = GetFamilyItem_Impl();
- }
-
- const SfxStyleFamily eFam = pItem->GetFamily();
-
- SfxStyleSearchBits nFilter (nActFilter < pItem->GetFilterList().size() ? pItem->GetFilterList()[nActFilter].nFlags : SfxStyleSearchBits::Auto);
- if (nFilter == SfxStyleSearchBits::Auto) // automatic
- nFilter = nAppFilter;
-
- OSL_ENSURE(pStyleSheetPool, "no StyleSheetPool");
- if(!pStyleSheetPool)
- return;
-
- pItem = GetFamilyItem_Impl();
- if(nFlags & StyleFlags::UpdateFamily) // Update view type list (Hierarchical, All, etc.
- {
- CheckItem(OString::number(nActFamily)); // check Button in Toolbox
-
- mxFilterLb->freeze();
- mxFilterLb->clear();
-
- //insert hierarchical at the beginning
- mxFilterLb->append(OUString::number(static_cast<int>(SfxStyleSearchBits::All)), SfxResId(STR_STYLE_FILTER_HIERARCHICAL));
- const SfxStyleFilter& rFilter = pItem->GetFilterList();
- for (const SfxFilterTuple& i : rFilter)
- mxFilterLb->append(OUString::number(static_cast<int>(i.nFlags)), i.aName);
- mxFilterLb->thaw();
-
- if (nActFilter < mxFilterLb->get_count() - 1)
- mxFilterLb->set_active(nActFilter + 1);
- else
- {
- nActFilter = 0;
- mxFilterLb->set_active(1);
- nFilter = (nActFilter < rFilter.size()) ? rFilter[nActFilter].nFlags : SfxStyleSearchBits::Auto;
- }
-
- // if the tree view again, select family hierarchy
- if (mxTreeBox->get_visible() || m_bWantHierarchical)
- {
- mxFilterLb->set_active_text(SfxResId(STR_STYLE_FILTER_HIERARCHICAL));
- EnableHierarchical(true);
- }
- }
- else
- {
- if (nActFilter < mxFilterLb->get_count() - 1)
- mxFilterLb->set_active(nActFilter + 1);
- else
- {
- nActFilter = 0;
- mxFilterLb->set_active(1);
- }
- }
-
- if(!(nFlags & StyleFlags::UpdateFamilyList))
- return;
-
- EnableItem("watercan", false);
-
- SfxStyleSheetBase *pStyle = pStyleSheetPool->First(eFam, nFilter);
-
- std::unique_ptr<weld::TreeIter> xEntry = mxFmtLb->make_iterator();
- bool bEntry = mxFmtLb->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 = 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] == mxFmtLb->get_text(*xEntry))
- {
- ++nPos;
- bEntry = mxFmtLb->iter_next(*xEntry);
- }
-
- if (nPos < nCount || bEntry)
- {
- // Fills the display box
- mxFmtLb->freeze();
- mxFmtLb->clear();
-
- for (nPos = 0; nPos < nCount; ++nPos)
- mxFmtLb->append(aStrings[nPos], aStrings[nPos]);
-
- mxFmtLb->thaw();
- }
- // Selects the current style if any
- SfxTemplateItem *pState = pFamilyState[nActFamily-1].get();
- OUString aStyle;
- if(pState)
- aStyle = pState->GetStyleName();
- SelectStyle(aStyle, false);
- EnableDelete();
-}
-
// Updated display: Watering the house
void SfxCommonTemplateDialog_Impl::SetWaterCanState(const SfxBoolItem *pItem)
{
@@ -1207,21 +450,7 @@ void SfxCommonTemplateDialog_Impl::SetWaterCanState(const SfxBoolItem *pItem)
// Ignore while in watercan mode statusupdates
- size_t nCount = mxStyleFamilies->size();
- 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();
- }
- }
- pBindings->LeaveRegistrations();
+ m_aStyleListSetWaterCanState.Call(pItem);
}
// Item with the status of a Family is copied and noted
@@ -1229,256 +458,16 @@ void SfxCommonTemplateDialog_Impl::SetWaterCanState(const SfxBoolItem *pItem)
// See also: <SfxBindings::AddDoneHdl(const Link &)>
void SfxCommonTemplateDialog_Impl::SetFamilyState( sal_uInt16 nSlotId, const SfxTemplateItem* pItem )
{
- sal_uInt16 nIdx = nSlotId - SID_STYLE_FAMILY_START;
- pFamilyState[nIdx].reset();
- if ( pItem )
- pFamilyState[nIdx].reset( new SfxTemplateItem(*pItem) );
+ m_aStyleList.SetFamilyState(nSlotId, pItem);
bUpdate = true;
// If used templates (how the hell you find this out??)
bUpdateFamily = true;
}
-// Notice from SfxBindings that the update is completed. Pushes out the update
-// of the display.
-void SfxCommonTemplateDialog_Impl::Update_Impl()
-{
- bool bDocChanged=false;
- SfxStyleSheetBasePool* pNewPool = nullptr;
- SfxViewFrame* pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame();
- SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
- if( pDocShell )
- pNewPool = pDocShell->GetStyleSheetPool();
-
- if ( pNewPool != pStyleSheetPool && pDocShell )
- {
- SfxModule* pNewModule = pDocShell->GetModule();
- if( pNewModule && pNewModule != pModule )
- {
- ClearResource();
- ReadResource();
- }
- if ( pStyleSheetPool )
- {
- EndListening(*pStyleSheetPool);
- pStyleSheetPool = nullptr;
- }
-
- if ( pNewPool )
- {
- StartListening(*pNewPool);
- pStyleSheetPool = pNewPool;
- bDocChanged=true;
- }
- }
-
- if (bUpdateFamily)
- UpdateFamily_Impl();
-
- sal_uInt16 i;
- for(i = 0; i < MAX_FAMILIES; ++i)
- if(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(nActFamily == 0xffff || nullptr == (pItem = pFamilyState[nActFamily-1].get() ) )
- {
- CheckItem(OString::number(nActFamily), false);
- const size_t nFamilyCount = mxStyleFamilies->size();
- size_t n;
- for( n = 0; n < nFamilyCount; n++ )
- if( pFamilyState[ StyleNrToInfoOffset(n) ] ) break;
-
- std::unique_ptr<SfxTemplateItem> & pNewItem = pFamilyState[StyleNrToInfoOffset(n)];
- nAppFilter = pNewItem->GetValue();
- FamilySelect( StyleNrToInfoOffset(n) + 1 );
- pItem = pNewItem.get();
- }
- else if( bDocChanged )
- {
- // other DocShell -> all new
- CheckItem(OString::number(nActFamily));
- nActFilter = static_cast< sal_uInt16 >( LoadFactoryStyleFilter( pDocShell ) );
- if ( 0xffff == nActFilter )
- nActFilter = pDocShell->GetAutoStyleFilterIndex();
-
- nAppFilter = pItem->GetValue();
- if (!mxTreeBox->get_visible())
- {
- UpdateStyles_Impl(StyleFlags::UpdateFamilyList);
- }
- else
- FillTreeBox();
- }
- else
- {
- // other filters for automatic
- CheckItem(OString::number(nActFamily));
- const SfxStyleFamilyItem *pStyleItem = GetFamilyItem_Impl();
- if ( pStyleItem && SfxStyleSearchBits::Auto == pStyleItem->GetFilterList()[nActFilter].nFlags
- && nAppFilter != pItem->GetValue())
- {
- nAppFilter = pItem->GetValue();
- if (!mxTreeBox->get_visible())
- UpdateStyles_Impl(StyleFlags::UpdateFamilyList);
- else
- FillTreeBox();
- }
- else
- nAppFilter = pItem->GetValue();
- }
- const OUString aStyle(pItem->GetStyleName());
- SelectStyle(aStyle, false);
- EnableDelete();
- EnableNew( bCanNew );
-}
-
-IMPL_LINK_NOARG( SfxCommonTemplateDialog_Impl, TimeOut, Timer *, void )
-{
- if(!bDontUpdate)
- {
- bDontUpdate=true;
- if (!mxTreeBox->get_visible())
- UpdateStyles_Impl(StyleFlags::UpdateFamilyList);
- else
- {
- FillTreeBox();
- SfxTemplateItem *pState = pFamilyState[nActFamily-1].get();
- if(pState)
- {
- SelectStyle(pState->GetStyleName(), false);
- EnableDelete();
- }
- }
- bDontUpdate=false;
- pIdle.reset();
- }
- else
- pIdle->Start();
-}
-
-void SfxCommonTemplateDialog_Impl::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
-{
- const SfxHintId nId = rHint.GetId();
-
- // tap update
- switch(nId)
- {
- case SfxHintId::UpdateDone:
- {
- SfxViewFrame *pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame();
- SfxObjectShell *pDocShell = pViewFrame->GetObjectShell();
- if (
- bUpdate &&
- (
- !IsCheckedItem("watercan") ||
- (pDocShell && pDocShell->GetStyleSheetPool() != pStyleSheetPool)
- )
- )
- {
- bUpdate = false;
- Update_Impl();
- }
- else if ( bUpdateFamily )
- {
- UpdateFamily_Impl();
- }
-
- if( pStyleSheetPool )
- {
- OUString aStr = GetSelectedEntry();
- if (!aStr.isEmpty())
- {
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- if( !pItem ) break;
- const SfxStyleFamily eFam = pItem->GetFamily();
- SfxStyleSheetBase *pStyle = pStyleSheetPool->Find( aStr, eFam );
- if( pStyle )
- {
- bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
- EnableEdit( bReadWrite );
- EnableHide( bReadWrite && !pStyle->IsUsed( ) && !pStyle->IsHidden( ) );
- EnableShow( bReadWrite && pStyle->IsHidden( ) );
- }
- else
- {
- EnableEdit(false);
- EnableHide(false);
- 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:
- bUpdate = true;
- break;
- case SfxHintId::Dying:
- {
- EndListening(*pStyleSheetPool);
- 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(!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,SfxCommonTemplateDialog_Impl,TimeOut));
- }
- pIdle->Start();
-
- }
-}
-
-// Other filters; can be switched by the users or as a result of new or
-// editing, if the current document has been assigned a different filter.
-void SfxCommonTemplateDialog_Impl::FilterSelect(
- sal_uInt16 nEntry, // Idx of the new Filters
- bool bForce ) // Force update, even if the new filter is
- // equal to the current
-{
- if( nEntry == nActFilter && !bForce )
- return;
-
- nActFilter = nEntry;
- SfxObjectShell *const pDocShell = SaveSelection();
- SfxStyleSheetBasePool *pOldStyleSheetPool = pStyleSheetPool;
- pStyleSheetPool = pDocShell? pDocShell->GetStyleSheetPool(): nullptr;
- if ( pOldStyleSheetPool != pStyleSheetPool )
- {
- if ( pOldStyleSheetPool )
- EndListening(*pOldStyleSheetPool);
- if ( pStyleSheetPool )
- StartListening(*pStyleSheetPool);
- }
-
- UpdateStyles_Impl(StyleFlags::UpdateFamilyList);
-}
-
// Internal: Perform functions through the Dispatcher
bool SfxCommonTemplateDialog_Impl::Execute_Impl(
- sal_uInt16 nId, const OUString &rStr, const OUString& rRefStr, sal_uInt16 nFamily,
+ sal_uInt16 nId, const OUString &rStr, const OUString& rRefStr, sal_uInt16 nFamily, StyleList& rStyleList,
SfxStyleSearchBits nMask, sal_uInt16 *pIdx, const sal_uInt16* pModifier)
{
SfxDispatcher &rDispatcher = *SfxGetpApp()->GetDispatcher_Impl();
@@ -1497,7 +486,7 @@ bool SfxCommonTemplateDialog_Impl::Execute_Impl(
if(SID_STYLE_UPDATE_BY_EXAMPLE == nId)
{
// Special solution for Numbering update in Writer
- const OUString aTemplName(GetSelectedEntry());
+ const OUString aTemplName(rStyleList.GetSelectedEntry());
aUpdName.SetValue(aTemplName);
pItems[ nCount++ ] = &aUpdName;
}
@@ -1518,14 +507,15 @@ bool SfxCommonTemplateDialog_Impl::Execute_Impl(
if ( !pItem || aDeleted )
return false;
- if ( (nId == SID_STYLE_NEW || SID_STYLE_EDIT == nId) && (mxTreeBox->get_visible() || mxFmtLb->count_selected_rows() <= 1) )
+ if ((nId == SID_STYLE_NEW || SID_STYLE_EDIT == nId)
+ && rStyleList.EnableExecute())
{
const SfxUInt16Item *pFilterItem = dynamic_cast< const SfxUInt16Item* >(pItem);
assert(pFilterItem);
SfxStyleSearchBits nFilterFlags = static_cast<SfxStyleSearchBits>(pFilterItem->GetValue()) & ~SfxStyleSearchBits::UserDefined;
if(nFilterFlags == SfxStyleSearchBits::Auto) // User Template?
nFilterFlags = static_cast<SfxStyleSearchBits>(pFilterItem->GetValue());
- const SfxStyleFamilyItem *pFamilyItem = GetFamilyItem_Impl();
+ const SfxStyleFamilyItem *pFamilyItem = rStyleList.GetFamilyItem();
const size_t nFilterCount = pFamilyItem->GetFilterList().size();
for ( size_t i = 0; i < nFilterCount; ++i )
@@ -1541,44 +531,52 @@ bool SfxCommonTemplateDialog_Impl::Execute_Impl(
}
// Handler Listbox of Filter
-void SfxCommonTemplateDialog_Impl::EnableHierarchical(bool const bEnable)
+void SfxCommonTemplateDialog_Impl::EnableHierarchical(bool const bEnable, StyleList& rStyleList)
{
if (bEnable)
{
- if (!bHierarchical)
+ if (!rStyleList.IsHierarchical())
{
// Turn on treeView
- bHierarchical=true;
m_bWantHierarchical = true;
- SaveSelection(); // fdo#61429 store "hierarchical"
- const OUString aSelectEntry( GetSelectedEntry());
- mxFmtLb->hide();
- FillTreeBox();
- SelectStyle(aSelectEntry, false);
- mxTreeBox->show();
+ SaveSelection_Hdl(nullptr); // fdo#61429 store "hierarchical"
+ m_aStyleList.SetHierarchical();
}
}
else
{
- mxTreeBox->hide();
- mxFmtLb->show();
+ m_aStyleList.SetFilterControlsHandle();
// If bHierarchical, then the family can have changed
// minus one since hierarchical is inserted at the start
m_bWantHierarchical = false; // before FilterSelect
- FilterSelect(mxFilterLb->get_active() - 1, bHierarchical );
- bHierarchical=false;
+ FilterSelect(mxFilterLb->get_active() - 1, rStyleList.IsHierarchical() );
}
}
+// Other filters; can be switched by the users or as a result of new or
+// editing, if the current document has been assigned a different filter.
+void SfxCommonTemplateDialog_Impl::FilterSelect(
+ sal_uInt16 nEntry, // Idx of the new Filters
+ bool bForce) // Force update, even if the new filter is equal to the current
+{
+ if (nEntry == nActFilter && !bForce)
+ return;
+
+ nActFilter = nEntry;
+ m_aStyleListFilterSelect.Call(nActFilter);
+
+ m_aStyleListUpdateStyles.Call(StyleFlags::UpdateFamilyList);
+}
+
IMPL_LINK(SfxCommonTemplateDialog_Impl, FilterSelectHdl, weld::ComboBox&, rBox, void)
{
if (SfxResId(STR_STYLE_FILTER_HIERARCHICAL) == rBox.get_active_text())
{
- EnableHierarchical(true);
+ EnableHierarchical(true, m_aStyleList);
}
else
{
- EnableHierarchical(false);
+ EnableHierarchical(false, m_aStyleList);
}
}
@@ -1590,17 +588,11 @@ void SfxCommonTemplateDialog_Impl::FamilySelect(sal_uInt16 nEntry, bool bPreview
{
CheckItem(OString::number(nActFamily), false);
nActFamily = nEntry;
- SfxDispatcher* pDispat = pBindings->GetDispatcher_Impl();
- SfxUInt16Item const aItem(SID_STYLE_FAMILY,
- static_cast<sal_uInt16>(SfxTemplate::NIdToSfxFamilyId(nEntry)));
- pDispat->ExecuteList(SID_STYLE_FAMILY, SfxCallMode::SYNCHRON, { &aItem });
- pBindings->Invalidate( SID_STYLE_FAMILY );
- pBindings->Update( SID_STYLE_FAMILY );
- UpdateFamily_Impl();
+ m_aStyleListFamilySelect.Call(nEntry);
}
}
-void SfxCommonTemplateDialog_Impl::ActionSelect(const OString& rEntry)
+void SfxCommonTemplateDialog_Impl::ActionSelect(const OString& rEntry, StyleList& rStyleList)
{
if (rEntry == "watercan")
{
@@ -1608,18 +600,16 @@ void SfxCommonTemplateDialog_Impl::ActionSelect(const OString& rEntry)
bool bCheck;
SfxBoolItem aBool;
// when a template is chosen.
- if (!bOldState && HasSelectedStyle())
+ if (!bOldState && m_aStyleListHasSelectedStyle.Call(nullptr))
{
- const OUString aTemplName(
- GetSelectedEntry());
- Execute_Impl(
- SID_STYLE_WATERCAN, aTemplName, "",
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()) );
+ const OUString aTemplName(rStyleList.GetSelectedEntry());
+ Execute_Impl(SID_STYLE_WATERCAN, aTemplName, "",
+ static_cast<sal_uInt16>(m_aStyleList.GetFamilyItem()->GetFamily()), rStyleList);
bCheck = true;
}
else
{
- Execute_Impl(SID_STYLE_WATERCAN, "", "", 0);
+ Execute_Impl(SID_STYLE_WATERCAN, "", "", 0, rStyleList);
bCheck = false;
}
CheckItem(rEntry, bCheck);
@@ -1628,35 +618,13 @@ void SfxCommonTemplateDialog_Impl::ActionSelect(const OString& rEntry)
}
else if (rEntry == "new" || rEntry == "newmenu")
{
- if(pStyleSheetPool && nActFamily != 0xffff)
- {
- const SfxStyleFamily eFam=GetFamilyItem_Impl()->GetFamily();
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- SfxStyleSearchBits nFilter(SfxStyleSearchBits::Auto);
- if (pItem && nActFilter != 0xffff)
- nFilter = pItem->GetFilterList()[nActFilter].nFlags;
- if (nFilter == SfxStyleSearchBits::Auto) // automatic
- nFilter = nAppFilter;
-
- // why? : FloatingWindow must not be parent of a modal dialog
- SfxNewStyleDlg aDlg(mpContainer, *pStyleSheetPool, eFam);
- auto nResult = aDlg.run();
- if (nResult == RET_OK)
- {
- const OUString aTemplName(aDlg.GetName());
- Execute_Impl(SID_STYLE_NEW_BY_EXAMPLE,
- aTemplName, "",
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()),
- nFilter);
- UpdateFamily_Impl();
- }
- }
+ m_aStyleListNewMenu.Call(nullptr);
}
else if (rEntry == "update")
{
Execute_Impl(SID_STYLE_UPDATE_BY_EXAMPLE,
"", "",
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()));
+ static_cast<sal_uInt16>(m_aStyleList.GetFamilyItem()->GetFamily()), rStyleList);
}
else if (rEntry == "load")
SfxGetpApp()->GetDispatcher_Impl()->Execute(SID_TEMPLATE_LOAD);
@@ -1687,7 +655,7 @@ static OUString getModuleIdentifier( const Reference< XModuleManager2 >& i_xModM
return sIdentifier;
}
-sal_Int32 SfxCommonTemplateDialog_Impl::LoadFactoryStyleFilter( SfxObjectShell const * i_pObjSh )
+IMPL_LINK(SfxCommonTemplateDialog_Impl, LoadFactoryStyleFilter_Hdl, SfxObjectShell const*, i_pObjSh, sal_Int32)
{
OSL_ENSURE( i_pObjSh, "SfxCommonTemplateDialog_Impl::LoadFactoryStyleFilter(): no ObjectShell" );
@@ -1710,7 +678,7 @@ void SfxCommonTemplateDialog_Impl::SaveFactoryStyleFilter( SfxObjectShell const
xModuleManager->replaceByName( getModuleIdentifier( xModuleManager, i_pObjSh ), makeAny( lProps ) );
}
-SfxObjectShell* SfxCommonTemplateDialog_Impl::SaveSelection()
+IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, SaveSelection_Hdl, void*, SfxObjectShell*)
{
SfxViewFrame *const pViewFrame(pBindings->GetDispatcher_Impl()->GetFrame());
SfxObjectShell *const pDocShell(pViewFrame->GetObjectShell());
@@ -1722,219 +690,6 @@ SfxObjectShell* SfxCommonTemplateDialog_Impl::SaveSelection()
return pDocShell;
}
-void SfxCommonTemplateDialog_Impl::DropHdl(const OUString& rStyle, const OUString& rParent)
-{
- bDontUpdate = true;
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- const SfxStyleFamily eFam = pItem->GetFamily();
- pStyleSheetPool->SetParent(eFam, rStyle, rParent);
- bDontUpdate = false;
-}
-
-// Handler for the New-Buttons
-void SfxCommonTemplateDialog_Impl::NewHdl()
-{
- if ( nActFamily == 0xffff || !(mxTreeBox->get_visible() || mxFmtLb->count_selected_rows() <= 1))
- return;
-
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- const SfxStyleFamily eFam = pItem->GetFamily();
- SfxStyleSearchBits nMask(SfxStyleSearchBits::Auto);
- if (nActFilter != 0xffff)
- nMask = pItem->GetFilterList()[nActFilter].nFlags;
- if (nMask == SfxStyleSearchBits::Auto) // automatic
- nMask = nAppFilter;
-
- Execute_Impl(SID_STYLE_NEW,
- "", GetSelectedEntry(),
- static_cast<sal_uInt16>(eFam),
- nMask);
-}
-
-// Handler for the edit-Buttons
-void SfxCommonTemplateDialog_Impl::EditHdl()
-{
- if(IsInitialized() && HasSelectedStyle())
- {
- sal_uInt16 nFilter = nActFilter;
- OUString aTemplName(GetSelectedEntry());
- GetSelectedStyle(); // -Wall required??
- Execute_Impl( SID_STYLE_EDIT, aTemplName, OUString(),
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()), SfxStyleSearchBits::Auto, &nFilter );
- }
-}
-
-// Handler for the Delete-Buttons
-void SfxCommonTemplateDialog_Impl::DeleteHdl()
-{
- if ( !IsInitialized() || !HasSelectedStyle() )
- 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 = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
-
- 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 = 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));
- bDontUpdate = true; // To prevent the Treelistbox to shut down while deleting
- Execute_Impl( SID_STYLE_DELETE, aTemplName,
- OUString(), static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()) );
-
- if (mxTreeBox->get_visible())
- {
- weld::RemoveParentKeepChildren(*mxTreeBox, *elem);
- bDontUpdate = false;
- }
- }
- bDontUpdate = false; //if everything is deleted set bDontUpdate back to false
- UpdateStyles_Impl(StyleFlags::UpdateFamilyList); //and force-update the list
-}
-
-void SfxCommonTemplateDialog_Impl::HideHdl()
-{
- if ( !IsInitialized() || !HasSelectedStyle() )
- return;
-
- weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
- pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry){
- OUString aTemplName = pTreeView->get_text(rEntry);
-
- Execute_Impl( SID_STYLE_HIDE, aTemplName,
- OUString(), static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()) );
-
- return false;
- });
-}
-
-void SfxCommonTemplateDialog_Impl::ShowHdl()
-{
- if ( !IsInitialized() || !HasSelectedStyle() )
- return;
-
- weld::TreeView* pTreeView = mxTreeBox->get_visible() ? mxTreeBox.get() : mxFmtLb.get();
- pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry){
- OUString aTemplName = pTreeView->get_text(rEntry);
-
- Execute_Impl( SID_STYLE_SHOW, aTemplName,
- OUString(), static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()) );
-
- return false;
- });
-}
-
-void SfxCommonTemplateDialog_Impl::EnableDelete()
-{
- bool bEnableDelete(false);
- if(IsInitialized() && HasSelectedStyle())
- {
- OSL_ENSURE(pStyleSheetPool, "No StyleSheetPool");
- const OUString aTemplName(GetSelectedEntry());
- const SfxStyleFamilyItem *pItem = GetFamilyItem_Impl();
- const SfxStyleFamily eFam = pItem->GetFamily();
- SfxStyleSearchBits nFilter = SfxStyleSearchBits::Auto;
- if (pItem->GetFilterList().size() > nActFilter)
- nFilter = pItem->GetFilterList()[nActFilter].nFlags;
- if(nFilter == SfxStyleSearchBits::Auto) // automatic
- nFilter = nAppFilter;
- const SfxStyleSheetBase *pStyle =
- pStyleSheetPool->Find(aTemplName,eFam, mxTreeBox->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 = GetObjectShell()->GetFrame();
- if (pFrame)
- {
- uno::Reference<frame::XFrame > xFrame = pFrame->GetFrame().GetFrameInterface();
- if (vcl::CommandInfoProvider::GetModuleIdentifier(xFrame) == "com.sun.star.sheet.SpreadsheetDocument")
- {
- bEnableDelete = true;
- }
- }
- }
- }
- }
- EnableDel(bEnableDelete);
-}
-
-IMPL_LINK(SfxCommonTemplateDialog_Impl, MousePressHdl, const MouseEvent&, rMEvt, bool)
-{
- m_nModifier = rMEvt.GetModifier();
- return false;
-}
-
-// Double-click on a style sheet in the ListBox is applied.
-IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, TreeListApplyHdl, weld::TreeView&, bool)
-{
- // only if that region is allowed
- if ( IsInitialized() && nullptr != pFamilyState[nActFamily-1] &&
- !GetSelectedEntry().isEmpty() )
- {
- Execute_Impl(SID_STYLE_APPLY,
- GetSelectedEntry(), OUString(),
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()),
- SfxStyleSearchBits::Auto, nullptr, &m_nModifier);
- }
- // After selecting a focused item if possible again on the app window
- if ( dynamic_cast< const SfxTemplateDialog_Impl* >(this) != nullptr )
- {
- SfxViewFrame *pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame();
- SfxViewShell *pVu = pViewFrame->GetViewShell();
- vcl::Window *pAppWin = pVu ? pVu->GetWindow(): nullptr;
- if(pAppWin)
- pAppWin->GrabFocus();
- }
-
- return true;
-}
-
IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, PreviewHdl, weld::Toggleable&, void)
{
std::shared_ptr<comphelper::ConfigurationChanges> batch( comphelper::ConfigurationChanges::create() );
@@ -1942,75 +697,16 @@ IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, PreviewHdl, weld::Toggleable&, voi
officecfg::Office::Common::StylesAndFormatting::Preview::set(bCustomPreview, batch );
batch->commit();
- mxFmtLb->clear();
- mxFmtLb->set_column_custom_renderer(0, bCustomPreview);
- mxTreeBox->clear();
- mxTreeBox->set_column_custom_renderer(0, bCustomPreview);
+ m_aStyleList.EnablePreview(bCustomPreview);
FamilySelect(nActFamily, true);
}
-// Selection of a template during the Watercan-Status
-IMPL_LINK(SfxCommonTemplateDialog_Impl, 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))
- UpdateStyleDependents();
-
- SelectStyle(rListBox.get_text(*xHdlEntry), true);
-}
-
-void SfxCommonTemplateDialog_Impl::UpdateStyleDependents()
+IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, UpdateStyleDependents_Hdl, void*, void)
{
- // Trigger Help PI. Only when the watercan is on
- if ( IsInitialized() &&
- IsCheckedItem("watercan") &&
- // only if that region is allowed
- nullptr != pFamilyState[nActFamily-1] && (mxTreeBox || mxFmtLb->count_selected_rows() <= 1) )
- {
- Execute_Impl(SID_STYLE_WATERCAN,
- "", "", 0);
- Execute_Impl(SID_STYLE_WATERCAN,
- GetSelectedEntry(), "",
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()));
- }
+ m_aStyleListUpdateStyleDependents.Call(nullptr);
EnableItem("watercan", !bWaterDisabled);
- EnableDelete();
-}
-
-void SfxCommonTemplateDialog_Impl::MenuSelect(const OString& rIdent)
-{
- sLastItemIdent = rIdent;
- if (sLastItemIdent.isEmpty())
- return;
- Application::PostUserEvent(
- LINK(this, SfxCommonTemplateDialog_Impl, MenuSelectAsyncHdl));
-}
-
-IMPL_LINK_NOARG(SfxCommonTemplateDialog_Impl, 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();
-}
-
-SfxStyleFamily SfxCommonTemplateDialog_Impl::GetActualFamily() const
-{
- const SfxStyleFamilyItem *pFamilyItem = GetFamilyItem_Impl();
- if( !pFamilyItem || nActFamily == 0xffff )
- return SfxStyleFamily::Para;
- else
- return pFamilyItem->GetFamily();
+ m_aStyleListEnableDelete.Call(nullptr);
}
void SfxCommonTemplateDialog_Impl::EnableExample_Impl(sal_uInt16 nId, bool bEnable)
@@ -2019,6 +715,7 @@ void SfxCommonTemplateDialog_Impl::EnableExample_Impl(sal_uInt16 nId, bool bEnab
if (nId == SID_STYLE_NEW_BY_EXAMPLE)
{
bNewByExampleDisabled = bDisable;
+ m_aStyleList.EnableNewByExample(bNewByExampleDisabled);
EnableItem("new", bEnable);
EnableItem("newmenu", bEnable);
}
@@ -2029,41 +726,6 @@ void SfxCommonTemplateDialog_Impl::EnableExample_Impl(sal_uInt16 nId, bool bEnab
}
}
-void SfxCommonTemplateDialog_Impl::CreateContextMenu()
-{
- if ( bBindingUpdate )
- {
- pBindings->Invalidate( SID_STYLE_NEW, true );
- pBindings->Update( SID_STYLE_NEW );
- bBindingUpdate = false;
- }
- mxMenu.reset();
- mxMenuBuilder.reset(Application::CreateBuilder(nullptr, "sfx/ui/stylecontextmenu.ui"));
- mxMenu = mxMenuBuilder->weld_menu("menu");
- mxMenu->set_sensitive("edit", bCanEdit);
- mxMenu->set_sensitive("delete", bCanDel);
- mxMenu->set_sensitive("new", bCanNew);
- mxMenu->set_sensitive("hide", bCanHide);
- mxMenu->set_sensitive("show", bCanShow);
-
- const SfxStyleFamilyItem* pItem = GetFamilyItem_Impl();
- 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);
- }
- }
-}
-
SfxTemplateDialog_Impl::SfxTemplateDialog_Impl(SfxBindings* pB, SfxTemplatePanelControl* pDlgWindow)
: SfxCommonTemplateDialog_Impl(pB, pDlgWindow->get_container(), pDlgWindow->get_builder())
, m_xActionTbL(pDlgWindow->get_builder()->weld_toolbar("left"))
@@ -2159,20 +821,6 @@ void SfxTemplateDialog_Impl::ClearFamilyList()
}
-void SfxCommonTemplateDialog_Impl::InvalidateBindings()
-{
- pBindings->Invalidate(SID_STYLE_NEW_BY_EXAMPLE, true);
- pBindings->Update( SID_STYLE_NEW_BY_EXAMPLE );
- pBindings->Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE, true);
- pBindings->Update( SID_STYLE_UPDATE_BY_EXAMPLE );
- pBindings->Invalidate( SID_STYLE_WATERCAN, true);
- pBindings->Update( SID_STYLE_WATERCAN );
- pBindings->Invalidate( SID_STYLE_NEW, true);
- pBindings->Update( SID_STYLE_NEW );
- pBindings->Invalidate( SID_STYLE_DRAGHIERARCHIE, true);
- pBindings->Update( SID_STYLE_DRAGHIERARCHIE );
-}
-
SfxTemplateDialog_Impl::~SfxTemplateDialog_Impl()
{
m_xToolbarDropTargetHelper.reset();
@@ -2183,7 +831,7 @@ SfxTemplateDialog_Impl::~SfxTemplateDialog_Impl()
void SfxTemplateDialog_Impl::EnableItem(const OString& rMesId, bool bCheck)
{
if (rMesId == "watercan" && !bCheck && IsCheckedItem("watercan"))
- Execute_Impl(SID_STYLE_WATERCAN, "", "", 0);
+ Execute_Impl(SID_STYLE_WATERCAN, "", "", 0, m_aStyleList);
m_xActionTbR->set_item_sensitive(rMesId, bCheck);
}
@@ -2215,7 +863,7 @@ IMPL_LINK(SfxTemplateDialog_Impl, ToolBoxRSelect, const OString&, rEntry, void)
if (rEntry == "newmenu")
m_xActionTbR->set_menu_item_active(rEntry, !m_xActionTbR->get_menu_item_active(rEntry));
else
- ActionSelect(rEntry);
+ ActionSelect(rEntry, m_aStyleList);
}
void SfxTemplateDialog_Impl::FillToolMenu()
@@ -2240,7 +888,7 @@ IMPL_LINK(SfxTemplateDialog_Impl, ToolMenuSelectHdl, const OString&, rMenuId, vo
{
if (rMenuId.isEmpty())
return;
- ActionSelect(rMenuId);
+ ActionSelect(rMenuId, m_aStyleList);
}
void SfxCommonTemplateDialog_Impl::SetFamily(SfxStyleFamily const nFamily)
@@ -2249,58 +897,28 @@ void SfxCommonTemplateDialog_Impl::SetFamily(SfxStyleFamily const nFamily)
assert((0 < nId && nId <= MAX_FAMILIES) || 0xffff == nId);
if ( nId != nActFamily )
{
- if ( nActFamily != 0xFFFF )
- CheckItem(OString::number(nActFamily), false);
+ m_aStyleListSetFamily.Call(nId);
nActFamily = nId;
if ( nId != 0xFFFF )
bUpdateFamily = true;
}
}
-void SfxCommonTemplateDialog_Impl::UpdateFamily_Impl()
+IMPL_LINK(SfxCommonTemplateDialog_Impl, UpdateFamily_Hdl, StyleList&, rStyleList, void)
{
bUpdateFamily = false;
-
- SfxDispatcher* pDispat = pBindings->GetDispatcher_Impl();
- SfxViewFrame *pViewFrame = pDispat->GetFrame();
- SfxObjectShell *pDocShell = pViewFrame->GetObjectShell();
-
- SfxStyleSheetBasePool *pOldStyleSheetPool = pStyleSheetPool;
- pStyleSheetPool = pDocShell? pDocShell->GetStyleSheetPool(): nullptr;
- if ( pOldStyleSheetPool != pStyleSheetPool )
- {
- if ( pOldStyleSheetPool )
- EndListening(*pOldStyleSheetPool);
- if ( pStyleSheetPool )
- StartListening(*pStyleSheetPool);
- }
-
bWaterDisabled = false;
- bCanNew = mxTreeBox->get_visible() || mxFmtLb->count_selected_rows() <= 1;
bTreeDrag = true;
bUpdateByExampleDisabled = false;
- if (pStyleSheetPool)
- {
- if (!mxTreeBox->get_visible())
- UpdateStyles_Impl(StyleFlags::UpdateFamily | StyleFlags::UpdateFamilyList);
- else
- {
- UpdateStyles_Impl(StyleFlags::UpdateFamily);
- FillTreeBox();
- }
- }
-
- InvalidateBindings();
+ m_aStyleListUpdateFamily.Call(nullptr);
if (IsCheckedItem("watercan") &&
- // only if that area is allowed
- nullptr != pFamilyState[nActFamily - 1])
+ // only if that area is allowed
+ rStyleList.CurrentFamilyHasState())
{
- Execute_Impl(SID_STYLE_APPLY,
- GetSelectedEntry(),
- OUString(),
- static_cast<sal_uInt16>(GetFamilyItem_Impl()->GetFamily()));
+ Execute_Impl(SID_STYLE_APPLY, rStyleList.GetSelectedEntry(), OUString(),
+ static_cast<sal_uInt16>(rStyleList.GetFamilyItem()->GetFamily()), rStyleList);
}
}
diff --git a/sfx2/source/inc/StyleList.hxx b/sfx2/source/inc/StyleList.hxx
new file mode 100644
index 000000000000..65bb21cf9e82
--- /dev/null
+++ b/sfx2/source/inc/StyleList.hxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+class SfxObjectShell;
+class SfxStyleFamilyItem;
+class SfxTemplateItem;
+class SfxCommonTemplateDialog_Impl;
+
+enum class StyleFlags
+{
+ NONE = 0,
+ UpdateFamilyList = 1,
+ UpdateFamily = 2
+};
+
+namespace o3tl
+{
+template <> struct typed_flags<StyleFlags> : is_typed_flags<StyleFlags, 3>
+{
+};
+}
+
+class TreeViewDropTarget;
+
+constexpr int MAX_FAMILIES = 6;
+constexpr int COUNT_BOUND_FUNC = 14;
+
+class StyleList : public SfxListener
+{
+ friend class TreeViewDropTarget;
+ friend class SfxTemplateControllerItem;
+
+public:
+ // Constructor
+ StyleList(weld::Builder* pBuilder, std::optional<SfxStyleFamilies> xFamilies,
+ SfxBindings* pBindings, SfxCommonTemplateDialog_Impl* Parent, SfxModule* Module,
+ weld::Container* pC, OString treeviewname, OString flatviewname);
+
+ // Destructor
+ ~StyleList();
+
+ // This function connects m_xTreeBox, m_xFmtLb and m_pParentDialog with certain LINKs
+ void Initialize();
+
+ // 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 SelectStyle(const OUString& rStr, bool bIsCallback);
+ // Checks whether a family has a saved state
+ bool CurrentFamilyHasState() { return nullptr != m_pFamilyState[m_nActFamily - 1]; }
+
+ // This function is a subpart of Dialog's SetFamilyState
+ // When a new style is selected for use, it resets it.
+ void SetFamilyState(sal_uInt16 nSlotId, const SfxTemplateItem* pItem);
+
+ // It is used in Dialog's EnableExample_Impl
+ // When the value of m_bNewbyExampleDisabled is updated there
+ // while creating a new style by example,
+ // the corresponding value gets updated here too.
+ void EnableNewByExample(bool newByExampleDisabled);
+
+ // This function is used to set a hierarchical view.
+ void SetHierarchical();
+ // This function handles the controls while setting a filter except heirarchical
+ void SetFilterControlsHandle();
+ // Return whether treeview is visible
+ // It is used in StyleList's UpdateStyles_Hdl
+ // It is used to defaultly set the heirarchical view
+ bool IsTreeView() { return m_xTreeBox->get_visible(); }
+
+ // Dialog and StyleList have their own copies of m_nActFilter
+ // When this value gets updated in Dialog's UpdateStyles_Hdl while setting a filter,
+ // the corresponding value gets updated here too.
+ void SetFilterIdx(sal_uInt16 filter) { m_nActFilter = filter; }
+
+ // Helper function: Access to the current family item
+ // Used in Dialog's updateStyleHandler, Execute_Impl etc...
+ const SfxStyleFamilyItem* GetFamilyItem() const;
+ // Used to get the current selected entry in treeview
+ // Used in Dialog's Execute_Impl, Action_Select etc...
+ OUString GetSelectedEntry() const;
+ // Returns the Family Item at ith index
+ // Used in Dialog's ReadResource_Hdl
+ const SfxStyleFamilyItem& GetFamilyItemByIndex(size_t i) const;
+ const SfxObjectShell* GetObjectShell() const { return m_pCurObjShell; }
+ bool IsHierarchical() const { return m_bHierarchical; }
+
+ void Enabledel(bool candel) { m_bCanDel = candel; }
+ void Enablehide(bool canhide) { m_bCanHide = canhide; }
+ void Enableshow(bool canshow) { m_bCanShow = canshow; }
+ void Enablenew(bool cannew) { m_bCanNew = cannew; }
+ void Enableedit(bool canedit) { m_bCanEdit = canedit; }
+ // Handles the enabling/Disabling of Preview
+ void EnablePreview(bool bCustomPreview);
+ // Used in Dialog's Execute_Impl
+ // It is a necessary condition to execute a style
+ bool EnableExecute();
+
+ void connect_UpdateStyles(const Link<StyleFlags, void>& rLink) { m_aUpdateStyles = rLink; }
+ void connect_ReadResource(const Link<StyleList&, void>& rLink) { m_aReadResource = rLink; }
+ void connect_ClearResource(const Link<void*, void>& rLink) { m_aClearResource = rLink; }
+ void connect_LoadFactoryStyleFilter(const Link<SfxObjectShell const*, sal_Int32>& rLink);
+ void connect_SaveSelection(const Link<void*, SfxObjectShell*> rLink);
+ void connect_UpdateStyleDependents(const Link<void*, void> rLink);
+ void connect_UpdateFamily(const Link<StyleList&, void> rLink) { m_aUpdateFamily = rLink; }
+
+private:
+ void FillTreeBox(SfxStyleFamily eFam);
+
+ OUString getDefaultStyleName(const SfxStyleFamily eFam);
+ SfxStyleFamily GetActualFamily() const;
+ void GetSelectedStyle() const;
+
+ sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt, const DropTargetHelper& rHelper);
+ void DropHdl(const OUString& rStyle, const OUString& rParent);
+
+ void MenuSelect(const OString& rIdent);
+ void PrepareMenu(const Point& rPos);
+ void ShowMenu(const CommandEvent& rCEvt);
+ void CreateContextMenu();
+
+ void Notify(SfxBroadcaster& rBC, const SfxHint& rHint);
+
+ // In which FamilyState do I have to look, in order to get the
+ // information of the ith Family in the pStyleFamilies.
+ sal_uInt16 StyleNrToInfoOffset(sal_uInt16 i);
+
+ DECL_LINK(ReadResource, void*, size_t);
+ DECL_LINK(Clear, void*, void);
+ DECL_LINK(Cleanup, void*, void);
+ DECL_LINK(ExecuteDrop, const ExecuteDropEvent&, sal_Int8);
+ DECL_LINK(NewMenuExecuteAction, void*, void);
+ DECL_LINK(IsSafeForWaterCan, void*, bool);
+ DECL_LINK(HasSelectedStyle, void*, bool);
+ DECL_LINK(UpdateFamily, void*, void);
+ DECL_LINK(UpdateStyles, StyleFlags, void);
+ DECL_LINK(UpdateStyleDependents, void*, void);
+ DECL_LINK(TimeOut, Timer*, void);
+ DECL_LINK(EnableTreeDrag, bool, void);
+ DECL_LINK(EnableDelete, void*, void);
+ DECL_LINK(FilterSelect, sal_uInt16, void);
+ DECL_LINK(SetWaterCanState, const SfxBoolItem*, void);
+ DECL_LINK(SetFamily, sal_uInt16, void);
+ DECL_LINK(FamilySelect, sal_uInt16, void);
+
+ void InvalidateBindings();
+
+ void Update();
+ Link<StyleFlags, void> m_aUpdateStyles;
+ Link<StyleList&, void> m_aReadResource;
+ Link<void*, void> m_aClearResource;
+ Link<SfxObjectShell const*, sal_Int32> m_aLoadFactoryStyleFilter;
+ Link<void*, SfxObjectShell*> m_aSaveSelection;
+ Link<void*, void> m_aUpdateStyleDependents;
+ Link<StyleList&, void> m_aUpdateFamily;
+
+ void NewHdl();
+ void EditHdl();
+ void DeleteHdl();
+ void HideHdl();
+ void ShowHdl();
+
+ DECL_LINK(DragBeginHdl, bool&, bool);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString);
+ DECL_LINK(CustomRenderHdl, weld::TreeView::render_args, void);
+ DECL_LINK(FmtSelectHdl, weld::TreeView&, void);
+ DECL_LINK(TreeListApplyHdl, weld::TreeView&, bool);
+ DECL_LINK(MousePressHdl, const MouseEvent&, bool);
+ DECL_STATIC_LINK(StyleList, CustomGetSizeHdl, weld::TreeView::get_size_args, Size);
+ DECL_LINK(PopupFlatMenuHdl, const CommandEvent&, bool);
+ DECL_LINK(PopupTreeMenuHdl, const CommandEvent&, bool);
+ DECL_LINK(MenuSelectAsyncHdl, void*, void);
+
+ bool m_bHierarchical : 1;
+
+ bool m_bAllowReParentDrop : 1;
+ bool m_bNewByExampleDisabled : 1;
+ bool m_bDontUpdate : 1;
+ bool m_bTreeDrag : 1;
+ bool m_bCanEdit : 1;
+ bool m_bCanHide : 1;
+ bool m_bCanShow : 1;
+ bool m_bCanNew : 1;
+ bool m_bUpdateFamily : 1;
+ bool m_bCanDel : 1;
+ bool m_bBindingUpdate : 1;
+ SfxStyleSheetBasePool* m_pStyleSheetPool;
+ sal_uInt16 m_nActFilter;
+ std::unique_ptr<weld::TreeView> m_xFmtLb;
+ std::unique_ptr<weld::TreeView> m_xTreeBox;
+
+ std::unique_ptr<weld::Builder> mxMenuBuilder;
+ std::unique_ptr<weld::Menu> mxMenu;
+
+ std::optional<SfxStyleFamilies> m_xStyleFamilies;
+ std::array<std::unique_ptr<SfxTemplateItem>, MAX_FAMILIES> m_pFamilyState;
+ SfxObjectShell* m_pCurObjShell;
+ sal_uInt16 m_nActFamily;
+ SfxStyleSearchBits m_nAppFilter;
+
+ std::unique_ptr<TreeViewDropTarget> m_xTreeView1DropTargetHelper;
+ std::unique_ptr<TreeViewDropTarget> m_xTreeView2DropTargetHelper;
+
+ SfxCommonTemplateDialog_Impl* m_pParentDialog;
+ SfxBindings* m_pBindings;
+ std::array<std::unique_ptr<SfxTemplateControllerItem>, COUNT_BOUND_FUNC> pBoundItems;
+
+ std::unique_ptr<Idle> pIdle;
+
+ OString sLastItemIdent;
+ SfxModule* m_Module;
+ sal_uInt16 m_nModifier;
+ weld::Container* m_pContainer;
+};
diff --git a/sfx2/source/inc/templdgi.hxx b/sfx2/source/inc/templdgi.hxx
index 61d6de8001cb..daedd86de98c 100644
--- a/sfx2/source/inc/templdgi.hxx
+++ b/sfx2/source/inc/templdgi.hxx
@@ -41,6 +41,8 @@ class SfxTemplateControllerItem;
#include <vcl/idle.hxx>
+#include "StyleList.hxx"
+
class SfxStyleFamilyItem;
class SfxTemplateItem;
class SfxBindings;
@@ -54,26 +56,14 @@ namespace com::sun::star::frame {
class XModuleManager2;
}
-enum class StyleFlags {
- NONE=0, UpdateFamilyList=1, UpdateFamily=2
-};
-namespace o3tl {
- template<> struct typed_flags<StyleFlags> : is_typed_flags<StyleFlags, 3> {};
-}
-
-class TreeViewDropTarget;
-
-class SfxCommonTemplateDialog_Impl : public SfxListener
+class SfxCommonTemplateDialog_Impl
{
private:
class DeletionWatcher;
friend class DeletionWatcher;
- void ReadResource();
- void ClearResource();
- void impl_clear();
DeletionWatcher* impl_setDeletionWatcher(DeletionWatcher* pNewWatcher);
- OUString getDefaultStyleName( const SfxStyleFamily eFam );
+ static OUString getDefaultStyleName( const SfxStyleFamily eFam, StyleList& rStyleList );
protected:
#define MAX_FAMILIES 6
@@ -82,177 +72,158 @@ protected:
friend class SfxTemplateControllerItem;
SfxBindings* pBindings;
- std::array<std::unique_ptr<SfxTemplateControllerItem>, COUNT_BOUND_FUNC> pBoundItems;
weld::Container* mpContainer;
- std::unique_ptr<weld::Builder> mxMenuBuilder;
- std::unique_ptr<weld::Menu> mxMenu;
- OString sLastItemIdent;
SfxModule* pModule;
- std::unique_ptr<Idle> pIdle;
std::optional<SfxStyleFamilies> mxStyleFamilies;
- std::array<std::unique_ptr<SfxTemplateItem>, MAX_FAMILIES> pFamilyState;
- SfxStyleSheetBasePool* pStyleSheetPool;
- SfxObjectShell* pCurObjShell;
css::uno::Reference<css::frame::XModuleManager2> xModuleManager;
DeletionWatcher* m_pDeletionWatcher;
- std::unique_ptr<weld::TreeView> mxFmtLb;
- std::unique_ptr<weld::TreeView> mxTreeBox;
+ StyleList m_aStyleList;
std::unique_ptr<weld::CheckButton> mxPreviewCheckbox;
std::unique_ptr<weld::ComboBox> mxFilterLb;
- std::unique_ptr<TreeViewDropTarget> m_xTreeView1DropTargetHelper;
- std::unique_ptr<TreeViewDropTarget> m_xTreeView2DropTargetHelper;
sal_uInt16 nActFamily; // Id in the ToolBox = Position - 1
sal_uInt16 nActFilter; // FilterIdx
SfxStyleSearchBits nAppFilter; // Filter, which has set the application (for automatic)
- sal_uInt16 m_nModifier;
- bool bDontUpdate :1;
bool bIsWater :1;
bool bUpdate :1;
bool bUpdateFamily :1;
- bool bCanEdit :1;
- bool bCanDel :1;
- bool bCanNew :1;
- bool bCanHide :1;
- bool bCanShow :1;
bool bWaterDisabled :1;
bool bNewByExampleDisabled :1;
bool bUpdateByExampleDisabled :1;
bool bTreeDrag :1;
- bool bAllowReParentDrop:1;
- bool bHierarchical :1;
bool m_bWantHierarchical :1;
- bool bBindingUpdate :1;
+
+ Link<void*, size_t> m_aStyleListReadResource;
+ Link<void*, void> m_aStyleListClear;
+ Link<void*, void> m_aStyleListCleanup;
+ Link<const ExecuteDropEvent&, sal_Int8> m_aStyleListExecuteDrop;
+ Link<void*, void> m_aStyleListNewMenu;
+ Link<void*, bool> m_aStyleListWaterCan;
+ Link<void*, bool> m_aStyleListHasSelectedStyle;
+ Link<StyleFlags, void> m_aStyleListUpdateStyles;
+ Link<void*, void> m_aStyleListUpdateFamily;
+ Link<SfxHintId, void> m_aStyleListNotify;
+ Link<void*, void> m_aStyleListUpdateStyleDependents;
+ Link<bool, void> m_aStyleListEnableTreeDrag;
+ Link<sal_uInt16, void> m_aStyleListFilterSelect;
+ Link<void*, void> m_aStyleListEnableDelete;
+ Link<const SfxBoolItem*, void> m_aStyleListSetWaterCanState;
+ Link<sal_uInt16, void> m_aStyleListFamilySelect;
+ Link<sal_uInt16, void> m_aStyleListSetFamily;
DECL_LINK(FilterSelectHdl, weld::ComboBox&, void );
- DECL_LINK(FmtSelectHdl, weld::TreeView&, void);
- DECL_LINK(TreeListApplyHdl, weld::TreeView&, bool);
- DECL_LINK(MousePressHdl, const MouseEvent&, bool);
- DECL_LINK(TimeOut, Timer*, void );
DECL_LINK(PreviewHdl, weld::Toggleable&, void);
- DECL_LINK(PopupFlatMenuHdl, const CommandEvent&, bool);
- DECL_LINK(PopupTreeMenuHdl, const CommandEvent&, bool);
- DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
- DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString);
- DECL_LINK(OnAsyncExecuteDrop, void *, void);
- DECL_LINK(DragBeginHdl, bool&, bool);
- DECL_LINK(CustomRenderHdl, weld::TreeView::render_args, void);
- DECL_STATIC_LINK(SfxCommonTemplateDialog_Impl, CustomGetSizeHdl, weld::TreeView::get_size_args, Size);
-
- void DropHdl(const OUString& rStyle, const OUString& rParent);
-
- virtual void EnableItem(const OString& /*rMesId*/, bool /*bCheck*/ = true)
- {}
- virtual void CheckItem(const OString& /*rMesId*/, bool /*bCheck*/ = true)
- {}
- virtual bool IsCheckedItem(const OString& /*rMesId*/ )
- {
- return true;
- }
-
- void InvalidateBindings();
+
virtual void InsertFamilyItem(sal_uInt16 nId, const SfxStyleFamilyItem& rItem) = 0;
virtual void EnableFamilyItem(sal_uInt16 nId, bool bEnabled) = 0;
virtual void ClearFamilyList() = 0;
virtual void ReplaceUpdateButtonByMenu();
- void NewHdl();
- void EditHdl();
- void DeleteHdl();
- void HideHdl();
- void ShowHdl();
-
- bool Execute_Impl(sal_uInt16 nId, const OUString& rStr, const OUString& rRefStr,
- sal_uInt16 nFamily, SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto,
- sal_uInt16* pIdx = nullptr, const sal_uInt16* pModifier = nullptr );
-
- void UpdateStyles_Impl(StyleFlags nFlags);
- const SfxStyleFamilyItem* GetFamilyItem_Impl() const;
- bool IsInitialized() const
- {
- return nActFamily != 0xffff;
- }
- void EnableDelete();
void Initialize();
- void EnableHierarchical(bool);
+ void EnableHierarchical(bool, StyleList& rStyleList);
void FilterSelect( sal_uInt16 nFilterIdx, bool bForce );
void SetFamilyState( sal_uInt16 nSlotId, const SfxTemplateItem* );
void SetWaterCanState( const SfxBoolItem* pItem );
bool IsSafeForWaterCan() const;
- void SelectStyle(const OUString& rStyle, bool bIsCallback);
- void UpdateStyleDependents();
- bool HasSelectedStyle() const;
- void GetSelectedStyle() const;
- void FillTreeBox();
- void Update_Impl();
- void UpdateFamily_Impl();
-
- // In which FamilyState do I have to look, in order to get the
- // information of the ith Family in the pStyleFamilies.
- sal_uInt16 StyleNrToInfoOffset( sal_uInt16 i );
-
- void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
-
- void FamilySelect( sal_uInt16 nId, bool bPreviewRefresh = false );
void SetFamily(SfxStyleFamily nFamily);
- void ActionSelect(const OString& rId);
+ void ActionSelect(const OString& rId, StyleList& rStyleList);
- sal_Int32 LoadFactoryStyleFilter( SfxObjectShell const * i_pObjSh );
- void SaveFactoryStyleFilter( SfxObjectShell const * i_pObjSh, sal_Int32 i_nFilter );
- SfxObjectShell* SaveSelection();
+ void SaveFactoryStyleFilter(SfxObjectShell const* i_pObjSh, sal_Int32 i_nFilter);
- void PrepareMenu(const Point& rPos);
- void ShowMenu(const CommandEvent& rCEvt);
+ DECL_LINK(ReadResource_Hdl, StyleList&, void);
+ DECL_LINK(ClearResource_Hdl, void*, void);
+ DECL_LINK(SaveSelection_Hdl, void*, SfxObjectShell*);
+ DECL_LINK(LoadFactoryStyleFilter_Hdl, SfxObjectShell const*, sal_Int32);
+ DECL_LINK(UpdateStyles_Hdl, StyleFlags, void);
+ DECL_LINK(UpdateFamily_Hdl, StyleList&, void);
+ DECL_LINK(UpdateStyleDependents_Hdl, void*, void);
public:
+ // Used in StyleList::NewMenuExecuteAction, StyleList::UpdateStyleDependents, StyleList::NewHdl, EditHdl...
+ // It comes into action whenever an existing style is selected for use, or a new style is created etc..
+ bool Execute_Impl(sal_uInt16 nId, const OUString& rStr, const OUString& rRefStr,
+ sal_uInt16 nFamily, StyleList& rStyleList, SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto,
+ sal_uInt16* pIdx = nullptr, const sal_uInt16* pModifier = nullptr);
+
+ // This function handles drop of content into the treeview to create a new style
+ sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt);
+ // This function is used when a newstyle is created
+ DECL_LINK(OnAsyncExecuteDrop, void*, void);
+
+ // Used in StyleList::UpdateStyles, StyleList::Update
+ // Whenever a new family(Eg. Character, List etc.) is selected it comes into action
+ void FamilySelect(sal_uInt16 nId, bool bPreviewRefresh = false);
+ // Constructor
SfxCommonTemplateDialog_Impl(SfxBindings* pB, weld::Container*, weld::Builder* pBuilder);
- virtual ~SfxCommonTemplateDialog_Impl() override;
-
- void MenuSelect(const OString& rIdent);
- DECL_LINK( MenuSelectAsyncHdl, void*, void );
-
- virtual void EnableEdit( bool b )
- {
- bCanEdit = b;
- }
- void EnableDel( bool b )
- {
- bCanDel = b;
- }
- void EnableNew( bool b )
- {
- bCanNew = b;
- }
- void EnableHide( bool b )
- {
- bCanHide = b;
- }
- void EnableShow( bool b )
- {
- bCanShow = b;
- }
- void EnableTreeDrag(bool b);
- void EnableExample_Impl(sal_uInt16 nId, bool bEnable);
- SfxStyleFamily GetActualFamily() const;
- OUString GetSelectedEntry() const;
+ // Destructor
+ virtual ~SfxCommonTemplateDialog_Impl();
- SfxObjectShell* GetObjectShell() const
- {
- return pCurObjShell;
- }
+ // Used in StyleList::SelectStyle, StyleList::Notify, IMPL_LINK(PopupFlatMenuHdl)
+ // These functions are used when a style is edited, deleted, created etc..
+ virtual void EnableEdit(bool b) { m_aStyleList.Enableedit(b); }
+ void EnableDel(bool b) { m_aStyleList.Enabledel(b); }
+ void EnableNew(bool b) { m_aStyleList.Enablenew(b); }
+ void EnableHide(bool b) { m_aStyleList.Enablehide(b); }
+ void EnableShow(bool b) { m_aStyleList.Enableshow(b); }
- sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt, const DropTargetHelper& rHelper);
- sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt);
+ // Used in TreeDrag
+ void EnableTreeDrag(bool b);
+ // Dialog and StyleList have their own copies of variable bTreeDrag.
+ // When TreeDrag is enabled in StyleList, the value of m_bTreeDrag is updated in StyleList
+ // This function updates the value of bTreeDrag here too.
+ void SetEnableDrag(bool treedrag) { bTreeDrag = treedrag; }
+ // It comes into action when a style is created or updated or newmenu is created
+ void EnableExample_Impl(sal_uInt16 nId, bool bEnable);
- void CreateContextMenu();
+ // This comes into action when a family is selected or a style is applied for use
+ virtual void CheckItem(const OString& /*rMesId*/, bool /*bCheck*/ = true) {}
+ // This is used for watercan or when newmenu or watercan is enabled or updated
+ virtual void EnableItem(const OString& /*rMesId*/, bool /*bCheck*/ = true) {}
+ // This is used for watercan
+ virtual bool IsCheckedItem(const OString& /*rMesId*/) { return true; }
+
+ // This is used when a style is selected
+ void SelectStyle(const OUString& rStyle, bool bIsCallback, StyleList& rStyleList);
+
+ // Dialog and StyleList have their own copies of variable nAppFilter.
+ // When a filter is applied, it comes into action and updates the value of nAppFilter
+ void SetApplicationFilter(SfxStyleSearchBits filter) { nAppFilter = filter; }
+ // Dialog and StyleList have their own copies of variable nActFilter.
+ // When a filter is applied, it comes into action and updates the value of nActFilter
+ void SetFilterByIndex(sal_uInt16 filter) { nActFilter = filter; }
+
+ // This function return the value of bUpdate in Stylelist
+ // This value is used in StyleList's Notify
+ bool GetNotifyUpdate() { return bUpdate; }
+ // This function sets the value of bUpdate in Dialog
+ // This function is used in StyleList's Notify to update the value of bUpdate when required
+ void SetNotifyupdate(bool b) { bUpdate = b; }
+
+ void connect_stylelist_read_resource(const Link<void*, size_t>& rLink) { m_aStyleListReadResource = rLink; }
+ void connect_stylelist_clear(const Link<void*, void>& rLink) { m_aStyleListClear = rLink; }
+ void connect_stylelist_cleanup(const Link<void*, void>& rLink) { m_aStyleListCleanup = rLink; }
+ void connect_stylelist_execute_drop(const Link<const ExecuteDropEvent&, sal_Int8>& rLink);
+ void connect_stylelist_execute_new_menu(const Link<void*, void>& rLink) { m_aStyleListNewMenu = rLink; }
+ void connect_stylelist_for_watercan(const Link<void*, bool>& rLink) { m_aStyleListWaterCan = rLink; }
+ void connect_stylelist_has_selected_style(const Link<void*, bool>& rLink);
+ void connect_stylelist_update_styles(const Link<StyleFlags, void> rLink) { m_aStyleListUpdateStyles = rLink; }
+ void connect_stylelist_update_family(const Link<void*, void> rLink) { m_aStyleListUpdateFamily = rLink; }
+ void connect_stylelist_update_style_dependents(const Link<void*, void>& rLink);
+ void connect_stylelist_enable_tree_drag(const Link<bool, void> rLink);
+ void connect_stylelist_notify(const Link<SfxHintId, void> rLink) { m_aStyleListNotify = rLink; }
+ void connect_stylelist_filter_select(Link<sal_uInt16, void> rLink);
+ void connect_stylelist_enable_delete(const Link<void*, void> rLink);
+ void connect_stylelist_set_water_can_state(const Link<const SfxBoolItem*, void> rLink);
+ void connect_family_select(const Link<sal_uInt16, void> rLink);
+ void connect_set_family(const Link<sal_uInt16, void> rLink) { m_aStyleListSetFamily = rLink; }
};
class ToolbarDropTarget;