LibreOffice Module sfx2 (master) 1
StyleList.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <unordered_map>
22
23#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
24#include <com/sun/star/beans/XPropertySet.hpp>
25#include <com/sun/star/container/XNameAccess.hpp>
26#include <utility>
27#include <vcl/commandevent.hxx>
29#include <vcl/event.hxx>
30#include <vcl/settings.hxx>
31#include <vcl/svapp.hxx>
32#include <vcl/weldutils.hxx>
33#include <vcl/window.hxx>
34#include <svl/intitem.hxx>
35#include <svl/style.hxx>
37#include <officecfg/Office/Common.hxx>
38
39#include <osl/diagnose.h>
40#include <sfx2/dispatch.hxx>
41#include <sfx2/bindings.hxx>
42#include <templdgi.hxx>
43#include <tplcitem.hxx>
44#include <sfx2/styfitem.hxx>
45#include <sfx2/objsh.hxx>
46#include <sfx2/viewsh.hxx>
47#include <sfx2/newstyle.hxx>
48#include <sfx2/tplpitem.hxx>
49#include <sfx2/sfxresid.hxx>
50
51#include <sfx2/sfxsids.hrc>
52#include <sfx2/strings.hrc>
53#include <sfx2/docfac.hxx>
54#include <sfx2/module.hxx>
55#include <helpids.h>
56#include <sfx2/viewfrm.hxx>
57
58#include <comphelper/string.hxx>
59
60#include <sfx2/StyleManager.hxx>
62
63#include <StyleList.hxx>
64
65#include <vcl/virdev.hxx>
67
68using namespace css;
69using namespace css::beans;
70using namespace css::frame;
71using namespace css::uno;
72
73class TreeViewDropTarget final : public DropTargetHelper
74{
75private:
77
78public:
80 : DropTargetHelper(rTreeView.get_drop_target())
81 , m_rParent(rStyleList)
82 {
83 }
84
85 virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
86 {
87 return m_rParent.AcceptDrop(rEvt, *this);
88 }
89
90 virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
91 {
92 return m_rParent.ExecuteDrop(rEvt);
93 }
94};
95
96namespace
97{
98Color ColorHash(std::u16string_view rString)
99{
100 static std::vector aSaturationArray{ 0.90, 0.75, 0.60 };
101 static std::vector aLightnessArray = aSaturationArray;
102
103 sal_uInt32 nStringHash = rtl_ustr_hashCode_WithLength(rString.data(), rString.length());
104
105 double nHue = nStringHash % 359;
106 double nSaturation = aSaturationArray[nStringHash / 360 % aSaturationArray.size()];
107 double nLightness
108 = aLightnessArray[nStringHash / 360 / aSaturationArray.size() % aLightnessArray.size()];
109
110 basegfx::BColor aHSLColor(nHue, nSaturation, nLightness);
111
112 return Color(basegfx::utils::hsl2rgb(aHSLColor));
113}
114
115// used to disallow the default character style in the styles highlighter character styles color map
116std::optional<OUString> sDefaultCharStyleUIName;
117}
118
119// Constructor
120
123 OUString treeviewname, OUString flatviewname)
124 : m_bHierarchical(false)
125 , m_bAllowReParentDrop(false)
126 , m_bNewByExampleDisabled(false)
127 , m_bDontUpdate(false)
128 , m_bTreeDrag(true)
129 , m_bCanEdit(false)
130 , m_bCanHide(true)
131 , m_bCanShow(false)
132 , m_bCanNew(true)
133 , m_bUpdateFamily(false)
134 , m_bCanDel(false)
135 , m_bBindingUpdate(true)
136 , m_pStyleSheetPool(nullptr)
137 , m_nActFilter(0)
138 , m_xFmtLb(pBuilder->weld_tree_view(flatviewname))
139 , m_xTreeBox(pBuilder->weld_tree_view(treeviewname))
140 , m_pCurObjShell(nullptr)
141 , m_nActFamily(0xffff)
142 , m_nAppFilter(SfxStyleSearchBits::Auto)
143 , m_pParentDialog(Parent)
144 , m_pBindings(pBindings)
145 , m_Module(nullptr)
146 , m_nModifier(0)
147 , m_pContainer(pC)
148{
149 m_xFmtLb->set_help_id(HID_TEMPLATE_FMT);
150
151 uno::Reference<frame::XFrame> xFrame
154 = vcl::CommandInfoProvider::GetModuleIdentifier(xFrame) == "com.sun.star.text.TextDocument";
155}
156
157// Destructor
158
160
161// Called in the destructor of Dialog
162// Cleans up the StyleList individual components while closing the application
163IMPL_LINK_NOARG(StyleList, Cleanup, void*, void)
164{
165 if (m_pStyleSheetPool)
166 EndListening(*m_pStyleSheetPool);
167 m_pStyleSheetPool = nullptr;
168 m_xTreeView1DropTargetHelper.reset();
169 m_xTreeView2DropTargetHelper.reset();
170 m_xTreeBox.reset();
171 m_xFmtLb.reset();
172 pIdle.reset();
173}
174
176{
178 {
179 m_pBindings->Invalidate(SID_STYLE_NEW, true);
180 m_pBindings->Update(SID_STYLE_NEW);
181 m_bBindingUpdate = false;
182 }
183 mxMenu.reset();
184 mxMenuBuilder = Application::CreateBuilder(nullptr, "sfx/ui/stylecontextmenu.ui");
185 mxMenu = mxMenuBuilder->weld_menu("menu");
186 mxMenu->set_sensitive("edit", m_bCanEdit);
187 mxMenu->set_sensitive("delete", m_bCanDel);
188 mxMenu->set_sensitive("new", m_bCanNew);
189 mxMenu->set_sensitive("hide", m_bCanHide);
190 mxMenu->set_sensitive("show", m_bCanShow);
191
192 const SfxStyleFamilyItem* pItem = GetFamilyItem();
193 if (pItem && pItem->GetFamily() == SfxStyleFamily::Table) //tdf#101648, no ui for this yet
194 {
195 mxMenu->set_sensitive("edit", false);
196 mxMenu->set_sensitive("new", false);
197 }
198 if (pItem && pItem->GetFamily() == SfxStyleFamily::Pseudo)
199 {
200 const OUString aTemplName(GetSelectedEntry());
201 if (aTemplName == "No List")
202 {
203 mxMenu->set_sensitive("edit", false);
204 mxMenu->set_sensitive("new", false);
205 mxMenu->set_sensitive("hide", false);
206 }
207 }
208}
209
210IMPL_LINK_NOARG(StyleList, ReadResource, void*, size_t)
211{
212 // Read global user resource
213 for (auto& i : m_pFamilyState)
214 i.reset();
215
216 SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
217 m_pCurObjShell = pViewFrame->GetObjectShell();
218 m_Module = m_pCurObjShell ? m_pCurObjShell->GetModule() : nullptr;
219 if (m_Module)
220 m_xStyleFamilies = m_Module->CreateStyleFamilies();
221 if (!m_xStyleFamilies)
222 m_xStyleFamilies.emplace();
223
224 m_nActFilter = 0xffff;
225
226 if (m_pCurObjShell)
227 {
228 m_nActFilter = static_cast<sal_uInt16>(m_aLoadFactoryStyleFilter.Call(m_pCurObjShell));
229 if (0xffff == m_nActFilter)
230 {
231 m_nActFilter = m_pCurObjShell->GetAutoStyleFilterIndex();
232 }
233 if (m_bModuleHasStylesHighlighterFeature)
234 sDefaultCharStyleUIName = getDefaultStyleName(SfxStyleFamily::Char);
235 }
236 size_t nCount = m_xStyleFamilies->size();
237 m_pBindings->ENTERREGISTRATIONS();
238
239 size_t i;
240 for (i = 0; i < nCount; ++i)
241 {
242 sal_uInt16 nSlot = 0;
243 switch (m_xStyleFamilies->at(i).GetFamily())
244 {
245 case SfxStyleFamily::Char:
246 nSlot = SID_STYLE_FAMILY1;
247 break;
248 case SfxStyleFamily::Para:
249 nSlot = SID_STYLE_FAMILY2;
250 break;
251 case SfxStyleFamily::Frame:
252 nSlot = SID_STYLE_FAMILY3;
253 break;
254 case SfxStyleFamily::Page:
255 nSlot = SID_STYLE_FAMILY4;
256 break;
257 case SfxStyleFamily::Pseudo:
258 nSlot = SID_STYLE_FAMILY5;
259 break;
260 case SfxStyleFamily::Table:
261 nSlot = SID_STYLE_FAMILY6;
262 break;
263 default:
264 OSL_FAIL("unknown StyleFamily");
265 break;
266 }
267 pBoundItems[i].reset(new SfxTemplateControllerItem(nSlot, *m_pParentDialog, *m_pBindings));
268 }
269 pBoundItems[i++].reset(
270 new SfxTemplateControllerItem(SID_STYLE_WATERCAN, *m_pParentDialog, *m_pBindings));
271 pBoundItems[i++].reset(
272 new SfxTemplateControllerItem(SID_STYLE_NEW_BY_EXAMPLE, *m_pParentDialog, *m_pBindings));
273 pBoundItems[i++].reset(
274 new SfxTemplateControllerItem(SID_STYLE_UPDATE_BY_EXAMPLE, *m_pParentDialog, *m_pBindings));
275 pBoundItems[i++].reset(
276 new SfxTemplateControllerItem(SID_STYLE_NEW, *m_pParentDialog, *m_pBindings));
277 pBoundItems[i++].reset(
278 new SfxTemplateControllerItem(SID_STYLE_DRAGHIERARCHIE, *m_pParentDialog, *m_pBindings));
279 pBoundItems[i++].reset(
280 new SfxTemplateControllerItem(SID_STYLE_EDIT, *m_pParentDialog, *m_pBindings));
281 pBoundItems[i++].reset(
282 new SfxTemplateControllerItem(SID_STYLE_DELETE, *m_pParentDialog, *m_pBindings));
283 pBoundItems[i++].reset(
284 new SfxTemplateControllerItem(SID_STYLE_FAMILY, *m_pParentDialog, *m_pBindings));
285 m_pBindings->LEAVEREGISTRATIONS();
286
287 for (; i < COUNT_BOUND_FUNC; ++i)
288 pBoundItems[i] = nullptr;
289
290 StartListening(*m_pBindings);
291
292 for (i = SID_STYLE_FAMILY1; i <= SID_STYLE_FAMILY4; i++)
293 m_pBindings->Update(i);
294
295 return nCount;
296}
297
298void StyleList::EnableNewByExample(bool newByExampleDisabled)
299{
300 m_bNewByExampleDisabled = newByExampleDisabled;
301}
302
303void StyleList::FilterSelect(sal_uInt16 nActFilter, bool bsetFilter)
304{
305 m_nActFilter = nActFilter;
306 if (bsetFilter)
307 {
308 SfxObjectShell* const pDocShell = m_aSaveSelection.Call(*this);
309 SfxStyleSheetBasePool* pOldStyleSheetPool = m_pStyleSheetPool;
310 m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
311 if (pOldStyleSheetPool != m_pStyleSheetPool)
312 {
313 if (pOldStyleSheetPool)
314 EndListening(*pOldStyleSheetPool);
317 }
318 }
320}
321
322IMPL_LINK(StyleList, SetFamily, sal_uInt16, nId, void)
323{
324 if (m_nActFamily != 0xFFFF)
325 m_pParentDialog->CheckItem(OUString::number(m_nActFamily), false);
326 m_nActFamily = nId;
327 if (nId != 0xFFFF)
328 {
329 m_bUpdateFamily = true;
330 }
331}
332
334{
335 m_pBindings->Invalidate(SID_STYLE_NEW_BY_EXAMPLE, true);
336 m_pBindings->Update(SID_STYLE_NEW_BY_EXAMPLE);
337 m_pBindings->Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE, true);
338 m_pBindings->Update(SID_STYLE_UPDATE_BY_EXAMPLE);
339 m_pBindings->Invalidate(SID_STYLE_WATERCAN, true);
340 m_pBindings->Update(SID_STYLE_WATERCAN);
341 m_pBindings->Invalidate(SID_STYLE_NEW, true);
342 m_pBindings->Update(SID_STYLE_NEW);
343 m_pBindings->Invalidate(SID_STYLE_DRAGHIERARCHIE, true);
344 m_pBindings->Update(SID_STYLE_DRAGHIERARCHIE);
345}
346
348{
349 m_pBindings->Invalidate(SID_STYLE_FAMILY);
350 m_pBindings->Update(SID_STYLE_FAMILY);
351
352 m_xFmtLb->connect_row_activated(LINK(this, StyleList, TreeListApplyHdl));
353 m_xFmtLb->connect_mouse_press(LINK(this, StyleList, MousePressHdl));
354 m_xFmtLb->connect_query_tooltip(LINK(this, StyleList, QueryTooltipHdl));
355 m_xFmtLb->connect_changed(LINK(this, StyleList, FmtSelectHdl));
356 m_xFmtLb->connect_popup_menu(LINK(this, StyleList, PopupFlatMenuHdl));
357 m_xFmtLb->connect_key_press(LINK(this, StyleList, KeyInputHdl));
358 m_xFmtLb->set_selection_mode(SelectionMode::Multiple);
359 m_xTreeBox->connect_changed(LINK(this, StyleList, FmtSelectHdl));
360 m_xTreeBox->connect_row_activated(LINK(this, StyleList, TreeListApplyHdl));
361 m_xTreeBox->connect_mouse_press(LINK(this, StyleList, MousePressHdl));
362 m_xTreeBox->connect_query_tooltip(LINK(this, StyleList, QueryTooltipHdl));
363 m_xTreeBox->connect_popup_menu(LINK(this, StyleList, PopupTreeMenuHdl));
364 m_xTreeBox->connect_key_press(LINK(this, StyleList, KeyInputHdl));
365 m_xTreeBox->connect_drag_begin(LINK(this, StyleList, DragBeginHdl));
368
374 LINK(this, StyleList, NewMenuExecuteAction));
378 LINK(this, StyleList, UpdateStyleDependents));
383
384 int nTreeHeight = m_xFmtLb->get_height_rows(8);
385 m_xFmtLb->set_size_request(-1, nTreeHeight);
386 m_xTreeBox->set_size_request(-1, nTreeHeight);
387
388 m_xFmtLb->connect_custom_get_size(LINK(this, StyleList, CustomGetSizeHdl));
389 m_xFmtLb->connect_custom_render(LINK(this, StyleList, CustomRenderHdl));
390 m_xTreeBox->connect_custom_get_size(LINK(this, StyleList, CustomGetSizeHdl));
391 m_xTreeBox->connect_custom_render(LINK(this, StyleList, CustomRenderHdl));
392 bool bCustomPreview = officecfg::Office::Common::StylesAndFormatting::Preview::get();
393 m_xFmtLb->set_column_custom_renderer(1, bCustomPreview);
394 m_xTreeBox->set_column_custom_renderer(1, bCustomPreview);
395
396 m_xFmtLb->set_visible(!m_bHierarchical);
397 m_xTreeBox->set_visible(m_bHierarchical);
398 Update();
399}
400
402{
403 m_bUpdateFamily = false;
404
406 SfxViewFrame* pViewFrame = pDispat->GetFrame();
407 SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
408
409 SfxStyleSheetBasePool* pOldStyleSheetPool = m_pStyleSheetPool;
410 m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
411 if (pOldStyleSheetPool != m_pStyleSheetPool)
412 {
413 if (pOldStyleSheetPool)
414 EndListening(*pOldStyleSheetPool);
417 }
418
419 m_bTreeDrag = true;
420 m_bCanNew = m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1;
422 m_bTreeDrag = true;
424 {
425 if (!m_xTreeBox->get_visible())
427 else
428 {
431 }
432 }
433
435}
436
438{
439 return m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1;
440}
441
443{
445}
446
448{
449 m_aSaveSelection = rLink;
450}
451
455sal_Int8 StyleList::AcceptDrop(const AcceptDropEvent& rEvt, const DropTargetHelper& rHelper)
456{
457 if (rHelper.IsDropFormatSupported(SotClipboardFormatId::OBJECTDESCRIPTOR))
458 {
459 // special case: page styles are allowed to create new styles by example
460 // but not allowed to be created by drag and drop
461 if (GetActualFamily() == SfxStyleFamily::Page || m_bNewByExampleDisabled)
462 return DND_ACTION_NONE;
463 else
464 return DND_ACTION_COPY;
465 }
466 // to enable the autoscroll when we're close to the edges
467 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
468 pTreeView->get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
469 return DND_ACTION_MOVE;
470}
471
472// handles drop of content in treeview when creating a new style
473IMPL_LINK(StyleList, ExecuteDrop, const ExecuteDropEvent&, rEvt, sal_Int8)
474{
475 SfxObjectShell* pDocShell = m_pCurObjShell;
476 if (pDocShell)
477 {
478 TransferableDataHelper aHelper(rEvt.maDropEvent.Transferable);
479 sal_uInt32 nFormatCount = aHelper.GetFormatCount();
480
482
483 bool bFormatFound = false;
484
485 for (sal_uInt32 i = 0; i < nFormatCount; ++i)
486 {
487 SotClipboardFormatId nId = aHelper.GetFormat(i);
489
490 if (aHelper.GetTransferableObjectDescriptor(nId, aDesc))
491 {
492 if (aDesc.maClassName == pDocShell->GetFactory().GetClassId())
493 {
495 LINK(m_pParentDialog, SfxCommonTemplateDialog_Impl, OnAsyncExecuteDrop),
496 this);
497
498 bFormatFound = true;
499 nRet = rEvt.mnAction;
500 break;
501 }
502 }
503 }
504
505 if (bFormatFound)
506 return nRet;
507 }
508
509 if (!m_xTreeBox->get_visible())
510 return DND_ACTION_NONE;
511
512 if (!m_bAllowReParentDrop)
513 return DND_ACTION_NONE;
514
515 // otherwise if we're dragging with the treeview to set a new parent of the dragged style
516 weld::TreeView* pSource = m_xTreeBox->get_drag_source();
517 // only dragging within the same widget allowed
518 if (!pSource || pSource != m_xTreeBox.get())
519 return DND_ACTION_NONE;
520
521 std::unique_ptr<weld::TreeIter> xSource(m_xTreeBox->make_iterator());
522 if (!m_xTreeBox->get_selected(xSource.get()))
523 return DND_ACTION_NONE;
524
525 std::unique_ptr<weld::TreeIter> xTarget(m_xTreeBox->make_iterator());
526 if (!m_xTreeBox->get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
527 {
528 // if nothing under the mouse, use the last row
529 int nChildren = m_xTreeBox->n_children();
530 if (!nChildren)
531 return DND_ACTION_NONE;
532 if (!m_xTreeBox->get_iter_first(*xTarget)
533 || !m_xTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
534 return DND_ACTION_NONE;
535 while (m_xTreeBox->get_row_expanded(*xTarget))
536 {
537 nChildren = m_xTreeBox->iter_n_children(*xTarget);
538 if (!m_xTreeBox->iter_children(*xTarget)
539 || !m_xTreeBox->iter_nth_sibling(*xTarget, nChildren - 1))
540 return DND_ACTION_NONE;
541 }
542 }
543 OUString aTargetStyle = m_xTreeBox->get_text(*xTarget);
544 DropHdl(m_xTreeBox->get_text(*xSource), aTargetStyle);
545 m_xTreeBox->unset_drag_dest_row();
546 FillTreeBox(GetActualFamily());
547 m_pParentDialog->SelectStyle(aTargetStyle, false, *this);
548 return DND_ACTION_NONE;
549}
550
551IMPL_LINK_NOARG(StyleList, NewMenuExecuteAction, void*, void)
552{
553 if (!m_pStyleSheetPool || m_nActFamily == 0xffff)
554 return;
555
556 const SfxStyleFamily eFam = GetFamilyItem()->GetFamily();
557 const SfxStyleFamilyItem* pItem = GetFamilyItem();
558 SfxStyleSearchBits nFilter(SfxStyleSearchBits::Auto);
559 if (pItem && m_nActFilter != 0xffff)
560 nFilter = pItem->GetFilterList()[m_nActFilter].nFlags;
561 if (nFilter == SfxStyleSearchBits::Auto) // automatic
562 nFilter = m_nAppFilter;
563
564 // why? : FloatingWindow must not be parent of a modal dialog
565 SfxNewStyleDlg aDlg(m_pContainer, *m_pStyleSheetPool, eFam);
566 auto nResult = aDlg.run();
567 if (nResult == RET_OK)
568 {
569 const OUString aTemplName(aDlg.GetName());
570 m_pParentDialog->Execute_Impl(SID_STYLE_NEW_BY_EXAMPLE, aTemplName, "",
571 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this,
572 nFilter);
573 UpdateFamily();
574 m_aUpdateFamily.Call(*this);
575 }
576}
577
578void StyleList::DropHdl(const OUString& rStyle, const OUString& rParent)
579{
580 m_bDontUpdate = true;
581 const SfxStyleFamilyItem* pItem = GetFamilyItem();
582 const SfxStyleFamily eFam = pItem->GetFamily();
583 if (auto pStyle = m_pStyleSheetPool->Find(rStyle, eFam))
584 pStyle->SetParent(rParent);
585 m_bDontUpdate = false;
586}
587
589{
590 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
591 std::unique_ptr<weld::TreeIter> xIter(pTreeView->make_iterator());
592 if (pTreeView->get_dest_row_at_pos(rPos, xIter.get(), false) && !pTreeView->is_selected(*xIter))
593 {
594 pTreeView->unselect_all();
595 pTreeView->set_cursor(*xIter);
596 pTreeView->select(*xIter);
597 }
598 FmtSelectHdl(*pTreeView);
599}
600
602namespace
603{
604class StyleTree_Impl;
605}
606
607typedef std::vector<std::unique_ptr<StyleTree_Impl>> StyleTreeArr_Impl;
608
609namespace
610{
611class StyleTree_Impl
612{
613private:
614 OUString aName;
615 OUString aParent;
616 StyleTreeArr_Impl pChildren;
617
618public:
619 bool HasParent() const { return !aParent.isEmpty(); }
620
621 StyleTree_Impl(OUString _aName, OUString _aParent)
622 : aName(std::move(_aName))
623 , aParent(std::move(_aParent))
624 , pChildren(0)
625 {
626 }
627
628 const OUString& getName() const { return aName; }
629 const OUString& getParent() const { return aParent; }
630 StyleTreeArr_Impl& getChildren() { return pChildren; }
631};
632}
633
634static void MakeTree_Impl(StyleTreeArr_Impl& rArr, const OUString& aUIName)
635{
637 ::comphelper::getProcessComponentContext(),
638 Application::GetSettings().GetLanguageTag().getLocale());
639
640 std::unordered_map<OUString, StyleTree_Impl*> styleFinder;
641 styleFinder.reserve(rArr.size());
642 for (const auto& pEntry : rArr)
643 {
644 styleFinder.emplace(pEntry->getName(), pEntry.get());
645 }
646
647 // Arrange all under their Parents
648 for (auto& pEntry : rArr)
649 {
650 if (!pEntry->HasParent())
651 continue;
652 auto it = styleFinder.find(pEntry->getParent());
653 if (it != styleFinder.end())
654 {
655 StyleTree_Impl* pCmp = it->second;
656 // Insert child entries sorted
657 auto iPos = std::lower_bound(
658 pCmp->getChildren().begin(), pCmp->getChildren().end(), pEntry,
659 [&aSorter](std::unique_ptr<StyleTree_Impl> const& pEntry1,
660 std::unique_ptr<StyleTree_Impl> const& pEntry2) {
661 return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0;
662 });
663 pCmp->getChildren().insert(iPos, std::move(pEntry));
664 }
665 }
666
667 // Only keep tree roots in rArr, child elements can be accessed through the hierarchy
668 rArr.erase(
669 std::remove_if(rArr.begin(), rArr.end(),
670 [](std::unique_ptr<StyleTree_Impl> const& pEntry) { return !pEntry; }),
671 rArr.end());
672
673 // tdf#91106 sort top level styles
674 std::sort(rArr.begin(), rArr.end());
675 std::sort(rArr.begin(), rArr.end(),
676 [&aSorter, &aUIName](std::unique_ptr<StyleTree_Impl> const& pEntry1,
677 std::unique_ptr<StyleTree_Impl> const& pEntry2) {
678 if (pEntry2->getName() == aUIName)
679 return false;
680 if (pEntry1->getName() == aUIName)
681 return true; // default always first
682 return aSorter.compare(pEntry1->getName(), pEntry2->getName()) < 0;
683 });
684}
685
686static bool IsExpanded_Impl(const std::vector<OUString>& rEntries, std::u16string_view rStr)
687{
688 for (const auto& rEntry : rEntries)
689 {
690 if (rEntry == rStr)
691 return true;
692 }
693 return false;
694}
695
696static void lcl_Insert(weld::TreeView& rTreeView, const OUString& rName, SfxStyleFamily eFam,
697 const weld::TreeIter* pParent, weld::TreeIter* pRet, SfxViewShell* pViewSh)
698{
699 Color aColor(ColorHash(rName));
700
701 int nColor;
702 if (eFam == SfxStyleFamily::Para)
703 {
704 StylesHighlighterColorMap& rParaStylesColorMap
706 nColor = rParaStylesColorMap.size();
707 rParaStylesColorMap[rName] = std::pair(aColor, nColor);
708 }
709 else
710 {
711 StylesHighlighterColorMap& rCharStylesColorMap
713 nColor = rCharStylesColorMap.size();
714 rCharStylesColorMap[rName] = std::pair(aColor, nColor);
715 // don't show a color or number for default character style 'No Character Style' entry
716 if (rName == sDefaultCharStyleUIName.value() /*"No Character Style"*/)
717 {
718 rTreeView.insert(pParent, -1, &rName, &rName, nullptr, nullptr, false, pRet);
719 return;
720 }
721 }
722
723 // draw the color rectangle and number image
724 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
725 Size aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
727 xDevice->SetOutputSize(aImageSize);
728 xDevice->SetFillColor(aColor);
729 const tools::Rectangle aRect(Point(0, 0), aImageSize);
730 xDevice->DrawRect(aRect);
731 xDevice->SetTextColor(COL_BLACK);
732 xDevice->DrawText(aRect, OUString::number(nColor),
733 DrawTextFlags::Center | DrawTextFlags::VCenter);
734
735 rTreeView.insert(pParent, -1, &rName, &rName, nullptr, xDevice.get(), false, pRet);
736}
737
738static void FillBox_Impl(weld::TreeView& rBox, StyleTree_Impl* pEntry,
739 const std::vector<OUString>& rEntries, SfxStyleFamily eStyleFamily,
740 const weld::TreeIter* pParent, bool blcl_insert, SfxViewShell* pViewShell)
741{
742 std::unique_ptr<weld::TreeIter> xResult = rBox.make_iterator();
743 const OUString& rName = pEntry->getName();
744
745 if (blcl_insert)
746 lcl_Insert(rBox, rName, eStyleFamily, pParent, xResult.get(), pViewShell);
747 else
748 rBox.insert(pParent, -1, &rName, &rName, nullptr, nullptr, false, xResult.get());
749
750 for (size_t i = 0; i < pEntry->getChildren().size(); ++i)
751 FillBox_Impl(rBox, pEntry->getChildren()[i].get(), rEntries, eStyleFamily, xResult.get(),
752 blcl_insert, pViewShell);
753}
754
755namespace SfxTemplate
756{
757// converts from SFX_STYLE_FAMILY Ids to 1-6
758static sal_uInt16 SfxFamilyIdToNId(SfxStyleFamily nFamily)
759{
760 switch (nFamily)
761 {
762 case SfxStyleFamily::Char:
763 return 1;
764 case SfxStyleFamily::Para:
765 return 2;
766 case SfxStyleFamily::Frame:
767 return 3;
768 case SfxStyleFamily::Page:
769 return 4;
770 case SfxStyleFamily::Pseudo:
771 return 5;
772 case SfxStyleFamily::Table:
773 return 6;
774 default:
775 return 0xffff;
776 }
777}
778// converts from 1-6 to SFX_STYLE_FAMILY Ids
779static SfxStyleFamily NIdToSfxFamilyId(sal_uInt16 nId)
780{
781 switch (nId)
782 {
783 case 1:
784 return SfxStyleFamily::Char;
785 case 2:
786 return SfxStyleFamily::Para;
787 case 3:
788 return SfxStyleFamily::Frame;
789 case 4:
790 return SfxStyleFamily::Page;
791 case 5:
792 return SfxStyleFamily::Pseudo;
793 case 6:
794 return SfxStyleFamily::Table;
795 default:
796 return SfxStyleFamily::All;
797 }
798}
799}
800
801sal_uInt16 StyleList::StyleNrToInfoOffset(sal_uInt16 nId)
802{
803 const SfxStyleFamilyItem& rItem = m_xStyleFamilies->at(nId);
804 return SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily()) - 1;
805}
806
807// Helper function: Access to the current family item
809{
810 const size_t nCount = m_xStyleFamilies->size();
811 for (size_t i = 0; i < nCount; ++i)
812 {
813 const SfxStyleFamilyItem& rItem = m_xStyleFamilies->at(i);
814 sal_uInt16 nId = SfxTemplate::SfxFamilyIdToNId(rItem.GetFamily());
815 if (nId == m_nActFamily)
816 return &rItem;
817 }
818 return nullptr;
819}
820
822{
823 const OUString aTemplName(GetSelectedEntry());
824 const SfxStyleFamilyItem* pItem = GetFamilyItem();
825 m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
826}
827
828// Used to get the current selected entry in visible treeview
830{
831 OUString aRet;
832 if (m_xTreeBox->get_visible())
833 aRet = m_xTreeBox->get_selected_text();
834 else
835 aRet = m_xFmtLb->get_selected_text();
836 return aRet;
837}
838
845IMPL_LINK_NOARG(StyleList, IsSafeForWaterCan, void*, bool)
846{
847 if (m_xTreeBox->get_visible())
848 return m_xTreeBox->get_selected_index() != -1;
849 else
850 return m_xFmtLb->count_selected_rows() == 1;
851}
852
853IMPL_LINK(StyleList, SetWaterCanState, const SfxBoolItem*, pItem, void)
854{
855 size_t nCount = m_xStyleFamilies->size();
856 m_pBindings->EnterRegistrations();
857 for (size_t n = 0; n < nCount; n++)
858 {
859 SfxControllerItem* pCItem = pBoundItems[n].get();
860 bool bChecked = pItem && pItem->GetValue();
861 if (pCItem->IsBound() == bChecked)
862 {
863 if (!bChecked)
864 pCItem->ReBind();
865 else
866 pCItem->UnBind();
867 }
868 }
869 m_pBindings->LeaveRegistrations();
870}
871
872void StyleList::FamilySelect(sal_uInt16 nEntry, bool bRefresh)
873{
874 if (bRefresh)
875 {
876 bool bCustomPreview = officecfg::Office::Common::StylesAndFormatting::Preview::get();
877 m_xFmtLb->clear();
878 m_xFmtLb->set_column_custom_renderer(1, bCustomPreview);
879 m_xTreeBox->clear();
880 m_xTreeBox->set_column_custom_renderer(1, bCustomPreview);
881 }
882 m_nActFamily = nEntry;
884 SfxUInt16Item const aItem(SID_STYLE_FAMILY,
885 static_cast<sal_uInt16>(SfxTemplate::NIdToSfxFamilyId(nEntry)));
886 pDispat->ExecuteList(SID_STYLE_FAMILY, SfxCallMode::SYNCHRON, { &aItem });
887 m_pBindings->Invalidate(SID_STYLE_FAMILY);
888 m_pBindings->Update(SID_STYLE_FAMILY);
889 UpdateFamily();
890 m_aUpdateFamily.Call(*this);
891}
892
893// It selects the style in treeview
894// bIsCallBack is true for the selected style. For eg. if "Addressee" is selected in
895// styles, bIsCallBack will be true for it.
896void StyleList::SelectStyle(const OUString& rStr, bool bIsCallback)
897{
898 const SfxStyleFamilyItem* pItem = GetFamilyItem();
899 if (!pItem)
900 return;
901 const SfxStyleFamily eFam = pItem->GetFamily();
902 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(rStr, eFam);
903 if (pStyle)
904 {
905 bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
906 m_pParentDialog->EnableEdit(bReadWrite, this);
907 m_pParentDialog->EnableHide(bReadWrite && !pStyle->IsHidden() && !pStyle->IsUsed(), this);
908 m_pParentDialog->EnableShow(bReadWrite && pStyle->IsHidden(), this);
909 }
910 else
911 {
912 m_pParentDialog->EnableEdit(false, this);
913 m_pParentDialog->EnableHide(false, this);
914 m_pParentDialog->EnableShow(false, this);
915 }
916
917 if (bIsCallback)
918 return;
919
920 if (m_xTreeBox->get_visible())
921 {
922 if (!rStr.isEmpty())
923 {
924 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
925 bool bEntry = m_xTreeBox->get_iter_first(*xEntry);
926 while (bEntry)
927 {
928 if (m_xTreeBox->get_text(*xEntry) == rStr)
929 {
930 m_xTreeBox->scroll_to_row(*xEntry);
931 m_xTreeBox->select(*xEntry);
932 break;
933 }
934 bEntry = m_xTreeBox->iter_next(*xEntry);
935 }
936 }
937 else if (eFam == SfxStyleFamily::Pseudo)
938 {
939 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
940 if (m_xTreeBox->get_iter_first(*xEntry))
941 {
942 m_xTreeBox->scroll_to_row(*xEntry);
943 m_xTreeBox->select(*xEntry);
944 }
945 }
946 else
947 m_xTreeBox->unselect_all();
948 }
949 else
950 {
951 bool bSelect = !rStr.isEmpty();
952 if (bSelect)
953 {
954 std::unique_ptr<weld::TreeIter> xEntry = m_xFmtLb->make_iterator();
955 bool bEntry = m_xFmtLb->get_iter_first(*xEntry);
956 while (bEntry && m_xFmtLb->get_text(*xEntry) != rStr)
957 bEntry = m_xFmtLb->iter_next(*xEntry);
958 if (!bEntry)
959 bSelect = false;
960 else
961 {
962 if (!m_xFmtLb->is_selected(*xEntry))
963 {
964 m_xFmtLb->unselect_all();
965 m_xFmtLb->scroll_to_row(*xEntry);
966 m_xFmtLb->select(*xEntry);
967 }
968 }
969 }
970
971 if (!bSelect)
972 {
973 m_xFmtLb->unselect_all();
974 m_pParentDialog->EnableEdit(false, this);
975 m_pParentDialog->EnableHide(false, this);
976 m_pParentDialog->EnableShow(false, this);
977 }
978 }
979}
980
981static void MakeExpanded_Impl(const weld::TreeView& rBox, std::vector<OUString>& rEntries)
982{
983 std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
984 if (rBox.get_iter_first(*xEntry))
985 {
986 do
987 {
988 if (rBox.get_row_expanded(*xEntry))
989 rEntries.push_back(rBox.get_text(*xEntry));
990 } while (rBox.iter_next(*xEntry));
991 }
992}
993
994IMPL_LINK(StyleList, EnableTreeDrag, bool, m_bEnable, void)
995{
996 if (m_pStyleSheetPool)
997 {
998 const SfxStyleFamilyItem* pItem = GetFamilyItem();
999 SfxStyleSheetBase* pStyle = pItem ? m_pStyleSheetPool->First(pItem->GetFamily()) : nullptr;
1000 m_bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && m_bEnable;
1001 }
1002 m_bTreeDrag = m_bEnable;
1003}
1004
1005// Fill the treeview
1006
1008{
1009 assert(m_xTreeBox && "FillTreeBox() without treebox");
1010 if (!m_pStyleSheetPool || m_nActFamily == 0xffff)
1011 return;
1012
1013 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1014 if (!pItem)
1015 return;
1016
1018 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->First(eFam, SfxStyleSearchBits::All);
1019
1020 m_bAllowReParentDrop = pStyle && pStyle->HasParentSupport() && m_bTreeDrag;
1021
1022 while (pStyle)
1023 {
1024 StyleTree_Impl* pNew = new StyleTree_Impl(pStyle->GetName(), pStyle->GetParent());
1025 aArr.emplace_back(pNew);
1026 pStyle = m_pStyleSheetPool->Next();
1027 }
1028 OUString aUIName = getDefaultStyleName(eFam);
1030 std::vector<OUString> aEntries;
1032 m_xTreeBox->freeze();
1033 m_xTreeBox->clear();
1034 const sal_uInt16 nCount = aArr.size();
1035
1036 SfxViewShell* pViewShell = m_pCurObjShell->GetViewShell();
1037 if (pViewShell && m_bModuleHasStylesHighlighterFeature)
1038 {
1039 if (eFam == SfxStyleFamily::Para)
1040 pViewShell->GetStylesHighlighterParaColorMap().clear();
1041 else if (eFam == SfxStyleFamily::Char)
1042 pViewShell->GetStylesHighlighterCharColorMap().clear();
1043 }
1044
1045 bool blcl_insert = pViewShell && m_bModuleHasStylesHighlighterFeature
1046 && ((eFam == SfxStyleFamily::Para && m_bHighlightParaStyles)
1047 || (eFam == SfxStyleFamily::Char && m_bHighlightCharStyles));
1048
1049 for (sal_uInt16 i = 0; i < nCount; ++i)
1050 {
1051 FillBox_Impl(*m_xTreeBox, aArr[i].get(), aEntries, eFam, nullptr, blcl_insert, pViewShell);
1052 aArr[i].reset();
1053 }
1054
1055 m_xTreeBox->columns_autosize();
1056
1057 m_pParentDialog->EnableItem("watercan", false);
1058
1059 SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
1060
1061 m_xTreeBox->thaw();
1062
1063 // hack for x11 to make view update
1064 if (pViewShell && m_bModuleHasStylesHighlighterFeature)
1065 {
1067 pViewFrame->Resize(true);
1068 }
1069
1070 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeBox->make_iterator();
1071 bool bEntry = m_xTreeBox->get_iter_first(*xEntry);
1072 if (bEntry && nCount)
1073 m_xTreeBox->expand_row(*xEntry);
1074
1075 while (bEntry)
1076 {
1077 if (IsExpanded_Impl(aEntries, m_xTreeBox->get_text(*xEntry)))
1078 m_xTreeBox->expand_row(*xEntry);
1079 bEntry = m_xTreeBox->iter_next(*xEntry);
1080 }
1081
1082 OUString aStyle;
1083 if (pState) // Select current entry
1084 aStyle = pState->GetStyleName();
1085 m_pParentDialog->SelectStyle(aStyle, false, *this);
1086 EnableDelete(nullptr);
1087}
1088
1090{
1091 if (nFamily == SfxStyleFamily::Char)
1092 return "CharacterStyles";
1093 if (nFamily == SfxStyleFamily::Para)
1094 return "ParagraphStyles";
1095 if (nFamily == SfxStyleFamily::Page)
1096 return "PageStyles";
1097 if (nFamily == SfxStyleFamily::Table)
1098 return "TableStyles";
1099 if (nFamily == SfxStyleFamily::Pseudo)
1100 return "NumberingStyles";
1101 return OUString();
1102}
1103
1105{
1106 OUString sDefaultStyle;
1107 OUString aFamilyName = lcl_GetStyleFamilyName(eFam);
1108 if (aFamilyName == "TableStyles")
1109 sDefaultStyle = "Default Style";
1110 else if (aFamilyName == "NumberingStyles")
1111 sDefaultStyle = "No List";
1112 else
1113 sDefaultStyle = "Standard";
1114 uno::Reference<style::XStyleFamiliesSupplier> xModel(m_pCurObjShell->GetModel(),
1115 uno::UNO_QUERY);
1116 OUString aUIName;
1117 try
1118 {
1119 uno::Reference<container::XNameAccess> xStyles;
1120 uno::Reference<container::XNameAccess> xCont = xModel->getStyleFamilies();
1121 xCont->getByName(aFamilyName) >>= xStyles;
1122 uno::Reference<beans::XPropertySet> xInfo;
1123 xStyles->getByName(sDefaultStyle) >>= xInfo;
1124 xInfo->getPropertyValue("DisplayName") >>= aUIName;
1125 }
1126 catch (const uno::Exception&)
1127 {
1128 }
1129 return aUIName;
1130}
1131
1133{
1134 const SfxStyleFamilyItem* pFamilyItem = GetFamilyItem();
1135 if (!pFamilyItem || m_nActFamily == 0xffff)
1136 return SfxStyleFamily::Para;
1137 else
1138 return pFamilyItem->GetFamily();
1139}
1140
1141IMPL_LINK_NOARG(StyleList, HasSelectedStyle, void*, bool)
1142{
1143 return m_xTreeBox->get_visible() ? m_xTreeBox->get_selected_index() != -1
1144 : m_xFmtLb->count_selected_rows() != 0;
1145}
1146
1147IMPL_LINK_NOARG(StyleList, UpdateStyleDependents, void*, void)
1148{
1149 // Trigger Help PI. Only when the watercan is on
1150 if (m_nActFamily != 0xffff && m_pParentDialog->IsCheckedItem("watercan") &&
1151 // only if that region is allowed
1152 nullptr != m_pFamilyState[m_nActFamily - 1] && IsSafeForWaterCan(nullptr))
1153 {
1154 m_pParentDialog->Execute_Impl(SID_STYLE_WATERCAN, "", "", 0, *this);
1155 m_pParentDialog->Execute_Impl(SID_STYLE_WATERCAN, GetSelectedEntry(), "",
1156 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
1157 }
1158}
1159
1160// Comes into action when the current style is changed
1162{
1163 OSL_ENSURE(nFlags != StyleFlags::NONE, "nothing to do");
1164 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1165 if (!pItem)
1166 {
1167 // Is the case for the template catalog
1168 const size_t nFamilyCount = m_xStyleFamilies->size();
1169 size_t n;
1170 for (n = 0; n < nFamilyCount; n++)
1172 break;
1173 if (n == nFamilyCount)
1174 // It happens sometimes, God knows why
1175 return;
1178 pItem = GetFamilyItem();
1179 }
1180
1181 const SfxStyleFamily eFam = pItem->GetFamily();
1182
1183 SfxStyleSearchBits nFilter(m_nActFilter < pItem->GetFilterList().size()
1184 ? pItem->GetFilterList()[m_nActFilter].nFlags
1185 : SfxStyleSearchBits::Auto);
1186 if (nFilter == SfxStyleSearchBits::Auto) // automatic
1187 nFilter = m_nAppFilter;
1188
1189 OSL_ENSURE(m_pStyleSheetPool, "no StyleSheetPool");
1190 if (!m_pStyleSheetPool)
1191 return;
1192
1193 m_aUpdateStyles.Call(nFlags);
1194
1195 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->First(eFam, nFilter);
1196
1197 std::unique_ptr<weld::TreeIter> xEntry = m_xFmtLb->make_iterator();
1198 std::vector<OUString> aStrings;
1199
1201 ::comphelper::getProcessComponentContext(),
1202 Application::GetSettings().GetLanguageTag().getLocale());
1203
1204 while (pStyle)
1205 {
1206 aStrings.push_back(pStyle->GetName());
1207 pStyle = m_pStyleSheetPool->Next();
1208 }
1209 OUString aUIName = getDefaultStyleName(eFam);
1210
1211 // Paradoxically, with a list and non-Latin style names,
1212 // sorting twice is faster than sorting once.
1213 // The first sort has a cheap comparator, and gets the list into mostly-sorted order.
1214 // Then the second sort needs to call its (much more expensive) comparator less often.
1215 std::sort(aStrings.begin(), aStrings.end());
1216 std::sort(aStrings.begin(), aStrings.end(),
1217 [&aSorter, &aUIName](const OUString& rLHS, const OUString& rRHS) {
1218 if (rRHS == aUIName)
1219 return false;
1220 if (rLHS == aUIName)
1221 return true; // default always first
1222 return aSorter.compare(rLHS, rRHS) < 0;
1223 });
1224
1225 // Fill the display box
1226 m_xFmtLb->freeze();
1227 m_xFmtLb->clear();
1228
1229 SfxViewShell* pViewShell = m_pCurObjShell->GetViewShell();
1230 if (pViewShell && m_bModuleHasStylesHighlighterFeature)
1231 {
1232 if (eFam == SfxStyleFamily::Para)
1233 pViewShell->GetStylesHighlighterParaColorMap().clear();
1234 else if (eFam == SfxStyleFamily::Char)
1235 pViewShell->GetStylesHighlighterCharColorMap().clear();
1236 }
1237
1238 size_t nCount = aStrings.size();
1239 size_t nPos = 0;
1240
1241 if (pViewShell && m_bModuleHasStylesHighlighterFeature
1242 && ((eFam == SfxStyleFamily::Para && m_bHighlightParaStyles)
1243 || (eFam == SfxStyleFamily::Char && m_bHighlightCharStyles)))
1244 {
1245 for (nPos = 0; nPos < nCount; ++nPos)
1246 lcl_Insert(*m_xFmtLb, aStrings[nPos], eFam, nullptr, nullptr, pViewShell);
1247 }
1248 else
1249 {
1250 for (nPos = 0; nPos < nCount; ++nPos)
1251 m_xFmtLb->append(aStrings[nPos], aStrings[nPos]);
1252 }
1253
1254 m_xFmtLb->columns_autosize();
1255
1256 m_xFmtLb->thaw();
1257
1258 // hack for x11 to make view update
1259 if (pViewShell && m_bModuleHasStylesHighlighterFeature)
1260 {
1262 pViewFrame->Resize(true);
1263 }
1264
1265 // Selects the current style if any
1266 SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
1267 OUString aStyle;
1268 if (pState)
1269 aStyle = pState->GetStyleName();
1270 m_pParentDialog->SelectStyle(aStyle, false, *this);
1271 EnableDelete(nullptr);
1272}
1273
1274void StyleList::SetFamilyState(sal_uInt16 nSlotId, const SfxTemplateItem* pItem)
1275{
1276 sal_uInt16 nIdx = nSlotId - SID_STYLE_FAMILY_START;
1277 m_pFamilyState[nIdx].reset();
1278 if (pItem)
1279 m_pFamilyState[nIdx].reset(new SfxTemplateItem(*pItem));
1280 m_bUpdateFamily = true;
1281}
1282
1284{
1285 m_bHierarchical = true;
1286 const OUString aSelectEntry(GetSelectedEntry());
1287 m_xFmtLb->hide();
1289 m_pParentDialog->SelectStyle(aSelectEntry, false, *this);
1290 m_xTreeBox->show();
1291}
1292
1294{
1295 m_xTreeBox->hide();
1296 m_xFmtLb->show();
1297 m_bHierarchical = false;
1298}
1299
1300// Handler for the New-Buttons
1302{
1303 if (m_nActFamily == 0xffff
1304 || !(m_xTreeBox->get_visible() || m_xFmtLb->count_selected_rows() <= 1))
1305 return;
1306
1307 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1308 const SfxStyleFamily eFam = pItem->GetFamily();
1309 SfxStyleSearchBits nMask(SfxStyleSearchBits::Auto);
1310 if (m_nActFilter != 0xffff)
1311 nMask = pItem->GetFilterList()[m_nActFilter].nFlags;
1312 if (nMask == SfxStyleSearchBits::Auto) // automatic
1313 nMask = m_nAppFilter;
1314
1315 m_pParentDialog->Execute_Impl(SID_STYLE_NEW, "", GetSelectedEntry(),
1316 static_cast<sal_uInt16>(eFam), *this, nMask);
1317}
1318
1319// Handler for the edit-Buttons
1321{
1322 if (m_nActFamily != 0xffff && HasSelectedStyle(nullptr))
1323 {
1324 sal_uInt16 nFilter = m_nActFilter;
1325 OUString aTemplName(GetSelectedEntry());
1326 GetSelectedStyle(); // -Wall required??
1327 m_pParentDialog->Execute_Impl(SID_STYLE_EDIT, aTemplName, OUString(),
1328 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this,
1329 SfxStyleSearchBits::Auto, &nFilter);
1330 }
1331}
1332
1333// Handler for the Delete-Buttons
1335{
1336 if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
1337 return;
1338
1339 bool bUsedStyle = false; // one of the selected styles are used in the document?
1340
1341 std::vector<std::unique_ptr<weld::TreeIter>> aList;
1342 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
1343 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1344
1345 OUStringBuffer aMsg(SfxResId(STR_DELETE_STYLE_USED) + SfxResId(STR_DELETE_STYLE));
1346
1347 pTreeView->selected_foreach(
1348 [this, pTreeView, pItem, &aList, &bUsedStyle, &aMsg](weld::TreeIter& rEntry) {
1349 aList.emplace_back(pTreeView->make_iterator(&rEntry));
1350 // check the style is used or not
1351 const OUString aTemplName(pTreeView->get_text(rEntry));
1352
1353 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
1354
1355 if (pStyle->IsUsed()) // pStyle is in use in the document?
1356 {
1357 if (bUsedStyle) // add a separator for the second and later styles
1358 aMsg.append(", ");
1359 aMsg.append(aTemplName);
1360 bUsedStyle = true;
1361 }
1362
1363 return false;
1364 });
1365
1366 bool aApproved = false;
1367
1368 // we only want to show the dialog once and if we want to delete a style in use (UX-advice)
1369 if (bUsedStyle)
1370 {
1371 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
1372 pTreeView, VclMessageType::Question, VclButtonsType::YesNo, aMsg.makeStringAndClear()));
1373 aApproved = xBox->run() == RET_YES;
1374 }
1375
1376 // if there are no used styles selected or the user approved the changes
1377 if (bUsedStyle && !aApproved)
1378 return;
1379
1380 for (auto const& elem : aList)
1381 {
1382 const OUString aTemplName(pTreeView->get_text(*elem));
1383 m_bDontUpdate = true; // To prevent the Treelistbox to shut down while deleting
1384 m_pParentDialog->Execute_Impl(SID_STYLE_DELETE, aTemplName, OUString(),
1385 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
1386
1387 if (m_xTreeBox->get_visible())
1388 {
1390 m_bDontUpdate = false;
1391 }
1392 }
1393 m_bDontUpdate = false; // if everything is deleted set m_bDontUpdate back to false
1394 UpdateStyles(StyleFlags::UpdateFamilyList); // and force-update the list
1395}
1396
1398{
1399 if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
1400 return;
1401
1402 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
1403 pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry) {
1404 OUString aTemplName = pTreeView->get_text(rEntry);
1405
1406 m_pParentDialog->Execute_Impl(SID_STYLE_HIDE, aTemplName, OUString(),
1407 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
1408
1409 return false;
1410 });
1411}
1412
1414{
1415 if (m_nActFamily == 0xffff || !HasSelectedStyle(nullptr))
1416 return;
1417
1418 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
1419 pTreeView->selected_foreach([this, pTreeView](weld::TreeIter& rEntry) {
1420 OUString aTemplName = pTreeView->get_text(rEntry);
1421
1422 m_pParentDialog->Execute_Impl(SID_STYLE_SHOW, aTemplName, OUString(),
1423 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this);
1424
1425 return false;
1426 });
1427}
1428
1429IMPL_LINK_NOARG(StyleList, EnableDelete, void*, void)
1430{
1431 bool bEnableDelete(false);
1432 if (m_nActFamily != 0xffff && HasSelectedStyle(nullptr))
1433 {
1434 OSL_ENSURE(m_pStyleSheetPool, "No StyleSheetPool");
1435 const OUString aTemplName(GetSelectedEntry());
1436 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1437 const SfxStyleFamily eFam = pItem->GetFamily();
1438 SfxStyleSearchBits nFilter = SfxStyleSearchBits::Auto;
1439 if (pItem->GetFilterList().size() > m_nActFilter)
1440 nFilter = pItem->GetFilterList()[m_nActFilter].nFlags;
1441 if (nFilter == SfxStyleSearchBits::Auto) // automatic
1442 nFilter = m_nAppFilter;
1443 const SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(
1444 aTemplName, eFam, m_xTreeBox->get_visible() ? SfxStyleSearchBits::All : nFilter);
1445
1446 OSL_ENSURE(pStyle, "Style not found");
1447 if (pStyle && pStyle->IsUserDefined())
1448 {
1449 if (pStyle->HasClearParentSupport() || !pStyle->IsUsed())
1450 {
1451 bEnableDelete = true;
1452 }
1453 }
1454 }
1455 m_pParentDialog->EnableDel(bEnableDelete, this);
1456}
1457
1458IMPL_LINK_NOARG(StyleList, Clear, void*, void)
1459{
1460 if (m_pCurObjShell && m_bModuleHasStylesHighlighterFeature)
1461 {
1462 SfxViewShell* pViewShell = m_pCurObjShell->GetViewShell();
1463 if (pViewShell)
1464 {
1465 pViewShell->GetStylesHighlighterParaColorMap().clear();
1466 pViewShell->GetStylesHighlighterCharColorMap().clear();
1467 }
1468 }
1469 m_xStyleFamilies.reset();
1470 for (auto& i : m_pFamilyState)
1471 i.reset();
1472 m_pCurObjShell = nullptr;
1473 for (auto& i : pBoundItems)
1474 i.reset();
1475}
1476
1478{
1480 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
1481 OUString sCommand(
1482 mxMenu->popup_at_rect(pTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
1483 MenuSelect(sCommand);
1484}
1485
1486void StyleList::MenuSelect(const OUString& rIdent)
1487{
1488 sLastItemIdent = rIdent;
1489 if (sLastItemIdent.isEmpty())
1490 return;
1491 Application::PostUserEvent(LINK(this, StyleList, MenuSelectAsyncHdl)); /***check this****/
1492}
1493
1494void StyleList::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
1495{
1496 const SfxHintId nId = rHint.GetId();
1497
1498 switch (nId)
1499 {
1500 case SfxHintId::UpdateDone:
1501 {
1503 SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
1505 && (!m_pParentDialog->IsCheckedItem("watercan")
1506 || (pDocShell && pDocShell->GetStyleSheetPool() != m_pStyleSheetPool)))
1507 {
1509 Update();
1510 }
1511 else if (m_bUpdateFamily)
1512 {
1513 UpdateFamily();
1514 m_aUpdateFamily.Call(*this);
1515 }
1516
1518 {
1519 OUString aStr = GetSelectedEntry();
1520 if (!aStr.isEmpty())
1521 {
1522 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1523 if (!pItem)
1524 break;
1525 const SfxStyleFamily eFam = pItem->GetFamily();
1526 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aStr, eFam);
1527 if (pStyle)
1528 {
1529 bool bReadWrite = !(pStyle->GetMask() & SfxStyleSearchBits::ReadOnly);
1530 m_pParentDialog->EnableEdit(bReadWrite, this);
1532 bReadWrite && !pStyle->IsUsed() && !pStyle->IsHidden(), this);
1533 m_pParentDialog->EnableShow(bReadWrite && pStyle->IsHidden(), this);
1534 }
1535 else
1536 {
1537 m_pParentDialog->EnableEdit(false, this);
1538 m_pParentDialog->EnableHide(false, this);
1539 m_pParentDialog->EnableShow(false, this);
1540 }
1541 }
1542 }
1543 break;
1544 }
1545
1546 // Necessary if switching between documents and in both documents
1547 // the same template is used. Do not immediately call Update_Impl,
1548 // for the case that one of the documents is an internal InPlaceObject!
1549 case SfxHintId::DocChanged:
1551 break;
1552 case SfxHintId::Dying:
1553 {
1555 m_pStyleSheetPool = nullptr;
1556 break;
1557 }
1558 default:
1559 break;
1560 }
1561
1562 // Do not set timer when the stylesheet pool is in the box, because it is
1563 // possible that a new one is registered after the timer is up -
1564 // works bad in UpdateStyles_Impl ()!
1565
1566 if (!m_bDontUpdate && nId != SfxHintId::Dying
1567 && (dynamic_cast<const SfxStyleSheetPoolHint*>(&rHint)
1568 || dynamic_cast<const SfxStyleSheetHint*>(&rHint)
1569 || dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint)))
1570 {
1571 if (!pIdle)
1572 {
1573 pIdle.reset(new Idle("SfxCommonTemplate"));
1574 pIdle->SetPriority(TaskPriority::LOWEST);
1575 pIdle->SetInvokeHandler(LINK(this, StyleList, TimeOut));
1576 }
1577 pIdle->Start();
1578 }
1579}
1580
1582{
1583 if (!m_bDontUpdate)
1584 {
1585 m_bDontUpdate = true;
1586 if (!m_xTreeBox->get_visible())
1587 UpdateStyles(StyleFlags::UpdateFamilyList);
1588 else
1589 {
1590 FillTreeBox(GetActualFamily());
1591 SfxTemplateItem* pState = m_pFamilyState[m_nActFamily - 1].get();
1592 if (pState)
1593 {
1594 m_pParentDialog->SelectStyle(pState->GetStyleName(), false, *this);
1595 EnableDelete(nullptr);
1596 }
1597 }
1598 m_bDontUpdate = false;
1599 pIdle.reset();
1600 }
1601 else
1602 pIdle->Start();
1603}
1604
1605IMPL_LINK_NOARG(StyleList, MenuSelectAsyncHdl, void*, void)
1606{
1607 if (sLastItemIdent == "new")
1608 NewHdl();
1609 else if (sLastItemIdent == "edit")
1610 EditHdl();
1611 else if (sLastItemIdent == "delete")
1612 DeleteHdl();
1613 else if (sLastItemIdent == "hide")
1614 HideHdl();
1615 else if (sLastItemIdent == "show")
1616 ShowHdl();
1617}
1618
1619// Double-click on a style sheet in the ListBox is applied.
1620IMPL_LINK(StyleList, DragBeginHdl, bool&, rUnsetDragIcon, bool)
1621{
1622 rUnsetDragIcon = false;
1623 // Allow normal processing. only if bAllowReParentDrop is true
1624 return !m_bAllowReParentDrop;
1625}
1626
1627IMPL_LINK(StyleList, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
1628{
1629 bool bRet = false;
1630 const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
1631 if (m_bCanDel && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_DELETE)
1632 {
1633 DeleteHdl();
1634 bRet = true;
1635 }
1636 return bRet;
1637}
1638
1639IMPL_LINK(StyleList, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
1640{
1641 weld::TreeView* pTreeView = m_xTreeBox->get_visible() ? m_xTreeBox.get() : m_xFmtLb.get();
1642 const OUString aTemplName(pTreeView->get_text(rEntry));
1643 OUString sQuickHelpText(aTemplName);
1644
1645 const SfxStyleFamilyItem* pItem = GetFamilyItem();
1646 if (!pItem)
1647 return sQuickHelpText;
1648 SfxStyleSheetBase* pStyle = m_pStyleSheetPool->Find(aTemplName, pItem->GetFamily());
1649 if (pStyle && pStyle->IsUsed()) // pStyle is in use in the document?
1650 {
1651 OUString sUsedBy;
1652 if (pStyle->GetFamily() == SfxStyleFamily::Pseudo)
1653 sUsedBy = pStyle->GetUsedBy();
1654
1655 if (!sUsedBy.isEmpty())
1656 {
1657 const sal_Int32 nMaxLen = 80;
1658 if (sUsedBy.getLength() > nMaxLen)
1659 {
1660 sUsedBy = OUString::Concat(sUsedBy.subView(0, nMaxLen)) + "...";
1661 }
1662
1663 OUString aMessage = SfxResId(STR_STYLEUSEDBY);
1664 aMessage = aMessage.replaceFirst("%STYLELIST", sUsedBy);
1665 sQuickHelpText = aTemplName + " " + aMessage;
1666 }
1667 }
1668
1669 return sQuickHelpText;
1670}
1671
1672IMPL_LINK(StyleList, CustomRenderHdl, weld::TreeView::render_args, aPayload, void)
1673{
1674 vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
1675 const ::tools::Rectangle& rRect = std::get<1>(aPayload);
1676 ::tools::Rectangle aRect(
1677 rRect.TopLeft(),
1678 Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), rRect.GetHeight()));
1679 bool bSelected = std::get<2>(aPayload);
1680 const OUString& rId = std::get<3>(aPayload);
1681
1682 rRenderContext.Push(vcl::PushFlags::TEXTCOLOR);
1683 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1684 if (bSelected)
1685 rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
1686 else
1687 rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
1688
1689 bool bSuccess = false;
1690
1692 sfx2::StyleManager* pStyleManager = pShell ? pShell->GetStyleManager() : nullptr;
1693
1694 if (pStyleManager)
1695 {
1696 if (const SfxStyleFamilyItem* pItem = GetFamilyItem())
1697 {
1698 SfxStyleSheetBase* pStyleSheet = pStyleManager->Search(rId, pItem->GetFamily());
1699
1700 if (pStyleSheet)
1701 {
1702 rRenderContext.Push(vcl::PushFlags::ALL);
1703 // tdf#119919 - show "hidden" styles as disabled to not move children onto root node
1704 if (pStyleSheet->IsHidden())
1705 rRenderContext.SetTextColor(rStyleSettings.GetDisableColor());
1706
1707 sal_Int32 nSize = aRect.GetHeight();
1708 std::unique_ptr<sfx2::StylePreviewRenderer> pStylePreviewRenderer(
1709 pStyleManager->CreateStylePreviewRenderer(rRenderContext, pStyleSheet, nSize));
1710 bSuccess
1711 = pStylePreviewRenderer->recalculate() && pStylePreviewRenderer->render(aRect);
1712 rRenderContext.Pop();
1713 }
1714 }
1715 }
1716
1717 if (!bSuccess)
1718 rRenderContext.DrawText(aRect, rId, DrawTextFlags::Left | DrawTextFlags::VCenter);
1719
1720 rRenderContext.Pop();
1721}
1722
1723// Selection of a template during the Watercan-Status
1724IMPL_LINK(StyleList, FmtSelectHdl, weld::TreeView&, rListBox, void)
1725{
1726 std::unique_ptr<weld::TreeIter> xHdlEntry = rListBox.make_iterator();
1727 if (!rListBox.get_cursor(xHdlEntry.get()))
1728 return;
1729
1730 m_pParentDialog->SelectStyle(rListBox.get_text(*xHdlEntry), true, *this);
1731}
1732
1733IMPL_LINK_NOARG(StyleList, TreeListApplyHdl, weld::TreeView&, bool)
1734{
1735 // only if that region is allowed
1736 if (m_nActFamily != 0xffff && nullptr != m_pFamilyState[m_nActFamily - 1]
1737 && !GetSelectedEntry().isEmpty())
1738 {
1739 m_pParentDialog->Execute_Impl(SID_STYLE_APPLY, GetSelectedEntry(), OUString(),
1740 static_cast<sal_uInt16>(GetFamilyItem()->GetFamily()), *this,
1741 SfxStyleSearchBits::Auto, nullptr, &m_nModifier);
1742 }
1743 // After selecting a focused item if possible again on the app window
1744 if (dynamic_cast<const SfxTemplateDialog_Impl*>(m_pParentDialog) != nullptr)
1745 {
1746 SfxViewFrame* pViewFrame = m_pBindings->GetDispatcher_Impl()->GetFrame();
1747 SfxViewShell* pVu = pViewFrame->GetViewShell();
1748 vcl::Window* pAppWin = pVu ? pVu->GetWindow() : nullptr;
1749 if (pAppWin)
1750 pAppWin->GrabFocus();
1751 }
1752
1753 return true;
1754}
1755
1756IMPL_LINK(StyleList, MousePressHdl, const MouseEvent&, rMEvt, bool)
1757{
1758 m_nModifier = rMEvt.GetModifier();
1759 return false;
1760}
1761
1762// Notice from SfxBindings that the update is completed. Pushes out the update
1763// of the display.
1765{
1766 bool bDocChanged = false;
1767 SfxStyleSheetBasePool* pNewPool = nullptr;
1769 SfxObjectShell* pDocShell = pViewFrame->GetObjectShell();
1770 if (pDocShell)
1771 pNewPool = pDocShell->GetStyleSheetPool();
1772
1773 if (pNewPool != m_pStyleSheetPool && pDocShell)
1774 {
1775 SfxModule* pNewModule = pDocShell->GetModule();
1776 if (pNewModule && pNewModule != m_Module)
1777 {
1778 m_aClearResource.Call(nullptr);
1779 m_aReadResource.Call(*this);
1780 }
1782 {
1784 m_pStyleSheetPool = nullptr;
1785 }
1786
1787 if (pNewPool)
1788 {
1789 StartListening(*pNewPool);
1790 m_pStyleSheetPool = pNewPool;
1791 bDocChanged = true;
1792 }
1793 }
1794
1795 if (m_bUpdateFamily)
1796 {
1797 UpdateFamily();
1798 m_aUpdateFamily.Call(*this);
1799 }
1800
1801 sal_uInt16 i;
1802 for (i = 0; i < MAX_FAMILIES; ++i)
1803 if (m_pFamilyState[i])
1804 break;
1805 if (i == MAX_FAMILIES || !pNewPool)
1806 // nothing is allowed
1807 return;
1808
1809 SfxTemplateItem* pItem = nullptr;
1810 // current region not within the allowed region or default
1811 if (m_nActFamily == 0xffff || nullptr == (pItem = m_pFamilyState[m_nActFamily - 1].get()))
1812 {
1813 m_pParentDialog->CheckItem(OUString::number(m_nActFamily), false);
1814 const size_t nFamilyCount = m_xStyleFamilies->size();
1815 size_t n;
1816 for (n = 0; n < nFamilyCount; n++)
1818 break;
1819
1820 std::unique_ptr<SfxTemplateItem>& pNewItem = m_pFamilyState[StyleNrToInfoOffset(n)];
1821 m_nAppFilter = pNewItem->GetValue();
1823 pItem = pNewItem.get();
1824 }
1825 else if (bDocChanged)
1826 {
1827 // other DocShell -> all new
1828 m_pParentDialog->CheckItem(OUString::number(m_nActFamily));
1829 m_nActFilter = static_cast<sal_uInt16>(m_aLoadFactoryStyleFilter.Call(pDocShell));
1830 m_pParentDialog->IsUpdate(*this);
1831 if (0xffff == m_nActFilter)
1832 {
1834 }
1835
1836 m_nAppFilter = pItem->GetValue();
1837 if (!m_xTreeBox->get_visible())
1838 {
1840 }
1841 else
1843 }
1844 else
1845 {
1846 // other filters for automatic
1847 m_pParentDialog->CheckItem(OUString::number(m_nActFamily));
1848 const SfxStyleFamilyItem* pStyleItem = GetFamilyItem();
1849 if (pStyleItem
1850 && SfxStyleSearchBits::Auto == pStyleItem->GetFilterList()[m_nActFilter].nFlags
1851 && m_nAppFilter != pItem->GetValue())
1852 {
1853 m_nAppFilter = pItem->GetValue();
1854 if (!m_xTreeBox->get_visible())
1856 else
1858 }
1859 else
1860 {
1861 m_nAppFilter = pItem->GetValue();
1862 }
1863 }
1864 const OUString aStyle(pItem->GetStyleName());
1865 m_pParentDialog->SelectStyle(aStyle, false, *this);
1866 EnableDelete(nullptr);
1868}
1869
1871{
1872 return m_xStyleFamilies->at(i);
1873}
1874
1876{
1877 vcl::RenderContext& rRenderContext = aPayload.first;
1878 return Size(42, 32 * rRenderContext.GetDPIScaleFactor());
1879}
1880
1881IMPL_LINK(StyleList, PopupFlatMenuHdl, const CommandEvent&, rCEvt, bool)
1882{
1883 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
1884 return false;
1885
1886 PrepareMenu(rCEvt.GetMousePosPixel());
1887
1888 if (m_xFmtLb->count_selected_rows() <= 0)
1889 {
1890 m_pParentDialog->EnableEdit(false, this);
1891 m_pParentDialog->EnableDel(false, this);
1892 }
1893
1894 ShowMenu(rCEvt);
1895
1896 return true;
1897}
1898
1899IMPL_LINK(StyleList, PopupTreeMenuHdl, const CommandEvent&, rCEvt, bool)
1900{
1901 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
1902 return false;
1903
1904 PrepareMenu(rCEvt.GetMousePosPixel());
1905
1906 ShowMenu(rCEvt);
1907
1908 return true;
1909}
1910/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(StyleList, Cleanup, void *, void)
Definition: StyleList.cxx:163
static void FillBox_Impl(weld::TreeView &rBox, StyleTree_Impl *pEntry, const std::vector< OUString > &rEntries, SfxStyleFamily eStyleFamily, const weld::TreeIter *pParent, bool blcl_insert, SfxViewShell *pViewShell)
Definition: StyleList.cxx:738
static OUString lcl_GetStyleFamilyName(SfxStyleFamily nFamily)
Definition: StyleList.cxx:1089
static void MakeTree_Impl(StyleTreeArr_Impl &rArr, const OUString &aUIName)
Definition: StyleList.cxx:634
IMPL_LINK(StyleList, SetFamily, sal_uInt16, nId, void)
Definition: StyleList.cxx:322
static void lcl_Insert(weld::TreeView &rTreeView, const OUString &rName, SfxStyleFamily eFam, const weld::TreeIter *pParent, weld::TreeIter *pRet, SfxViewShell *pViewSh)
Definition: StyleList.cxx:696
IMPL_STATIC_LINK(StyleList, CustomGetSizeHdl, weld::TreeView::get_size_args, aPayload, Size)
Definition: StyleList.cxx:1875
static void MakeExpanded_Impl(const weld::TreeView &rBox, std::vector< OUString > &rEntries)
Definition: StyleList.cxx:981
static bool IsExpanded_Impl(const std::vector< OUString > &rEntries, std::u16string_view rStr)
Definition: StyleList.cxx:686
std::vector< std::unique_ptr< StyleTree_Impl > > StyleTreeArr_Impl
Definition: StyleList.cxx:607
constexpr int COUNT_BOUND_FUNC
Definition: StyleList.hxx:56
StyleFlags
Definition: StyleList.hxx:40
constexpr int MAX_FAMILIES
Definition: StyleList.hxx:55
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
const Point & GetMousePosPixel() const
Size GetOutputSize() const
float GetDPIScaleFactor() const
void SetTextColor(const Color &rColor)
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
SAL_DLLPRIVATE SfxDispatcher * GetDispatcher_Impl()
Definition: bindings.hxx:180
void Update(sal_uInt16 nId)
Definition: bindings.cxx:302
SfxDispatcher * GetDispatcher() const
Definition: bindings.hxx:172
void Invalidate(sal_uInt16 nId)
Definition: bindings.cxx:639
void SelectStyle(const OUString &rStyle, bool bIsCallback, StyleList &rStyleList)
Definition: templdlg.cxx:372
virtual void EnableItem(const OUString &, bool=true)
Definition: templdgi.hxx:167
void FamilySelect(sal_uInt16 nId, StyleList &rStyleList, bool bRefresh=false)
Definition: templdlg.cxx:547
void IsUpdate(StyleList &)
Definition: templdlg.cxx:523
void connect_stylelist_enable_delete(const Link< void *, void > rLink)
Definition: templdlg.cxx:181
void connect_stylelist_cleanup(const Link< void *, void > &rLink)
Definition: templdgi.hxx:186
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)
Definition: templdlg.cxx:424
void EnableShow(bool b, const StyleList *rStyleList)
Definition: templdlg.cxx:952
void connect_stylelist_execute_new_menu(const Link< void *, void > &rLink)
Definition: templdgi.hxx:188
void connect_stylelist_execute_drop(const Link< const ExecuteDropEvent &, sal_Int8 > &rLink)
Definition: templdlg.cxx:160
virtual void EnableEdit(bool b, StyleList *rStyleList)
Definition: templdlg.cxx:932
void EnableHide(bool b, const StyleList *rStyleList)
Definition: templdlg.cxx:947
void connect_stylelist_set_water_can_state(const Link< const SfxBoolItem *, void > rLink)
Definition: templdlg.cxx:186
void connect_stylelist_update_style_dependents(const Link< void *, void > &rLink)
Definition: templdlg.cxx:171
void connect_stylelist_for_watercan(const Link< void *, bool > &rLink)
Definition: templdgi.hxx:189
void connect_stylelist_enable_tree_drag(const Link< bool, void > rLink)
Definition: templdlg.cxx:176
void connect_stylelist_has_selected_style(const Link< void *, bool > &rLink)
Definition: templdlg.cxx:166
void EnableNew(bool b, const StyleList *rStyleList)
Definition: templdlg.cxx:942
virtual bool IsCheckedItem(const OUString &)
Definition: templdgi.hxx:169
void connect_set_family(const Link< sal_uInt16, void > rLink)
Definition: templdgi.hxx:195
void connect_stylelist_read_resource(const Link< void *, size_t > &rLink)
Definition: templdgi.hxx:184
virtual void CheckItem(const OUString &, bool=true)
Definition: templdgi.hxx:165
void connect_stylelist_clear(const Link< void *, void > &rLink)
Definition: templdgi.hxx:185
bool IsBound() const
Definition: ctrlitem.cxx:39
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
Method to execute a <SfxSlot>s over the Slot-Id.
Definition: dispatch.cxx:931
SfxViewFrame * GetFrame() const
Returns a pointer to the <SfxViewFrame> instance, which belongs to this SfxDispatcher.
Definition: dispatch.cxx:557
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
SfxHintId GetId() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
virtual std::optional< SfxStyleFamilies > CreateStyleFamilies()
Definition: module.hxx:82
OUString GetName() const
Definition: newstyle.hxx:47
const SvGlobalName & GetClassId() const
Definition: docfac.cxx:294
virtual SfxStyleSheetBasePool * GetStyleSheetPool()
Definition: objcont.cxx:346
sal_uInt16 GetAutoStyleFilterIndex() const
Definition: objxtor.cxx:864
virtual sfx2::StyleManager * GetStyleManager()
Definition: objcont.cxx:411
virtual SfxObjectFactory & GetFactory() const =0
SfxModule * GetModule() const
Definition: objmisc.cxx:1321
css::uno::Reference< css::frame::XModel3 > GetModel() const
Definition: objxtor.cxx:838
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
Definition: objxtor.cxx:481
SfxViewShell * GetViewShell() const
Returns the SfxViewShell in which they are located in the subshells.
Definition: shell.cxx:129
SfxStyleFamily GetFamily() const
Definition: styfitem.hxx:54
const SfxStyleFilter & GetFilterList() const
Definition: styfitem.hxx:55
SfxStyleSheetBase * First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask=SfxStyleSearchBits::All)
SfxStyleSheetBase * Next()
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
SfxStyleSearchBits GetMask() const
virtual bool HasClearParentSupport() const
virtual const OUString & GetParent() const
const OUString & GetName() const
SfxStyleFamily GetFamily() const
bool IsUserDefined() const
virtual bool HasParentSupport() const
virtual bool IsHidden() const
virtual bool IsUsed() const
virtual OUString GetUsedBy()
const OUString & GetStyleName() const
Definition: tplpitem.hxx:39
SfxStyleSearchBits GetValue() const
Definition: tplpitem.hxx:47
void Resize(bool bForce=false)
Definition: viewfrm.cxx:2835
SfxFrame & GetFrame() const
Definition: viewfrm.cxx:2782
virtual SfxObjectShell * GetObjectShell() override
Definition: viewfrm.cxx:2218
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
StylesHighlighterColorMap & GetStylesHighlighterCharColorMap()
Definition: viewsh.hxx:481
StylesHighlighterColorMap & GetStylesHighlighterParaColorMap()
Definition: viewsh.hxx:480
vcl::Window * GetWindow() const
Definition: viewsh.hxx:272
constexpr tools::Long Width() const
const SfxStyleFamilyItem & GetFamilyItemByIndex(size_t i) const
Definition: StyleList.cxx:1870
sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt, const DropTargetHelper &rHelper)
Drop is enabled as long as it is allowed to create a new style by example, i.e.
Definition: StyleList.cxx:455
void FamilySelect(sal_uInt16 nEntry, bool bRefresh=false)
Definition: StyleList.cxx:872
bool m_bNewByExampleDisabled
Definition: StyleList.hxx:207
Link< StyleFlags, void > m_aUpdateStyles
Definition: StyleList.hxx:179
std::unique_ptr< weld::TreeView > m_xTreeBox
Definition: StyleList.hxx:220
void Initialize()
Definition: StyleList.cxx:347
void UpdateStyles(StyleFlags nFlags)
Definition: StyleList.cxx:1161
SfxStyleFamily GetActualFamily() const
Definition: StyleList.cxx:1132
bool m_bHighlightCharStyles
Definition: StyleList.hxx:247
void UpdateFamily()
Definition: StyleList.cxx:401
OUString getDefaultStyleName(const SfxStyleFamily eFam)
Definition: StyleList.cxx:1104
void CreateContextMenu()
Definition: StyleList.cxx:175
std::optional< SfxStyleFamilies > m_xStyleFamilies
Definition: StyleList.hxx:225
std::array< std::unique_ptr< SfxTemplateItem >, MAX_FAMILIES > m_pFamilyState
Definition: StyleList.hxx:226
bool m_bBindingUpdate
Definition: StyleList.hxx:216
std::unique_ptr< Idle > pIdle
Definition: StyleList.hxx:238
bool m_bTreeDrag
Definition: StyleList.hxx:209
bool m_bCanShow
Definition: StyleList.hxx:212
SfxModule * m_Module
Definition: StyleList.hxx:241
void EditHdl()
Definition: StyleList.cxx:1320
void HideHdl()
Definition: StyleList.cxx:1397
Link< StyleList &, SfxObjectShell * > m_aSaveSelection
Definition: StyleList.hxx:183
SfxCommonTemplateDialog_Impl * m_pParentDialog
Definition: StyleList.hxx:234
Link< void *, void > m_aClearResource
Definition: StyleList.hxx:181
void connect_LoadFactoryStyleFilter(const Link< SfxObjectShell const *, sal_Int32 > &rLink)
Definition: StyleList.cxx:442
Link< StyleList &, void > m_aUpdateFamily
Definition: StyleList.hxx:184
void SelectStyle(const OUString &rStr, bool bIsCallback)
Definition: StyleList.cxx:896
bool m_bHierarchical
Definition: StyleList.hxx:204
Link< StyleList &, void > m_aReadResource
Definition: StyleList.hxx:180
const SfxStyleFamilyItem * GetFamilyItem() const
Definition: StyleList.cxx:808
void SetFamilyState(sal_uInt16 nSlotId, const SfxTemplateItem *pItem)
Definition: StyleList.cxx:1274
bool m_bCanEdit
Definition: StyleList.hxx:210
void DeleteHdl()
Definition: StyleList.cxx:1334
void PrepareMenu(const Point &rPos)
Definition: StyleList.cxx:588
void EnableNewByExample(bool newByExampleDisabled)
Definition: StyleList.cxx:298
void connect_SaveSelection(const Link< StyleList &, SfxObjectShell * > rLink)
Definition: StyleList.cxx:447
std::unique_ptr< weld::Menu > mxMenu
Definition: StyleList.hxx:223
sal_uInt16 m_nActFamily
Definition: StyleList.hxx:228
void MenuSelect(const OUString &rIdent)
Definition: StyleList.cxx:1486
bool m_bDontUpdate
Definition: StyleList.hxx:208
void Update()
Definition: StyleList.cxx:1764
bool m_bHighlightParaStyles
Definition: StyleList.hxx:246
std::unique_ptr< TreeViewDropTarget > m_xTreeView2DropTargetHelper
Definition: StyleList.hxx:232
SfxObjectShell * m_pCurObjShell
Definition: StyleList.hxx:227
StyleList(weld::Builder *pBuilder, SfxBindings *pBindings, SfxCommonTemplateDialog_Impl *Parent, weld::Container *pC, OUString treeviewname, OUString flatviewname)
Definition: StyleList.cxx:121
void SetFilterControlsHandle()
Definition: StyleList.cxx:1293
void ShowMenu(const CommandEvent &rCEvt)
Definition: StyleList.cxx:1477
void FillTreeBox(SfxStyleFamily eFam)
Definition: StyleList.cxx:1007
sal_uInt16 StyleNrToInfoOffset(sal_uInt16 i)
Definition: StyleList.cxx:801
SfxStyleSearchBits m_nAppFilter
Definition: StyleList.hxx:229
void NewHdl()
Definition: StyleList.cxx:1301
std::unique_ptr< TreeViewDropTarget > m_xTreeView1DropTargetHelper
Definition: StyleList.hxx:231
void FilterSelect(sal_uInt16 nActFilter, bool bsetFilter)
Definition: StyleList.cxx:303
SfxBindings * m_pBindings
Definition: StyleList.hxx:235
bool m_bModuleHasStylesHighlighterFeature
Definition: StyleList.hxx:245
std::unique_ptr< weld::TreeView > m_xFmtLb
Definition: StyleList.hxx:219
Link< SfxObjectShell const *, sal_Int32 > m_aLoadFactoryStyleFilter
Definition: StyleList.hxx:182
bool m_bCanNew
Definition: StyleList.hxx:213
void ShowHdl()
Definition: StyleList.cxx:1413
bool m_bAllowReParentDrop
Definition: StyleList.hxx:206
void InvalidateBindings()
Definition: StyleList.cxx:333
void SetHierarchical()
Definition: StyleList.cxx:1283
SfxStyleSheetBasePool * m_pStyleSheetPool
Definition: StyleList.hxx:217
sal_uInt16 m_nActFilter
Definition: StyleList.hxx:218
bool m_bUpdateFamily
Definition: StyleList.hxx:214
bool m_bCanHide
Definition: StyleList.hxx:211
void Notify(SfxBroadcaster &rBC, const SfxHint &rHint)
Definition: StyleList.cxx:1494
OUString sLastItemIdent
Definition: StyleList.hxx:240
void DropHdl(const OUString &rStyle, const OUString &rParent)
Definition: StyleList.cxx:578
std::unique_ptr< weld::Builder > mxMenuBuilder
Definition: StyleList.hxx:222
friend class TreeViewDropTarget
Definition: StyleList.hxx:60
void GetSelectedStyle() const
Definition: StyleList.cxx:821
bool EnableExecute()
Definition: StyleList.cxx:437
OUString GetSelectedEntry() const
Definition: StyleList.cxx:829
bool m_bCanDel
Definition: StyleList.hxx:215
const Color & GetDialogTextColor() const
const Color & GetHighlightTextColor() const
const Color & GetDisableColor() const
const Size & GetListBoxPreviewDefaultPixelSize() const
virtual sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt) override
Definition: StyleList.cxx:85
StyleList & m_rParent
Definition: StyleList.cxx:76
TreeViewDropTarget(StyleList &rStyleList, weld::TreeView &rTreeView)
Definition: StyleList.cxx:79
virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt) override
Definition: StyleList.cxx:90
reference_type * get() const
virtual std::unique_ptr< StylePreviewRenderer > CreateStylePreviewRenderer(OutputDevice &rOutputDev, SfxStyleSheetBase *pStyle, tools::Long nMaxHeight)=0
SfxStyleSheetBase * Search(std::u16string_view rStyleName, SfxStyleFamily eFamily)
constexpr tools::Long GetHeight() const
sal_uInt16 GetCode() const
sal_uInt16 GetModifier() const
void GrabFocus()
virtual short run()
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const=0
virtual bool get_row_expanded(const TreeIter &rIter) const=0
virtual OUString get_text(int row, int col=-1) const=0
std::tuple< vcl::RenderContext &, const tools::Rectangle &, bool, const OUString & > render_args
void unselect_all()
virtual void insert(const TreeIter *pParent, int pos, const OUString *pStr, const OUString *pId, const OUString *pIconName, VirtualDevice *pImageSurface, bool bChildrenOnDemand, TreeIter *pRet)=0
virtual TreeView * get_drag_source() const=0
virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter *pResult, bool bDnDMode, bool bAutoScroll=true)=0
virtual void selected_foreach(const std::function< bool(TreeIter &)> &func)=0
virtual bool get_iter_first(TreeIter &rIter) const=0
virtual bool is_selected(int pos) const=0
virtual void select(int pos)=0
virtual bool iter_next(TreeIter &rIter) const=0
std::pair< vcl::RenderContext &, const OUString & > get_size_args
virtual void set_cursor(int pos)=0
virtual bool get_visible() const=0
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
int nCount
ScXMLEditAttributeMap::Entry const aEntries[]
Any aHelper
Reference< XInterface > xTarget
OUString aUIName
SotClipboardFormatId
constexpr OUStringLiteral HID_TEMPLATE_FMT
Definition: helpids.h:24
SfxHintId
OUString aName
sal_Int64 n
constexpr sal_uInt16 KEY_DELETE
std::vector< SvLinkSource_Entry_Impl * > aArr
Definition: linksrc.cxx:116
sal_uInt16 nPos
Definition: linksrc.cxx:118
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
aStr
Definition: mgetempl.cxx:407
static SfxStyleFamily NIdToSfxFamilyId(sal_uInt16 nId)
Definition: StyleList.cxx:779
static sal_uInt16 SfxFamilyIdToNId(SfxStyleFamily nFamily)
Definition: StyleList.cxx:758
void Clear(EHistoryType eHistory)
BColor hsl2rgb(const BColor &rHSLColor)
size
const LanguageTag & getLocale()
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
void RemoveParentKeepChildren(weld::TreeView &rTreeView, const weld::TreeIter &rParent)
sal_Int16 nId
OUString SfxResId(TranslateId aId)
Definition: sfxresid.cxx:22
SfxStyleFamily
SfxStyleSearchBits
Reference< XFrame > xFrame
Reference< XModel > xModel
#define DND_ACTION_MOVE
#define DND_ACTION_COPY
#define DND_ACTION_NONE
signed char sal_Int8
RET_OK
RET_YES
std::unordered_map< OUString, std::pair< Color, int > > StylesHighlighterColorMap
Definition: viewsh.hxx:158