Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tbcontrl.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SVXCORE_DLLIMPLEMENTATION -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/svx/inc -I /home/maarten/src/libreoffice/core/svx/source/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/svx/sdi -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx

/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx

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 <typeinfo>
21#include <utility>
22
23#include <comphelper/configurationlistener.hxx>
24#include <comphelper/propertysequence.hxx>
25#include <tools/color.hxx>
26#include <svl/poolitem.hxx>
27#include <svl/itemset.hxx>
28#include <vcl/commandinfoprovider.hxx>
29#include <vcl/event.hxx>
30#include <vcl/toolbox.hxx>
31#include <vcl/customweld.hxx>
32#include <vcl/vclptr.hxx>
33#include <vcl/weldutils.hxx>
34#include <svtools/valueset.hxx>
35#include <svtools/ctrlbox.hxx>
36#include <svl/style.hxx>
37#include <svtools/ctrltool.hxx>
38#include <svtools/borderhelper.hxx>
39#include <vcl/InterimItemWindow.hxx>
40#include <sfx2/tbxctrl.hxx>
41#include <sfx2/tplpitem.hxx>
42#include <sfx2/sfxstatuslistener.hxx>
43#include <toolkit/helper/vclunohelper.hxx>
44#include <sfx2/viewfrm.hxx>
45#include <vcl/svapp.hxx>
46#include <vcl/settings.hxx>
47#include <vcl/virdev.hxx>
48#include <com/sun/star/awt/FontDescriptor.hpp>
49#include <com/sun/star/table/BorderLine2.hpp>
50#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
51#include <com/sun/star/lang/XServiceInfo.hpp>
52#include <com/sun/star/beans/XPropertySet.hpp>
53#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
54#include <com/sun/star/frame/XDispatchProvider.hpp>
55#include <com/sun/star/frame/XFrame.hpp>
56#include <svx/strings.hrc>
57#include <svx/svxids.hrc>
58#include <helpids.h>
59#include <sfx2/sidebar/Sidebar.hxx>
60#include <sfx2/sidebar/SidebarToolBox.hxx>
61#include <svx/xtable.hxx>
62#include <editeng/editids.hrc>
63#include <editeng/fontitem.hxx>
64#include <editeng/fhgtitem.hxx>
65#include <editeng/boxitem.hxx>
66#include <editeng/charreliefitem.hxx>
67#include <editeng/contouritem.hxx>
68#include <editeng/colritem.hxx>
69#include <editeng/crossedoutitem.hxx>
70#include <editeng/emphasismarkitem.hxx>
71#include <editeng/flstitem.hxx>
72#include <editeng/lineitem.hxx>
73#include <editeng/postitem.hxx>
74#include <editeng/shdditem.hxx>
75#include <editeng/udlnitem.hxx>
76#include <editeng/wghtitem.hxx>
77#include <editeng/svxfont.hxx>
78#include <editeng/cmapitem.hxx>
79#include <svx/colorwindow.hxx>
80#include <svx/colorbox.hxx>
81#include <svx/tbcontrl.hxx>
82#include <svx/dialmgr.hxx>
83#include <svx/PaletteManager.hxx>
84#include <memory>
85
86#include <tbxcolorupdate.hxx>
87#include <editeng/eerdll.hxx>
88#include <editeng/editrids.hrc>
89#include <svx/xdef.hxx>
90#include <svx/xfillit0.hxx>
91#include <svx/xflclit.hxx>
92#include <svl/currencytable.hxx>
93#include <svtools/langtab.hxx>
94#include <cppu/unotype.hxx>
95#include <cppuhelper/supportsservice.hxx>
96#include <officecfg/Office/Common.hxx>
97#include <o3tl/safeint.hxx>
98#include <o3tl/typed_flags_set.hxx>
99#include <bitmaps.hlst>
100#include <sal/log.hxx>
101#include <unotools/collatorwrapper.hxx>
102
103#include <comphelper/lok.hxx>
104#include <tools/json_writer.hxx>
105
106#define MAX_MRU_FONTNAME_ENTRIES5 5
107
108#define COMBO_WIDTH_IN_CHARS18 18
109
110// namespaces
111using namespace ::editeng;
112using namespace ::com::sun::star;
113using namespace ::com::sun::star::uno;
114using namespace ::com::sun::star::frame;
115using namespace ::com::sun::star::beans;
116using namespace ::com::sun::star::lang;
117
118namespace
119{
120class SvxStyleBox_Base
121{
122public:
123 SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget, const OUString& rCommand, SfxStyleFamily eFamily,
124 const Reference<XDispatchProvider>& rDispatchProvider,
125 const Reference<XFrame>& _xFrame,const OUString& rClearFormatKey,
126 const OUString& rMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);
127
128 virtual ~SvxStyleBox_Base()
129 {
130 }
131
132 void SetFamily( SfxStyleFamily eNewFamily );
133
134 void SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
135
136 int get_count() const { return m_xWidget->get_count(); }
137 OUString get_text(int nIndex) const { return m_xWidget->get_text(nIndex); }
138 OUString get_active_text() const { return m_xWidget->get_active_text(); }
139
140 void append_text(const OUString& rStr)
141 {
142 OUString sId(OUString::number(m_xWidget->get_count()));
143 m_xWidget->append(sId, rStr);
144 }
145
146 void insert_separator(int pos, const OUString& rId)
147 {
148 m_xWidget->insert_separator(pos, rId);
149 }
150
151 void set_active_or_entry_text(const OUString& rText)
152 {
153 const int nFound = m_xWidget->find_text(rText);
154 if (nFound != -1)
155 m_xWidget->set_active(nFound);
156 else
157 m_xWidget->set_entry_text(rText);
158 }
159
160 void set_active(int nActive)
161 {
162 m_xWidget->set_active(nActive);
163 }
164
165 void freeze()
166 {
167 m_xWidget->freeze();
168 }
169
170 void save_value()
171 {
172 m_xWidget->save_value();
173 }
174
175 void clear()
176 {
177 m_xWidget->clear();
178 m_nMaxUserDrawFontWidth = 0;
179 }
180
181 void thaw()
182 {
183 m_xWidget->thaw();
184 }
185
186 virtual bool DoKeyInput(const KeyEvent& rKEvt);
187
188private:
189 DECL_LINK(SelectHdl, weld::ComboBox&, void)static void LinkStubSelectHdl(void *, weld::ComboBox&); void
SelectHdl(weld::ComboBox&)
;
190 DECL_LINK(KeyInputHdl, const KeyEvent&, bool)static bool LinkStubKeyInputHdl(void *, const KeyEvent&);
bool KeyInputHdl(const KeyEvent&)
;
191 DECL_LINK(ActivateHdl, weld::ComboBox&, bool)static bool LinkStubActivateHdl(void *, weld::ComboBox&);
bool ActivateHdl(weld::ComboBox&)
;
192 DECL_LINK(FocusOutHdl, weld::Widget&, void)static void LinkStubFocusOutHdl(void *, weld::Widget&); void
FocusOutHdl(weld::Widget&)
;
193 DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void)static void LinkStubDumpAsPropertyTreeHdl(void *, tools::JsonWriter
&); void DumpAsPropertyTreeHdl(tools::JsonWriter&)
;
194 DECL_LINK(CustomRenderHdl, weld::ComboBox::render_args, void)static void LinkStubCustomRenderHdl(void *, weld::ComboBox::render_args
); void CustomRenderHdl(weld::ComboBox::render_args)
;
195 DECL_LINK(CustomGetSizeHdl, OutputDevice&, Size)static Size LinkStubCustomGetSizeHdl(void *, OutputDevice&
); Size CustomGetSizeHdl(OutputDevice&)
;
196
197 /// Calculate the optimal width of the dropdown. Very expensive operation, triggers lots of font measurement.
198 void CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext);
199
200 void Select(bool bNonTravelSelect);
201
202protected:
203 SvxStyleToolBoxControl& m_rCtrl;
204
205 std::unique_ptr<weld::Builder> m_xMenuBuilder;
206 std::unique_ptr<weld::Menu> m_xMenu;
207 std::unique_ptr<weld::ComboBox> m_xWidget;
208
209 SfxStyleFamily eStyleFamily;
210 int m_nMaxUserDrawFontWidth;
211 bool bRelease;
212 Reference< XDispatchProvider > m_xDispatchProvider;
213 Reference< XFrame > m_xFrame;
214 OUString m_aCommand;
215 OUString aClearFormatKey;
216 OUString aMoreKey;
217 OUString sDefaultStyle;
218 bool bInSpecialMode;
219
220 void ReleaseFocus();
221 static Color TestColorsVisible(const Color &FontCol, const Color &BackCol);
222 static void UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const OUString &rStyleName);
223 void SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected);
224 static bool AdjustFontForItemHeight(OutputDevice& rDevice, tools::Rectangle const & rTextRect, long nHeight);
225 DECL_LINK(MenuSelectHdl, const OString&, void)static void LinkStubMenuSelectHdl(void *, const OString&)
; void MenuSelectHdl(const OString&)
;
226 DECL_STATIC_LINK(SvxStyleBox_Base, ShowMoreHdl, void*, void)static void LinkStubShowMoreHdl(void *, void*); static void ShowMoreHdl
(SvxStyleBox_Base *, void*)
;
227};
228
229class SvxStyleBox_Impl final : public InterimItemWindow
230 , public SvxStyleBox_Base
231{
232public:
233 SvxStyleBox_Impl(vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily, const Reference< XDispatchProvider >& rDispatchProvider,
234 const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);
235
236 virtual ~SvxStyleBox_Impl() override
237 {
238 disposeOnce();
239 }
240
241 virtual void dispose() override
242 {
243 m_xWidget.reset();
244 m_xMenu.reset();
245 m_xMenuBuilder.reset();
246 InterimItemWindow::dispose();
247 }
248
249 virtual bool DoKeyInput(const KeyEvent& rKEvt) override;
250
251private:
252
253 virtual void DataChanged(const DataChangedEvent& rDCEvt) override;
254 void SetOptimalSize();
255};
256
257class SvxFontNameBox_Impl;
258class SvxFontNameBox_Base;
259
260class SvxFontNameToolBoxControl final : public cppu::ImplInheritanceHelper<svt::ToolboxController,
261 css::lang::XServiceInfo>
262{
263public:
264 SvxFontNameToolBoxControl();
265
266 // XStatusListener
267 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
268
269 // XToolbarController
270 virtual css::uno::Reference<css::awt::XWindow> SAL_CALL createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent) override;
271
272 // XComponent
273 virtual void SAL_CALL dispose() override;
274
275 // XServiceInfo
276 virtual OUString SAL_CALL getImplementationName() override;
277 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
278 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
279
280private:
281 VclPtr<SvxFontNameBox_Impl> m_xVclBox;
282 std::unique_ptr<SvxFontNameBox_Base> m_xWeldBox;
283 SvxFontNameBox_Base* m_pBox;
284};
285
286class FontOptionsListener final : public comphelper::ConfigurationListenerProperty<bool>
287{
288private:
289 SvxFontNameBox_Base& m_rBox;
290
291 virtual void setProperty(const css::uno::Any &rProperty) override;
292public:
293 FontOptionsListener(const rtl::Reference<comphelper::ConfigurationListener>& rListener, const OUString& rProp, SvxFontNameBox_Base& rBox)
294 : comphelper::ConfigurationListenerProperty<bool>(rListener, rProp)
295 , m_rBox(rBox)
296 {
297 }
298};
299
300class SvxFontNameBox_Base
301{
302private:
303 rtl::Reference<comphelper::ConfigurationListener> m_xListener;
304 FontOptionsListener m_aWYSIWYG;
305 FontOptionsListener m_aHistory;
306
307protected:
308 SvxFontNameToolBoxControl& m_rCtrl;
309
310 std::unique_ptr<FontNameBox> m_xWidget;
311 const FontList* pFontList;
312 ::std::unique_ptr<FontList> m_aOwnFontList;
313 vcl::Font aCurFont;
314 sal_uInt16 nFtCount;
315 bool bRelease;
316 Reference< XDispatchProvider > m_xDispatchProvider;
317 Reference< XFrame > m_xFrame;
318 bool mbCheckingUnknownFont;
319
320 void ReleaseFocus_Impl();
321
322 void Select(bool bNonTravelSelect);
323
324 void EndPreview()
325 {
326 Sequence< PropertyValue > aArgs;
327 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
328 ".uno:CharEndPreviewFontName",
329 aArgs );
330 }
331 void CheckAndMarkUnknownFont();
332
333public:
334 SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget, const Reference<XDispatchProvider>& rDispatchProvider,
335 const Reference<XFrame>& rFrame, SvxFontNameToolBoxControl& rCtrl);
336 virtual ~SvxFontNameBox_Base()
337 {
338 m_xListener->dispose();
339 }
340
341 void FillList();
342 void Update( const css::awt::FontDescriptor* pFontDesc );
343 sal_uInt16 GetListCount() const { return nFtCount; }
344 void Clear() { m_xWidget->clear(); nFtCount = 0; }
345 void Fill( const FontList* pList )
346 {
347 m_xWidget->Fill(pList);
348 nFtCount = pList->GetFontNameCount();
349 }
350
351 void SetOwnFontList(::std::unique_ptr<FontList> && _aOwnFontList) { m_aOwnFontList = std::move(_aOwnFontList); }
352
353 virtual void set_sensitive(bool bSensitive)
354 {
355 m_xWidget->set_sensitive(bSensitive);
356 }
357
358 void set_active_or_entry_text(const OUString& rText);
359
360 void statusChanged_Impl(const css::frame::FeatureStateEvent& rEvent);
361
362 virtual bool DoKeyInput(const KeyEvent& rKEvt);
363
364 void EnableControls();
365
366 DECL_LINK(SelectHdl, weld::ComboBox&, void)static void LinkStubSelectHdl(void *, weld::ComboBox&); void
SelectHdl(weld::ComboBox&)
;
367 DECL_LINK(KeyInputHdl, const KeyEvent&, bool)static bool LinkStubKeyInputHdl(void *, const KeyEvent&);
bool KeyInputHdl(const KeyEvent&)
;
368 DECL_LINK(ActivateHdl, weld::ComboBox&, bool)static bool LinkStubActivateHdl(void *, weld::ComboBox&);
bool ActivateHdl(weld::ComboBox&)
;
369 DECL_LINK(FocusInHdl, weld::Widget&, void)static void LinkStubFocusInHdl(void *, weld::Widget&); void
FocusInHdl(weld::Widget&)
;
370 DECL_LINK(FocusOutHdl, weld::Widget&, void)static void LinkStubFocusOutHdl(void *, weld::Widget&); void
FocusOutHdl(weld::Widget&)
;
371 DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void)static void LinkStubDumpAsPropertyTreeHdl(void *, tools::JsonWriter
&); void DumpAsPropertyTreeHdl(tools::JsonWriter&)
;
372};
373
374void FontOptionsListener::setProperty(const css::uno::Any &rProperty)
375{
376 comphelper::ConfigurationListenerProperty<bool>::setProperty(rProperty);
377 m_rBox.EnableControls();
378}
379
380class SvxFontNameBox_Impl final : public InterimItemWindow
381 , public SvxFontNameBox_Base
382{
383private:
384 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
385 virtual void GetFocus() override
386 {
387 if (m_xWidget)
388 m_xWidget->grab_focus();
389 InterimItemWindow::GetFocus();
390 }
391
392 void SetOptimalSize();
393
394 virtual bool DoKeyInput(const KeyEvent& rKEvt) override;
395
396public:
397 SvxFontNameBox_Impl(vcl::Window* pParent, const Reference<XDispatchProvider>& rDispatchProvider,
398 const Reference<XFrame>& rFrame, SvxFontNameToolBoxControl& rCtrl);
399
400 virtual void dispose() override
401 {
402 m_xWidget.reset();
403 InterimItemWindow::dispose();
404 }
405
406 virtual ~SvxFontNameBox_Impl() override
407 {
408 disposeOnce();
409 }
410
411 virtual Reference< css::accessibility::XAccessible > CreateAccessible() override;
412
413 virtual void set_sensitive(bool bSensitive) override
414 {
415 m_xWidget->set_sensitive(bSensitive);
416 if (bSensitive)
417 InterimItemWindow::Enable();
418 else
419 InterimItemWindow::Disable();
420 }
421};
422
423
424// SelectHdl needs the Modifiers, get them in MouseButtonUp
425class SvxFrmValueSet_Impl final : public ValueSet
426{
427private:
428 sal_uInt16 nModifier;
429
430 virtual bool MouseButtonUp(const MouseEvent& rMEvt) override
431 {
432 nModifier = rMEvt.GetModifier();
433 return ValueSet::MouseButtonUp(rMEvt);
434 }
435
436public:
437 SvxFrmValueSet_Impl()
438 : ValueSet(nullptr)
439 , nModifier(0)
440 {
441 }
442 sal_uInt16 GetModifier() const {return nModifier;}
443};
444
445}
446
447namespace {
448
449class SvxFrameToolBoxControl;
450
451class SvxFrameWindow_Impl final : public WeldToolbarPopup
452{
453private:
454 rtl::Reference<SvxFrameToolBoxControl> mxControl;
455 std::unique_ptr<SvxFrmValueSet_Impl> mxFrameSet;
456 std::unique_ptr<weld::CustomWeld> mxFrameSetWin;
457 std::vector<BitmapEx> aImgVec;
458 bool bParagraphMode;
459
460 void InitImageList();
461 void CalcSizeValueSet();
462 DECL_LINK( SelectHdl, ValueSet*, void )static void LinkStubSelectHdl(void *, ValueSet*); void SelectHdl
(ValueSet*)
;
463
464public:
465 SvxFrameWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
466 virtual void GrabFocus() override
467 {
468 mxFrameSet->GrabFocus();
469 }
470
471 virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
472};
473
474class SvxFrameToolBoxControl : public svt::PopupWindowController
475{
476public:
477 explicit SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext );
478
479 // XInitialization
480 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) override;
481
482 // XServiceInfo
483 virtual OUString SAL_CALL getImplementationName() override;
484 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
485
486 virtual void SAL_CALL execute(sal_Int16 nKeyModifier) override;
487private:
488 virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
489 virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
490};
491
492 class LineListBox final : public ValueSet
493 {
494 public:
495 typedef Color (*ColorFunc)(Color);
496 typedef Color (*ColorDistFunc)(Color, Color);
497
498 LineListBox();
499
500 /** Set the width in Twips */
501 Size SetWidth( long nWidth )
502 {
503 long nOldWidth = m_nWidth;
504 m_nWidth = nWidth;
505 return UpdateEntries( nOldWidth );
506 }
507
508 void SetNone( const OUString& sNone )
509 {
510 m_sNone = sNone;
511 }
512
513 /** Insert a listbox entry with all widths in Twips. */
514 void InsertEntry(const BorderWidthImpl& rWidthImpl,
515 SvxBorderLineStyle nStyle, long nMinWidth = 0,
516 ColorFunc pColor1Fn = &sameColor,
517 ColorFunc pColor2Fn = &sameColor,
518 ColorDistFunc pColorDistFn = &sameDistColor);
519
520 SvxBorderLineStyle GetEntryStyle( sal_Int32 nPos ) const;
521
522 SvxBorderLineStyle GetSelectEntryStyle() const;
523
524 void SetSourceUnit( FieldUnit eNewUnit ) { eSourceUnit = eNewUnit; }
525
526 const Color& GetColor() const { return aColor; }
527
528 virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
529 private:
530
531 void ImpGetLine(long nLine1, long nLine2, long nDistance,
532 Color nColor1, Color nColor2, Color nColorDist,
533 SvxBorderLineStyle nStyle, BitmapEx& rBmp);
534
535 void UpdatePaintLineColor(); // returns sal_True if maPaintCol has changed
536
537 Size UpdateEntries( long nOldWidth );
538 sal_Int32 GetStylePos( sal_Int32 nListPos, long nWidth );
539
540 const Color& GetPaintColor() const
541 {
542 return maPaintCol;
543 }
544
545 Color GetColorLine1( sal_Int32 nPos );
546 Color GetColorLine2( sal_Int32 nPos );
547 Color GetColorDist( sal_Int32 nPos );
548
549 LineListBox( const LineListBox& ) = delete;
550 LineListBox& operator =( const LineListBox& ) = delete;
551
552 std::vector<std::unique_ptr<ImpLineListData>> m_vLineList;
553 long m_nWidth;
554 OUString m_sNone;
555 ScopedVclPtr<VirtualDevice> aVirDev;
556 Size aTxtSize;
557 Color const aColor;
558 Color maPaintCol;
559 FieldUnit eSourceUnit;
560 };
561
562 SvxBorderLineStyle LineListBox::GetSelectEntryStyle() const
563 {
564 SvxBorderLineStyle nStyle = SvxBorderLineStyle::SOLID;
565 size_t nPos = GetSelectItemPos();
566 if (nPos != VALUESET_ITEM_NOTFOUND(size_t(-1)))
567 {
568 if (!m_sNone.isEmpty())
569 --nPos;
570 nStyle = GetEntryStyle( nPos );
571 }
572
573 return nStyle;
574 }
575
576 void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
577 Color aColor1, Color aColor2, Color aColorDist,
578 SvxBorderLineStyle nStyle, BitmapEx& rBmp )
579 {
580 auto nMinWidth = GetDrawingArea()->get_ref_device().approximate_digit_width() * COMBO_WIDTH_IN_CHARS18;
581 Size aSize(nMinWidth, aTxtSize.Height());
582 aSize.AdjustWidth( -(aTxtSize.Width()) );
583 aSize.AdjustWidth( -6 );
584
585 // SourceUnit to Twips
586 if ( eSourceUnit == FieldUnit::POINT )
587 {
588 nLine1 /= 5;
589 nLine2 /= 5;
590 nDistance /= 5;
591 }
592
593 // Paint the lines
594 aSize = aVirDev->PixelToLogic( aSize );
595 long nPix = aVirDev->PixelToLogic( Size( 0, 1 ) ).Height();
596 sal_uInt32 n1 = nLine1;
597 sal_uInt32 n2 = nLine2;
598 long nDist = nDistance;
599 n1 += nPix-1;
600 n1 -= n1%nPix;
601 if ( n2 )
602 {
603 nDist += nPix-1;
604 nDist -= nDist%nPix;
605 n2 += nPix-1;
606 n2 -= n2%nPix;
607 }
608 long nVirHeight = n1+nDist+n2;
609 if ( nVirHeight > aSize.Height() )
610 aSize.setHeight( nVirHeight );
611 // negative width should not be drawn
612 if ( aSize.Width() <= 0 )
613 return;
614
615 Size aVirSize = aVirDev->LogicToPixel( aSize );
616 if ( aVirDev->GetOutputSizePixel() != aVirSize )
617 aVirDev->SetOutputSizePixel( aVirSize );
618 aVirDev->SetFillColor( aColorDist );
619 aVirDev->DrawRect( tools::Rectangle( Point(), aSize ) );
620
621 aVirDev->SetFillColor( aColor1 );
622
623 double y1 = double( n1 ) / 2;
624 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y1 ), basegfx::B2DPoint( aSize.Width( ), y1 ), n1, nStyle );
625
626 if ( n2 )
627 {
628 double y2 = n1 + nDist + double( n2 ) / 2;
629 aVirDev->SetFillColor( aColor2 );
630 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, SvxBorderLineStyle::SOLID );
631 }
632 rBmp = aVirDev->GetBitmapEx( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
633 }
634
635 LineListBox::LineListBox()
636 : ValueSet(nullptr)
637 , m_nWidth( 5 )
638 , m_sNone()
639 , aVirDev(VclPtr<VirtualDevice>::Create())
640 , aColor(COL_BLACK)
641 , maPaintCol(COL_BLACK)
642 , eSourceUnit(FieldUnit::POINT)
643 {
644 aVirDev->SetLineColor();
645 aVirDev->SetMapMode( MapMode( MapUnit::MapTwip ) );
646 }
647
648 void LineListBox::SetDrawingArea(weld::DrawingArea* pDrawingArea)
649 {
650 ValueSet::SetDrawingArea(pDrawingArea);
651
652 OutputDevice& rDevice = pDrawingArea->get_ref_device();
653
654 aTxtSize.setWidth( rDevice.approximate_digit_width() );
655 aTxtSize.setHeight( rDevice.GetTextHeight() );
656
657 UpdatePaintLineColor();
658 }
659
660 sal_Int32 LineListBox::GetStylePos( sal_Int32 nListPos, long nWidth )
661 {
662 sal_Int32 nPos = -1;
663 if (!m_sNone.isEmpty())
664 nListPos--;
665
666 sal_Int32 n = 0;
667 size_t i = 0;
668 size_t nCount = m_vLineList.size();
669 while ( nPos == -1 && i < nCount )
670 {
671 auto& pData = m_vLineList[ i ];
672 if ( pData->GetMinWidth() <= nWidth )
673 {
674 if ( nListPos == n )
675 nPos = static_cast<sal_Int32>(i);
676 n++;
677 }
678 i++;
679 }
680
681 return nPos;
682 }
683
684 void LineListBox::InsertEntry(
685 const BorderWidthImpl& rWidthImpl, SvxBorderLineStyle nStyle, long nMinWidth,
686 ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
687 {
688 m_vLineList.emplace_back(new ImpLineListData(
689 rWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn));
690 }
691
692 SvxBorderLineStyle LineListBox::GetEntryStyle( sal_Int32 nPos ) const
693 {
694 ImpLineListData* pData = (0 <= nPos && o3tl::make_unsigned(nPos) < m_vLineList.size()) ? m_vLineList[ nPos ].get() : nullptr;
695 return pData ? pData->GetStyle() : SvxBorderLineStyle::NONE;
696 }
697
698 void LineListBox::UpdatePaintLineColor()
699 {
700 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
701 Color aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
702
703 bool bRet = aNewCol != maPaintCol;
704
705 if( bRet )
706 maPaintCol = aNewCol;
707 }
708
709 Size LineListBox::UpdateEntries( long nOldWidth )
710 {
711 Size aSize;
712
713 UpdatePaintLineColor( );
714
715 sal_Int32 nSelEntry = GetSelectItemPos();
716 sal_Int32 nTypePos = GetStylePos( nSelEntry, nOldWidth );
717
718 // Remove the old entries
719 Clear();
720
721 sal_uInt16 nId(1);
722
723 // Add the new entries based on the defined width
724 if (!m_sNone.isEmpty())
725 InsertItem(nId++, Image(), m_sNone);
726
727 sal_uInt16 n = 0;
728 sal_uInt16 nCount = m_vLineList.size( );
729 while ( n < nCount )
730 {
731 auto& pData = m_vLineList[ n ];
732 if ( pData->GetMinWidth() <= m_nWidth )
733 {
734 BitmapEx aBmp;
735 ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
736 pData->GetLine2ForWidth( m_nWidth ),
737 pData->GetDistForWidth( m_nWidth ),
738 GetColorLine1( GetItemCount( ) ),
739 GetColorLine2( GetItemCount( ) ),
740 GetColorDist( GetItemCount( ) ),
741 pData->GetStyle(), aBmp );
742 InsertItem(nId, Image(aBmp));
743 Size aBmpSize = aBmp.GetSizePixel();
744 if (aBmpSize.Width() > aSize.Width())
745 aSize.setWidth(aBmpSize.getWidth());
746 if (aBmpSize.Height() > aSize.Height())
747 aSize.setHeight(aBmpSize.getHeight());
748 if ( n == nTypePos )
749 SelectItem(nId);
750 }
751 else if ( n == nTypePos )
752 SetNoSelection();
753 n++;
754 ++nId;
755 }
756
757 Invalidate();
758
759 return aSize;
760 }
761
762 Color LineListBox::GetColorLine1( sal_Int32 nPos )
763 {
764 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
765 if (nStyle == -1)
766 return GetPaintColor( );
767 auto& pData = m_vLineList[ nStyle ];
768 return pData->GetColorLine1( GetColor( ) );
769 }
770
771 Color LineListBox::GetColorLine2( sal_Int32 nPos )
772 {
773 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
774 if (nStyle == -1)
775 return GetPaintColor( );
776 auto& pData = m_vLineList[ nStyle ];
777 return pData->GetColorLine2( GetColor( ) );
778 }
779
780 Color LineListBox::GetColorDist( sal_Int32 nPos )
781 {
782 Color rResult = Application::GetSettings().GetStyleSettings().GetFieldColor();
783
784 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
785 if (nStyle == -1)
786 return rResult;
787 auto& pData = m_vLineList[ nStyle ];
788 return pData->GetColorDist( GetColor( ), rResult );
789 }
790}
791
792namespace {
793
794class SvxLineWindow_Impl final : public WeldToolbarPopup
795{
796private:
797 rtl::Reference<SvxFrameToolBoxControl> m_xControl;
798 std::unique_ptr<LineListBox> m_xLineStyleLb;
799 std::unique_ptr<weld::CustomWeld> m_xLineStyleLbWin;
800 bool m_bIsWriter;
801
802 DECL_LINK( SelectHdl, ValueSet*, void )static void LinkStubSelectHdl(void *, ValueSet*); void SelectHdl
(ValueSet*)
;
803
804public:
805 SvxLineWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
806 virtual void GrabFocus() override
807 {
808 m_xLineStyleLb->GrabFocus();
809 }
810};
811
812}
813
814class SvxStyleToolBoxControl;
815
816class SfxStyleControllerItem_Impl : public SfxStatusListener
817{
818 public:
819 SfxStyleControllerItem_Impl( const Reference< XDispatchProvider >& rDispatchProvider,
820 sal_uInt16 nSlotId,
821 const OUString& rCommand,
822 SvxStyleToolBoxControl& rTbxCtl );
823
824 protected:
825 virtual void StateChanged( SfxItemState eState, const SfxPoolItem* pState ) override;
826
827 private:
828 SvxStyleToolBoxControl& rControl;
829};
830
831#define BUTTON_PADDING10 10
832#define ITEM_HEIGHT30 30
833
834SvxStyleBox_Base::SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
835 const OUString& rCommand,
836 SfxStyleFamily eFamily,
837 const Reference< XDispatchProvider >& rDispatchProvider,
838 const Reference< XFrame >& _xFrame,
839 const OUString& rClearFormatKey,
840 const OUString& rMoreKey,
841 bool bInSpec, SvxStyleToolBoxControl& rCtrl)
842 : m_rCtrl(rCtrl)
843 , m_xMenuBuilder(Application::CreateBuilder(nullptr, "svx/ui/stylemenu.ui"))
844 , m_xMenu(m_xMenuBuilder->weld_menu("menu"))
845 , m_xWidget(std::move(xWidget))
846 , eStyleFamily( eFamily )
847 , m_nMaxUserDrawFontWidth(0)
848 , bRelease( true )
849 , m_xDispatchProvider( rDispatchProvider )
850 , m_xFrame(_xFrame)
851 , m_aCommand( rCommand )
852 , aClearFormatKey( rClearFormatKey )
853 , aMoreKey( rMoreKey )
854 , bInSpecialMode( bInSpec )
855{
856 m_xWidget->connect_changed(LINK(this, SvxStyleBox_Base, SelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubSelectHdl)
);
857 m_xWidget->connect_key_press(LINK(this, SvxStyleBox_Base, KeyInputHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubKeyInputHdl)
);
858 m_xWidget->connect_entry_activate(LINK(this, SvxStyleBox_Base, ActivateHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubActivateHdl)
);
859 m_xWidget->connect_focus_out(LINK(this, SvxStyleBox_Base, FocusOutHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubFocusOutHdl)
);
860 m_xWidget->connect_get_property_tree(LINK(this, SvxStyleBox_Base, DumpAsPropertyTreeHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubDumpAsPropertyTreeHdl
)
);
861 m_xWidget->set_help_id(HID_STYLE_LISTBOX"SVX_HID_STYLE_LISTBOX");
862 m_xWidget->set_entry_completion(true);
863 m_xMenu->connect_activate(LINK(this, SvxStyleBox_Base, MenuSelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubMenuSelectHdl)
);
864
865 m_xWidget->connect_custom_get_size(LINK(this, SvxStyleBox_Base, CustomGetSizeHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubCustomGetSizeHdl
)
);
866 m_xWidget->connect_custom_render(LINK(this, SvxStyleBox_Base, CustomRenderHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(this), &SvxStyleBox_Base::LinkStubCustomRenderHdl)
);
867 m_xWidget->set_custom_renderer(true);
868
869 m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS18);
870}
871
872IMPL_LINK(SvxStyleBox_Base, CustomGetSizeHdl, OutputDevice&, rArg, Size)Size SvxStyleBox_Base::LinkStubCustomGetSizeHdl(void * instance
, OutputDevice& data) { return static_cast<SvxStyleBox_Base
*>(instance)->CustomGetSizeHdl(data); } Size SvxStyleBox_Base
::CustomGetSizeHdl(OutputDevice& rArg)
873{
874 CalcOptimalExtraUserWidth(rArg);
875 return Size(m_nMaxUserDrawFontWidth, ITEM_HEIGHT30);
876}
877
878SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
879 const OUString& rCommand,
880 SfxStyleFamily eFamily,
881 const Reference< XDispatchProvider >& rDispatchProvider,
882 const Reference< XFrame >& _xFrame,
883 const OUString& rClearFormatKey,
884 const OUString& rMoreKey,
885 bool bInSpec, SvxStyleToolBoxControl& rCtrl)
886 : InterimItemWindow(pParent, "svx/ui/applystylebox.ui", "ApplyStyleBox")
887 , SvxStyleBox_Base(m_xBuilder->weld_combo_box("applystyle"), rCommand, eFamily,
888 rDispatchProvider, _xFrame, rClearFormatKey, rMoreKey, bInSpec, rCtrl)
889{
890 InitControlBase(m_xWidget.get());
891
892 set_id("applystyle");
893 SetOptimalSize();
894}
895
896void SvxStyleBox_Base::ReleaseFocus()
897{
898 if ( !bRelease )
899 {
900 bRelease = true;
901 return;
902 }
903 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
904 m_xFrame->getContainerWindow()->setFocus();
905}
906
907IMPL_LINK(SvxStyleBox_Base, MenuSelectHdl, const OString&, rMenuIdent, void)void SvxStyleBox_Base::LinkStubMenuSelectHdl(void * instance,
const OString& data) { return static_cast<SvxStyleBox_Base
*>(instance)->MenuSelectHdl(data); } void SvxStyleBox_Base
::MenuSelectHdl(const OString& rMenuIdent)
908{
909 OUString sEntry = m_xWidget->get_active_text();
910
911 ReleaseFocus(); // It must be after getting entry pos!
912 Sequence<PropertyValue> aArgs(2);
913 aArgs[0].Name = "Param";
914 aArgs[0].Value <<= sEntry;
915 aArgs[1].Name = "Family";
916 aArgs[1].Value <<= sal_Int16( eStyleFamily );
917
918 if (rMenuIdent == "update")
919 {
920 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
921 ".uno:StyleUpdateByExample", aArgs );
922 }
923 else if (rMenuIdent == "edit")
924 {
925 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
926 ".uno:EditStyle", aArgs );
927 }
928}
929
930IMPL_STATIC_LINK_NOARG(SvxStyleBox_Base, ShowMoreHdl, void*, void)void SvxStyleBox_Base::LinkStubShowMoreHdl(void * instance, void
* data) { return ShowMoreHdl(static_cast<SvxStyleBox_Base *
>(instance), data); } void SvxStyleBox_Base::ShowMoreHdl( __attribute__
((unused)) SvxStyleBox_Base *, __attribute__ ((unused)) void
*)
931{
932 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
933 DBG_ASSERT( pViewFrm, "SvxStyleBox_Base::Select(): no viewframe" )do { if (true && (!(pViewFrm))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "933" ": "), "%s", "SvxStyleBox_Base::Select(): no viewframe"
); } } while (false)
;
934 if (!pViewFrm)
935 return;
936 pViewFrm->ShowChildWindow(SID_SIDEBAR(10000 + 336));
937 ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel", pViewFrm->GetFrame().GetFrameInterface(), true);
938}
939
940IMPL_LINK(SvxStyleBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)void SvxStyleBox_Base::LinkStubSelectHdl(void * instance, weld
::ComboBox& data) { return static_cast<SvxStyleBox_Base
*>(instance)->SelectHdl(data); } void SvxStyleBox_Base
::SelectHdl(weld::ComboBox& rCombo)
941{
942 Select(rCombo.changed_by_direct_pick()); // only when picked from the list
943}
944
945IMPL_LINK_NOARG(SvxStyleBox_Base, ActivateHdl, weld::ComboBox&, bool)bool SvxStyleBox_Base::LinkStubActivateHdl(void * instance, weld
::ComboBox& data) { return static_cast<SvxStyleBox_Base
*>(instance)->ActivateHdl(data); } bool SvxStyleBox_Base
::ActivateHdl(__attribute__ ((unused)) weld::ComboBox&)
946{
947 Select(true);
948 return true;
949}
950
951void SvxStyleBox_Base::Select(bool bNonTravelSelect)
952{
953 if (!bNonTravelSelect)
954 return;
955
956 OUString aSearchEntry(m_xWidget->get_active_text());
957 bool bDoIt = true, bClear = false;
958 if( bInSpecialMode )
959 {
960 if( aSearchEntry == aClearFormatKey && m_xWidget->get_active() == 0 )
961 {
962 aSearchEntry = sDefaultStyle;
963 bClear = true;
964 //not only apply default style but also call 'ClearFormatting'
965 Sequence< PropertyValue > aEmptyVals;
966 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:ResetAttributes",
967 aEmptyVals);
968 }
969 else if (aSearchEntry == aMoreKey && m_xWidget->get_active() == (m_xWidget->get_count() - 1))
970 {
971 Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Base, ShowMoreHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxStyleBox_Base
*>(nullptr), &SvxStyleBox_Base::LinkStubShowMoreHdl)
);
972 //tdf#113214 change text back to previous entry
973 set_active_or_entry_text(m_xWidget->get_saved_value());
974 bDoIt = false;
975 }
976 }
977
978 //Do we need to create a new style?
979 SfxObjectShell *pShell = SfxObjectShell::Current();
980 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
981 SfxStyleSheetBase* pStyle = nullptr;
982
983 bool bCreateNew = false;
984
985 if ( pPool )
986 {
987 pStyle = pPool->First(eStyleFamily);
988 while ( pStyle && pStyle->GetName() != aSearchEntry )
989 pStyle = pPool->Next();
990 }
991
992 if ( !pStyle )
993 {
994 // cannot find the style for whatever reason
995 // therefore create a new style
996 bCreateNew = true;
997 }
998
999 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1000 This instance may be deleted in the meantime (i.e. when a dialog is opened
1001 while in Dispatch()), accessing members will crash in this case. */
1002 ReleaseFocus();
1003
1004 if( !bDoIt )
1005 return;
1006
1007 if ( bClear )
1008 set_active_or_entry_text(aSearchEntry);
1009 m_xWidget->save_value();
1010
1011 Sequence< PropertyValue > aArgs( 2 );
1012 aArgs[0].Value <<= aSearchEntry;
1013 aArgs[1].Name = "Family";
1014 aArgs[1].Value <<= sal_Int16( eStyleFamily );
1015 if( bCreateNew )
1016 {
1017 aArgs[0].Name = "Param";
1018 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:StyleNewByExample", aArgs);
1019 }
1020 else
1021 {
1022 aArgs[0].Name = "Template";
1023 SfxToolBoxControl::Dispatch( m_xDispatchProvider, m_aCommand, aArgs );
1024 }
1025}
1026
1027void SvxStyleBox_Base::SetFamily( SfxStyleFamily eNewFamily )
1028{
1029 eStyleFamily = eNewFamily;
1030}
1031
1032IMPL_LINK_NOARG(SvxStyleBox_Base, FocusOutHdl, weld::Widget&, void)void SvxStyleBox_Base::LinkStubFocusOutHdl(void * instance, weld
::Widget& data) { return static_cast<SvxStyleBox_Base *
>(instance)->FocusOutHdl(data); } void SvxStyleBox_Base
::FocusOutHdl(__attribute__ ((unused)) weld::Widget&)
1033{
1034 if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1035 set_active_or_entry_text(m_xWidget->get_saved_value());
1036}
1037
1038IMPL_LINK(SvxStyleBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)bool SvxStyleBox_Base::LinkStubKeyInputHdl(void * instance, const
KeyEvent& data) { return static_cast<SvxStyleBox_Base
*>(instance)->KeyInputHdl(data); } bool SvxStyleBox_Base
::KeyInputHdl(const KeyEvent& rKEvt)
1039{
1040 return DoKeyInput(rKEvt);
1041}
1042
1043bool SvxStyleBox_Base::DoKeyInput(const KeyEvent& rKEvt)
1044{
1045 bool bHandled = false;
1046
1047 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1048
1049 switch (nCode)
1050 {
1051 case KEY_TAB:
1052 bRelease = false;
1053 Select(true);
1054 break;
1055 case KEY_ESCAPE:
1056 set_active_or_entry_text(m_xWidget->get_saved_value());
1057 if (!m_rCtrl.IsInSidebar())
1058 {
1059 ReleaseFocus();
1060 bHandled = true;
1061 }
1062 break;
1063 }
1064
1065 return bHandled;
1066}
1067
1068bool SvxStyleBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
1069{
1070 return SvxStyleBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
1071}
1072
1073void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1074{
1075 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1076 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1077 {
1078 SetOptimalSize();
1079 }
1080
1081 InterimItemWindow::DataChanged( rDCEvt );
1082}
1083
1084bool SvxStyleBox_Base::AdjustFontForItemHeight(OutputDevice& rDevice, tools::Rectangle const & rTextRect, long nHeight)
1085{
1086 if (rTextRect.Bottom() > nHeight)
1087 {
1088 // the text does not fit, adjust the font size
1089 double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
1090 vcl::Font aFont(rDevice.GetFont());
1091 Size aPixelSize(aFont.GetFontSize());
1092 aPixelSize.setWidth( aPixelSize.Width() * ratio );
1093 aPixelSize.setHeight( aPixelSize.Height() * ratio );
1094 aFont.SetFontSize(aPixelSize);
1095 rDevice.SetFont(aFont);
1096 return true;
1097 }
1098 return false;
1099}
1100
1101void SvxStyleBox_Impl::SetOptimalSize()
1102{
1103 // set width in chars low so the size request will not be overridden
1104 m_xWidget->set_entry_width_chars(1);
1105 // tdf#132338 purely using this calculation to keep things their traditional width
1106 Size aSize(LogicToPixel(Size(COMBO_WIDTH_IN_CHARS18 * 4, 0), MapMode(MapUnit::MapAppFont)));
1107 m_xWidget->set_size_request(aSize.Width(), -1);
1108
1109 SetSizePixel(get_preferred_size());
1110}
1111
1112void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const OUString &rStyleName)
1113{
1114 // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
1115 // nBorder, and we are adding 1 in order to look better when
1116 // italics is present
1117 const int nLeftDistance = 8;
1118
1119 tools::Rectangle aTextRect;
1120 rRenderContext.GetTextBoundRect(aTextRect, rStyleName);
1121
1122 Point aPos(rRect.TopLeft());
1123 aPos.AdjustX(nLeftDistance );
1124
1125 if (!AdjustFontForItemHeight(rRenderContext, aTextRect, rRect.GetHeight()))
1126 aPos.AdjustY((rRect.GetHeight() - aTextRect.Bottom() ) / 2);
1127
1128 rRenderContext.DrawText(aPos, rStyleName);
1129}
1130
1131void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected)
1132{
1133 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1134 if (!bIsNotSelected)
1135 rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
1136 else
1137 rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
1138
1139 // handle the push-button
1140 if (!bIsNotSelected)
1141 {
1142 if (nItem == 0 || nItem == m_xWidget->get_count() - 1)
1143 m_xWidget->set_item_menu(OString::number(nItem), nullptr);
1144 else
1145 m_xWidget->set_item_menu(OString::number(nItem), m_xMenu.get());
1146 }
1147
1148 if (nItem <= 0 || nItem >= m_xWidget->get_count() - 1)
1149 return;
1150
1151 SfxObjectShell *pShell = SfxObjectShell::Current();
1152 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
1153 SfxStyleSheetBase* pStyle = nullptr;
1154
1155 if ( pPool )
1156 {
1157 pStyle = pPool->First(eStyleFamily);
1158 while (pStyle && pStyle->GetName() != rStyleName)
1159 pStyle = pPool->Next();
1160 }
1161
1162 if (!pStyle )
1163 return;
1164
1165 std::unique_ptr<const SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
1166 if (!pItemSet) return;
1167
1168 const SvxFontItem * const pFontItem =
1169 pItemSet->GetItem<SvxFontItem>(SID_ATTR_CHAR_FONT( 10000 + 7 ));
1170 const SvxFontHeightItem * const pFontHeightItem =
1171 pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ));
1172
1173 if ( !(pFontItem && pFontHeightItem) )
1174 return;
1175
1176 Size aFontSize( 0, pFontHeightItem->GetHeight() );
1177 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
1178
1179 // setup the font properties
1180 SvxFont aFont;
1181 aFont.SetFamilyName(pFontItem->GetFamilyName());
1182 aFont.SetStyleName(pFontItem->GetStyleName());
1183 aFont.SetFontSize(aPixelSize);
1184
1185 const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_WEIGHT( 10000 + 9 ) );
1186 if ( pItem )
1187 aFont.SetWeight( static_cast< const SvxWeightItem* >( pItem )->GetWeight() );
1188
1189 pItem = pItemSet->GetItem( SID_ATTR_CHAR_POSTURE( 10000 + 8 ) );
1190 if ( pItem )
1191 aFont.SetItalic( static_cast< const SvxPostureItem* >( pItem )->GetPosture() );
1192
1193 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR( 10000 + 12 ) );
1194 if ( pItem )
1195 aFont.SetOutline( static_cast< const SvxContourItem* >( pItem )->GetValue() );
1196
1197 pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED( 10000 + 10 ) );
1198 if ( pItem )
1199 aFont.SetShadow( static_cast< const SvxShadowedItem* >( pItem )->GetValue() );
1200
1201 pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF( 10000 + 920 ) );
1202 if ( pItem )
1203 aFont.SetRelief( static_cast< const SvxCharReliefItem* >( pItem )->GetValue() );
1204
1205 pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ) );
1206 if ( pItem )
1207 aFont.SetUnderline( static_cast< const SvxUnderlineItem* >( pItem )->GetLineStyle() );
1208
1209 pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE( ((10000 + 1499) + 1) + 68 ) );
1210 if ( pItem )
1211 aFont.SetOverline( static_cast< const SvxOverlineItem* >( pItem )->GetValue() );
1212
1213 pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT( 10000 + 13 ) );
1214 if ( pItem )
1215 aFont.SetStrikeout( static_cast< const SvxCrossedOutItem* >( pItem )->GetStrikeout() );
1216
1217 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP( 10000 + 19 ) );
1218 if ( pItem )
1219 aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
1220
1221 pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK( 10000 + 899 ) );
1222 if ( pItem )
1223 aFont.SetEmphasisMark( static_cast< const SvxEmphasisMarkItem* >( pItem )->GetEmphasisMark() );
1224
1225 // setup the device & draw
1226 Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
1227
1228 rRenderContext.SetFont(aFont);
1229
1230 pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR( 10000 + 17 ) );
1231 // text color, when nothing is selected
1232 if ( (nullptr != pItem) && bIsNotSelected)
1233 aFontCol = static_cast< const SvxColorItem* >( pItem )->GetValue();
1234
1235 drawing::FillStyle style = drawing::FillStyle_NONE;
1236 // which kind of Fill style is selected
1237 pItem = pItemSet->GetItem( XATTR_FILLSTYLE );
1238 // only when ok and not selected
1239 if ( (nullptr != pItem) && bIsNotSelected)
1240 style = static_cast< const XFillStyleItem* >( pItem )->GetValue();
1241
1242 switch(style)
1243 {
1244 case drawing::FillStyle_SOLID:
1245 {
1246 // set background color
1247 pItem = pItemSet->GetItem( XATTR_FILLCOLOR );
1248 if ( nullptr != pItem )
1249 aBackCol = static_cast< const XFillColorItem* >( pItem )->GetColorValue();
1250
1251 if ( aBackCol != COL_AUTO )
1252 {
1253 rRenderContext.SetFillColor(aBackCol);
1254 rRenderContext.DrawRect(rRect);
1255 }
1256 }
1257 break;
1258
1259 default: break;
1260 //TODO Draw the other background styles: gradient, hatching and bitmap
1261 }
1262
1263 // when the font and background color are too similar, adjust the Font-Color
1264 if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
1265 aFontCol = TestColorsVisible(aFontCol, (aBackCol != COL_AUTO) ? aBackCol : rRenderContext.GetBackground().GetColor());
1266
1267 // set text color
1268 if ( aFontCol != COL_AUTO )
1269 rRenderContext.SetTextColor(aFontCol);
1270}
1271
1272IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, weld::ComboBox::render_args, aPayload, void)void SvxStyleBox_Base::LinkStubCustomRenderHdl(void * instance
, weld::ComboBox::render_args data) { return static_cast<SvxStyleBox_Base
*>(instance)->CustomRenderHdl(data); } void SvxStyleBox_Base
::CustomRenderHdl(weld::ComboBox::render_args aPayload)
1273{
1274 vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
1275 const ::tools::Rectangle& rRect = std::get<1>(aPayload);
1276 bool bSelected = std::get<2>(aPayload);
1277 const OUString& rId = std::get<3>(aPayload);
1278
1279 sal_uInt32 nIndex = rId.toUInt32();
1280
1281 OUString aStyleName(m_xWidget->get_text(nIndex));
1282
1283 rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
1284
1285 SetupEntry(rRenderContext, nIndex, rRect, aStyleName, !bSelected);
1286
1287 UserDrawEntry(rRenderContext, rRect, aStyleName);
1288
1289 rRenderContext.Pop();
1290}
1291
1292void SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext)
1293{
1294 if (m_nMaxUserDrawFontWidth)
1295 return;
1296
1297 long nMaxNormalFontWidth = 0;
1298 sal_Int32 nEntryCount = m_xWidget->get_count();
1299 for (sal_Int32 i = 0; i < nEntryCount; ++i)
1300 {
1301 OUString sStyleName(get_text(i));
1302 tools::Rectangle aTextRectForDefaultFont;
1303 rRenderContext.GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
1304
1305 const long nWidth = aTextRectForDefaultFont.GetWidth();
1306
1307 nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
1308 }
1309
1310 m_nMaxUserDrawFontWidth = nMaxNormalFontWidth;
1311 for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
1312 {
1313 OUString sStyleName(get_text(i));
1314
1315 rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
1316 SetupEntry(rRenderContext, i, tools::Rectangle(0, 0, RECT_MAX9223372036854775807L, ITEM_HEIGHT30), sStyleName, true);
1317 tools::Rectangle aTextRectForActualFont;
1318 rRenderContext.GetTextBoundRect(aTextRectForActualFont, sStyleName);
1319 if (AdjustFontForItemHeight(rRenderContext, aTextRectForActualFont, ITEM_HEIGHT30))
1320 {
1321 //Font didn't fit, so it was changed, refetch with final font size
1322 rRenderContext.GetTextBoundRect(aTextRectForActualFont, sStyleName);
1323 }
1324 rRenderContext.Pop();
1325
1326 const int nWidth = aTextRectForActualFont.GetWidth() + m_xWidget->get_menu_button_width() + BUTTON_PADDING10;
1327
1328 m_nMaxUserDrawFontWidth = std::max(nWidth, m_nMaxUserDrawFontWidth);
1329 }
1330}
1331
1332// test is the color between Font- and background-color to be identify
1333// return is always the Font-Color
1334// when both light or dark, change the Contrast
1335// in other case do not change the origin color
1336// when the color is R=G=B=128 the DecreaseContrast make 128 the need an exception
1337Color SvxStyleBox_Base::TestColorsVisible(const Color &FontCol, const Color &BackCol)
1338{
1339 constexpr sal_uInt8 ChgVal = 60; // increase/decrease the Contrast
1340
1341 Color retCol = FontCol;
1342 if ((FontCol.IsDark() == BackCol.IsDark()) && (FontCol.IsBright() == BackCol.IsBright()))
1343 {
1344 sal_uInt8 lumi = retCol.GetLuminance();
1345
1346 if((lumi > 120) && (lumi < 140))
1347 retCol.DecreaseLuminance(ChgVal / 2);
1348 else
1349 retCol.DecreaseContrast(ChgVal);
1350 }
1351
1352 return retCol;
1353}
1354
1355IMPL_LINK(SvxStyleBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)void SvxStyleBox_Base::LinkStubDumpAsPropertyTreeHdl(void * instance
, tools::JsonWriter& data) { return static_cast<SvxStyleBox_Base
*>(instance)->DumpAsPropertyTreeHdl(data); } void SvxStyleBox_Base
::DumpAsPropertyTreeHdl(tools::JsonWriter& rJsonWriter)
1356{
1357 {
1358 auto entriesNode = rJsonWriter.startNode("entries");
1359 for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
1360 {
1361 auto entryNode = rJsonWriter.startNode("");
1362 rJsonWriter.put("", m_xWidget->get_text(i));
1363 }
1364 }
1365
1366 int nActive = m_xWidget->get_active();
1367 rJsonWriter.put("selectedCount", static_cast<sal_Int32>(nActive == -1 ? 0 : 1));
1368
1369 {
1370 auto selectedNode = rJsonWriter.startNode("selectedEntries");
1371 if (nActive != -1)
1372 {
1373 auto node = rJsonWriter.startNode("");
1374 rJsonWriter.put("", static_cast<sal_Int32>(nActive));
1375 }
1376 }
1377
1378 rJsonWriter.put("command", ".uno:StyleApply");
1379}
1380
1381static bool lcl_GetDocFontList(const FontList** ppFontList, SvxFontNameBox_Base* pBox)
1382{
1383 bool bChanged = false;
1384 const SfxObjectShell* pDocSh = SfxObjectShell::Current();
1385 const SvxFontListItem* pFontListItem = nullptr;
1386
1387 if ( pDocSh )
1388 pFontListItem =
1389 static_cast<const SvxFontListItem*>(pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST( 10000 + 22 ) ));
1390 else
1391 {
1392 ::std::unique_ptr<FontList> aFontList(new FontList(Application::GetDefaultDevice()));
1393 *ppFontList = aFontList.get();
1394 pBox->SetOwnFontList(std::move(aFontList));
1395 bChanged = true;
1396 }
1397
1398 if ( pFontListItem )
1399 {
1400 const FontList* pNewFontList = pFontListItem->GetFontList();
1401 DBG_ASSERT( pNewFontList, "Doc-FontList not available!" )do { if (true && (!(pNewFontList))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "1401" ": "), "%s", "Doc-FontList not available!"); } } while
(false)
;
1402
1403 // No old list, but a new list
1404 if ( !*ppFontList && pNewFontList )
1405 {
1406 // => take over
1407 *ppFontList = pNewFontList;
1408 bChanged = true;
1409 }
1410 else
1411 {
1412 // Comparing the font lists is not perfect.
1413 // When you change the font list in the Doc, you can track
1414 // changes here only on the Listbox, because ppFontList
1415 // has already been updated.
1416 bChanged =
1417 ( ( *ppFontList != pNewFontList ) ||
1418 pBox->GetListCount() != pNewFontList->GetFontNameCount() );
1419 // HACK: Comparing is incomplete
1420
1421 if ( bChanged )
1422 *ppFontList = pNewFontList;
1423 }
1424
1425 if ( pBox )
1426 pBox->set_sensitive(true);
1427 }
1428 else if ( pBox && ( pDocSh || !ppFontList ))
1429 {
1430 // Disable box only when we have a SfxObjectShell and didn't get a font list OR
1431 // we don't have a SfxObjectShell and no current font list.
1432 // It's possible that we currently have no SfxObjectShell, but a current font list.
1433 // See #i58471: When a user set the focus into the font name combo box and opens
1434 // the help window with F1. After closing the help window, we disable the font name
1435 // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
1436 // font list hasn't changed and therefore the combo box shouldn't be disabled!
1437 pBox->set_sensitive(false);
1438 }
1439
1440 // Fill the FontBox, also the new list if necessary
1441 if ( pBox && bChanged )
1442 {
1443 if ( *ppFontList )
1444 pBox->Fill( *ppFontList );
1445 else
1446 pBox->Clear();
1447 }
1448 return bChanged;
1449}
1450
1451SvxFontNameBox_Base::SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
1452 const Reference<XDispatchProvider>& rDispatchProvider,
1453 const Reference<XFrame>& rFrame,
1454 SvxFontNameToolBoxControl& rCtrl)
1455 : m_xListener(new comphelper::ConfigurationListener("/org.openoffice.Office.Common/Font/View"))
1456 , m_aWYSIWYG(m_xListener, "ShowFontBoxWYSIWYG", *this)
1457 , m_aHistory(m_xListener, "History", *this)
1458 , m_rCtrl(rCtrl)
1459 , m_xWidget(new FontNameBox(std::move(xWidget)))
1460 , pFontList(nullptr)
1461 , nFtCount(0)
1462 , bRelease(true)
1463 , m_xDispatchProvider(rDispatchProvider)
1464 , m_xFrame(rFrame)
1465 , mbCheckingUnknownFont(false)
1466{
1467 EnableControls();
1468
1469 m_xWidget->connect_changed(LINK(this, SvxFontNameBox_Base, SelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubSelectHdl)
);
1470 m_xWidget->connect_key_press(LINK(this, SvxFontNameBox_Base, KeyInputHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubKeyInputHdl)
);
1471 m_xWidget->connect_entry_activate(LINK(this, SvxFontNameBox_Base, ActivateHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubActivateHdl)
);
1472 m_xWidget->connect_focus_in(LINK(this, SvxFontNameBox_Base, FocusInHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubFocusInHdl)
);
1473 m_xWidget->connect_focus_out(LINK(this, SvxFontNameBox_Base, FocusOutHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubFocusOutHdl)
);
1474 m_xWidget->connect_get_property_tree(LINK(this, SvxFontNameBox_Base, DumpAsPropertyTreeHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxFontNameBox_Base
*>(this), &SvxFontNameBox_Base::LinkStubDumpAsPropertyTreeHdl
)
);
1475
1476 m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS18);
1477}
1478
1479SvxFontNameBox_Impl::SvxFontNameBox_Impl(vcl::Window* pParent, const Reference<XDispatchProvider>& rDispatchProvider,
1480 const Reference<XFrame>& rFrame, SvxFontNameToolBoxControl& rCtrl)
1481 : InterimItemWindow(pParent, "svx/ui/fontnamebox.ui", "FontNameBox")
1482 , SvxFontNameBox_Base(m_xBuilder->weld_combo_box("fontnamecombobox"), rDispatchProvider, rFrame, rCtrl)
1483{
1484 set_id("fontnamecombobox");
1485 SetOptimalSize();
1486}
1487
1488void SvxFontNameBox_Base::FillList()
1489{
1490 if (!m_xWidget) // e.g. disposed
1491 return;
1492 // Save old Selection, set back in the end
1493 int nStartPos, nEndPos;
1494 m_xWidget->get_entry_selection_bounds(nStartPos, nEndPos);
1495
1496 // Did Doc-Fontlist change?
1497 lcl_GetDocFontList(&pFontList, this);
1498
1499 m_xWidget->select_entry_region(nStartPos, nEndPos);
1500}
1501
1502void SvxFontNameBox_Base::CheckAndMarkUnknownFont()
1503{
1504 if (mbCheckingUnknownFont) //tdf#117537 block rentry
1505 return;
1506 mbCheckingUnknownFont = true;
1507 OUString fontname = m_xWidget->get_active_text();
1508 lcl_GetDocFontList( &pFontList, this );
1509 // If the font is unknown, show it in italic.
1510 vcl::Font font = m_xWidget->get_entry_font();
1511 if( pFontList != nullptr && pFontList->IsAvailable( fontname ))
1512 {
1513 if( font.GetItalic() != ITALIC_NONE )
1514 {
1515 font.SetItalic( ITALIC_NONE );
1516 m_xWidget->set_entry_font(font);
1517 m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAMEreinterpret_cast<char const *>("RID_SVXSTR_CHARFONTNAME"
"\004" u8"Font Name")
));
1518 }
1519 }
1520 else
1521 {
1522 if( font.GetItalic() != ITALIC_NORMAL )
1523 {
1524 font.SetItalic( ITALIC_NORMAL );
1525 m_xWidget->set_entry_font(font);
1526 m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME_NOTAVAILABLEreinterpret_cast<char const *>("RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE"
"\004" u8"Font Name. The current font is not available and will be substituted."
)
));
1527 }
1528 }
1529 mbCheckingUnknownFont = false;
1530}
1531
1532void SvxFontNameBox_Base::Update( const css::awt::FontDescriptor* pFontDesc )
1533{
1534 if ( pFontDesc )
1535 {
1536 aCurFont.SetFamilyName ( pFontDesc->Name );
1537 aCurFont.SetFamily ( FontFamily( pFontDesc->Family ) );
1538 aCurFont.SetStyleName ( pFontDesc->StyleName );
1539 aCurFont.SetPitch ( FontPitch( pFontDesc->Pitch ) );
1540 aCurFont.SetCharSet ( rtl_TextEncoding( pFontDesc->CharSet ) );
1541 }
1542 OUString aCurName = aCurFont.GetFamilyName();
1543 OUString aText = m_xWidget->get_active_text();
1544 if (aText != aCurName)
1545 set_active_or_entry_text(aCurName);
1546}
1547
1548void SvxFontNameBox_Base::set_active_or_entry_text(const OUString& rText)
1549{
1550 m_xWidget->set_active_or_entry_text(rText);
1551 CheckAndMarkUnknownFont();
1552}
1553
1554IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusInHdl, weld::Widget&, void)void SvxFontNameBox_Base::LinkStubFocusInHdl(void * instance,
weld::Widget& data) { return static_cast<SvxFontNameBox_Base
*>(instance)->FocusInHdl(data); } void SvxFontNameBox_Base
::FocusInHdl(__attribute__ ((unused)) weld::Widget&)
1555{
1556 FillList();
1557}
1558
1559IMPL_LINK(SvxFontNameBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)bool SvxFontNameBox_Base::LinkStubKeyInputHdl(void * instance
, const KeyEvent& data) { return static_cast<SvxFontNameBox_Base
*>(instance)->KeyInputHdl(data); } bool SvxFontNameBox_Base
::KeyInputHdl(const KeyEvent& rKEvt)
1560{
1561 return DoKeyInput(rKEvt);
1562}
1563
1564bool SvxFontNameBox_Base::DoKeyInput(const KeyEvent& rKEvt)
1565{
1566 bool bHandled = false;
1567
1568 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1569
1570 switch (nCode)
1571 {
1572 case KEY_TAB:
1573 bRelease = false;
1574 Select(true);
1575 break;
1576
1577 case KEY_ESCAPE:
1578 set_active_or_entry_text(m_xWidget->get_saved_value());
1579 if (!m_rCtrl.IsInSidebar())
1580 {
1581 ReleaseFocus_Impl();
1582 bHandled = true;
1583 }
1584 EndPreview();
1585 break;
1586 }
1587
1588 return bHandled;
1589}
1590
1591bool SvxFontNameBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
1592{
1593 return SvxFontNameBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
1594}
1595
1596IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusOutHdl, weld::Widget&, void)void SvxFontNameBox_Base::LinkStubFocusOutHdl(void * instance
, weld::Widget& data) { return static_cast<SvxFontNameBox_Base
*>(instance)->FocusOutHdl(data); } void SvxFontNameBox_Base
::FocusOutHdl(__attribute__ ((unused)) weld::Widget&)
1597{
1598 if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1599 {
1600 set_active_or_entry_text(m_xWidget->get_saved_value());
1601 // send EndPreview
1602 EndPreview();
1603 }
1604}
1605
1606void SvxFontNameBox_Impl::SetOptimalSize()
1607{
1608 // set width in chars low so the size request will not be overridden
1609 m_xWidget->set_entry_width_chars(1);
1610 // tdf#132338 purely using this calculation to keep things their traditional width
1611 Size aSize(LogicToPixel(Size(COMBO_WIDTH_IN_CHARS18 * 4, 0), MapMode(MapUnit::MapAppFont)));
1612 m_xWidget->set_size_request(aSize.Width(), -1);
1613
1614 SetSizePixel(get_preferred_size());
1615}
1616
1617void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1618{
1619 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1620 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1621 {
1622 SetOptimalSize();
1623 }
1624 else if ( ( rDCEvt.GetType() == DataChangedEventType::FONTS ) ||
1625 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) )
1626 {
1627 // The old font list in shell has likely been destroyed at this point, so we need to get
1628 // the new one before doing anything further.
1629 lcl_GetDocFontList( &pFontList, this );
1630 }
1631}
1632
1633void SvxFontNameBox_Base::ReleaseFocus_Impl()
1634{
1635 if ( !bRelease )
1636 {
1637 bRelease = true;
1638 return;
1639 }
1640 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
1641 m_xFrame->getContainerWindow()->setFocus();
1642}
1643
1644void SvxFontNameBox_Base::EnableControls()
1645{
1646 bool bEnableMRU = m_aHistory.get();
1647 sal_uInt16 nEntries = bEnableMRU ? MAX_MRU_FONTNAME_ENTRIES5 : 0;
1648
1649 bool bNewWYSIWYG = m_aWYSIWYG.get();
1650 bool bOldWYSIWYG = m_xWidget->IsWYSIWYGEnabled();
1651
1652 if (m_xWidget->get_max_mru_count() != nEntries || bNewWYSIWYG != bOldWYSIWYG)
1653 {
1654 // refill in the next GetFocus-Handler
1655 pFontList = nullptr;
1656 Clear();
1657 m_xWidget->set_max_mru_count(nEntries);
1658 }
1659
1660 if (bNewWYSIWYG != bOldWYSIWYG)
1661 m_xWidget->EnableWYSIWYG(bNewWYSIWYG);
1662}
1663
1664IMPL_LINK(SvxFontNameBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)void SvxFontNameBox_Base::LinkStubSelectHdl(void * instance, weld
::ComboBox& data) { return static_cast<SvxFontNameBox_Base
*>(instance)->SelectHdl(data); } void SvxFontNameBox_Base
::SelectHdl(weld::ComboBox& rCombo)
1665{
1666 Select(rCombo.changed_by_direct_pick()); // only when picked from the list
1667}
1668
1669IMPL_LINK_NOARG(SvxFontNameBox_Base, ActivateHdl, weld::ComboBox&, bool)bool SvxFontNameBox_Base::LinkStubActivateHdl(void * instance
, weld::ComboBox& data) { return static_cast<SvxFontNameBox_Base
*>(instance)->ActivateHdl(data); } bool SvxFontNameBox_Base
::ActivateHdl(__attribute__ ((unused)) weld::ComboBox&)
1670{
1671 Select(true);
1672 return true;
1673}
1674
1675void SvxFontNameBox_Base::Select(bool bNonTravelSelect)
1676{
1677 Sequence< PropertyValue > aArgs( 1 );
1678 std::unique_ptr<SvxFontItem> pFontItem;
1679 if ( pFontList )
1680 {
1681 FontMetric aFontMetric( pFontList->Get(m_xWidget->get_active_text(),
1682 aCurFont.GetWeight(),
1683 aCurFont.GetItalic() ) );
1684 aCurFont = aFontMetric;
1685
1686 pFontItem.reset( new SvxFontItem( aFontMetric.GetFamilyType(),
1687 aFontMetric.GetFamilyName(),
1688 aFontMetric.GetStyleName(),
1689 aFontMetric.GetPitch(),
1690 aFontMetric.GetCharSet(),
1691 SID_ATTR_CHAR_FONT( 10000 + 7 ) ) );
1692
1693 Any a;
1694 pFontItem->QueryValue( a );
1695 aArgs[0].Value = a;
1696 }
1697
1698 if (bNonTravelSelect)
1699 {
1700 CheckAndMarkUnknownFont();
1701 // #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1702 // This instance may be deleted in the meantime (i.e. when a dialog is opened
1703 // while in Dispatch()), accessing members will crash in this case.
1704 ReleaseFocus_Impl();
1705 EndPreview();
1706 if (pFontItem)
1707 {
1708 aArgs[0].Name = "CharFontName";
1709 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1710 ".uno:CharFontName",
1711 aArgs );
1712 }
1713 }
1714 else
1715 {
1716 if (pFontItem)
1717 {
1718 aArgs[0].Name = "CharPreviewFontName";
1719 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1720 ".uno:CharPreviewFontName",
1721 aArgs );
1722 }
1723 }
1724}
1725
1726IMPL_LINK(SvxFontNameBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)void SvxFontNameBox_Base::LinkStubDumpAsPropertyTreeHdl(void *
instance, tools::JsonWriter& data) { return static_cast<
SvxFontNameBox_Base *>(instance)->DumpAsPropertyTreeHdl
(data); } void SvxFontNameBox_Base::DumpAsPropertyTreeHdl(tools
::JsonWriter& rJsonWriter)
1727{
1728 {
1729 auto entriesNode = rJsonWriter.startNode("entries");
1730 for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
1731 {
1732 auto entryNode = rJsonWriter.startNode("");
1733 rJsonWriter.put("", m_xWidget->get_text(i));
1734 }
1735 }
1736
1737 int nSelectedEntry = m_xWidget->get_active();
1738 rJsonWriter.put("selectedCount", static_cast<sal_Int32>(nSelectedEntry == -1 ? 0 : 1));
1739
1740 {
1741 auto selectedNode = rJsonWriter.startNode("selectedEntries");
1742 if (nSelectedEntry != -1)
1743 {
1744 auto entryNode = rJsonWriter.startNode("");
1745 rJsonWriter.put("", m_xWidget->get_text(nSelectedEntry));
1746 }
1747 }
1748
1749 rJsonWriter.put("command", ".uno:CharFontName");
1750}
1751
1752ColorWindow::ColorWindow(const OUString& rCommand,
1753 std::shared_ptr<PaletteManager> const & rPaletteManager,
1754 ColorStatus& rColorStatus,
1755 sal_uInt16 nSlotId,
1756 const Reference< XFrame >& rFrame,
1757 weld::Window* pParentWindow,
1758 const MenuOrToolMenuButton& rMenuButton,
1759 ColorSelectFunction const & aFunction)
1760 : WeldToolbarPopup(rFrame, rMenuButton.get_widget(), "svx/ui/colorwindow.ui", "palette_popup_window")
1761 , theSlotId(nSlotId)
1762 , maCommand(rCommand)
1763 , mpParentWindow(pParentWindow)
1764 , maMenuButton(rMenuButton)
1765 , mxPaletteManager(rPaletteManager)
1766 , mrColorStatus(rColorStatus)
1767 , maColorSelectFunction(aFunction)
1768 , mxColorSet(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin", true)))
1769 , mxRecentColorSet(new SvxColorValueSet(nullptr))
1770 , mxPaletteListBox(m_xBuilder->weld_combo_box("palette_listbox"))
1771 , mxButtonAutoColor(m_xBuilder->weld_button("auto_color_button"))
1772 , mxButtonNoneColor(m_xBuilder->weld_button("none_color_button"))
1773 , mxButtonPicker(m_xBuilder->weld_button("color_picker_button"))
1774 , mxAutomaticSeparator(m_xBuilder->weld_widget("separator4"))
1775 , mxColorSetWin(new weld::CustomWeld(*m_xBuilder, "colorset", *mxColorSet))
1776 , mxRecentColorSetWin(new weld::CustomWeld(*m_xBuilder, "recent_colorset", *mxRecentColorSet))
1777 , mpDefaultButton(nullptr)
1778{
1779 mxColorSet->SetStyle( WinBits(WB_FLATVALUESET(WinBits(0x02000000)) | WB_ITEMBORDER(WinBits(0x00010000)) | WB_3DLOOK | WB_NO_DIRECTSELECT(WinBits(0x04000000)) | WB_TABSTOP) );
1780 mxRecentColorSet->SetStyle( WinBits(WB_FLATVALUESET(WinBits(0x02000000)) | WB_ITEMBORDER(WinBits(0x00010000)) | WB_3DLOOK | WB_NO_DIRECTSELECT(WinBits(0x04000000)) | WB_TABSTOP) );
1781
1782 switch ( theSlotId )
1783 {
1784 case SID_ATTR_CHAR_COLOR_BACKGROUND(10000 + 489):
1785 case SID_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 186 ):
1786 case SID_ATTR_CHAR_BACK_COLOR( 10000 + 1153 ):
1787 case SID_TABLE_CELL_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 1189 ):
1788 {
1789 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_NOFILLreinterpret_cast<char const *>("RID_SVXSTR_NOFILL" "\004"
u8"No Fill")
) );
1790 break;
1791 }
1792 case SID_AUTHOR_COLOR( 10000 + 1168 ):
1793 {
1794 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_BY_AUTHORreinterpret_cast<char const *>("RID_SVXSTR_BY_AUTHOR" "\004"
u8"By author")
) );
1795 break;
1796 }
1797 case SID_BMPMASK_COLOR( 10000 + 1169 ):
1798 {
1799 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_TRANSPARENTreinterpret_cast<char const *>("RID_SVXSTR_TRANSPARENT"
"\004" u8"Transparent")
) );
1800 break;
1801 }
1802 case SID_ATTR_CHAR_COLOR( 10000 + 17 ):
1803 case SID_ATTR_CHAR_COLOR2(10000 + 537):
1804 case SID_EXTRUSION_3D_COLOR( 10000 + 969 ):
1805 {
1806 mxButtonAutoColor->set_label(EditResId(RID_SVXSTR_AUTOMATICreinterpret_cast<char const *>("RID_SVXSTR_AUTOMATIC" "\004"
u8"Automatic")
));
1807 break;
1808 }
1809 case SID_FM_CTL_PROPERTIES( 10000 + 613 ):
1810 {
1811 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_DEFAULTreinterpret_cast<char const *>("RID_SVXSTR_DEFAULT" "\004"
u8"Default")
) );
1812 break;
1813 }
1814 default:
1815 {
1816 mxButtonAutoColor->hide();
1817 mxAutomaticSeparator->hide();
1818 break;
1819 }
1820 }
1821
1822 mxPaletteListBox->connect_changed(LINK(this, ColorWindow, SelectPaletteHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubSelectPaletteHdl)
);
1823 std::vector<OUString> aPaletteList = mxPaletteManager->GetPaletteList();
1824 mxPaletteListBox->freeze();
1825 for (const auto& rPalette : aPaletteList)
1826 mxPaletteListBox->append_text(rPalette);
1827 mxPaletteListBox->thaw();
1828 OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
1829 mxPaletteListBox->set_active_text(aPaletteName);
1830 const int nSelectedEntry(mxPaletteListBox->get_active());
1831 if (nSelectedEntry != -1)
1832 mxPaletteManager->SetPalette(nSelectedEntry);
1833
1834 mxButtonAutoColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubAutoColorClickHdl)
);
1835 mxButtonNoneColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubAutoColorClickHdl)
);
1836 mxButtonPicker->connect_clicked(LINK(this, ColorWindow, OpenPickerClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubOpenPickerClickHdl)
);
1837
1838 mxColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubSelectHdl)
);
1839 mxRecentColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorWindow
*>(this), &ColorWindow::LinkStubSelectHdl)
);
1840 m_xTopLevel->set_help_id(HID_POPUP_COLOR"SVX_HID_POPUP_COLOR");
1841 mxColorSet->SetHelpId(HID_POPUP_COLOR_CTRL"SVX_HID_POPUP_COLOR_CTRL");
1842
1843 mxPaletteManager->ReloadColorSet(*mxColorSet);
1844 const sal_uInt32 nMaxItems(SvxColorValueSet::getMaxRowCount() * SvxColorValueSet::getColumnCount());
1845 Size aSize = mxColorSet->layoutAllVisible(nMaxItems);
1846 mxColorSet->set_size_request(aSize.Width(), aSize.Height());
1847
1848 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
1849 aSize = mxRecentColorSet->layoutAllVisible(mxPaletteManager->GetRecentColorCount());
1850 mxRecentColorSet->set_size_request(aSize.Width(), aSize.Height());
1851
1852 AddStatusListener( ".uno:ColorTableState" );
1853 AddStatusListener( maCommand );
1854 if ( maCommand == ".uno:FrameLineColor" )
1855 {
1856 AddStatusListener( ".uno:BorderTLBR" );
1857 AddStatusListener( ".uno:BorderBLTR" );
1858 }
1859}
1860
1861void ColorWindow::GrabFocus()
1862{
1863 if (mxColorSet->IsNoSelection() && mpDefaultButton)
1864 mpDefaultButton->grab_focus();
1865 else
1866 mxColorSet->GrabFocus();
1867}
1868
1869void ColorWindow::ShowNoneButton()
1870{
1871 mxButtonNoneColor->show();
1872}
1873
1874ColorWindow::~ColorWindow()
1875{
1876}
1877
1878NamedColor ColorWindow::GetSelectEntryColor(ValueSet const * pColorSet)
1879{
1880 Color aColor = pColorSet->GetItemColor(pColorSet->GetSelectedItemId());
1881 OUString sColorName = pColorSet->GetItemText(pColorSet->GetSelectedItemId());
1882 return std::make_pair(aColor, sColorName);
1883}
1884
1885namespace
1886{
1887 NamedColor GetAutoColor(sal_uInt16 nSlotId)
1888 {
1889 Color aColor;
1890 OUString sColorName;
1891 switch (nSlotId)
1892 {
1893 case SID_ATTR_CHAR_COLOR_BACKGROUND(10000 + 489):
1894 case SID_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 186 ):
1895 case SID_ATTR_CHAR_BACK_COLOR( 10000 + 1153 ):
1896 case SID_TABLE_CELL_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 1189 ):
1897 aColor = COL_TRANSPARENT;
1898 sColorName = SvxResId(RID_SVXSTR_NOFILLreinterpret_cast<char const *>("RID_SVXSTR_NOFILL" "\004"
u8"No Fill")
);
1899 break;
1900 case SID_AUTHOR_COLOR( 10000 + 1168 ):
1901 aColor = COL_TRANSPARENT;
1902 sColorName = SvxResId(RID_SVXSTR_BY_AUTHORreinterpret_cast<char const *>("RID_SVXSTR_BY_AUTHOR" "\004"
u8"By author")
);
1903 break;
1904 case SID_BMPMASK_COLOR( 10000 + 1169 ):
1905 aColor = COL_TRANSPARENT;
1906 sColorName = SvxResId(RID_SVXSTR_TRANSPARENTreinterpret_cast<char const *>("RID_SVXSTR_TRANSPARENT"
"\004" u8"Transparent")
);
1907 break;
1908 case SID_FM_CTL_PROPERTIES( 10000 + 613 ):
1909 aColor = COL_TRANSPARENT;
1910 sColorName = SvxResId(RID_SVXSTR_DEFAULTreinterpret_cast<char const *>("RID_SVXSTR_DEFAULT" "\004"
u8"Default")
);
1911 break;
1912 case SID_ATTR_CHAR_COLOR( 10000 + 17 ):
1913 case SID_ATTR_CHAR_COLOR2(10000 + 537):
1914 case SID_EXTRUSION_3D_COLOR( 10000 + 969 ):
1915 default:
1916 aColor = COL_AUTO;
1917 sColorName = EditResId(RID_SVXSTR_AUTOMATICreinterpret_cast<char const *>("RID_SVXSTR_AUTOMATIC" "\004"
u8"Automatic")
);
1918 break;
1919 }
1920
1921 return std::make_pair(aColor, sColorName);
1922 }
1923
1924 NamedColor GetNoneColor()
1925 {
1926 return std::make_pair(COL_NONE_COLOR::Color(0x80, 0xFF, 0xFF, 0xFF), comphelper::LibreOfficeKit::isActive() ? SvxResId(RID_SVXSTR_INVISIBLEreinterpret_cast<char const *>("RID_SVXSTR_INVISIBLE" "\004"
u8"None")
)
1927 : SvxResId(RID_SVXSTR_NONEreinterpret_cast<char const *>("RID_SVXSTR_NONE" "\004"
u8"- none -")
));
1928 }
1929}
1930
1931NamedColor ColorWindow::GetSelectEntryColor() const
1932{
1933 if (!mxColorSet->IsNoSelection())
1934 return GetSelectEntryColor(mxColorSet.get());
1935 if (!mxRecentColorSet->IsNoSelection())
1936 return GetSelectEntryColor(mxRecentColorSet.get());
1937 if (mxButtonNoneColor.get() == mpDefaultButton)
1938 return GetNoneColor();
1939 return GetAutoColor();
1940}
1941
1942IMPL_LINK(ColorWindow, SelectHdl, ValueSet*, pColorSet, void)void ColorWindow::LinkStubSelectHdl(void * instance, ValueSet
* data) { return static_cast<ColorWindow *>(instance)->
SelectHdl(data); } void ColorWindow::SelectHdl(ValueSet* pColorSet
)
1943{
1944 NamedColor aNamedColor = GetSelectEntryColor(pColorSet);
1945
1946 if (pColorSet != mxRecentColorSet.get())
1947 {
1948 mxPaletteManager->AddRecentColor(aNamedColor.first, aNamedColor.second);
1949 if (!maMenuButton.get_active())
1950 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
1951 }
1952
1953 maSelectedLink.Call(aNamedColor);
1954
1955 // deliberate take a copy here in case maMenuButton.set_inactive
1956 // triggers a callback that destroys ourself
1957 ColorSelectFunction aColorSelectFunction(maColorSelectFunction);
1958 OUString sCommand(maCommand);
1959
1960 maMenuButton.set_inactive();
1961
1962 aColorSelectFunction(sCommand, aNamedColor);
1963}
1964
1965IMPL_LINK_NOARG(ColorWindow, SelectPaletteHdl, weld::ComboBox&, void)void ColorWindow::LinkStubSelectPaletteHdl(void * instance, weld
::ComboBox& data) { return static_cast<ColorWindow *>
(instance)->SelectPaletteHdl(data); } void ColorWindow::SelectPaletteHdl
(__attribute__ ((unused)) weld::ComboBox&)
1966{
1967 int nPos = mxPaletteListBox->get_active();
1968 mxPaletteManager->SetPalette( nPos );
1969 mxPaletteManager->ReloadColorSet(*mxColorSet);
1970 mxColorSet->layoutToGivenHeight(mxColorSet->GetOutputSizePixel().Height(), mxPaletteManager->GetColorCount());
1971}
1972
1973NamedColor ColorWindow::GetAutoColor() const
1974{
1975 return ::GetAutoColor(theSlotId);
1976}
1977
1978IMPL_LINK(ColorWindow, AutoColorClickHdl, weld::Button&, rButton, void)void ColorWindow::LinkStubAutoColorClickHdl(void * instance, weld
::Button& data) { return static_cast<ColorWindow *>
(instance)->AutoColorClickHdl(data); } void ColorWindow::AutoColorClickHdl
(weld::Button& rButton)
1979{
1980 NamedColor aNamedColor = &rButton == mxButtonAutoColor.get() ? GetAutoColor() : GetNoneColor();
1981
1982 mxColorSet->SetNoSelection();
1983 mxRecentColorSet->SetNoSelection();
1984 mpDefaultButton = &rButton;
1985
1986 maSelectedLink.Call(aNamedColor);
1987
1988 // deliberate take a copy here in case maMenuButton.set_inactive
1989 // triggers a callback that destroys ourself
1990 ColorSelectFunction aColorSelectFunction(maColorSelectFunction);
1991 OUString sCommand(maCommand);
1992
1993 maMenuButton.set_inactive();
1994
1995 aColorSelectFunction(sCommand, aNamedColor);
1996}
1997
1998IMPL_LINK_NOARG(ColorWindow, OpenPickerClickHdl, weld::Button&, void)void ColorWindow::LinkStubOpenPickerClickHdl(void * instance,
weld::Button& data) { return static_cast<ColorWindow *
>(instance)->OpenPickerClickHdl(data); } void ColorWindow
::OpenPickerClickHdl(__attribute__ ((unused)) weld::Button&
)
1999{
2000 // copy before set_inactive
2001 auto nColor = GetSelectEntryColor().first;
2002 auto pParentWindow = mpParentWindow;
2003 OUString sCommand = maCommand;
2004 std::shared_ptr<PaletteManager> xPaletteManager(mxPaletteManager);
2005
2006 maMenuButton.set_inactive();
2007
2008 xPaletteManager->PopupColorPicker(pParentWindow, sCommand, nColor);
2009}
2010
2011void ColorWindow::SetNoSelection()
2012{
2013 mxColorSet->SetNoSelection();
2014 mxRecentColorSet->SetNoSelection();
2015 mpDefaultButton = nullptr;
2016}
2017
2018bool ColorWindow::IsNoSelection() const
2019{
2020 if (!mxColorSet->IsNoSelection())
2021 return false;
2022 if (!mxRecentColorSet->IsNoSelection())
2023 return false;
2024 return !mxButtonAutoColor->get_visible() && !mxButtonNoneColor->get_visible();
2025}
2026
2027void ColorWindow::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2028{
2029 if (rEvent.FeatureURL.Complete == ".uno:ColorTableState")
2030 {
2031 if (rEvent.IsEnabled && mxPaletteManager->GetPalette() == 0)
2032 {
2033 mxPaletteManager->ReloadColorSet(*mxColorSet);
2034 mxColorSet->layoutToGivenHeight(mxColorSet->GetOutputSizePixel().Height(), mxPaletteManager->GetColorCount());
2035 }
2036 }
2037 else
2038 {
2039 mrColorStatus.statusChanged(rEvent);
2040 SelectEntry(mrColorStatus.GetColor());
2041 }
2042}
2043
2044bool ColorWindow::SelectValueSetEntry(SvxColorValueSet* pColorSet, const Color& rColor)
2045{
2046 for (size_t i = 1; i <= pColorSet->GetItemCount(); ++i)
2047 {
2048 if (rColor == pColorSet->GetItemColor(i))
2049 {
2050 pColorSet->SelectItem(i);
2051 return true;
2052 }
2053 }
2054 return false;
2055}
2056
2057void ColorWindow::SelectEntry(const NamedColor& rNamedColor)
2058{
2059 SetNoSelection();
2060
2061 const Color &rColor = rNamedColor.first;
2062
2063 if (mxButtonAutoColor->get_visible() && (rColor == COL_TRANSPARENT || rColor == COL_AUTO))
2064 {
2065 mpDefaultButton = mxButtonAutoColor.get();
2066 return;
2067 }
2068
2069 if (mxButtonNoneColor->get_visible() && rColor == COL_NONE_COLOR::Color(0x80, 0xFF, 0xFF, 0xFF))
2070 {
2071 mpDefaultButton = mxButtonNoneColor.get();
2072 return;
2073 }
2074
2075 // try current palette
2076 bool bFoundColor = SelectValueSetEntry(mxColorSet.get(), rColor);
2077 // try recently used
2078 if (!bFoundColor)
2079 bFoundColor = SelectValueSetEntry(mxRecentColorSet.get(), rColor);
2080 // if it's not there, add it there now to the end of the recently used
2081 // so its available somewhere handy, but not without trashing the
2082 // whole recently used
2083 if (!bFoundColor)
2084 {
2085 const OUString& rColorName = rNamedColor.second;
2086 mxPaletteManager->AddRecentColor(rColor, rColorName, false);
2087 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2088 SelectValueSetEntry(mxRecentColorSet.get(), rColor);
2089 }
2090}
2091
2092void ColorWindow::SelectEntry(const Color& rColor)
2093{
2094 OUString sColorName = "#" + rColor.AsRGBHexString().toAsciiUpperCase();
2095 ColorWindow::SelectEntry(std::make_pair(rColor, sColorName));
2096}
2097
2098ColorStatus::ColorStatus() :
2099 maColor( COL_TRANSPARENT ),
2100 maTLBRColor( COL_TRANSPARENT ),
2101 maBLTRColor( COL_TRANSPARENT )
2102{
2103}
2104
2105ColorStatus::~ColorStatus()
2106{
2107}
2108
2109void ColorStatus::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2110{
2111 Color aColor( COL_TRANSPARENT );
2112 css::table::BorderLine2 aTable;
2113
2114 if ( rEvent.State >>= aTable )
2115 {
2116 SvxBorderLine aLine;
2117 SvxBoxItem::LineToSvxLine( aTable, aLine, false );
2118 if ( !aLine.isEmpty() )
2119 aColor = aLine.GetColor();
2120 }
2121 else
2122 rEvent.State >>= aColor;
2123
2124 if ( rEvent.FeatureURL.Path == "BorderTLBR" )
2125 maTLBRColor = aColor;
2126 else if ( rEvent.FeatureURL.Path == "BorderBLTR" )
2127 maBLTRColor = aColor;
2128 else
2129 maColor = aColor;
2130}
2131
2132Color ColorStatus::GetColor()
2133{
2134 Color aColor( maColor );
2135
2136 if ( maTLBRColor != COL_TRANSPARENT )
2137 {
2138 if ( aColor != maTLBRColor && aColor != COL_TRANSPARENT )
2139 return COL_TRANSPARENT;
2140 aColor = maTLBRColor;
2141 }
2142
2143 if ( maBLTRColor != COL_TRANSPARENT )
2144 {
2145 if ( aColor != maBLTRColor && aColor != COL_TRANSPARENT )
2146 return COL_TRANSPARENT;
2147 return maBLTRColor;
2148 }
2149
2150 return aColor;
2151}
2152
2153
2154SvxFrameWindow_Impl::SvxFrameWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent)
2155 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/floatingframeborder.ui", "FloatingFrameBorder")
2156 , mxControl(pControl)
2157 , mxFrameSet(new SvxFrmValueSet_Impl)
2158 , mxFrameSetWin(new weld::CustomWeld(*m_xBuilder, "valueset", *mxFrameSet))
2159 , bParagraphMode(false)
2160{
2161 mxFrameSet->SetStyle(WB_ITEMBORDER(WinBits(0x00010000)) | WB_DOUBLEBORDER(WinBits(0x00020000)) | WB_3DLOOK | WB_NO_DIRECTSELECT(WinBits(0x04000000)));
2162 AddStatusListener(".uno:BorderReducedMode");
2163 InitImageList();
2164
2165 /*
2166 * 1 2 3 4
2167 * -------------------------------------
2168 * NONE LEFT RIGHT LEFTRIGHT
2169 * TOP BOTTOM TOPBOTTOM OUTER
2170 * -------------------------------------
2171 * HOR HORINNER VERINNER ALL <- can be switched of via bParagraphMode
2172 */
2173
2174 sal_uInt16 i = 0;
2175
2176 for ( i=1; i<9; i++ )
2177 mxFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2178
2179 //bParagraphMode should have been set in StateChanged
2180 if ( !bParagraphMode )
2181 for ( i = 9; i < 13; i++ )
2182 mxFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2183
2184 mxFrameSet->SetColCount( 4 );
2185 mxFrameSet->SetSelectHdl( LINK( this, SvxFrameWindow_Impl, SelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SvxFrameWindow_Impl
*>(this), &SvxFrameWindow_Impl::LinkStubSelectHdl)
);
2186 CalcSizeValueSet();
2187
2188 mxFrameSet->SetHelpId( HID_POPUP_FRAME"SVX_HID_POPUP_FRAME" );
2189 mxFrameSet->SetAccessibleName( SvxResId(RID_SVXSTR_FRAMEreinterpret_cast<char const *>("RID_SVXSTR_FRAME" "\004"
u8"Borders")
) );
2190}
2191
2192namespace {
2193
2194enum class FrmValidFlags {
2195 NONE = 0x00,
2196 Left = 0x01,
2197 Right = 0x02,
2198 Top = 0x04,
2199 Bottom = 0x08,
2200 HInner = 0x10,
2201 VInner = 0x20,
2202 AllMask = 0x3f,
2203};
2204
2205}
2206
2207namespace o3tl {
2208 template<> struct typed_flags<FrmValidFlags> : is_typed_flags<FrmValidFlags, 0x3f> {};
2209}
2210
2211// By default unset lines remain unchanged.
2212// Via Shift unset lines are reset
2213
2214IMPL_LINK_NOARG(SvxFrameWindow_Impl, SelectHdl, ValueSet*, void)void SvxFrameWindow_Impl::LinkStubSelectHdl(void * instance, ValueSet
* data) { return static_cast<SvxFrameWindow_Impl *>(instance
)->SelectHdl(data); } void SvxFrameWindow_Impl::SelectHdl(
__attribute__ ((unused)) ValueSet*)
2215{
2216 SvxBoxItem aBorderOuter( SID_ATTR_BORDER_OUTER( 10000 + 24 ) );
2217 SvxBoxInfoItem aBorderInner( SID_ATTR_BORDER_INNERTypedWhichId<SvxBoxInfoItem>( 10000 + 23 ) );
2218 SvxBorderLine theDefLine;
2219 SvxBorderLine *pLeft = nullptr,
2220 *pRight = nullptr,
2221 *pTop = nullptr,
2222 *pBottom = nullptr;
2223 sal_uInt16 nSel = mxFrameSet->GetSelectedItemId();
2224 sal_uInt16 nModifier = mxFrameSet->GetModifier();
2225 FrmValidFlags nValidFlags = FrmValidFlags::NONE;
2226
2227 theDefLine.GuessLinesWidths(theDefLine.GetBorderLineStyle(),
2228 DEF_LINE_WIDTH_01);
2229 switch ( nSel )
2230 {
2231 case 1: nValidFlags |= FrmValidFlags::AllMask;
2232 break; // NONE
2233 case 2: pLeft = &theDefLine;
2234 nValidFlags |= FrmValidFlags::Left;
2235 break; // LEFT
2236 case 3: pRight = &theDefLine;
2237 nValidFlags |= FrmValidFlags::Right;
2238 break; // RIGHT
2239 case 4: pLeft = pRight = &theDefLine;
2240 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left;
2241 break; // LEFTRIGHT
2242 case 5: pTop = &theDefLine;
2243 nValidFlags |= FrmValidFlags::Top;
2244 break; // TOP
2245 case 6: pBottom = &theDefLine;
2246 nValidFlags |= FrmValidFlags::Bottom;
2247 break; // BOTTOM
2248 case 7: pTop = pBottom = &theDefLine;
2249 nValidFlags |= FrmValidFlags::Bottom|FrmValidFlags::Top;
2250 break; // TOPBOTTOM
2251 case 8: pLeft = pRight = pTop = pBottom = &theDefLine;
2252 nValidFlags |= FrmValidFlags::Left | FrmValidFlags::Right | FrmValidFlags::Top | FrmValidFlags::Bottom;
2253 break; // OUTER
2254
2255 // Inner Table:
2256 case 9: // HOR
2257 pTop = pBottom = &theDefLine;
2258 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2259 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
2260 nValidFlags |= FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2261 break;
2262
2263 case 10: // HORINNER
2264 pLeft = pRight = pTop = pBottom = &theDefLine;
2265 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2266 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
2267 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2268 break;
2269
2270 case 11: // VERINNER
2271 pLeft = pRight = pTop = pBottom = &theDefLine;
2272 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
2273 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
2274 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::VInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2275 break;
2276
2277 case 12: // ALL
2278 pLeft = pRight = pTop = pBottom = &theDefLine;
2279 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2280 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
2281 nValidFlags |= FrmValidFlags::AllMask;
2282 break;
2283
2284 default:
2285 break;
2286 }
2287 aBorderOuter.SetLine( pLeft, SvxBoxItemLine::LEFT );
2288 aBorderOuter.SetLine( pRight, SvxBoxItemLine::RIGHT );
2289 aBorderOuter.SetLine( pTop, SvxBoxItemLine::TOP );
2290 aBorderOuter.SetLine( pBottom, SvxBoxItemLine::BOTTOM );
2291
2292 if(nModifier == KEY_SHIFT)
2293 nValidFlags |= FrmValidFlags::AllMask;
2294 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::TOP, bool(nValidFlags&FrmValidFlags::Top ));
2295 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, bool(nValidFlags&FrmValidFlags::Bottom ));
2296 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::LEFT, bool(nValidFlags&FrmValidFlags::Left));
2297 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::RIGHT, bool(nValidFlags&FrmValidFlags::Right ));
2298 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::HORI, bool(nValidFlags&FrmValidFlags::HInner ));
2299 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::VERT, bool(nValidFlags&FrmValidFlags::VInner));
2300 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
2301 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISABLE, false );
2302
2303 Any a;
2304 Sequence< PropertyValue > aArgs( 2 );
2305 aArgs[0].Name = "OuterBorder";
2306 aBorderOuter.QueryValue( a );
2307 aArgs[0].Value = a;
2308 aArgs[1].Name = "InnerBorder";
2309 aBorderInner.QueryValue( a );
2310 aArgs[1].Value = a;
2311
2312 if (mxFrameSet)
2313 {
2314 /* #i33380# Moved the following line above the Dispatch() call.
2315 This instance may be deleted in the meantime (i.e. when a dialog is opened
2316 while in Dispatch()), accessing members will crash in this case. */
2317 mxFrameSet->SetNoSelection();
2318 }
2319
2320 mxControl->dispatchCommand( ".uno:SetBorderStyle", aArgs );
2321
2322 mxControl->EndPopupMode();
2323}
2324
2325void SvxFrameWindow_Impl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2326{
2327 if ( rEvent.FeatureURL.Complete != ".uno:BorderReducedMode" )
2328 return;
2329
2330 bool bValue;
2331 if ( !(rEvent.State >>= bValue) )
2332 return;
2333
2334 bParagraphMode = bValue;
2335 //initial calls mustn't insert or remove elements
2336 if(!mxFrameSet->GetItemCount())
2337 return;
2338
2339 bool bTableMode = ( mxFrameSet->GetItemCount() == 12 );
2340 bool bResize = false;
2341
2342 if ( bTableMode && bParagraphMode )
2343 {
2344 for ( sal_uInt16 i = 9; i < 13; i++ )
2345 mxFrameSet->RemoveItem(i);
2346 bResize = true;
2347 }
2348 else if ( !bTableMode && !bParagraphMode )
2349 {
2350 for ( sal_uInt16 i = 9; i < 13; i++ )
2351 mxFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2352 bResize = true;
2353 }
2354
2355 if ( bResize )
2356 {
2357 CalcSizeValueSet();
2358 }
2359}
2360
2361void SvxFrameWindow_Impl::CalcSizeValueSet()
2362{
2363 weld::DrawingArea* pDrawingArea = mxFrameSet->GetDrawingArea();
2364 const OutputDevice& rDevice = pDrawingArea->get_ref_device();
2365 Size aItemSize( 20 * rDevice.GetDPIScaleFactor(), 20 * rDevice.GetDPIScaleFactor() );
2366 Size aSize = mxFrameSet->CalcWindowSizePixel( aItemSize );
2367 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
2368 mxFrameSet->SetOutputSizePixel(aSize);
2369}
2370
2371void SvxFrameWindow_Impl::InitImageList()
2372{
2373 aImgVec.clear();
2374 aImgVec.emplace_back(RID_SVXBMP_FRAME1"svx/res/fr01.png");
2375 aImgVec.emplace_back(RID_SVXBMP_FRAME2"svx/res/fr02.png");
2376 aImgVec.emplace_back(RID_SVXBMP_FRAME3"svx/res/fr03.png");
2377 aImgVec.emplace_back(RID_SVXBMP_FRAME4"svx/res/fr04.png");
2378 aImgVec.emplace_back(RID_SVXBMP_FRAME5"svx/res/fr05.png");
2379 aImgVec.emplace_back(RID_SVXBMP_FRAME6"svx/res/fr06.png");
2380 aImgVec.emplace_back(RID_SVXBMP_FRAME7"svx/res/fr07.png");
2381 aImgVec.emplace_back(RID_SVXBMP_FRAME8"svx/res/fr08.png");
2382 aImgVec.emplace_back(RID_SVXBMP_FRAME9"svx/res/fr09.png");
2383 aImgVec.emplace_back(RID_SVXBMP_FRAME10"svx/res/fr010.png");
2384 aImgVec.emplace_back(RID_SVXBMP_FRAME11"svx/res/fr011.png");
2385 aImgVec.emplace_back(RID_SVXBMP_FRAME12"svx/res/fr012.png");
2386}
2387
2388static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
2389{
2390 return SvxBorderLine::threeDMediumColor( aMain );
2391}
2392
2393SvxLineWindow_Impl::SvxLineWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent)
2394 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/floatingframeborder.ui", "FloatingFrameBorder")
2395 , m_xControl(pControl)
2396 , m_xLineStyleLb(new LineListBox)
2397 , m_xLineStyleLbWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xLineStyleLb))
2398 , m_bIsWriter(false)
2399{
2400 try
2401 {
2402 Reference< lang::XServiceInfo > xServices(m_xFrame->getController()->getModel(), UNO_QUERY_THROW);
2403 m_bIsWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2404 }
2405 catch(const uno::Exception& )
2406 {
2407 }
2408
2409 m_xLineStyleLb->SetStyle( WinBits(WB_FLATVALUESET(WinBits(0x02000000)) | WB_ITEMBORDER(WinBits(0x00010000)) | WB_3DLOOK | WB_NO_DIRECTSELECT(WinBits(0x04000000)) | WB_TABSTOP) );
2410
2411 m_xLineStyleLb->SetSourceUnit( FieldUnit::TWIP );
2412 m_xLineStyleLb->SetNone( comphelper::LibreOfficeKit::isActive() ? SvxResId(RID_SVXSTR_INVISIBLEreinterpret_cast<char const *>("RID_SVXSTR_INVISIBLE" "\004"
u8"None")
)
2413 :SvxResId(RID_SVXSTR_NONEreinterpret_cast<char const *>("RID_SVXSTR_NONE" "\004"
u8"- none -")
) );
2414
2415 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::SOLID ), SvxBorderLineStyle::SOLID );
2416 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOTTED ), SvxBorderLineStyle::DOTTED );
2417 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DASHED ), SvxBorderLineStyle::DASHED );
2418
2419 // Double lines
2420 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOUBLE ), SvxBorderLineStyle::DOUBLE );
2421 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_SMALLGAP ), SvxBorderLineStyle::THINTHICK_SMALLGAP, 20 );
2422 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_MEDIUMGAP ), SvxBorderLineStyle::THINTHICK_MEDIUMGAP );
2423 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_LARGEGAP ), SvxBorderLineStyle::THINTHICK_LARGEGAP );
2424 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_SMALLGAP ), SvxBorderLineStyle::THICKTHIN_SMALLGAP, 20 );
2425 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_MEDIUMGAP ), SvxBorderLineStyle::THICKTHIN_MEDIUMGAP );
2426 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_LARGEGAP ), SvxBorderLineStyle::THICKTHIN_LARGEGAP );
2427
2428 // Engraved / Embossed
2429 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::EMBOSSED ), SvxBorderLineStyle::EMBOSSED, 15,
2430 &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor,
2431 &lcl_mediumColor );
2432 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::ENGRAVED ), SvxBorderLineStyle::ENGRAVED, 15,
2433 &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor,
2434 &lcl_mediumColor );
2435
2436 // Inset / Outset
2437 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::OUTSET ), SvxBorderLineStyle::OUTSET, 10,
2438 &SvxBorderLine::lightColor, &SvxBorderLine::darkColor );
2439 m_xLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::INSET ), SvxBorderLineStyle::INSET, 10,
2440 &SvxBorderLine::darkColor, &SvxBorderLine::lightColor );
2441 Size aSize = m_xLineStyleLb->SetWidth( 20 ); // 1pt by default
2442
2443 m_xLineStyleLb->SetSelectHdl( LINK( this, SvxLineWindow_Impl, SelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SvxLineWindow_Impl
*>(this), &SvxLineWindow_Impl::LinkStubSelectHdl)
);
2444
2445 m_xContainer->set_help_id(HID_POPUP_LINE"SVX_HID_POPUP_LINE");
2446
2447 aSize.AdjustWidth(6);
2448 aSize.AdjustHeight(6);
2449 aSize = m_xLineStyleLb->CalcWindowSizePixel(aSize);
2450 m_xLineStyleLb->GetDrawingArea()->set_size_request(aSize.Width(), aSize.Height());
2451 m_xLineStyleLb->SetOutputSizePixel(aSize);
2452}
2453
2454IMPL_LINK_NOARG(SvxLineWindow_Impl, SelectHdl, ValueSet*, void)void SvxLineWindow_Impl::LinkStubSelectHdl(void * instance, ValueSet
* data) { return static_cast<SvxLineWindow_Impl *>(instance
)->SelectHdl(data); } void SvxLineWindow_Impl::SelectHdl(__attribute__
((unused)) ValueSet*)
2455{
2456 SvxLineItem aLineItem( SID_FRAME_LINESTYLETypedWhichId<SvxLineItem>( 10000 + 201 ) );
2457 SvxBorderLineStyle nStyle = m_xLineStyleLb->GetSelectEntryStyle();
2458
2459 if ( m_xLineStyleLb->GetSelectItemPos( ) > 0 )
2460 {
2461 SvxBorderLine aTmp;
2462 aTmp.SetBorderLineStyle( nStyle );
2463 aTmp.SetWidth( 20 ); // TODO Make it depend on a width field
2464 aLineItem.SetLine( &aTmp );
2465 }
2466 else
2467 aLineItem.SetLine( nullptr );
2468
2469 Any a;
2470 Sequence< PropertyValue > aArgs( 1 );
2471 aArgs[0].Name = "LineStyle";
2472 aLineItem.QueryValue( a, m_bIsWriter ? CONVERT_TWIPS0x80 : 0 );
2473 aArgs[0].Value = a;
2474
2475 m_xControl->dispatchCommand( ".uno:LineStyle", aArgs );
2476
2477 m_xControl->EndPopupMode();
2478}
2479
2480SfxStyleControllerItem_Impl::SfxStyleControllerItem_Impl(
2481 const Reference< XDispatchProvider >& rDispatchProvider,
2482 sal_uInt16 nSlotId, // Family-ID
2483 const OUString& rCommand, // .uno: command bound to this item
2484 SvxStyleToolBoxControl& rTbxCtl ) // controller instance, which the item is assigned to.
2485 : SfxStatusListener( rDispatchProvider, nSlotId, rCommand ),
2486 rControl( rTbxCtl )
2487{
2488}
2489
2490void SfxStyleControllerItem_Impl::StateChanged(
2491 SfxItemState eState, const SfxPoolItem* pState )
2492{
2493 switch ( GetId() )
2494 {
2495 case SID_STYLE_FAMILY1((5000 + 541)):
2496 case SID_STYLE_FAMILY2((5000 + 541) + 1):
2497 case SID_STYLE_FAMILY3((5000 + 541) + 2):
2498 case SID_STYLE_FAMILY4((5000 + 541) + 3):
2499 case SID_STYLE_FAMILY5((5000 + 541) + 4):
2500 {
2501 const sal_uInt16 nIdx = GetId() - SID_STYLE_FAMILY_START(5000 + 541);
2502
2503 if ( SfxItemState::DEFAULT == eState )
2504 {
2505 const SfxTemplateItem* pStateItem =
2506 dynamic_cast<const SfxTemplateItem*>( pState );
2507 DBG_ASSERT( pStateItem != nullptr, "SfxTemplateItem expected" )do { if (true && (!(pStateItem != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2507" ": "), "%s", "SfxTemplateItem expected"); } } while
(false)
;
2508 rControl.SetFamilyState( nIdx, pStateItem );
2509 }
2510 else
2511 rControl.SetFamilyState( nIdx, nullptr );
2512 break;
2513 }
2514 }
2515}
2516
2517struct SvxStyleToolBoxControl::Impl
2518{
2519 OUString aClearForm;
2520 OUString aMore;
2521 ::std::vector< OUString > aDefaultStyles;
2522 bool bSpecModeWriter;
2523 bool bSpecModeCalc;
2524
2525 VclPtr<SvxStyleBox_Impl> m_xVclBox;
2526 std::unique_ptr<SvxStyleBox_Base> m_xWeldBox;
2527 SvxStyleBox_Base* m_pBox;
2528
2529 Impl()
2530 :aClearForm ( SvxResId( RID_SVXSTR_CLEARFORMreinterpret_cast<char const *>("RID_SVXSTR_CLEARFORM" "\004"
u8"Clear formatting")
) )
2531 ,aMore ( SvxResId( RID_SVXSTR_MORE_STYLESreinterpret_cast<char const *>("RID_SVXSTR_MORE_STYLES"
"\004" u8"More Styles...")
) )
2532 ,bSpecModeWriter ( false )
2533 ,bSpecModeCalc ( false )
2534 ,m_pBox ( nullptr )
2535 {
2536
2537
2538 }
2539 void InitializeStyles(const Reference < frame::XModel >& xModel)
2540 {
2541 aDefaultStyles.clear();
2542
2543 //now convert the default style names to the localized names
2544 try
2545 {
2546 Reference< style::XStyleFamiliesSupplier > xStylesSupplier( xModel, UNO_QUERY_THROW );
2547 Reference< lang::XServiceInfo > xServices( xModel, UNO_QUERY_THROW );
2548 bSpecModeWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2549 if(bSpecModeWriter)
2550 {
2551 Reference<container::XNameAccess> xParaStyles;
2552 xStylesSupplier->getStyleFamilies()->getByName("ParagraphStyles") >>=
2553 xParaStyles;
2554 static const std::vector<OUString> aWriterStyles =
2555 {
2556 "Standard",
2557 "Text body",
2558 "Title",
2559 "Subtitle",
2560 "Heading 1",
2561 "Heading 2",
2562 "Heading 3",
2563 "Quotations"
2564 };
2565 for( const OUString& aStyle: aWriterStyles )
2566 {
2567 try
2568 {
2569 Reference< beans::XPropertySet > xStyle;
2570 xParaStyles->getByName( aStyle ) >>= xStyle;
2571 OUString sName;
2572 xStyle->getPropertyValue("DisplayName") >>= sName;
2573 if( !sName.isEmpty() )
2574 aDefaultStyles.push_back(sName);
2575 }
2576 catch( const uno::Exception& )
2577 {}
2578 }
2579
2580 }
2581 else if( (
2582 bSpecModeCalc = xServices->supportsService(
2583 "com.sun.star.sheet.SpreadsheetDocument")))
2584 {
2585 static const char* aCalcStyles[] =
2586 {
2587 "Default",
2588 "Heading1",
2589 "Result",
2590 "Result2"
2591 };
2592 Reference<container::XNameAccess> xCellStyles;
2593 xStylesSupplier->getStyleFamilies()->getByName("CellStyles") >>= xCellStyles;
2594 for(const char* pCalcStyle : aCalcStyles)
2595 {
2596 try
2597 {
2598 const OUString sStyleName( OUString::createFromAscii( pCalcStyle ) );
2599 if( xCellStyles->hasByName( sStyleName ) )
2600 {
2601 Reference< beans::XPropertySet > xStyle( xCellStyles->getByName( sStyleName), UNO_QUERY_THROW );
2602 OUString sName;
2603 xStyle->getPropertyValue("DisplayName") >>= sName;
2604 if( !sName.isEmpty() )
2605 aDefaultStyles.push_back(sName);
2606 }
2607 }
2608 catch( const uno::Exception& )
2609 {}
2610 }
2611 }
2612 }
2613 catch(const uno::Exception& )
2614 {
2615 OSL_FAIL("error while initializing style names")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2615" ": "), "%s", "error while initializing style names"
); } } while (false)
;
2616 }
2617 }
2618};
2619
2620// mapping table from bound items. BE CAREFUL this table must be in the
2621// same order as the uno commands bound to the slots SID_STYLE_FAMILY1..n
2622// MAX_FAMILIES must also be correctly set!
2623static const char* StyleSlotToStyleCommand[MAX_FAMILIES5] =
2624{
2625 ".uno:CharStyle",
2626 ".uno:ParaStyle",
2627 ".uno:FrameStyle",
2628 ".uno:PageStyle",
2629 ".uno:TemplateFamily5"
2630};
2631
2632SvxStyleToolBoxControl::SvxStyleToolBoxControl()
2633 : pImpl(new Impl)
2634 , pStyleSheetPool(nullptr)
2635 , nActFamily(0xffff)
2636{
2637 for (sal_uInt16 i = 0; i < MAX_FAMILIES5; ++i)
2638 {
2639 pBoundItems[i] = nullptr;
2640 m_xBoundItems[i].clear();
2641 pFamilyState[i] = nullptr;
2642 }
2643}
2644
2645SvxStyleToolBoxControl::~SvxStyleToolBoxControl()
2646{
2647}
2648
2649void SAL_CALL SvxStyleToolBoxControl::initialize(const Sequence<Any>& rArguments)
2650{
2651 svt::ToolboxController::initialize(rArguments);
2652
2653 // After initialize we should have a valid frame member where we can retrieve our
2654 // dispatch provider.
2655 if ( !m_xFrame.is() )
2656 return;
2657
2658 pImpl->InitializeStyles(m_xFrame->getController()->getModel());
2659 Reference< XDispatchProvider > xDispatchProvider( m_xFrame->getController(), UNO_QUERY );
2660 for ( sal_uInt16 i=0; i<MAX_FAMILIES5; i++ )
2661 {
2662 pBoundItems[i] = new SfxStyleControllerItem_Impl( xDispatchProvider,
2663 SID_STYLE_FAMILY_START(5000 + 541) + i,
2664 OUString::createFromAscii( StyleSlotToStyleCommand[i] ),
2665 *this );
2666 m_xBoundItems[i].set( static_cast< OWeakObject* >( pBoundItems[i] ), UNO_QUERY );
2667 pFamilyState[i] = nullptr;
2668 }
2669}
2670
2671// XComponent
2672void SAL_CALL SvxStyleToolBoxControl::dispose()
2673{
2674 svt::ToolboxController::dispose();
2675
2676 SolarMutexGuard aSolarMutexGuard;
2677 pImpl->m_xVclBox.disposeAndClear();
2678 pImpl->m_xWeldBox.reset();
2679 pImpl->m_pBox = nullptr;
2680
2681 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
2682 {
2683 if (!pBoundItem)
2684 continue;
2685 pBoundItem->UnBind();
2686 }
2687 unbindListener();
2688
2689 for( sal_uInt16 i=0; i<MAX_FAMILIES5; i++ )
2690 {
2691 if ( m_xBoundItems[i].is() )
2692 {
2693 try
2694 {
2695 m_xBoundItems[i]->dispose();
2696 }
2697 catch ( Exception& )
2698 {
2699 }
2700
2701 m_xBoundItems[i].clear();
2702 pBoundItems[i] = nullptr;
2703 }
2704 pFamilyState[i].reset();
2705 }
2706 pStyleSheetPool = nullptr;
2707 pImpl.reset();
2708}
2709
2710OUString SvxStyleToolBoxControl::getImplementationName()
2711{
2712 return "com.sun.star.comp.svx.StyleToolBoxControl";
2713}
2714
2715sal_Bool SvxStyleToolBoxControl::supportsService( const OUString& rServiceName )
2716{
2717 return cppu::supportsService( this, rServiceName );
2718}
2719
2720css::uno::Sequence< OUString > SvxStyleToolBoxControl::getSupportedServiceNames()
2721{
2722 return { "com.sun.star.frame.ToolbarController" };
2723}
2724
2725extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
2726com_sun_star_comp_svx_StyleToolBoxControl_get_implementation(
2727 css::uno::XComponentContext*,
2728 css::uno::Sequence<css::uno::Any> const & )
2729{
2730 return cppu::acquire( new SvxStyleToolBoxControl() );
2731}
2732
2733void SAL_CALL SvxStyleToolBoxControl::update()
2734{
2735 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
2736 pBoundItem->ReBind();
2737 bindListener();
2738}
2739
2740SfxStyleFamily SvxStyleToolBoxControl::GetActFamily() const
2741{
2742 switch ( nActFamily-1 + SID_STYLE_FAMILY_START(5000 + 541) )
2743 {
2744 case SID_STYLE_FAMILY1((5000 + 541)): return SfxStyleFamily::Char;
2745 case SID_STYLE_FAMILY2((5000 + 541) + 1): return SfxStyleFamily::Para;
2746 case SID_STYLE_FAMILY3((5000 + 541) + 2): return SfxStyleFamily::Frame;
2747 case SID_STYLE_FAMILY4((5000 + 541) + 3): return SfxStyleFamily::Page;
2748 case SID_STYLE_FAMILY5((5000 + 541) + 4): return SfxStyleFamily::Pseudo;
2749 default:
2750 OSL_FAIL( "unknown style family" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2750" ": "), "%s", "unknown style family"); } } while (
false)
;
2751 break;
2752 }
2753 return SfxStyleFamily::Para;
2754}
2755
2756void SvxStyleToolBoxControl::FillStyleBox()
2757{
2758 SvxStyleBox_Base* pBox = pImpl->m_pBox;
2759
2760 DBG_ASSERT( pStyleSheetPool, "StyleSheetPool not found!" )do { if (true && (!(pStyleSheetPool))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2760" ": "), "%s", "StyleSheetPool not found!"); } } while
(false)
;
2761 DBG_ASSERT( pBox, "Control not found!" )do { if (true && (!(pBox))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2761" ": "), "%s", "Control not found!"); } } while (false
)
;
2762
2763 if ( !(pStyleSheetPool && pBox && nActFamily!=0xffff) )
2764 return;
2765
2766 const SfxStyleFamily eFamily = GetActFamily();
2767 SfxStyleSheetBase* pStyle = nullptr;
2768 bool bDoFill = false;
2769
2770 auto xIter = pStyleSheetPool->CreateIterator(eFamily, SfxStyleSearchBits::Used);
2771 sal_uInt16 nCount = xIter->Count();
2772
2773 // Check whether fill is necessary
2774 pStyle = xIter->First();
2775 //!!! TODO: This condition isn't right any longer, because we always show some default entries
2776 //!!! so the list doesn't show the count
2777 if ( nCount != pBox->get_count() )
2778 {
2779 bDoFill = true;
2780 }
2781 else
2782 {
2783 sal_uInt16 i= 0;
2784 while ( pStyle && !bDoFill )
2785 {
2786 bDoFill = ( pBox->get_text(i) != pStyle->GetName() );
2787 pStyle = xIter->Next();
2788 i++;
2789 }
2790 }
2791
2792 if ( !bDoFill )
2793 return;
2794
2795 OUString aStrSel(pBox->get_active_text());
2796 pBox->freeze();
2797 pBox->clear();
2798
2799 std::vector<OUString> aStyles;
2800
2801 {
2802 pStyle = xIter->Next();
2803
2804 if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
2805 {
2806 while ( pStyle )
2807 {
2808 // sort out default styles
2809 bool bInsert = true;
2810 OUString aName( pStyle->GetName() );
2811 for( auto const & _i: pImpl->aDefaultStyles )
2812 {
2813 if( _i == aName )
2814 {
2815 bInsert = false;
2816 break;
2817 }
2818 }
2819
2820 if( bInsert )
2821 aStyles.push_back(aName);
2822 pStyle = xIter->Next();
2823 }
2824 }
2825 else
2826 {
2827 while ( pStyle )
2828 {
2829 aStyles.push_back(pStyle->GetName());
2830 pStyle = xIter->Next();
2831 }
2832 }
2833 }
2834
2835 if (pImpl->bSpecModeWriter || pImpl->bSpecModeCalc)
2836 {
2837 pBox->append_text(pImpl->aClearForm);
2838 pBox->insert_separator(1, "separator");
2839
2840 // insert default styles
2841 for (const auto &rStyle : pImpl->aDefaultStyles)
2842 pBox->append_text(rStyle);
2843 }
2844
2845 std::sort(aStyles.begin(), aStyles.end());
2846
2847 for (const auto& rStyle : aStyles)
2848 pBox->append_text(rStyle);
2849
2850 if ((pImpl->bSpecModeWriter || pImpl->bSpecModeCalc) && !comphelper::LibreOfficeKit::isActive())
2851 pBox->append_text(pImpl->aMore);
2852
2853 pBox->thaw();
2854 pBox->set_active_or_entry_text(aStrSel);
2855 pBox->SetFamily( eFamily );
2856}
2857
2858void SvxStyleToolBoxControl::SelectStyle( const OUString& rStyleName )
2859{
2860 SvxStyleBox_Base* pBox = pImpl->m_pBox;
2861 DBG_ASSERT( pBox, "Control not found!" )do { if (true && (!(pBox))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "2861" ": "), "%s", "Control not found!"); } } while (false
)
;
2862
2863 if ( !pBox )
2864 return;
2865
2866 OUString aStrSel(pBox->get_active_text());
2867
2868 if ( !rStyleName.isEmpty() )
2869 {
2870 if ( rStyleName != aStrSel )
2871 pBox->set_active_or_entry_text( rStyleName );
2872 }
2873 else
2874 pBox->set_active(-1);
2875 pBox->save_value();
2876}
2877
2878void SvxStyleToolBoxControl::Update()
2879{
2880 SfxStyleSheetBasePool* pPool = nullptr;
2881 SfxObjectShell* pDocShell = SfxObjectShell::Current();
2882
2883 if ( pDocShell )
2884 pPool = pDocShell->GetStyleSheetPool();
2885
2886 sal_uInt16 i;
2887 for ( i=0; i<MAX_FAMILIES5; i++ )
2888 if( pFamilyState[i] )
2889 break;
2890
2891 if ( i==MAX_FAMILIES5 || !pPool )
2892 {
2893 pStyleSheetPool = pPool;
2894 return;
2895 }
2896
2897
2898 const SfxTemplateItem* pItem = nullptr;
2899
2900 if ( nActFamily == 0xffff || nullptr == (pItem = pFamilyState[nActFamily-1].get()) )
2901 // Current range not within allowed ranges or default
2902 {
2903 pStyleSheetPool = pPool;
2904 nActFamily = 2;
2905
2906 pItem = pFamilyState[nActFamily-1].get();
2907 if ( !pItem )
2908 {
2909 nActFamily++;
2910 pItem = pFamilyState[nActFamily-1].get();
2911 }
2912 }
2913 else if ( pPool != pStyleSheetPool )
2914 pStyleSheetPool = pPool;
2915
2916 FillStyleBox(); // Decides by itself whether Fill is needed
2917
2918 if ( pItem )
2919 SelectStyle( pItem->GetStyleName() );
2920}
2921
2922void SvxStyleToolBoxControl::SetFamilyState( sal_uInt16 nIdx,
2923 const SfxTemplateItem* pItem )
2924{
2925 pFamilyState[nIdx].reset( pItem == nullptr ? nullptr : new SfxTemplateItem( *pItem ) );
2926 Update();
2927}
2928
2929void SvxStyleToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2930{
2931 SolarMutexGuard aGuard;
2932
2933 if (m_pToolbar)
2934 m_pToolbar->set_item_sensitive(m_aCommandURL.toUtf8(), rEvent.IsEnabled);
2935 else
2936 {
2937 ToolBox* pToolBox = nullptr;
2938 sal_uInt16 nId = 0;
2939 if (!getToolboxId( nId, &pToolBox ) )
2940 return;
2941 pToolBox->EnableItem( nId, rEvent.IsEnabled );
2942 }
2943
2944 if (rEvent.IsEnabled)
2945 Update();
2946}
2947
2948css::uno::Reference<css::awt::XWindow> SvxStyleToolBoxControl::createItemWindow(const css::uno::Reference< css::awt::XWindow>& rParent)
2949{
2950 uno::Reference< awt::XWindow > xItemWindow;
2951
2952 if (m_pBuilder)
2953 {
2954 SolarMutexGuard aSolarMutexGuard;
2955
2956 std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("applystyle"));
2957
2958 xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
2959
2960 pImpl->m_xWeldBox.reset(new SvxStyleBox_Base(std::move(xWidget),
2961 ".uno:StyleApply",
2962 SfxStyleFamily::Para,
2963 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
2964 m_xFrame,
2965 pImpl->aClearForm,
2966 pImpl->aMore,
2967 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this));
2968 pImpl->m_pBox = pImpl->m_xWeldBox.get();
2969 }
2970 else
2971 {
2972 VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
2973 if ( pParent )
2974 {
2975 SolarMutexGuard aSolarMutexGuard;
2976
2977 pImpl->m_xVclBox = VclPtr<SvxStyleBox_Impl>::Create(pParent,
2978 ".uno:StyleApply",
2979 SfxStyleFamily::Para,
2980 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
2981 m_xFrame,
2982 pImpl->aClearForm,
2983 pImpl->aMore,
2984 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this);
2985 pImpl->m_pBox = pImpl->m_xVclBox.get();
2986 xItemWindow = VCLUnoHelper::GetInterface(pImpl->m_xVclBox);
2987 }
2988 }
2989
2990 if (pImpl->m_pBox && !pImpl->aDefaultStyles.empty())
2991 pImpl->m_pBox->SetDefaultStyle(pImpl->aDefaultStyles[0]);
2992
2993 return xItemWindow;
2994}
2995
2996SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
2997 : m_pBox(nullptr)
2998{
2999}
3000
3001void SvxFontNameBox_Base::statusChanged_Impl( const css::frame::FeatureStateEvent& rEvent )
3002{
3003 if ( !rEvent.IsEnabled )
3004 {
3005 set_sensitive(false);
3006 Update( nullptr );
3007 }
3008 else
3009 {
3010 set_sensitive(true);
3011
3012 css::awt::FontDescriptor aFontDesc;
3013 if ( rEvent.State >>= aFontDesc )
3014 Update(&aFontDesc);
3015 else
3016 set_active_or_entry_text("");
3017 m_xWidget->save_value();
3018 }
3019}
3020
3021void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3022{
3023 SolarMutexGuard aGuard;
3024 m_pBox->statusChanged_Impl(rEvent);
3025
3026 if (m_pToolbar)
3027 m_pToolbar->set_item_sensitive(m_aCommandURL.toUtf8(), rEvent.IsEnabled);
3028 else
3029 {
3030 ToolBox* pToolBox = nullptr;
3031 sal_uInt16 nId = 0;
3032 if (!getToolboxId( nId, &pToolBox ) )
3033 return;
3034 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3035 }
3036}
3037
3038css::uno::Reference<css::awt::XWindow> SvxFontNameToolBoxControl::createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent)
3039{
3040 uno::Reference< awt::XWindow > xItemWindow;
3041
3042 if (m_pBuilder)
3043 {
3044 SolarMutexGuard aSolarMutexGuard;
3045
3046 std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("fontnamecombobox"));
3047
3048 xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
3049
3050 m_xWeldBox.reset(new SvxFontNameBox_Base(std::move(xWidget),
3051 Reference<XDispatchProvider>(m_xFrame->getController(), UNO_QUERY),
3052 m_xFrame, *this));
3053 m_pBox = m_xWeldBox.get();
3054 }
3055 else
3056 {
3057 VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
3058 if ( pParent )
3059 {
3060 SolarMutexGuard aSolarMutexGuard;
3061 m_xVclBox = VclPtr<SvxFontNameBox_Impl>::Create(pParent,
3062 Reference<XDispatchProvider>(m_xFrame->getController(), UNO_QUERY),
3063 m_xFrame, *this);
3064 m_pBox = m_xVclBox.get();
3065 xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox);
3066 }
3067 }
3068
3069 return xItemWindow;
3070}
3071
3072void SvxFontNameToolBoxControl::dispose()
3073{
3074 ToolboxController::dispose();
3075
3076 SolarMutexGuard aSolarMutexGuard;
3077 m_xVclBox.disposeAndClear();
1
Calling 'VclPtr::disposeAndClear'
3078 m_xWeldBox.reset();
3079 m_pBox = nullptr;
3080}
3081
3082OUString SvxFontNameToolBoxControl::getImplementationName()
3083{
3084 return "com.sun.star.comp.svx.FontNameToolBoxControl";
3085}
3086
3087sal_Bool SvxFontNameToolBoxControl::supportsService( const OUString& rServiceName )
3088{
3089 return cppu::supportsService( this, rServiceName );
3090}
3091
3092css::uno::Sequence< OUString > SvxFontNameToolBoxControl::getSupportedServiceNames()
3093{
3094 return { "com.sun.star.frame.ToolbarController" };
3095}
3096
3097extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
3098com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation(
3099 css::uno::XComponentContext*,
3100 css::uno::Sequence<css::uno::Any> const & )
3101{
3102 return cppu::acquire( new SvxFontNameToolBoxControl() );
3103}
3104
3105SvxColorToolBoxControl::SvxColorToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3106 ImplInheritanceHelper( rContext, nullptr, OUString() ),
3107 m_bSplitButton(true),
3108 m_nSlotId(0),
3109 m_aColorSelectFunction(PaletteManager::DispatchColorCommand)
3110{
3111}
3112
3113namespace {
3114
3115sal_uInt16 MapCommandToSlotId(const OUString& rCommand)
3116{
3117 if (rCommand == ".uno:Color")
3118 return SID_ATTR_CHAR_COLOR( 10000 + 17 );
3119 else if (rCommand == ".uno:FontColor")
3120 return SID_ATTR_CHAR_COLOR2(10000 + 537);
3121 else if (rCommand == ".uno:BackColor")
3122 return SID_ATTR_CHAR_COLOR_BACKGROUND(10000 + 489);
3123 else if (rCommand == ".uno:CharBackColor")
3124 return SID_ATTR_CHAR_BACK_COLOR( 10000 + 1153 );
3125 else if (rCommand == ".uno:BackgroundColor")
3126 return SID_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 186 );
3127 else if (rCommand == ".uno:TableCellBackgroundColor")
3128 return SID_TABLE_CELL_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 1189 );
3129 else if (rCommand == ".uno:Extrusion3DColor")
3130 return SID_EXTRUSION_3D_COLOR( 10000 + 969 );
3131 else if (rCommand == ".uno:XLineColor")
3132 return SID_ATTR_LINE_COLOR( 10000 + 172 );
3133 else if (rCommand == ".uno:FillColor")
3134 return SID_ATTR_FILL_COLOR( 10000 + 165 );
3135 else if (rCommand == ".uno:FrameLineColor")
3136 return SID_FRAME_LINECOLORTypedWhichId<SvxColorItem>( 10000 + 202 );
3137
3138 SAL_WARN("svx.tbxcrtls", "Unknown color command: " << rCommand)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.tbxcrtls")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Unknown color command: "
<< rCommand) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.tbxcrtls"), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "3138" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Unknown color command: " << rCommand
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Unknown color command: " << rCommand; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.tbxcrtls"),
("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "3138" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Unknown color command: " << rCommand) == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.tbxcrtls"
), ("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "3138" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Unknown color command: " << rCommand
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Unknown color command: " << rCommand; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.tbxcrtls"),
("/home/maarten/src/libreoffice/core/svx/source/tbxctrls/tbcontrl.cxx"
":" "3138" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3139 return 0;
3140}
3141
3142}
3143
3144void SvxColorToolBoxControl::initialize( const css::uno::Sequence<css::uno::Any>& rArguments )
3145{
3146 PopupWindowController::initialize( rArguments );
3147
3148 m_nSlotId = MapCommandToSlotId( m_aCommandURL );
3149
3150 if ( m_nSlotId == SID_ATTR_LINE_COLOR( 10000 + 172 ) || m_nSlotId == SID_ATTR_FILL_COLOR( 10000 + 165 ) ||
3151 m_nSlotId == SID_FRAME_LINECOLORTypedWhichId<SvxColorItem>( 10000 + 202 ) || m_nSlotId == SID_BACKGROUND_COLORTypedWhichId<SvxColorItem>( 10000 + 186 ) )
3152 {
3153 // Sidebar uses wide buttons for those.
3154 m_bSplitButton = !m_bSidebar;
3155 }
3156
3157 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(getCommandURL(), getModuleName());
3158 OUString aCommandLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
3159
3160 OString aId(m_aCommandURL.toUtf8());
3161
3162 if (m_pToolbar)
3163 {
3164 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3165 m_pToolbar->set_item_popover(aId, mxPopoverContainer->getTopLevel());
3166 m_xBtnUpdater.reset(new svx::ToolboxButtonColorUpdater(m_nSlotId, aId, m_pToolbar, !m_bSplitButton, aCommandLabel, m_xFrame));
3167 return;
3168 }
3169
3170 ToolBox* pToolBox = nullptr;
3171 sal_uInt16 nId = 0;
3172 if (getToolboxId(nId, &pToolBox))
3173 {
3174 m_xBtnUpdater.reset( new svx::VclToolboxButtonColorUpdater( m_nSlotId, nId, pToolBox, !m_bSplitButton, aCommandLabel, m_aCommandURL, m_xFrame ) );
3175 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
3176 }
3177}
3178
3179void SvxColorToolBoxControl::update()
3180{
3181 PopupWindowController::update();
3182
3183 switch( m_nSlotId )
3184 {
3185 case SID_ATTR_CHAR_COLOR2(10000 + 537):
3186 addStatusListener( ".uno:CharColorExt");
3187 break;
3188
3189 case SID_ATTR_CHAR_COLOR_BACKGROUND(10000 + 489):
3190 addStatusListener( ".uno:CharBackgroundExt");
3191 break;
3192
3193 case SID_FRAME_LINECOLORTypedWhichId<SvxColorItem>( 10000 + 202 ):
3194 addStatusListener( ".uno:BorderTLBR");
3195 addStatusListener( ".uno:BorderBLTR");
3196 break;
3197 }
3198}
3199
3200void SvxColorToolBoxControl::EnsurePaletteManager()
3201{
3202 if (!m_xPaletteManager)
3203 {
3204 m_xPaletteManager = std::make_shared<PaletteManager>();
3205 m_xPaletteManager->SetBtnUpdater(m_xBtnUpdater.get());
3206 }
3207}
3208
3209SvxColorToolBoxControl::~SvxColorToolBoxControl()
3210{
3211 if (m_xPaletteManager)
3212 m_xPaletteManager->SetBtnUpdater(nullptr);
3213}
3214
3215void SvxColorToolBoxControl::setColorSelectFunction(const ColorSelectFunction& aColorSelectFunction)
3216{
3217 m_aColorSelectFunction = aColorSelectFunction;
3218 if (m_xPaletteManager)
3219 m_xPaletteManager->SetColorSelectFunction(aColorSelectFunction);
3220}
3221
3222std::unique_ptr<WeldToolbarPopup> SvxColorToolBoxControl::weldPopupWindow()
3223{
3224 EnsurePaletteManager();
3225
3226 const css::uno::Reference<css::awt::XWindow> xParent = m_xFrame->getContainerWindow();
3227 weld::Window* pParentFrame = Application::GetFrameWeld(xParent);
3228
3229 const OString aId(m_aCommandURL.toUtf8());
3230
3231 auto xPopover = std::make_unique<ColorWindow>(
3232 m_aCommandURL,
3233 m_xPaletteManager,
3234 m_aColorStatus,
3235 m_nSlotId,
3236 m_xFrame,
3237 pParentFrame,
3238 MenuOrToolMenuButton(m_pToolbar, aId),
3239 m_aColorSelectFunction);
3240
3241 if ( m_bSplitButton )
3242 xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl )::tools::detail::makeLink( ::tools::detail::castTo<SvxColorToolBoxControl
*>(this), &SvxColorToolBoxControl::LinkStubSelectedHdl
)
);
3243
3244 return xPopover;
3245}
3246
3247VclPtr<vcl::Window> SvxColorToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
3248{
3249 ToolBox* pToolBox = nullptr;
3250 sal_uInt16 nId = 0;
3251 if (!getToolboxId(nId, &pToolBox))
3252 return nullptr;
3253
3254 const css::uno::Reference<css::awt::XWindow> xParent = m_xFrame->getContainerWindow();
3255 weld::Window* pParentFrame = Application::GetFrameWeld(xParent);
3256
3257 EnsurePaletteManager();
3258
3259 auto xPopover = std::make_unique<ColorWindow>(
3260 m_aCommandURL,
3261 m_xPaletteManager,
3262 m_aColorStatus,
3263 m_nSlotId,
3264 m_xFrame,
3265 pParentFrame,
3266 MenuOrToolMenuButton(this, pToolBox, nId),
3267 m_aColorSelectFunction);
3268
3269 if ( m_bSplitButton )
3270 xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl )::tools::detail::makeLink( ::tools::detail::castTo<SvxColorToolBoxControl
*>(this), &SvxColorToolBoxControl::LinkStubSelectedHdl
)
);
3271
3272 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3273 std::move(xPopover), true);
3274
3275 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(m_aCommandURL, m_sModuleName);
3276 OUString aWindowTitle = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
3277 mxInterimPopover->SetText(aWindowTitle);
3278
3279 mxInterimPopover->Show();
3280
3281 return mxInterimPopover;
3282}
3283
3284IMPL_LINK(SvxColorToolBoxControl, SelectedHdl, const NamedColor&, rColor, void)void SvxColorToolBoxControl::LinkStubSelectedHdl(void * instance
, const NamedColor& data) { return static_cast<SvxColorToolBoxControl
*>(instance)->SelectedHdl(data); } void SvxColorToolBoxControl
::SelectedHdl(const NamedColor& rColor)
3285{
3286 m_xBtnUpdater->Update(rColor);
3287}
3288
3289void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3290{
3291 ToolBox* pToolBox = nullptr;
3292 sal_uInt16 nId = 0;
3293 if (!getToolboxId(nId, &pToolBox) && !m_pToolbar)
3294 return;
3295
3296 if ( rEvent.FeatureURL.Complete == m_aCommandURL )
3297 {
3298 if (m_pToolbar)
3299 m_pToolbar->set_item_sensitive(m_aCommandURL.toUtf8(), rEvent.IsEnabled);
3300 else
3301 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3302 }
3303
3304 bool bValue;
3305 if ( !m_bSplitButton )
3306 {
3307 m_aColorStatus.statusChanged( rEvent );
3308 m_xBtnUpdater->Update( m_aColorStatus.GetColor() );
3309 }
3310 else if ( rEvent.State >>= bValue )
3311 {
3312 if (m_pToolbar)
3313 m_pToolbar->set_item_active(m_aCommandURL.toUtf8(), bValue);
3314 else if (pToolBox)
3315 pToolBox->CheckItem( nId, bValue );
3316 }
3317}
3318
3319void SvxColorToolBoxControl::execute(sal_Int16 /*nSelectModifier*/)
3320{
3321 if ( !m_bSplitButton )
3322 {
3323 if (m_pToolbar)
3324 {
3325 // Toggle the popup also when toolbutton is activated
3326 const OString aId(m_aCommandURL.toUtf8());
3327 m_pToolbar->set_menu_item_active(aId, !m_pToolbar->get_menu_item_active(aId));
3328 }
3329 else
3330 {
3331 // Open the popup also when Enter key is pressed.
3332 createPopupWindow();
3333 }
3334 return;
3335 }
3336
3337 OUString aCommand = m_aCommandURL;
3338 Color aColor = m_xBtnUpdater->GetCurrentColor();
3339
3340 switch( m_nSlotId )
3341 {
3342 case SID_ATTR_CHAR_COLOR2(10000 + 537) :
3343 aCommand = ".uno:CharColorExt";
3344 break;
3345
3346 case SID_ATTR_CHAR_COLOR_BACKGROUND(10000 + 489) :
3347 aCommand = ".uno:CharBackgroundExt";
3348 break;
3349 }
3350
3351 auto aArgs( comphelper::InitPropertySequence( {
3352 { m_aCommandURL.copy(5), css::uno::makeAny(aColor) }
3353 } ) );
3354 dispatchCommand( aCommand, aArgs );
3355
3356 EnsurePaletteManager();
3357 OUString sColorName = m_xBtnUpdater->GetCurrentColorName();
3358 m_xPaletteManager->AddRecentColor(aColor, sColorName);
3359}
3360
3361sal_Bool SvxColorToolBoxControl::opensSubToolbar()
3362{
3363 // We mark this controller as a sub-toolbar controller, so we get notified
3364 // (through updateImage method) on button image changes, and could redraw
3365 // the last used color on top of it.
3366 return true;
3367}
3368
3369void SvxColorToolBoxControl::updateImage()
3370{
3371 m_xBtnUpdater->Update(m_xBtnUpdater->GetCurrentColor(), true);
3372}
3373
3374OUString SvxColorToolBoxControl::getSubToolbarName()
3375{
3376 return OUString();
3377}
3378
3379void SvxColorToolBoxControl::functionSelected( const OUString& /*rCommand*/ )
3380{
3381}
3382
3383OUString SvxColorToolBoxControl::getImplementationName()
3384{
3385 return "com.sun.star.comp.svx.ColorToolBoxControl";
3386}
3387
3388css::uno::Sequence<OUString> SvxColorToolBoxControl::getSupportedServiceNames()
3389{
3390 return { "com.sun.star.frame.ToolbarController" };
3391}
3392
3393extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
3394com_sun_star_comp_svx_ColorToolBoxControl_get_implementation(
3395 css::uno::XComponentContext* rContext,
3396 css::uno::Sequence<css::uno::Any> const & )
3397{
3398 return cppu::acquire( new SvxColorToolBoxControl( rContext ) );
3399}
3400
3401SvxFrameToolBoxControl::SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext )
3402 : svt::PopupWindowController( rContext, nullptr, OUString() )
3403{
3404}
3405
3406void SAL_CALL SvxFrameToolBoxControl::execute(sal_Int16 /*KeyModifier*/)
3407{
3408 if (m_pToolbar)
3409 {
3410 // Toggle the popup also when toolbutton is activated
3411 const OString aId(m_aCommandURL.toUtf8());
3412 m_pToolbar->set_menu_item_active(aId, !m_pToolbar->get_menu_item_active(aId));
3413 }
3414 else
3415 {
3416 // Open the popup also when Enter key is pressed.
3417 createPopupWindow();
3418 }
3419}
3420
3421void SvxFrameToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3422{
3423 svt::PopupWindowController::initialize( rArguments );
3424
3425 if (m_pToolbar)
3426 {
3427 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3428 m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel());
3429 }
3430
3431 ToolBox* pToolBox = nullptr;
3432 sal_uInt16 nId = 0;
3433 if (getToolboxId(nId, &pToolBox))
3434 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
3435}
3436
3437std::unique_ptr<WeldToolbarPopup> SvxFrameToolBoxControl::weldPopupWindow()
3438{
3439 if ( m_aCommandURL == ".uno:LineStyle" )
3440 return std::make_unique<SvxLineWindow_Impl>(this, m_pToolbar);
3441 return std::make_unique<SvxFrameWindow_Impl>(this, m_pToolbar);
3442}
3443
3444VclPtr<vcl::Window> SvxFrameToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
3445{
3446 if ( m_aCommandURL == ".uno:LineStyle" )
3447 {
3448 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3449 std::make_unique<SvxLineWindow_Impl>(this, pParent->GetFrameWeld()));
3450
3451 mxInterimPopover->Show();
3452
3453 mxInterimPopover->SetText(SvxResId(RID_SVXSTR_FRAME_STYLEreinterpret_cast<char const *>("RID_SVXSTR_FRAME_STYLE"
"\004" u8"Border Style")
));
3454
3455 return mxInterimPopover;
3456 }
3457
3458 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3459 std::make_unique<SvxFrameWindow_Impl>(this, pParent->GetFrameWeld()));
3460
3461 mxInterimPopover->Show();
3462
3463 mxInterimPopover->SetText(SvxResId(RID_SVXSTR_FRAMEreinterpret_cast<char const *>("RID_SVXSTR_FRAME" "\004"
u8"Borders")
));
3464
3465 return mxInterimPopover;
3466}
3467
3468OUString SvxFrameToolBoxControl::getImplementationName()
3469{
3470 return "com.sun.star.comp.svx.FrameToolBoxControl";
3471}
3472
3473css::uno::Sequence< OUString > SvxFrameToolBoxControl::getSupportedServiceNames()
3474{
3475 return { "com.sun.star.frame.ToolbarController" };
3476}
3477
3478extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
3479com_sun_star_comp_svx_FrameToolBoxControl_get_implementation(
3480 css::uno::XComponentContext* rContext,
3481 css::uno::Sequence<css::uno::Any> const & )
3482{
3483 return cppu::acquire( new SvxFrameToolBoxControl( rContext ) );
3484}
3485
3486SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3487 PopupWindowController( rContext, nullptr, OUString() ),
3488 m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
3489 m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND )
3490{
3491}
3492
3493SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}
3494
3495namespace
3496{
3497 class SvxCurrencyList_Impl : public WeldToolbarPopup
3498 {
3499 private:
3500 rtl::Reference<SvxCurrencyToolBoxControl> m_xControl;
3501 std::unique_ptr<weld::Label> m_xLabel;
3502 std::unique_ptr<weld::TreeView> m_xCurrencyLb;
3503 std::unique_ptr<weld::Button> m_xOkBtn;
3504 OUString& m_rSelectedFormat;
3505 LanguageType& m_eSelectedLanguage;
3506
3507 std::vector<OUString> m_aFormatEntries;
3508 LanguageType m_eFormatLanguage;
3509 DECL_LINK(RowActivatedHdl, weld::TreeView&, bool)static bool LinkStubRowActivatedHdl(void *, weld::TreeView&
); bool RowActivatedHdl(weld::TreeView&)
;
3510 DECL_LINK(OKHdl, weld::Button&, void)static void LinkStubOKHdl(void *, weld::Button&); void OKHdl
(weld::Button&)
;
3511
3512 virtual void GrabFocus() override;
3513
3514 public:
3515 SvxCurrencyList_Impl(SvxCurrencyToolBoxControl* pControl, weld::Widget* pParent, OUString& rSelectedFormat, LanguageType& eSelectedLanguage)
3516 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/currencywindow.ui", "CurrencyWindow")
3517 , m_xControl(pControl)
3518 , m_xLabel(m_xBuilder->weld_label("label"))
3519 , m_xCurrencyLb(m_xBuilder->weld_tree_view("currency"))
3520 , m_xOkBtn(m_xBuilder->weld_button("ok"))
3521 , m_rSelectedFormat(rSelectedFormat)
3522 , m_eSelectedLanguage(eSelectedLanguage)
3523 {
3524 std::vector< OUString > aList;
3525 std::vector< sal_uInt16 > aCurrencyList;
3526 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
3527 sal_uInt16 nLen = rCurrencyTable.size();
3528
3529 SvNumberFormatter aFormatter( m_xControl->getContext(), LANGUAGE_SYSTEMLanguageType(0x0000) );
3530 m_eFormatLanguage = aFormatter.GetLanguage();
3531
3532 SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, aCurrencyList );
3533
3534 sal_uInt16 nPos = 0, nCount = 0;
3535 sal_Int32 nSelectedPos = -1;
3536 bool bIsSymbol;
3537 NfWSStringsDtor aStringsDtor;
3538
3539 OUString sLongestString;
3540
3541 m_xCurrencyLb->freeze();
3542 for( const auto& rItem : aList )
3543 {
3544 sal_uInt16& rCurrencyIndex = aCurrencyList[ nCount ];
3545 if ( rCurrencyIndex < nLen )
3546 {
3547 m_xCurrencyLb->append_text(rItem);
3548
3549 if (rItem.getLength() > sLongestString.getLength())
3550 sLongestString = rItem;
3551
3552 const NfCurrencyEntry& aCurrencyEntry = rCurrencyTable[ rCurrencyIndex ];
3553
3554 bIsSymbol = nPos >= nLen;
3555
3556 sal_uInt16 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, aCurrencyEntry, bIsSymbol );
3557 const OUString& rFormatStr = aStringsDtor[ nDefaultFormat ];
3558 m_aFormatEntries.push_back( rFormatStr );
3559 if( rFormatStr == m_rSelectedFormat )
3560 nSelectedPos = nPos;
3561 ++nPos;
3562 }
3563 ++nCount;
3564 }
3565 m_xCurrencyLb->thaw();
3566 // enable multiple selection enabled so we can start with nothing selected
3567 m_xCurrencyLb->set_selection_mode(SelectionMode::Multiple);
3568 m_xCurrencyLb->connect_row_activated( LINK( this, SvxCurrencyList_Impl, RowActivatedHdl )::tools::detail::makeLink( ::tools::detail::castTo<SvxCurrencyList_Impl
*>(this), &SvxCurrencyList_Impl::LinkStubRowActivatedHdl
)
);
3569 m_xLabel->set_label(SvxResId(RID_SVXSTR_TBLAFMT_CURRENCYreinterpret_cast<char const *>("RID_SVXSTR_TBLAFMT_CURRENCY"
"\004" u8"Currency")
));
3570 m_xCurrencyLb->select( nSelectedPos );
3571 m_xOkBtn->connect_clicked(LINK(this, SvxCurrencyList_Impl, OKHdl)::tools::detail::makeLink( ::tools::detail::castTo<SvxCurrencyList_Impl
*>(this), &SvxCurrencyList_Impl::LinkStubOKHdl)
);
3572
3573 // gtk will initially make a best guess depending on the first few entries, so copy the probable
3574 // longest entry to the start temporarily and force in the width at this point
3575 m_xCurrencyLb->insert_text(0, sLongestString);
3576 m_xCurrencyLb->set_size_request(m_xCurrencyLb->get_preferred_size().Width(), m_xCurrencyLb->get_height_rows(12));
3577 m_xCurrencyLb->remove(0);
3578 }
3579 };
3580
3581 void SvxCurrencyList_Impl::GrabFocus()
3582 {
3583 m_xCurrencyLb->grab_focus();
3584 }
3585
3586 IMPL_LINK_NOARG(SvxCurrencyList_Impl, OKHdl, weld::Button&, void)void SvxCurrencyList_Impl::LinkStubOKHdl(void * instance, weld
::Button& data) { return static_cast<SvxCurrencyList_Impl
*>(instance)->OKHdl(data); } void SvxCurrencyList_Impl
::OKHdl(__attribute__ ((unused)) weld::Button&)
3587 {
3588 RowActivatedHdl(*m_xCurrencyLb);
3589 }
3590
3591 IMPL_LINK_NOARG(SvxCurrencyList_Impl, RowActivatedHdl, weld::TreeView&, bool)bool SvxCurrencyList_Impl::LinkStubRowActivatedHdl(void * instance
, weld::TreeView& data) { return static_cast<SvxCurrencyList_Impl
*>(instance)->RowActivatedHdl(data); } bool SvxCurrencyList_Impl
::RowActivatedHdl(__attribute__ ((unused)) weld::TreeView&
)
3592 {
3593 if (!m_xControl.is())
3594 return true;
3595
3596 // multiple selection enabled so we can start with nothing selected,
3597 // so force single selection after something is picked
3598 int nSelected = m_xCurrencyLb->get_selected_index();
3599 if (nSelected == -1)
3600 return true;
3601
3602 m_xCurrencyLb->set_selection_mode(SelectionMode::Single);
3603
3604 m_rSelectedFormat = m_aFormatEntries[nSelected];
3605 m_eSelectedLanguage = m_eFormatLanguage;
3606
3607 m_xControl->execute(nSelected + 1);
3608
3609 m_xControl->EndPopupMode();
3610
3611 return true;
3612 }
3613}
3614
3615void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3616{
3617 PopupWindowController::initialize(rArguments);
3618
3619 if (m_pToolbar)
3620 {
3621 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3622 m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel());
3623 return;
3624 }
3625
3626 ToolBox* pToolBox = nullptr;
3627 sal_uInt16 nId = 0;
3628 if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL)
3629 pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId));
3630}
3631
3632std::unique_ptr<WeldToolbarPopup> SvxCurrencyToolBoxControl::weldPopupWindow()
3633{
3634 return std::make_unique<SvxCurrencyList_Impl>(this, m_pToolbar, m_aFormatString, m_eLanguage);
3635}
3636
3637VclPtr<vcl::Window> SvxCurrencyToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
3638{
3639 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3640 std::make_unique<SvxCurrencyList_Impl>(this, pParent->GetFrameWeld(), m_aFormatString, m_eLanguage));
3641
3642 mxInterimPopover->Show();
3643
3644 return mxInterimPopover;
3645}
3646
3647void SvxCurrencyToolBoxControl::execute( sal_Int16 nSelectModifier )
3648{
3649 sal_uInt32 nFormatKey;
3650 if (m_aFormatString.isEmpty())
3651 nFormatKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
3652 else
3653 {
3654 if ( nSelectModifier > 0 )
3655 {
3656 try
3657 {
3658 uno::Reference< util::XNumberFormatsSupplier > xRef( m_xFrame->getController()->getModel(), uno::UNO_QUERY );
3659 uno::Reference< util::XNumberFormats > rxNumberFormats( xRef->getNumberFormats(), uno::UNO_SET_THROW );
3660 css::lang::Locale aLocale = LanguageTag::convertToLocale( m_eLanguage );
3661 nFormatKey = rxNumberFormats->queryKey( m_aFormatString, aLocale, false );
3662 if ( nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND )
3663 nFormatKey = rxNumberFormats->addNew( m_aFormatString, aLocale );
3664 }
3665 catch( const uno::Exception& )
3666 {
3667 nFormatKey = m_nFormatKey;
3668 }
3669 }
3670 else
3671 nFormatKey = m_nFormatKey;
3672 }
3673
3674 if( nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
3675 {
3676 Sequence< PropertyValue > aArgs( 1 );
3677 aArgs[0].Name = "NumberFormatCurrency";
3678 aArgs[0].Value <<= nFormatKey;
3679 dispatchCommand( m_aCommandURL, aArgs );
3680 m_nFormatKey = nFormatKey;
3681 }
3682 else
3683 PopupWindowController::execute( nSelectModifier );
3684}
3685
3686OUString SvxCurrencyToolBoxControl::getImplementationName()
3687{
3688 return "com.sun.star.comp.svx.CurrencyToolBoxControl";
3689}
3690
3691css::uno::Sequence<OUString> SvxCurrencyToolBoxControl::getSupportedServiceNames()
3692{
3693 return { "com.sun.star.frame.ToolbarController" };
3694}
3695
3696extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
3697com_sun_star_comp_svx_CurrencyToolBoxControl_get_implementation(
3698 css::uno::XComponentContext* rContext,
3699 css::uno::Sequence<css::uno::Any> const & )
3700{
3701 return cppu::acquire( new SvxCurrencyToolBoxControl( rContext ) );
3702}
3703
3704Reference< css::accessibility::XAccessible > SvxFontNameBox_Impl::CreateAccessible()
3705{
3706 FillList();
3707 return InterimItemWindow::CreateAccessible();
3708}
3709
3710//static
3711void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
3712 std::vector<sal_uInt16>& rCurrencyList )
3713{
3714 rCurrencyList.clear();
3715
3716 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
3717 sal_uInt16 nCount = rCurrencyTable.size();
3718
3719 sal_uInt16 nStart = 1;
3720
3721 OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) + " " );
3722 aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3723 rCurrencyTable[0].GetLanguage() ) );
3724
3725 rList.push_back( aString );
3726 rCurrencyList.push_back( sal_uInt16(-1) ); // nAuto
3727
3728 if( bFlag )
3729 {
3730 rList.push_back( aString );
3731 rCurrencyList.push_back( 0 );
3732 ++nStart;
3733 }
3734
3735 CollatorWrapper aCollator( ::comphelper::getProcessComponentContext() );
3736 aCollator.loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
3737
3738 const OUString aTwoSpace(" ");
3739
3740 for( sal_uInt16 i = 1; i < nCount; ++i )
3741 {
3742 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3743 aStr += aTwoSpace;
3744 aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
3745 aStr += aTwoSpace;
3746 aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3747 rCurrencyTable[i].GetLanguage() ) );
3748
3749 std::vector<OUString>::size_type j = nStart;
3750 for( ; j < rList.size(); ++j )
3751 if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3752 break; // insert before first greater than
3753
3754 rList.insert( rList.begin() + j, aStr );
3755 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3756 }
3757
3758 // Append ISO codes to symbol list.
3759 // XXX If this is to be changed, various other places would had to be
3760 // adapted that assume this order!
3761 std::vector<OUString>::size_type nCont = rList.size();
3762
3763 for ( sal_uInt16 i = 1; i < nCount; ++i )
3764 {
3765 bool bInsert = true;
3766 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3767
3768 std::vector<OUString>::size_type j = nCont;
3769 for ( ; j < rList.size() && bInsert; ++j )
3770 {
3771 if( rList[j] == aStr )
3772 bInsert = false;
3773 else if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3774 break; // insert before first greater than
3775 }
3776 if ( bInsert )
3777 {
3778 rList.insert( rList.begin() + j, aStr );
3779 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3780 }
3781 }
3782}
3783
3784ListBoxColorWrapper::ListBoxColorWrapper(ColorListBox* pControl)
3785 : mpControl(pControl)
3786{
3787}
3788
3789void ListBoxColorWrapper::operator()(const OUString& /*rCommand*/, const NamedColor& rColor)
3790{
3791 mpControl->Selected(rColor);
3792}
3793
3794void ColorListBox::EnsurePaletteManager()
3795{
3796 if (!m_xPaletteManager)
3797 {
3798 m_xPaletteManager = std::make_shared<PaletteManager>();
3799 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
3800 }
3801}
3802
3803void ColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
3804{
3805 m_nSlotId = nSlotId;
3806 m_bShowNoneButton = bShowNoneButton;
3807 m_xButton->set_popover(nullptr);
3808 m_xColorWindow.reset();
3809 m_aSelectedColor = bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId);
3810 ShowPreview(m_aSelectedColor);
3811 createColorWindow();
3812}
3813
3814ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl, weld::Window* pTopLevel)
3815 : m_xButton(std::move(pControl))
3816 , m_pTopLevel(pTopLevel)
3817 , m_aColorWrapper(this)
3818 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
3819 , m_nSlotId(0)
3820 , m_bShowNoneButton(false)
3821{
3822 m_xButton->connect_toggled(LINK(this, ColorListBox, ToggleHdl)::tools::detail::makeLink( ::tools::detail::castTo<ColorListBox
*>(this), &ColorListBox::LinkStubToggleHdl)
);
3823 m_aSelectedColor = GetAutoColor(m_nSlotId);
3824 LockWidthRequest();
3825 ShowPreview(m_aSelectedColor);
3826}
3827
3828IMPL_LINK(ColorListBox, ToggleHdl, weld::ToggleButton&, rButton, void)void ColorListBox::LinkStubToggleHdl(void * instance, weld::ToggleButton
& data) { return static_cast<ColorListBox *>(instance
)->ToggleHdl(data); } void ColorListBox::ToggleHdl(weld::ToggleButton
& rButton)
3829{
3830 if (rButton.get_active())
3831 getColorWindow()->GrabFocus();
3832}
3833
3834ColorListBox::~ColorListBox()
3835{
3836}
3837
3838ColorWindow* ColorListBox::getColorWindow() const
3839{
3840 if (!m_xColorWindow)
3841 const_cast<ColorListBox*>(this)->createColorWindow();
3842 return m_xColorWindow.get();
3843}
3844
3845void ColorListBox::createColorWindow()
3846{
3847 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
3848 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
3849 css::uno::Reference<css::frame::XFrame> xFrame(pFrame ? pFrame->GetFrameInterface() : uno::Reference<css::frame::XFrame>());
3850
3851 EnsurePaletteManager();
3852
3853 m_xColorWindow.reset(new ColorWindow(
3854 OUString() /*m_aCommandURL*/,
3855 m_xPaletteManager,
3856 m_aColorStatus,
3857 m_nSlotId,
3858 xFrame,
3859 m_pTopLevel,
3860 m_xButton.get(),
3861 m_aColorWrapper));
3862
3863 SetNoSelection();
3864 m_xButton->set_popover(m_xColorWindow->getTopLevel());
3865 if (m_bShowNoneButton)
3866 m_xColorWindow->ShowNoneButton();
3867 m_xColorWindow->SelectEntry(m_aSelectedColor);
3868}
3869
3870void ColorListBox::SelectEntry(const NamedColor& rColor)
3871{
3872 if (rColor.second.trim().isEmpty())
3873 {
3874 SelectEntry(rColor.first);
3875 return;
3876 }
3877 ColorWindow* pColorWindow = getColorWindow();
3878 pColorWindow->SelectEntry(rColor);
3879 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
3880 ShowPreview(m_aSelectedColor);
3881}
3882
3883void ColorListBox::SelectEntry(const Color& rColor)
3884{
3885 ColorWindow* pColorWindow = getColorWindow();
3886 pColorWindow->SelectEntry(rColor);
3887 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
3888 ShowPreview(m_aSelectedColor);
3889}
3890
3891void ColorListBox::Selected(const NamedColor& rColor)
3892{
3893 ShowPreview(rColor);
3894 m_aSelectedColor = rColor;
3895 if (m_aSelectedLink.IsSet())
3896 m_aSelectedLink.Call(*this);
3897}
3898
3899//to avoid the box resizing every time the color is changed to
3900//the optimal size of the individual color, get the longest
3901//standard color and stick with that as the size for all
3902void ColorListBox::LockWidthRequest()
3903{
3904 NamedColor aLongestColor;
3905 long nMaxStandardColorTextWidth = 0;
3906 XColorListRef const xColorTable = XColorList::CreateStdColorList();
3907 for (long i = 0; i != xColorTable->Count(); ++i)
3908 {
3909 XColorEntry& rEntry = *xColorTable->GetColor(i);
3910 auto nColorTextWidth = m_xButton->get_pixel_size(rEntry.GetName()).Width();
3911 if (nColorTextWidth > nMaxStandardColorTextWidth)
3912 {
3913 nMaxStandardColorTextWidth = nColorTextWidth;
3914 aLongestColor.second = rEntry.GetName();
3915 }
3916 }
3917 ShowPreview(aLongestColor);
3918 m_xButton->set_size_request(m_xButton->get_preferred_size().Width(), -1);
3919}
3920
3921void ColorListBox::ShowPreview(const NamedColor &rColor)
3922{
3923 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3924 Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
3925
3926 ScopedVclPtrInstance<VirtualDevice> xDevice;
3927 xDevice->SetOutputSize(aImageSize);
3928 const tools::Rectangle aRect(Point(0, 0), aImageSize);
3929 if (m_bShowNoneButton && rColor.first == COL_NONE_COLOR::Color(0x80, 0xFF, 0xFF, 0xFF))
3930 {
3931 const Color aW(COL_WHITE);
3932 const Color aG(0xef, 0xef, 0xef);
3933 xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 8, aW, aG);
3934 xDevice->SetFillColor();
3935 }
3936 else
3937 {
3938 if (rColor.first == COL_AUTO)
3939 xDevice->SetFillColor(m_aAutoDisplayColor);
3940 else
3941 xDevice->SetFillColor(rColor.first);
3942 }
3943
3944 xDevice->SetLineColor(rStyleSettings.GetDisableColor());
3945 xDevice->DrawRect(aRect);
3946
3947 m_xButton->set_image(xDevice.get());
3948 m_xButton->set_label(rColor.second);
3949}
3950
3951MenuOrToolMenuButton::MenuOrToolMenuButton(weld::MenuButton* pMenuButton)
3952 : m_pMenuButton(pMenuButton)
3953 , m_pToolbar(nullptr)
3954 , m_pControl(nullptr)
3955 , m_nId(0)
3956{
3957}
3958
3959MenuOrToolMenuButton::MenuOrToolMenuButton(weld::Toolbar* pToolbar, const OString& rIdent)
3960 : m_pMenuButton(nullptr)
3961 , m_pToolbar(pToolbar)
3962 , m_aIdent(rIdent)
3963 , m_pControl(nullptr)
3964 , m_nId(0)
3965{
3966}
3967
3968MenuOrToolMenuButton::MenuOrToolMenuButton(SvxColorToolBoxControl* pControl, ToolBox* pToolbar, sal_uInt16 nId)
3969 : m_pMenuButton(nullptr)
3970 , m_pToolbar(nullptr)
3971 , m_pControl(pControl)
3972 , m_xToolBox(pToolbar)
3973 , m_nId(nId)
3974{
3975}
3976
3977MenuOrToolMenuButton::~MenuOrToolMenuButton()
3978{
3979}
3980
3981bool MenuOrToolMenuButton::get_active() const
3982{
3983 if (m_pMenuButton)
3984 return m_pMenuButton->get_active();
3985 if (m_pToolbar)
3986 return m_pToolbar->get_menu_item_active(m_aIdent);
3987 return m_xToolBox->GetDownItemId() == m_nId;
3988}
3989
3990void MenuOrToolMenuButton::set_inactive() const
3991{
3992 if (m_pMenuButton)
3993 {
3994 if (m_pMenuButton->get_active())
3995 m_pMenuButton->set_active(false);
3996 return;
3997 }
3998 if (m_pToolbar)
3999 {
4000 if (m_pToolbar->get_menu_item_active(m_aIdent))
4001 m_pToolbar->set_menu_item_active(m_aIdent, false);
4002 return;
4003 }
4004 m_pControl->EndPopupMode();
4005}
4006
4007weld::Widget* MenuOrToolMenuButton::get_widget() const
4008{
4009 if (m_pMenuButton)
4010 return m_pMenuButton;
4011 if (m_pToolbar)
4012 return m_pToolbar;
4013 return m_xToolBox->GetFrameWeld();
4014}
4015
4016/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
2
Calling copy constructor for 'Reference<(anonymous namespace)::SvxFontNameBox_Impl>'
5
Returning from copy constructor for 'Reference<(anonymous namespace)::SvxFontNameBox_Impl>'
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
6
Calling 'Reference::clear'
13
Returning; memory was released
205 if (aTmp.get()) {
14
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
3
Assuming field 'm_pBody' is non-null
4
Taking true branch
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
6.1
Field 'm_pBody' is non-null
6.1
Field 'm_pBody' is non-null
6.1
Field 'm_pBody' is non-null
6.1
Field 'm_pBody' is non-null
)
7
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
8
Calling 'VclReferenceBase::release'
12
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
15
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
9
Assuming the condition is true
10
Taking true branch
40 delete this;
11
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif