tdf#160404 tdf#160535 tdf#160536 - sc improve sheet protection
[LibreOffice.git] / svx / source / tbxctrls / bulletsnumbering.cxx
blob8e06d125ae4f8abaa35f377b0a90a0e58a990fe3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
11 #include <com/sun/star/text/XNumberingFormatter.hpp>
12 #include <com/sun/star/uno/Sequence.hxx>
14 #include <comphelper/propertysequence.hxx>
15 #include <i18nlangtag/languagetag.hxx>
16 #include <officecfg/Office/Common.hxx>
17 #include <svtools/popupwindowcontroller.hxx>
18 #include <svtools/toolbarmenu.hxx>
19 #include <svx/strings.hrc>
20 #include <svx/dialmgr.hxx>
21 #include <svx/numvset.hxx>
22 #include <vcl/commandinfoprovider.hxx>
23 #include <vcl/toolbox.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/svapp.hxx>
27 namespace {
29 class NumberingToolBoxControl;
31 class NumberingPopup : public WeldToolbarPopup
33 NumberingPageType mePageType;
34 NumberingToolBoxControl& mrController;
35 std::unique_ptr<SvxNumValueSet> mxValueSet;
36 std::unique_ptr<weld::CustomWeld> mxValueSetWin;
37 std::unique_ptr<SvxNumValueSet> mxValueSetDoc;
38 std::unique_ptr<weld::CustomWeld> mxValueSetWinDoc;
39 std::unique_ptr<weld::Button> mxMoreButton;
40 std::unique_ptr<weld::Label> mxBulletsLabel;
41 std::unique_ptr<weld::Label> mxDocBulletsLabel;
42 DECL_LINK(VSSelectValueSetHdl, ValueSet*, void);
43 DECL_LINK(VSSelectValueSetDocHdl, ValueSet*, void);
44 DECL_LINK(VSButtonClickSetHdl, weld::Button&, void);
46 virtual void GrabFocus() override;
48 public:
49 NumberingPopup(NumberingToolBoxControl& rController, weld::Widget* pParent, NumberingPageType ePageType);
51 virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
54 class NumberingToolBoxControl : public svt::PopupWindowController
56 NumberingPageType mePageType;
58 public:
59 explicit NumberingToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
60 virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
61 std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
63 // XInitialization
64 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
66 // XServiceInfo
67 virtual OUString SAL_CALL getImplementationName() override;
68 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
73 NumberingPopup::NumberingPopup(NumberingToolBoxControl& rController,
74 weld::Widget* pParent, NumberingPageType ePageType)
75 : WeldToolbarPopup(rController.getFrameInterface(), pParent, u"svx/ui/numberingwindow.ui"_ustr, u"NumberingWindow"_ustr)
76 , mePageType(ePageType)
77 , mrController(rController)
78 , mxValueSet(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
79 , mxValueSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *mxValueSet))
80 , mxValueSetDoc(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin_doc"_ustr, true)))
81 , mxValueSetWinDoc(new weld::CustomWeld(*m_xBuilder, u"valueset_doc"_ustr, *mxValueSetDoc))
82 , mxMoreButton(m_xBuilder->weld_button(u"more"_ustr))
83 , mxBulletsLabel(m_xBuilder->weld_label(u"label_default"_ustr))
84 , mxDocBulletsLabel(m_xBuilder->weld_label(u"label_doc"_ustr))
86 mxValueSet->SetStyle(WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NO_DIRECTSELECT);
87 mxValueSetDoc->SetStyle(WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NO_DIRECTSELECT);
88 mxValueSet->init(mePageType);
89 mxValueSetDoc->init(NumberingPageType::DOCBULLET);
90 mxValueSetWinDoc->hide();
91 mxDocBulletsLabel->hide();
93 if ( mePageType != NumberingPageType::BULLET )
95 mxBulletsLabel->hide();
96 css::uno::Reference< css::text::XDefaultNumberingProvider > xDefNum = css::text::DefaultNumberingProvider::create( mrController.getContext() );
97 if ( xDefNum.is() )
99 css::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale();
100 css::uno::Reference< css::text::XNumberingFormatter > xFormat( xDefNum, css::uno::UNO_QUERY );
102 if ( mePageType == NumberingPageType::SINGLENUM )
104 css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aNumberings(
105 xDefNum->getDefaultContinuousNumberingLevels( aLocale ) );
106 mxValueSet->SetNumberingSettings( aNumberings, xFormat, aLocale );
108 else if ( mePageType == NumberingPageType::OUTLINE )
110 css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > aOutline(
111 xDefNum->getDefaultOutlineNumberings( aLocale ) );
112 mxValueSet->SetOutlineNumberingSettings( aOutline, xFormat, aLocale );
117 weld::DrawingArea* pDrawingArea = mxValueSet->GetDrawingArea();
118 weld::DrawingArea* pDrawingAreaDoc = mxValueSetDoc->GetDrawingArea();
119 OutputDevice& rRefDevice = pDrawingArea->get_ref_device();
120 Size aItemSize(rRefDevice.LogicToPixel(Size(30, 42), MapMode(MapUnit::MapAppFont)));
121 mxValueSet->SetExtraSpacing( 2 );
122 mxValueSetDoc->SetExtraSpacing( 2 );
123 Size aSize(mxValueSet->CalcWindowSizePixel(aItemSize));
124 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
125 pDrawingAreaDoc->set_size_request(aSize.Width(), aSize.Height());
126 mxValueSet->SetOutputSizePixel(aSize);
127 mxValueSetDoc->SetOutputSizePixel(aSize);
128 mxValueSet->SetColor(Application::GetSettings().GetStyleSettings().GetFieldColor());
129 mxValueSetDoc->SetColor(Application::GetSettings().GetStyleSettings().GetFieldColor());
131 if ( mePageType == NumberingPageType::BULLET )
133 AddStatusListener( u".uno:CurrentBulletListType"_ustr );
134 AddStatusListener( u".uno:DocumentBulletList"_ustr );
136 else if ( mePageType == NumberingPageType::SINGLENUM )
137 AddStatusListener( u".uno:CurrentNumListType"_ustr );
138 else
139 AddStatusListener( u".uno:CurrentOutlineType"_ustr );
141 auto xImage = vcl::CommandInfoProvider::GetXGraphicForCommand(u".uno:OutlineBullet"_ustr, mrController.getFrameInterface());
142 mxMoreButton->set_image(xImage);
143 mxMoreButton->connect_clicked(LINK(this, NumberingPopup, VSButtonClickSetHdl));
145 mxValueSet->SetSelectHdl(LINK(this, NumberingPopup, VSSelectValueSetHdl));
146 mxValueSetDoc->SetSelectHdl(LINK(this, NumberingPopup, VSSelectValueSetDocHdl));
149 namespace
151 bool lcl_BulletIsDefault(std::u16string_view aSymbol, std::u16string_view aFont)
153 css::uno::Sequence<OUString> aBulletSymbols
154 = officecfg::Office::Common::BulletsNumbering::DefaultBullets::get();
155 css::uno::Sequence<OUString> aBulletFonts
156 = officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get();
157 for (sal_Int32 i = 0; i < aBulletSymbols.getLength(); i++)
159 if (aBulletSymbols[i] == aSymbol && aBulletFonts[i] == aFont)
160 return true;
162 return false;
166 void NumberingPopup::statusChanged( const css::frame::FeatureStateEvent& rEvent )
168 if (rEvent.FeatureURL.Complete == ".uno:DocumentBulletList")
170 css::uno::Sequence<OUString> aSeq;
171 if (rEvent.State >>= aSeq)
173 std::vector<std::pair<OUString, OUString>> aList;
174 mxValueSetDoc->Clear();
175 int i = 1;
176 // The string contains the bullet as first character, and then the font name
177 for (const OUString& sBulletFont : aSeq)
179 OUString sBullet(sBulletFont.copy(0, 1));
180 OUString sFont(sBulletFont.copy(1, sBulletFont.getLength() - 1));
181 if (lcl_BulletIsDefault(sBullet, sFont))
182 continue;
183 mxValueSetDoc->InsertItem(i, sBullet, i);
184 aList.emplace_back(sBullet, sFont);
185 i++;
187 if (!aList.empty())
189 mxValueSetWinDoc->show();
190 mxDocBulletsLabel->show();
191 mxValueSetDoc->SetCustomBullets(aList);
193 else
195 mxValueSetWinDoc->hide();
196 mxDocBulletsLabel->hide();
200 else
202 mxValueSet->SetNoSelection();
203 sal_Int32 nSelItem;
204 if ( rEvent.State >>= nSelItem )
205 mxValueSet->SelectItem( nSelItem );
209 IMPL_LINK_NOARG(NumberingPopup, VSSelectValueSetHdl, ValueSet*, void)
211 sal_uInt16 nSelItem = mxValueSet->GetSelectedItemId();
212 if ( mePageType == NumberingPageType::BULLET )
214 auto aArgs( comphelper::InitPropertySequence( { { "BulletIndex", css::uno::Any( nSelItem ) } } ) );
215 mrController.dispatchCommand( u".uno:SetBullet"_ustr, aArgs );
217 else if ( mePageType == NumberingPageType::SINGLENUM )
219 auto aArgs( comphelper::InitPropertySequence( { { "SetNumber", css::uno::Any( nSelItem ) } } ) );
220 mrController.dispatchCommand( u".uno:SetNumber"_ustr, aArgs );
222 else
224 auto aArgs( comphelper::InitPropertySequence( { { "SetOutline", css::uno::Any( nSelItem ) } } ) );
225 mrController.dispatchCommand( u".uno:SetOutline"_ustr, aArgs );
227 mrController.EndPopupMode();
230 IMPL_LINK_NOARG(NumberingPopup, VSSelectValueSetDocHdl, ValueSet*, void)
232 sal_uInt16 nSelItem = mxValueSetDoc->GetSelectedItemId() - 1;
233 auto aCustomBullets = mxValueSetDoc->GetCustomBullets();
234 OUString nChar(aCustomBullets[nSelItem].first);
235 OUString sFont(aCustomBullets[nSelItem].second);
236 auto aArgs(comphelper::InitPropertySequence(
237 { { "BulletChar", css::uno::Any(nChar) }, { "BulletFont", css::uno::Any(sFont) } }));
238 mrController.dispatchCommand(u".uno:SetBullet"_ustr, aArgs);
239 mrController.EndPopupMode();
242 void NumberingPopup::GrabFocus()
244 mxValueSet->GrabFocus();
247 IMPL_LINK_NOARG(NumberingPopup, VSButtonClickSetHdl, weld::Button&, void)
249 auto aArgs( comphelper::InitPropertySequence( { { "Page", css::uno::Any( u"customize"_ustr ) } } ) );
250 mrController.dispatchCommand( u".uno:OutlineBullet"_ustr, aArgs );
252 mrController.EndPopupMode();
255 NumberingToolBoxControl::NumberingToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext ):
256 svt::PopupWindowController( rxContext, css::uno::Reference< css::frame::XFrame >(), OUString() ),
257 mePageType( NumberingPageType::SINGLENUM )
261 std::unique_ptr<WeldToolbarPopup> NumberingToolBoxControl::weldPopupWindow()
263 return std::make_unique<NumberingPopup>(*this, m_pToolbar, mePageType);
266 VclPtr<vcl::Window> NumberingToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
268 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
269 std::make_unique<NumberingPopup>(*this, pParent->GetFrameWeld(), mePageType));
271 mxInterimPopover->Show();
273 return mxInterimPopover;
276 void SAL_CALL NumberingToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
278 svt::PopupWindowController::initialize( aArguments );
280 if ( m_aCommandURL == ".uno:DefaultBullet" )
281 mePageType = NumberingPageType::BULLET;
282 else if ( m_aCommandURL == ".uno:SetOutline" )
283 mePageType = NumberingPageType::OUTLINE;
285 if (m_pToolbar)
287 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
288 m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
289 return;
292 ToolBox* pToolBox = nullptr;
293 ToolBoxItemId nId;
294 if (getToolboxId(nId, &pToolBox))
296 ToolBoxItemBits nBits = mePageType == NumberingPageType::OUTLINE
297 ? ToolBoxItemBits::DROPDOWNONLY
298 : ToolBoxItemBits::DROPDOWN;
299 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | nBits );
303 OUString SAL_CALL NumberingToolBoxControl::getImplementationName()
305 return u"com.sun.star.comp.svx.NumberingToolBoxControl"_ustr;
308 css::uno::Sequence< OUString > SAL_CALL NumberingToolBoxControl::getSupportedServiceNames()
310 return { u"com.sun.star.frame.ToolbarController"_ustr };
313 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
314 com_sun_star_comp_svx_NumberingToolBoxControl_get_implementation(
315 css::uno::XComponentContext *rxContext,
316 css::uno::Sequence<css::uno::Any> const & )
318 return cppu::acquire( new NumberingToolBoxControl( rxContext ) );
321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */