1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <comphelper/configurationlistener.hxx>
23 #include <comphelper/propertysequence.hxx>
24 #include <comphelper/propertyvalue.hxx>
25 #include <tools/color.hxx>
26 #include <svl/numformat.hxx>
27 #include <svl/poolitem.hxx>
28 #include <svl/itemset.hxx>
29 #include <svl/itempool.hxx>
30 #include <vcl/commandinfoprovider.hxx>
31 #include <vcl/event.hxx>
32 #include <vcl/toolbox.hxx>
33 #include <vcl/customweld.hxx>
34 #include <vcl/vclptr.hxx>
35 #include <vcl/weldutils.hxx>
36 #include <svtools/valueset.hxx>
37 #include <svtools/ctrlbox.hxx>
38 #include <svl/style.hxx>
39 #include <svtools/ctrltool.hxx>
40 #include <svtools/borderhelper.hxx>
41 #include <vcl/InterimItemWindow.hxx>
42 #include <sfx2/tbxctrl.hxx>
43 #include <sfx2/tplpitem.hxx>
44 #include <sfx2/sfxstatuslistener.hxx>
45 #include <sfx2/viewsh.hxx>
46 #include <toolkit/helper/vclunohelper.hxx>
47 #include <sfx2/viewfrm.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/settings.hxx>
50 #include <vcl/virdev.hxx>
51 #include <com/sun/star/awt/FontDescriptor.hpp>
52 #include <com/sun/star/table/BorderLine2.hpp>
53 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
54 #include <com/sun/star/lang/XServiceInfo.hpp>
55 #include <com/sun/star/beans/XPropertySet.hpp>
56 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
57 #include <com/sun/star/frame/XDispatchProvider.hpp>
58 #include <com/sun/star/frame/XFrame.hpp>
59 #include <svx/strings.hrc>
60 #include <svx/svxids.hrc>
62 #include <sfx2/sidebar/Sidebar.hxx>
63 #include <svx/xtable.hxx>
64 #include <editeng/editids.hrc>
65 #include <editeng/fontitem.hxx>
66 #include <editeng/fhgtitem.hxx>
67 #include <editeng/boxitem.hxx>
68 #include <editeng/charreliefitem.hxx>
69 #include <editeng/contouritem.hxx>
70 #include <editeng/colritem.hxx>
71 #include <editeng/crossedoutitem.hxx>
72 #include <editeng/emphasismarkitem.hxx>
73 #include <editeng/flstitem.hxx>
74 #include <editeng/lineitem.hxx>
75 #include <editeng/postitem.hxx>
76 #include <editeng/shdditem.hxx>
77 #include <editeng/udlnitem.hxx>
78 #include <editeng/wghtitem.hxx>
79 #include <editeng/svxfont.hxx>
80 #include <editeng/cmapitem.hxx>
81 #include <svx/colorwindow.hxx>
82 #include <svx/colorbox.hxx>
83 #include <svx/tbcontrl.hxx>
84 #include <svx/dialmgr.hxx>
85 #include <svx/PaletteManager.hxx>
88 #include <tbxcolorupdate.hxx>
89 #include <editeng/eerdll.hxx>
90 #include <editeng/editrids.hrc>
91 #include <svx/xdef.hxx>
92 #include <svx/xfillit0.hxx>
93 #include <svx/xflclit.hxx>
94 #include <svl/currencytable.hxx>
95 #include <svl/zformat.hxx>
96 #include <svtools/langtab.hxx>
97 #include <cppu/unotype.hxx>
98 #include <cppuhelper/supportsservice.hxx>
99 #include <officecfg/Office/Common.hxx>
100 #include <o3tl/temporary.hxx>
101 #include <o3tl/safeint.hxx>
102 #include <o3tl/string_view.hxx>
103 #include <o3tl/typed_flags_set.hxx>
104 #include <bitmaps.hlst>
105 #include <sal/log.hxx>
106 #include <unotools/collatorwrapper.hxx>
107 #include <sfx2/IDocumentModelAccessor.hxx>
109 #include <comphelper/lok.hxx>
110 #include <tools/json_writer.hxx>
112 #include <editeng/editeng.hxx>
114 #define MAX_MRU_FONTNAME_ENTRIES 5
116 #define COMBO_WIDTH_IN_CHARS 18
119 using namespace ::editeng
;
120 using namespace ::com::sun::star
;
121 using namespace ::com::sun::star::uno
;
122 using namespace ::com::sun::star::frame
;
123 using namespace ::com::sun::star::beans
;
124 using namespace ::com::sun::star::lang
;
130 tools::Long textWidth
;
131 SvtScriptType scriptType
;
133 ScriptInfo(SvtScriptType scrptType
, sal_Int32 position
)
135 , scriptType(scrptType
)
136 , changePos(position
)
141 class SvxStyleBox_Base
144 SvxStyleBox_Base(std::unique_ptr
<weld::ComboBox
> xWidget
, OUString rCommand
, SfxStyleFamily eFamily
,
145 const Reference
<XFrame
>& _xFrame
, OUString aClearFormatKey
,
146 OUString aMoreKey
, bool bInSpecialMode
, SvxStyleToolBoxControl
& rCtrl
);
148 virtual ~SvxStyleBox_Base()
152 void SetFamily( SfxStyleFamily eNewFamily
);
154 void SetDefaultStyle( const OUString
& rDefault
) { sDefaultStyle
= rDefault
; }
156 int get_count() const { return m_xWidget
->get_count(); }
157 OUString
get_text(int nIndex
) const { return m_xWidget
->get_text(nIndex
); }
158 OUString
get_active_text() const { return m_xWidget
->get_active_text(); }
160 void append_text(const OUString
& rStr
)
162 OUString
sId(OUString::number(m_xWidget
->get_count()));
163 m_xWidget
->append(sId
, rStr
);
166 void insert_separator(int pos
, const OUString
& rId
)
168 m_xWidget
->insert_separator(pos
, rId
);
171 void set_active_or_entry_text(const OUString
& rText
)
173 const int nFound
= m_xWidget
->find_text(rText
);
175 m_xWidget
->set_active(nFound
);
177 m_xWidget
->set_entry_text(rText
);
180 void set_active(int nActive
)
182 m_xWidget
->set_active(nActive
);
192 m_xWidget
->save_value();
198 m_nMaxUserDrawFontWidth
= 0;
206 virtual bool DoKeyInput(const KeyEvent
& rKEvt
);
209 std::optional
<SvxFont
> m_oFont
;
210 std::optional
<SvxFont
> m_oCJKFont
;
211 std::optional
<SvxFont
> m_oCTLFont
;
213 DECL_LINK(SelectHdl
, weld::ComboBox
&, void);
214 DECL_LINK(KeyInputHdl
, const KeyEvent
&, bool);
215 DECL_LINK(ActivateHdl
, weld::ComboBox
&, bool);
216 DECL_LINK(FocusOutHdl
, weld::Widget
&, void);
217 DECL_LINK(DumpAsPropertyTreeHdl
, tools::JsonWriter
&, void);
218 DECL_LINK(CustomRenderHdl
, weld::ComboBox::render_args
, void);
219 DECL_LINK(CustomGetSizeHdl
, OutputDevice
&, Size
);
221 /// Calculate the optimal width of the dropdown. Very expensive operation, triggers lots of font measurement.
222 void CalcOptimalExtraUserWidth(vcl::RenderContext
& rRenderContext
);
224 void Select(bool bNonTravelSelect
);
226 tools::Rectangle
CalcBoundRect(vcl::RenderContext
& rRenderContext
, const OUString
&rStyleName
, std::vector
<ScriptInfo
>& rScriptChanges
, double fRatio
= 1);
229 SvxStyleToolBoxControl
& m_rCtrl
;
231 std::unique_ptr
<weld::Builder
> m_xMenuBuilder
;
232 std::unique_ptr
<weld::Menu
> m_xMenu
;
233 std::unique_ptr
<weld::ComboBox
> m_xWidget
;
235 SfxStyleFamily eStyleFamily
;
236 int m_nMaxUserDrawFontWidth
;
237 int m_nLastItemWithMenu
;
239 Reference
< XFrame
> m_xFrame
;
241 OUString aClearFormatKey
;
243 OUString sDefaultStyle
;
247 static Color
TestColorsVisible(const Color
&FontCol
, const Color
&BackCol
);
248 void UserDrawEntry(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
, const tools::Rectangle
& rTextRect
, const OUString
&rStyleName
, const std::vector
<ScriptInfo
>& rScriptChanges
);
249 void SetupEntry(vcl::RenderContext
& rRenderContext
, sal_Int32 nItem
, const tools::Rectangle
& rRect
, std::u16string_view rStyleName
, bool bIsNotSelected
);
250 DECL_LINK(MenuSelectHdl
, const OUString
&, void);
251 DECL_STATIC_LINK(SvxStyleBox_Base
, ShowMoreHdl
, void*, void);
254 class SvxStyleBox_Impl final
: public InterimItemWindow
255 , public SvxStyleBox_Base
258 SvxStyleBox_Impl(vcl::Window
* pParent
, const OUString
& rCommand
, SfxStyleFamily eFamily
,
259 const Reference
< XFrame
>& _xFrame
,const OUString
& rClearFormatKey
, const OUString
& rMoreKey
, bool bInSpecialMode
, SvxStyleToolBoxControl
& rCtrl
);
261 virtual ~SvxStyleBox_Impl() override
266 virtual void dispose() override
270 m_xMenuBuilder
.reset();
271 InterimItemWindow::dispose();
274 virtual bool DoKeyInput(const KeyEvent
& rKEvt
) override
;
278 virtual void DataChanged(const DataChangedEvent
& rDCEvt
) override
;
279 void SetOptimalSize();
282 class SvxFontNameBox_Impl
;
283 class SvxFontNameBox_Base
;
285 class SvxFontNameToolBoxControl final
: public cppu::ImplInheritanceHelper
<svt::ToolboxController
,
286 css::lang::XServiceInfo
>
289 SvxFontNameToolBoxControl();
292 virtual void SAL_CALL
statusChanged( const css::frame::FeatureStateEvent
& rEvent
) override
;
294 // XToolbarController
295 virtual css::uno::Reference
<css::awt::XWindow
> SAL_CALL
createItemWindow(const css::uno::Reference
<css::awt::XWindow
>& rParent
) override
;
298 virtual void SAL_CALL
dispose() override
;
301 virtual OUString SAL_CALL
getImplementationName() override
;
302 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) override
;
303 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
306 VclPtr
<SvxFontNameBox_Impl
> m_xVclBox
;
307 std::unique_ptr
<SvxFontNameBox_Base
> m_xWeldBox
;
308 SvxFontNameBox_Base
* m_pBox
;
311 class FontOptionsListener final
: public comphelper::ConfigurationListenerProperty
<bool>
314 SvxFontNameBox_Base
& m_rBox
;
316 virtual void setProperty(const css::uno::Any
&rProperty
) override
;
318 FontOptionsListener(const rtl::Reference
<comphelper::ConfigurationListener
>& rListener
, const OUString
& rProp
, SvxFontNameBox_Base
& rBox
)
319 : comphelper::ConfigurationListenerProperty
<bool>(rListener
, rProp
)
325 class SvxFontNameBox_Base
328 rtl::Reference
<comphelper::ConfigurationListener
> m_xListener
;
329 FontOptionsListener m_aWYSIWYG
;
330 FontOptionsListener m_aHistory
;
333 SvxFontNameToolBoxControl
& m_rCtrl
;
335 std::unique_ptr
<FontNameBox
> m_xWidget
;
336 const FontList
* pFontList
;
337 ::std::unique_ptr
<FontList
> m_aOwnFontList
;
341 Reference
< XFrame
> m_xFrame
;
342 bool mbCheckingUnknownFont
;
343 bool mbDropDownActive
;
345 void ReleaseFocus_Impl();
347 void Select(bool bNonTravelSelect
);
351 Sequence
< PropertyValue
> aArgs
;
352 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
353 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:CharEndPreviewFontName"_ustr
, aArgs
);
356 bool CheckFontIsAvailable(std::u16string_view fontname
);
357 void CheckAndMarkUnknownFont();
360 SvxFontNameBox_Base(std::unique_ptr
<weld::ComboBox
> xWidget
, const Reference
<XFrame
>& rFrame
,
361 SvxFontNameToolBoxControl
& rCtrl
);
362 virtual ~SvxFontNameBox_Base()
364 m_xListener
->dispose();
368 void Update( const css::awt::FontDescriptor
* pFontDesc
);
369 sal_uInt16
GetListCount() const { return nFtCount
; }
370 void Clear() { m_xWidget
->clear(); nFtCount
= 0; }
371 void Fill( const FontList
* pList
)
373 m_xWidget
->Fill(pList
);
374 nFtCount
= pList
->GetFontNameCount();
377 void SetOwnFontList(::std::unique_ptr
<FontList
> && _aOwnFontList
) { m_aOwnFontList
= std::move(_aOwnFontList
); }
379 virtual void set_sensitive(bool bSensitive
)
381 m_xWidget
->set_sensitive(bSensitive
);
384 void set_active_or_entry_text(const OUString
& rText
);
386 void statusChanged_Impl(const css::frame::FeatureStateEvent
& rEvent
);
388 virtual bool DoKeyInput(const KeyEvent
& rKEvt
);
390 void EnableControls();
392 DECL_LINK(SelectHdl
, weld::ComboBox
&, void);
393 DECL_LINK(KeyInputHdl
, const KeyEvent
&, bool);
394 DECL_LINK(ActivateHdl
, weld::ComboBox
&, bool);
395 DECL_LINK(FocusInHdl
, weld::Widget
&, void);
396 DECL_LINK(FocusOutHdl
, weld::Widget
&, void);
397 DECL_LINK(PopupToggledHdl
, weld::ComboBox
&, void);
398 DECL_LINK(LivePreviewHdl
, const FontMetric
&, void);
399 DECL_LINK(DumpAsPropertyTreeHdl
, tools::JsonWriter
&, void);
402 void FontOptionsListener::setProperty(const css::uno::Any
&rProperty
)
404 comphelper::ConfigurationListenerProperty
<bool>::setProperty(rProperty
);
405 m_rBox
.EnableControls();
408 class SvxFontNameBox_Impl final
: public InterimItemWindow
409 , public SvxFontNameBox_Base
412 virtual void DataChanged( const DataChangedEvent
& rDCEvt
) override
;
413 virtual void GetFocus() override
416 m_xWidget
->grab_focus();
417 InterimItemWindow::GetFocus();
420 void SetOptimalSize();
422 virtual bool DoKeyInput(const KeyEvent
& rKEvt
) override
;
425 SvxFontNameBox_Impl(vcl::Window
* pParent
,
426 const Reference
<XFrame
>& rFrame
, SvxFontNameToolBoxControl
& rCtrl
);
428 virtual void dispose() override
431 InterimItemWindow::dispose();
434 virtual ~SvxFontNameBox_Impl() override
439 virtual Reference
< css::accessibility::XAccessible
> CreateAccessible() override
;
441 virtual void set_sensitive(bool bSensitive
) override
443 m_xWidget
->set_sensitive(bSensitive
);
445 InterimItemWindow::Enable();
447 InterimItemWindow::Disable();
452 // SelectHdl needs the Modifiers, get them in MouseButtonUp
453 class SvxFrmValueSet_Impl final
: public ValueSet
456 sal_uInt16 nModifier
;
458 virtual bool MouseButtonUp(const MouseEvent
& rMEvt
) override
460 nModifier
= rMEvt
.GetModifier();
461 return ValueSet::MouseButtonUp(rMEvt
);
465 SvxFrmValueSet_Impl()
470 sal_uInt16
GetModifier() const {return nModifier
;}
477 class SvxFrameToolBoxControl
;
479 class SvxFrameWindow_Impl final
: public WeldToolbarPopup
482 rtl::Reference
<SvxFrameToolBoxControl
> mxControl
;
483 std::unique_ptr
<SvxFrmValueSet_Impl
> mxFrameSet
;
484 std::unique_ptr
<weld::CustomWeld
> mxFrameSetWin
;
485 std::vector
<std::pair
<BitmapEx
, OUString
>> aImgVec
;
489 void InitImageList();
490 void CalcSizeValueSet();
491 DECL_LINK( SelectHdl
, ValueSet
*, void );
493 void SetDiagonalDownBorder(const SvxLineItem
& dDownLineItem
);
494 void SetDiagonalUpBorder(const SvxLineItem
& dUpLineItem
);
497 SvxFrameWindow_Impl(SvxFrameToolBoxControl
* pControl
, weld::Widget
* pParent
);
498 virtual void GrabFocus() override
500 mxFrameSet
->GrabFocus();
503 virtual void statusChanged( const css::frame::FeatureStateEvent
& rEvent
) override
;
506 class SvxFrameToolBoxControl
: public svt::PopupWindowController
509 explicit SvxFrameToolBoxControl( const css::uno::Reference
< css::uno::XComponentContext
>& rContext
);
512 virtual void SAL_CALL
initialize( const css::uno::Sequence
< css::uno::Any
>& rArguments
) override
;
515 virtual OUString SAL_CALL
getImplementationName() override
;
516 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
518 virtual void SAL_CALL
execute(sal_Int16 nKeyModifier
) override
;
520 virtual std::unique_ptr
<WeldToolbarPopup
> weldPopupWindow() override
;
521 virtual VclPtr
<vcl::Window
> createVclPopupWindow( vcl::Window
* pParent
) override
;
524 class LineListBox final
: public ValueSet
527 typedef Color (*ColorFunc
)(Color
);
528 typedef Color (*ColorDistFunc
)(Color
, Color
);
532 /** Set the width in Twips */
533 Size
SetWidth( tools::Long nWidth
)
535 tools::Long nOldWidth
= m_nWidth
;
537 return UpdateEntries( nOldWidth
);
540 void SetNone( const OUString
& sNone
)
545 /** Insert a listbox entry with all widths in Twips. */
546 void InsertEntry(const BorderWidthImpl
& rWidthImpl
,
547 SvxBorderLineStyle nStyle
, tools::Long nMinWidth
= 0,
548 ColorFunc pColor1Fn
= &sameColor
,
549 ColorFunc pColor2Fn
= &sameColor
,
550 ColorDistFunc pColorDistFn
= &sameDistColor
);
552 SvxBorderLineStyle
GetEntryStyle( sal_Int32 nPos
) const;
554 SvxBorderLineStyle
GetSelectEntryStyle() const;
556 void SetSourceUnit( FieldUnit eNewUnit
) { eSourceUnit
= eNewUnit
; }
558 const Color
& GetColor() const { return aColor
; }
560 virtual void SetDrawingArea(weld::DrawingArea
* pDrawingArea
) override
;
563 void ImpGetLine(tools::Long nLine1
, tools::Long nLine2
, tools::Long nDistance
,
564 Color nColor1
, Color nColor2
, Color nColorDist
,
565 SvxBorderLineStyle nStyle
, BitmapEx
& rBmp
);
567 void UpdatePaintLineColor(); // returns sal_True if maPaintCol has changed
569 Size
UpdateEntries( tools::Long nOldWidth
);
570 sal_Int32
GetStylePos( sal_Int32 nListPos
, tools::Long nWidth
);
572 const Color
& GetPaintColor() const
577 Color
GetColorLine1( sal_Int32 nPos
);
578 Color
GetColorLine2( sal_Int32 nPos
);
579 Color
GetColorDist( sal_Int32 nPos
);
581 LineListBox( const LineListBox
& ) = delete;
582 LineListBox
& operator =( const LineListBox
& ) = delete;
584 std::vector
<std::unique_ptr
<ImpLineListData
>> m_vLineList
;
585 tools::Long m_nWidth
;
587 ScopedVclPtr
<VirtualDevice
> aVirDev
;
591 FieldUnit eSourceUnit
;
594 SvxBorderLineStyle
LineListBox::GetSelectEntryStyle() const
596 SvxBorderLineStyle nStyle
= SvxBorderLineStyle::SOLID
;
597 size_t nPos
= GetSelectItemPos();
598 if (nPos
!= VALUESET_ITEM_NOTFOUND
)
600 if (!m_sNone
.isEmpty())
602 nStyle
= GetEntryStyle( nPos
);
608 void LineListBox::ImpGetLine( tools::Long nLine1
, tools::Long nLine2
, tools::Long nDistance
,
609 Color aColor1
, Color aColor2
, Color aColorDist
,
610 SvxBorderLineStyle nStyle
, BitmapEx
& rBmp
)
612 auto nMinWidth
= GetDrawingArea()->get_ref_device().approximate_digit_width() * COMBO_WIDTH_IN_CHARS
;
613 Size
aSize(nMinWidth
, aTxtSize
.Height());
614 aSize
.AdjustWidth( -(aTxtSize
.Width()) );
615 aSize
.AdjustWidth( -6 );
617 // SourceUnit to Twips
618 if ( eSourceUnit
== FieldUnit::POINT
)
626 aSize
= aVirDev
->PixelToLogic( aSize
);
627 tools::Long nPix
= aVirDev
->PixelToLogic( Size( 0, 1 ) ).Height();
628 sal_uInt32 n1
= nLine1
;
629 sal_uInt32 n2
= nLine2
;
630 tools::Long nDist
= nDistance
;
640 tools::Long nVirHeight
= n1
+nDist
+n2
;
641 if ( nVirHeight
> aSize
.Height() )
642 aSize
.setHeight( nVirHeight
);
643 // negative width should not be drawn
644 if ( aSize
.Width() <= 0 )
647 Size aVirSize
= aVirDev
->LogicToPixel( aSize
);
648 if ( aVirDev
->GetOutputSizePixel() != aVirSize
)
649 aVirDev
->SetOutputSizePixel( aVirSize
);
650 aVirDev
->SetFillColor( aColorDist
);
651 aVirDev
->DrawRect( tools::Rectangle( Point(), aSize
) );
653 aVirDev
->SetFillColor( aColor1
);
655 double y1
= double( n1
) / 2;
656 svtools::DrawLine( *aVirDev
, basegfx::B2DPoint( 0, y1
), basegfx::B2DPoint( aSize
.Width( ), y1
), n1
, nStyle
);
660 double y2
= n1
+ nDist
+ double( n2
) / 2;
661 aVirDev
->SetFillColor( aColor2
);
662 svtools::DrawLine( *aVirDev
, basegfx::B2DPoint( 0, y2
), basegfx::B2DPoint( aSize
.Width(), y2
), n2
, SvxBorderLineStyle::SOLID
);
664 rBmp
= aVirDev
->GetBitmapEx( Point(), Size( aSize
.Width(), n1
+nDist
+n2
) );
667 LineListBox::LineListBox()
670 , aVirDev(VclPtr
<VirtualDevice
>::Create())
671 , aColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor())
672 , maPaintCol(COL_BLACK
)
673 , eSourceUnit(FieldUnit::POINT
)
675 aVirDev
->SetLineColor();
676 aVirDev
->SetMapMode( MapMode( MapUnit::MapTwip
) );
679 void LineListBox::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
681 ValueSet::SetDrawingArea(pDrawingArea
);
683 OutputDevice
& rDevice
= pDrawingArea
->get_ref_device();
685 aTxtSize
.setWidth( rDevice
.approximate_digit_width() );
686 aTxtSize
.setHeight( rDevice
.GetTextHeight() );
688 UpdatePaintLineColor();
691 sal_Int32
LineListBox::GetStylePos( sal_Int32 nListPos
, tools::Long nWidth
)
694 if (!m_sNone
.isEmpty())
699 size_t nCount
= m_vLineList
.size();
700 while ( nPos
== -1 && i
< nCount
)
702 auto& pData
= m_vLineList
[ i
];
703 if ( pData
->GetMinWidth() <= nWidth
)
706 nPos
= static_cast<sal_Int32
>(i
);
715 void LineListBox::InsertEntry(
716 const BorderWidthImpl
& rWidthImpl
, SvxBorderLineStyle nStyle
, tools::Long nMinWidth
,
717 ColorFunc pColor1Fn
, ColorFunc pColor2Fn
, ColorDistFunc pColorDistFn
)
719 m_vLineList
.emplace_back(new ImpLineListData(
720 rWidthImpl
, nStyle
, nMinWidth
, pColor1Fn
, pColor2Fn
, pColorDistFn
));
723 SvxBorderLineStyle
LineListBox::GetEntryStyle( sal_Int32 nPos
) const
725 ImpLineListData
* pData
= (0 <= nPos
&& o3tl::make_unsigned(nPos
) < m_vLineList
.size()) ? m_vLineList
[ nPos
].get() : nullptr;
726 return pData
? pData
->GetStyle() : SvxBorderLineStyle::NONE
;
729 void LineListBox::UpdatePaintLineColor()
731 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
732 Color
aNewCol( rSettings
.GetWindowColor().IsDark()? rSettings
.GetLabelTextColor() : aColor
);
734 bool bRet
= aNewCol
!= maPaintCol
;
737 maPaintCol
= aNewCol
;
740 Size
LineListBox::UpdateEntries( tools::Long nOldWidth
)
744 UpdatePaintLineColor( );
746 sal_Int32 nSelEntry
= GetSelectItemPos();
747 sal_Int32 nTypePos
= GetStylePos( nSelEntry
, nOldWidth
);
749 // Remove the old entries
754 // Add the new entries based on the defined width
755 if (!m_sNone
.isEmpty())
756 InsertItem(nId
++, Image(), m_sNone
);
759 sal_uInt16 nCount
= m_vLineList
.size( );
762 auto& pData
= m_vLineList
[ n
];
763 if ( pData
->GetMinWidth() <= m_nWidth
)
766 ImpGetLine( pData
->GetLine1ForWidth( m_nWidth
),
767 pData
->GetLine2ForWidth( m_nWidth
),
768 pData
->GetDistForWidth( m_nWidth
),
769 GetColorLine1( GetItemCount( ) ),
770 GetColorLine2( GetItemCount( ) ),
771 GetColorDist( GetItemCount( ) ),
772 pData
->GetStyle(), aBmp
);
773 InsertItem(nId
, Image(aBmp
), SvtLineListBox::GetLineStyleName(pData
->GetStyle()));
774 Size aBmpSize
= aBmp
.GetSizePixel();
775 if (aBmpSize
.Width() > aSize
.Width())
776 aSize
.setWidth(aBmpSize
.getWidth());
777 if (aBmpSize
.Height() > aSize
.Height())
778 aSize
.setHeight(aBmpSize
.getHeight());
782 else if ( n
== nTypePos
)
793 Color
LineListBox::GetColorLine1( sal_Int32 nPos
)
795 sal_Int32 nStyle
= GetStylePos( nPos
, m_nWidth
);
797 return GetPaintColor( );
798 auto& pData
= m_vLineList
[ nStyle
];
799 return pData
->GetColorLine1( GetColor( ) );
802 Color
LineListBox::GetColorLine2( sal_Int32 nPos
)
804 sal_Int32 nStyle
= GetStylePos( nPos
, m_nWidth
);
806 return GetPaintColor( );
807 auto& pData
= m_vLineList
[ nStyle
];
808 return pData
->GetColorLine2( GetColor( ) );
811 Color
LineListBox::GetColorDist( sal_Int32 nPos
)
813 Color rResult
= Application::GetSettings().GetStyleSettings().GetFieldColor();
815 sal_Int32 nStyle
= GetStylePos( nPos
, m_nWidth
);
818 auto& pData
= m_vLineList
[ nStyle
];
819 return pData
->GetColorDist( GetColor( ), rResult
);
825 class SvxLineWindow_Impl final
: public WeldToolbarPopup
828 rtl::Reference
<SvxFrameToolBoxControl
> m_xControl
;
829 std::unique_ptr
<LineListBox
> m_xLineStyleLb
;
830 std::unique_ptr
<weld::CustomWeld
> m_xLineStyleLbWin
;
833 DECL_LINK( SelectHdl
, ValueSet
*, void );
836 SvxLineWindow_Impl(SvxFrameToolBoxControl
* pControl
, weld::Widget
* pParent
);
837 virtual void GrabFocus() override
839 m_xLineStyleLb
->GrabFocus();
845 class SvxStyleToolBoxControl
;
847 class SfxStyleControllerItem_Impl
: public SfxStatusListener
850 SfxStyleControllerItem_Impl( const Reference
< XDispatchProvider
>& rDispatchProvider
,
852 const OUString
& rCommand
,
853 SvxStyleToolBoxControl
& rTbxCtl
);
856 virtual void StateChangedAtStatusListener( SfxItemState eState
, const SfxPoolItem
* pState
) override
;
859 SvxStyleToolBoxControl
& rControl
;
862 #define BUTTON_PADDING 10
863 #define ITEM_HEIGHT 30
865 SvxStyleBox_Base::SvxStyleBox_Base(std::unique_ptr
<weld::ComboBox
> xWidget
,
867 SfxStyleFamily eFamily
,
868 const Reference
< XFrame
>& _xFrame
,
869 OUString _aClearFormatKey
,
871 bool bInSpec
, SvxStyleToolBoxControl
& rCtrl
)
873 , m_xMenuBuilder(Application::CreateBuilder(nullptr, u
"svx/ui/stylemenu.ui"_ustr
))
874 , m_xMenu(m_xMenuBuilder
->weld_menu(u
"menu"_ustr
))
875 , m_xWidget(std::move(xWidget
))
876 , eStyleFamily( eFamily
)
877 , m_nMaxUserDrawFontWidth(0)
878 , m_nLastItemWithMenu(-1)
881 , m_aCommand(std::move( aCommand
))
882 , aClearFormatKey(std::move( _aClearFormatKey
))
883 , aMoreKey(std::move( _aMoreKey
))
884 , bInSpecialMode( bInSpec
)
886 m_xWidget
->connect_changed(LINK(this, SvxStyleBox_Base
, SelectHdl
));
887 m_xWidget
->connect_key_press(LINK(this, SvxStyleBox_Base
, KeyInputHdl
));
888 m_xWidget
->connect_entry_activate(LINK(this, SvxStyleBox_Base
, ActivateHdl
));
889 m_xWidget
->connect_focus_out(LINK(this, SvxStyleBox_Base
, FocusOutHdl
));
890 m_xWidget
->connect_get_property_tree(LINK(this, SvxStyleBox_Base
, DumpAsPropertyTreeHdl
));
891 m_xWidget
->set_help_id(HID_STYLE_LISTBOX
);
892 m_xWidget
->set_entry_completion(true);
893 m_xMenu
->connect_activate(LINK(this, SvxStyleBox_Base
, MenuSelectHdl
));
895 m_xWidget
->connect_custom_get_size(LINK(this, SvxStyleBox_Base
, CustomGetSizeHdl
));
896 m_xWidget
->connect_custom_render(LINK(this, SvxStyleBox_Base
, CustomRenderHdl
));
897 m_xWidget
->set_custom_renderer(true);
899 m_xWidget
->set_entry_width_chars(COMBO_WIDTH_IN_CHARS
+ 3);
902 IMPL_LINK(SvxStyleBox_Base
, CustomGetSizeHdl
, OutputDevice
&, rArg
, Size
)
904 CalcOptimalExtraUserWidth(rArg
);
905 if (comphelper::LibreOfficeKit::isActive())
906 return Size(m_nMaxUserDrawFontWidth
* rArg
.GetDPIX() / 96, ITEM_HEIGHT
* rArg
.GetDPIY() / 96);
907 return Size(m_nMaxUserDrawFontWidth
, ITEM_HEIGHT
);
910 SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window
* pParent
,
911 const OUString
& rCommand
,
912 SfxStyleFamily eFamily
,
913 const Reference
< XFrame
>& _xFrame
,
914 const OUString
& rClearFormatKey
,
915 const OUString
& rMoreKey
,
916 bool bInSpec
, SvxStyleToolBoxControl
& rCtrl
)
917 : InterimItemWindow(pParent
, u
"svx/ui/applystylebox.ui"_ustr
, u
"ApplyStyleBox"_ustr
)
918 , SvxStyleBox_Base(m_xBuilder
->weld_combo_box(u
"applystyle"_ustr
), rCommand
, eFamily
, _xFrame
,
919 rClearFormatKey
, rMoreKey
, bInSpec
, rCtrl
)
921 InitControlBase(m_xWidget
.get());
923 set_id(u
"applystyle"_ustr
);
927 void SvxStyleBox_Base::ReleaseFocus()
934 if ( m_xFrame
.is() && m_xFrame
->getContainerWindow().is() )
935 m_xFrame
->getContainerWindow()->setFocus();
938 IMPL_LINK(SvxStyleBox_Base
, MenuSelectHdl
, const OUString
&, rMenuIdent
, void)
940 if (m_nLastItemWithMenu
< 0 || m_nLastItemWithMenu
>= m_xWidget
->get_count())
943 OUString sEntry
= m_xWidget
->get_text(m_nLastItemWithMenu
);
945 ReleaseFocus(); // It must be after getting entry pos!
946 Sequence
<PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"Param"_ustr
, sEntry
),
947 comphelper::makePropertyValue(u
"Family"_ustr
,
948 sal_Int16( eStyleFamily
)) };
950 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
951 if (rMenuIdent
== "update")
953 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:StyleUpdateByExample"_ustr
, aArgs
);
955 else if (rMenuIdent
== "edit")
957 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:EditStyle"_ustr
, aArgs
);
961 IMPL_STATIC_LINK_NOARG(SvxStyleBox_Base
, ShowMoreHdl
, void*, void)
963 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
964 DBG_ASSERT( pViewFrm
, "SvxStyleBox_Base::Select(): no viewframe" );
967 pViewFrm
->ShowChildWindow(SID_SIDEBAR
);
968 ::sfx2::sidebar::Sidebar::ShowPanel(u
"StyleListPanel", pViewFrm
->GetFrame().GetFrameInterface(), true);
971 IMPL_LINK(SvxStyleBox_Base
, SelectHdl
, weld::ComboBox
&, rCombo
, void)
973 Select(rCombo
.changed_by_direct_pick()); // only when picked from the list
976 IMPL_LINK_NOARG(SvxStyleBox_Base
, ActivateHdl
, weld::ComboBox
&, bool)
982 void SvxStyleBox_Base::Select(bool bNonTravelSelect
)
984 if (!bNonTravelSelect
)
987 OUString
aSearchEntry(m_xWidget
->get_active_text());
988 bool bDoIt
= true, bClear
= false;
991 if( aSearchEntry
== aClearFormatKey
&& m_xWidget
->get_active() == 0 )
993 aSearchEntry
= sDefaultStyle
;
995 //not only apply default style but also call 'ClearFormatting'
996 Sequence
< PropertyValue
> aEmptyVals
;
997 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
998 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:ResetAttributes"_ustr
, aEmptyVals
);
1000 else if (aSearchEntry
== aMoreKey
&& m_xWidget
->get_active() == (m_xWidget
->get_count() - 1))
1002 Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Base
, ShowMoreHdl
));
1003 //tdf#113214 change text back to previous entry
1004 set_active_or_entry_text(m_xWidget
->get_saved_value());
1009 //Do we need to create a new style?
1010 SfxObjectShell
*pShell
= SfxObjectShell::Current();
1014 SfxStyleSheetBasePool
* pPool
= pShell
->GetStyleSheetPool();
1015 SfxStyleSheetBase
* pStyle
= nullptr;
1017 bool bCreateNew
= false;
1021 pStyle
= pPool
->First(eStyleFamily
);
1022 while ( pStyle
&& pStyle
->GetName() != aSearchEntry
)
1023 pStyle
= pPool
->Next();
1028 // cannot find the style for whatever reason
1029 // therefore create a new style
1033 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1034 This instance may be deleted in the meantime (i.e. when a dialog is opened
1035 while in Dispatch()), accessing members will crash in this case. */
1042 set_active_or_entry_text(aSearchEntry
);
1043 m_xWidget
->save_value();
1045 Sequence
< PropertyValue
> aArgs( 2 );
1046 auto pArgs
= aArgs
.getArray();
1047 pArgs
[0].Value
<<= aSearchEntry
;
1048 pArgs
[1].Name
= "Family";
1049 pArgs
[1].Value
<<= sal_Int16( eStyleFamily
);
1051 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
1054 pArgs
[0].Name
= "Param";
1055 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:StyleNewByExample"_ustr
, aArgs
);
1059 pArgs
[0].Name
= "Template";
1060 SfxToolBoxControl::Dispatch(xProvider
, m_aCommand
, aArgs
);
1064 void SvxStyleBox_Base::SetFamily( SfxStyleFamily eNewFamily
)
1066 eStyleFamily
= eNewFamily
;
1069 IMPL_LINK_NOARG(SvxStyleBox_Base
, FocusOutHdl
, weld::Widget
&, void)
1071 if (!m_xWidget
->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1072 set_active_or_entry_text(m_xWidget
->get_saved_value());
1075 IMPL_LINK(SvxStyleBox_Base
, KeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
1077 return DoKeyInput(rKEvt
);
1080 bool SvxStyleBox_Base::DoKeyInput(const KeyEvent
& rKEvt
)
1082 bool bHandled
= false;
1084 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
1093 set_active_or_entry_text(m_xWidget
->get_saved_value());
1094 if (!m_rCtrl
.IsInSidebar())
1105 bool SvxStyleBox_Impl::DoKeyInput(const KeyEvent
& rKEvt
)
1107 return SvxStyleBox_Base::DoKeyInput(rKEvt
) || ChildKeyInput(rKEvt
);
1110 void SvxStyleBox_Impl::DataChanged( const DataChangedEvent
& rDCEvt
)
1112 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1113 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1118 InterimItemWindow::DataChanged( rDCEvt
);
1121 void SvxStyleBox_Impl::SetOptimalSize()
1123 // set width in chars low so the size request will not be overridden
1124 m_xWidget
->set_entry_width_chars(1);
1125 // tdf#132338 purely using this calculation to keep things their traditional width
1126 Size
aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS
+ 3) * 4, 0), MapMode(MapUnit::MapAppFont
)));
1127 m_xWidget
->set_size_request(aSize
.Width(), -1);
1129 SetSizePixel(get_preferred_size());
1134 std::vector
<ScriptInfo
> CheckScript(const OUString
&rStyleName
)
1136 assert(!rStyleName
.isEmpty()); // must have a preview text here!
1138 std::vector
<ScriptInfo
> aScriptChanges
;
1140 auto aEditEngine
= EditEngine(nullptr);
1141 aEditEngine
.SetText(rStyleName
);
1143 auto aScript
= aEditEngine
.GetScriptType({ 0, 0, 0, 0 });
1144 for (sal_Int32 i
= 1; i
<= rStyleName
.getLength(); i
++)
1146 auto aNextScript
= aEditEngine
.GetScriptType({ 0, i
, 0, i
});
1147 if (aNextScript
!= aScript
|| i
== rStyleName
.getLength())
1148 aScriptChanges
.emplace_back(aScript
, i
);
1149 aScript
= aNextScript
;
1152 return aScriptChanges
;
1156 tools::Rectangle
SvxStyleBox_Base::CalcBoundRect(vcl::RenderContext
& rRenderContext
, const OUString
&rStyleName
, std::vector
<ScriptInfo
>& rScriptChanges
, double fRatio
)
1158 tools::Rectangle aTextRect
;
1160 SvtScriptType aScript
;
1161 sal_uInt16 nIdx
= 0;
1162 sal_Int32 nStart
= 0;
1164 size_t nCnt
= rScriptChanges
.size();
1168 nEnd
= rScriptChanges
[nIdx
].changePos
;
1169 aScript
= rScriptChanges
[nIdx
].scriptType
;
1173 nEnd
= rStyleName
.getLength();
1174 aScript
= SvtScriptType::LATIN
;
1179 auto oFont
= (aScript
== SvtScriptType::ASIAN
) ?
1181 ((aScript
== SvtScriptType::COMPLEX
) ?
1185 rRenderContext
.Push(vcl::PushFlags::FONT
);
1188 rRenderContext
.SetFont(*oFont
);
1192 vcl::Font
aFont(rRenderContext
.GetFont());
1193 Size
aPixelSize(aFont
.GetFontSize());
1194 aPixelSize
.setWidth(aPixelSize
.Width() * fRatio
);
1195 aPixelSize
.setHeight(aPixelSize
.Height() * fRatio
);
1196 aFont
.SetFontSize(aPixelSize
);
1197 rRenderContext
.SetFont(aFont
);
1200 tools::Rectangle aRect
;
1201 rRenderContext
.GetTextBoundRect(aRect
, rStyleName
, nStart
, nStart
, nEnd
- nStart
);
1202 aTextRect
= aTextRect
.Union(aRect
);
1204 tools::Long nWidth
= rRenderContext
.GetTextWidth(rStyleName
, nStart
, nEnd
- nStart
);
1206 rRenderContext
.Pop();
1208 if (nIdx
>= rScriptChanges
.size())
1211 rScriptChanges
[nIdx
++].textWidth
= nWidth
;
1213 if (nEnd
< rStyleName
.getLength() && nIdx
< nCnt
)
1216 nEnd
= rScriptChanges
[nIdx
].changePos
;
1217 aScript
= rScriptChanges
[nIdx
].scriptType
;
1227 void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
, const tools::Rectangle
& rTextRect
, const OUString
&rStyleName
, const std::vector
<ScriptInfo
>& rScriptChanges
)
1229 // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
1230 // nBorder, and we are adding 1 in order to look better when
1231 // italics is present
1232 const int nLeftDistance
= 8;
1234 Point
aPos(rRect
.TopLeft());
1235 aPos
.AdjustX(nLeftDistance
);
1238 if (rTextRect
.Bottom() > rRect
.GetHeight())
1239 fRatio
= static_cast<double>(rRect
.GetHeight()) / rTextRect
.Bottom();
1241 aPos
.AdjustY((rRect
.GetHeight() - rTextRect
.Bottom()) / 2);
1243 SvtScriptType aScript
;
1244 sal_uInt16 nIdx
= 0;
1245 sal_Int32 nStart
= 0;
1247 size_t nCnt
= rScriptChanges
.size();
1251 nEnd
= rScriptChanges
[nIdx
].changePos
;
1252 aScript
= rScriptChanges
[nIdx
].scriptType
;
1256 nEnd
= rStyleName
.getLength();
1257 aScript
= SvtScriptType::LATIN
;
1263 auto oFont
= (aScript
== SvtScriptType::ASIAN
) ?
1265 ((aScript
== SvtScriptType::COMPLEX
) ?
1269 rRenderContext
.Push(vcl::PushFlags::FONT
);
1272 rRenderContext
.SetFont(*oFont
);
1276 vcl::Font
aFont(rRenderContext
.GetFont());
1277 Size
aPixelSize(aFont
.GetFontSize());
1278 aPixelSize
.setWidth(aPixelSize
.Width() * fRatio
);
1279 aPixelSize
.setHeight(aPixelSize
.Height() * fRatio
);
1280 aFont
.SetFontSize(aPixelSize
);
1281 rRenderContext
.SetFont(aFont
);
1284 rRenderContext
.DrawText(aPos
, rStyleName
, nStart
, nEnd
- nStart
);
1286 rRenderContext
.Pop();
1288 aPos
.AdjustX(rScriptChanges
[nIdx
++].textWidth
* fRatio
);
1289 if (nEnd
< rStyleName
.getLength() && nIdx
< nCnt
)
1292 nEnd
= rScriptChanges
[nIdx
].changePos
;
1293 aScript
= rScriptChanges
[nIdx
].scriptType
;
1301 static bool GetWhich(const SfxItemSet
& rSet
, sal_uInt16 nSlot
, sal_uInt16
& rWhich
)
1303 rWhich
= rSet
.GetPool()->GetWhichIDFromSlotID(nSlot
);
1304 return rSet
.GetItemState(rWhich
) >= SfxItemState::DEFAULT
;
1307 static bool SetFont(const SfxItemSet
& rSet
, sal_uInt16 nSlot
, SvxFont
& rFont
)
1310 if (GetWhich(rSet
, nSlot
, nWhich
))
1312 const auto& rFontItem
= static_cast<const SvxFontItem
&>(rSet
.Get(nWhich
));
1313 rFont
.SetFamilyName(rFontItem
.GetFamilyName());
1314 rFont
.SetStyleName(rFontItem
.GetStyleName());
1320 static bool SetFontSize(vcl::RenderContext
& rRenderContext
, const SfxItemSet
& rSet
, sal_uInt16 nSlot
, SvxFont
& rFont
)
1323 if (GetWhich(rSet
, nSlot
, nWhich
))
1325 const auto& rFontHeightItem
= static_cast<const SvxFontHeightItem
&>(rSet
.Get(nWhich
));
1326 if (SfxObjectShell
*pShell
= SfxObjectShell::Current())
1328 Size
aFontSize(0, rFontHeightItem
.GetHeight());
1329 Size
aPixelSize(rRenderContext
.LogicToPixel(aFontSize
, MapMode(pShell
->GetMapUnit())));
1330 rFont
.SetFontSize(aPixelSize
);
1337 static void SetFontStyle(const SfxItemSet
& rSet
, sal_uInt16 nPosture
, sal_uInt16 nWeight
, SvxFont
& rFont
)
1340 if (GetWhich(rSet
, nPosture
, nWhich
))
1342 const auto& rItem
= static_cast<const SvxPostureItem
&>(rSet
.Get(nWhich
));
1343 rFont
.SetItalic(rItem
.GetPosture());
1346 if (GetWhich(rSet
, nWeight
, nWhich
))
1348 const auto& rItem
= static_cast<const SvxWeightItem
&>(rSet
.Get(nWhich
));
1349 rFont
.SetWeight(rItem
.GetWeight());
1353 void SvxStyleBox_Base::SetupEntry(vcl::RenderContext
& rRenderContext
, sal_Int32 nItem
, const tools::Rectangle
& rRect
, std::u16string_view rStyleName
, bool bIsNotSelected
)
1355 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1356 if (!bIsNotSelected
)
1357 rRenderContext
.SetTextColor(rStyleSettings
.GetHighlightTextColor());
1359 rRenderContext
.SetTextColor(rStyleSettings
.GetDialogTextColor());
1361 // handle the push-button
1362 if (!bIsNotSelected
)
1364 if (nItem
== 0 || nItem
== m_xWidget
->get_count() - 1)
1365 m_xWidget
->set_item_menu(OUString::number(nItem
), nullptr);
1368 m_nLastItemWithMenu
= nItem
;
1369 m_xWidget
->set_item_menu(OUString::number(nItem
), m_xMenu
.get());
1373 if (nItem
<= 0 || nItem
>= m_xWidget
->get_count() - 1)
1376 SfxObjectShell
*pShell
= SfxObjectShell::Current();
1380 SfxStyleSheetBasePool
* pPool
= pShell
->GetStyleSheetPool();
1384 SfxStyleSheetBase
* pStyle
= pPool
->First(eStyleFamily
);
1385 while (pStyle
&& pStyle
->GetName() != rStyleName
)
1386 pStyle
= pPool
->Next();
1391 std::optional
<SfxItemSet
> const pItemSet(pStyle
->GetItemSetForPreview());
1392 if (!pItemSet
) return;
1398 SetFontStyle(*pItemSet
, SID_ATTR_CHAR_POSTURE
, SID_ATTR_CHAR_WEIGHT
, aFont
);
1399 SetFontStyle(*pItemSet
, SID_ATTR_CHAR_CJK_POSTURE
, SID_ATTR_CHAR_CJK_WEIGHT
, aCJKFont
);
1400 SetFontStyle(*pItemSet
, SID_ATTR_CHAR_CTL_POSTURE
, SID_ATTR_CHAR_CTL_WEIGHT
, aCTLFont
);
1402 const SfxPoolItem
*pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_CONTOUR
);
1405 auto aVal
= static_cast< const SvxContourItem
* >( pItem
)->GetValue();
1406 aFont
.SetOutline(aVal
);
1407 aCJKFont
.SetOutline(aVal
);
1408 aCTLFont
.SetOutline(aVal
);
1411 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_SHADOWED
);
1414 auto aVal
= static_cast< const SvxShadowedItem
* >( pItem
)->GetValue();
1415 aFont
.SetShadow(aVal
);
1416 aCJKFont
.SetShadow(aVal
);
1417 aCTLFont
.SetShadow(aVal
);
1420 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_RELIEF
);
1423 auto aVal
= static_cast< const SvxCharReliefItem
* >( pItem
)->GetValue();
1424 aFont
.SetRelief(aVal
);
1425 aCJKFont
.SetRelief(aVal
);
1426 aCTLFont
.SetRelief(aVal
);
1429 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_UNDERLINE
);
1432 auto aVal
= static_cast<const SvxUnderlineItem
*>(pItem
)->GetLineStyle();
1433 aFont
.SetUnderline(aVal
);
1434 aCJKFont
.SetUnderline(aVal
);
1435 aCTLFont
.SetUnderline(aVal
);
1438 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_OVERLINE
);
1441 auto aVal
= static_cast< const SvxOverlineItem
* >( pItem
)->GetValue();
1442 aFont
.SetOverline(aVal
);
1443 aCJKFont
.SetOverline(aVal
);
1444 aCTLFont
.SetOverline(aVal
);
1447 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_STRIKEOUT
);
1450 auto aVal
= static_cast< const SvxCrossedOutItem
* >( pItem
)->GetStrikeout();
1451 aFont
.SetStrikeout(aVal
);
1452 aCJKFont
.SetStrikeout(aVal
);
1453 aCTLFont
.SetStrikeout(aVal
);
1456 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_CASEMAP
);
1459 auto aVal
= static_cast<const SvxCaseMapItem
*>(pItem
)->GetCaseMap();
1460 aFont
.SetCaseMap(aVal
);
1461 aCJKFont
.SetCaseMap(aVal
);
1462 aCTLFont
.SetCaseMap(aVal
);
1465 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_EMPHASISMARK
);
1468 auto aVal
= static_cast< const SvxEmphasisMarkItem
* >( pItem
)->GetEmphasisMark();
1469 aFont
.SetEmphasisMark(aVal
);
1470 aCJKFont
.SetEmphasisMark(aVal
);
1471 aCTLFont
.SetEmphasisMark(aVal
);
1474 // setup the device & draw
1475 Color aFontCol
= COL_AUTO
, aBackCol
= COL_AUTO
;
1477 pItem
= pItemSet
->GetItem( SID_ATTR_CHAR_COLOR
);
1478 // text color, when nothing is selected
1479 if ( (nullptr != pItem
) && bIsNotSelected
)
1480 aFontCol
= static_cast< const SvxColorItem
* >( pItem
)->GetValue();
1482 drawing::FillStyle style
= drawing::FillStyle_NONE
;
1483 // which kind of Fill style is selected
1484 pItem
= pItemSet
->GetItem( XATTR_FILLSTYLE
);
1485 // only when ok and not selected
1486 if ( (nullptr != pItem
) && bIsNotSelected
)
1487 style
= static_cast< const XFillStyleItem
* >( pItem
)->GetValue();
1491 case drawing::FillStyle_SOLID
:
1493 // set background color
1494 pItem
= pItemSet
->GetItem( XATTR_FILLCOLOR
);
1495 if ( nullptr != pItem
)
1496 aBackCol
= static_cast< const XFillColorItem
* >( pItem
)->GetColorValue();
1498 if ( aBackCol
!= COL_AUTO
)
1500 rRenderContext
.SetFillColor(aBackCol
);
1501 rRenderContext
.DrawRect(rRect
);
1507 //TODO Draw the other background styles: gradient, hatching and bitmap
1510 // when the font and background color are too similar, adjust the Font-Color
1511 if( (aFontCol
!= COL_AUTO
) || (aBackCol
!= COL_AUTO
) )
1512 aFontCol
= TestColorsVisible(aFontCol
, (aBackCol
!= COL_AUTO
) ? aBackCol
: rRenderContext
.GetBackground().GetColor());
1515 if ( aFontCol
!= COL_AUTO
)
1516 rRenderContext
.SetTextColor(aFontCol
);
1518 if (SetFont(*pItemSet
, SID_ATTR_CHAR_FONT
, aFont
) &&
1519 SetFontSize(rRenderContext
, *pItemSet
, SID_ATTR_CHAR_FONTHEIGHT
, aFont
))
1522 if (SetFont(*pItemSet
, SID_ATTR_CHAR_CJK_FONT
, aCJKFont
) &&
1523 SetFontSize(rRenderContext
, *pItemSet
, SID_ATTR_CHAR_CJK_FONTHEIGHT
, aCJKFont
))
1524 m_oCJKFont
= aCJKFont
;
1526 if (SetFont(*pItemSet
, SID_ATTR_CHAR_CTL_FONT
, aCTLFont
) &&
1527 SetFontSize(rRenderContext
, *pItemSet
, SID_ATTR_CHAR_CTL_FONTHEIGHT
, aCTLFont
))
1528 m_oCTLFont
= aCTLFont
;
1531 IMPL_LINK(SvxStyleBox_Base
, CustomRenderHdl
, weld::ComboBox::render_args
, aPayload
, void)
1533 vcl::RenderContext
& rRenderContext
= std::get
<0>(aPayload
);
1534 const ::tools::Rectangle
& rRect
= std::get
<1>(aPayload
);
1535 bool bSelected
= std::get
<2>(aPayload
);
1536 const OUString
& rId
= std::get
<3>(aPayload
);
1538 sal_uInt32 nIndex
= rId
.toUInt32();
1540 OUString
aStyleName(m_xWidget
->get_text(nIndex
));
1542 rRenderContext
.Push(vcl::PushFlags::FILLCOLOR
| vcl::PushFlags::FONT
| vcl::PushFlags::TEXTCOLOR
);
1544 SetupEntry(rRenderContext
, nIndex
, rRect
, aStyleName
, !bSelected
);
1545 auto aScriptChanges
= CheckScript(aStyleName
);
1546 auto aTextRect
= CalcBoundRect(rRenderContext
, aStyleName
, aScriptChanges
);
1547 UserDrawEntry(rRenderContext
, rRect
, aTextRect
, aStyleName
, aScriptChanges
);
1549 rRenderContext
.Pop();
1552 void SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext
& rRenderContext
)
1554 if (m_nMaxUserDrawFontWidth
)
1557 tools::Long nMaxNormalFontWidth
= 0;
1558 sal_Int32 nEntryCount
= m_xWidget
->get_count();
1559 for (sal_Int32 i
= 0; i
< nEntryCount
; ++i
)
1561 OUString
sStyleName(get_text(i
));
1562 tools::Rectangle aTextRectForDefaultFont
;
1563 rRenderContext
.GetTextBoundRect(aTextRectForDefaultFont
, sStyleName
);
1565 const tools::Long nWidth
= aTextRectForDefaultFont
.GetWidth();
1567 nMaxNormalFontWidth
= std::max(nWidth
, nMaxNormalFontWidth
);
1570 m_nMaxUserDrawFontWidth
= nMaxNormalFontWidth
;
1571 for (sal_Int32 i
= 1; i
< nEntryCount
-1; ++i
)
1573 OUString
sStyleName(get_text(i
));
1575 if (sStyleName
.isEmpty())
1578 rRenderContext
.Push(vcl::PushFlags::FILLCOLOR
| vcl::PushFlags::FONT
| vcl::PushFlags::TEXTCOLOR
);
1579 SetupEntry(rRenderContext
, i
, tools::Rectangle(0, 0, RECT_MAX
, ITEM_HEIGHT
), sStyleName
, true);
1580 auto aScriptChanges
= CheckScript(sStyleName
);
1581 tools::Rectangle aTextRectForActualFont
= CalcBoundRect(rRenderContext
, sStyleName
, aScriptChanges
);
1582 if (aTextRectForActualFont
.Bottom() > ITEM_HEIGHT
)
1584 //Font didn't fit, re-calculate with adjustment ratio.
1585 double fRatio
= static_cast<double>(ITEM_HEIGHT
) / aTextRectForActualFont
.Bottom();
1586 aTextRectForActualFont
= CalcBoundRect(rRenderContext
, sStyleName
, aScriptChanges
, fRatio
);
1588 rRenderContext
.Pop();
1590 const int nWidth
= aTextRectForActualFont
.GetWidth() + m_xWidget
->get_menu_button_width() + BUTTON_PADDING
;
1592 m_nMaxUserDrawFontWidth
= std::max(nWidth
, m_nMaxUserDrawFontWidth
);
1596 // test is the color between Font- and background-color to be identify
1597 // return is always the Font-Color
1598 // when both light or dark, change the Contrast
1599 // in other case do not change the origin color
1600 // when the color is R=G=B=128 the DecreaseContrast make 128 the need an exception
1601 Color
SvxStyleBox_Base::TestColorsVisible(const Color
&FontCol
, const Color
&BackCol
)
1603 constexpr sal_uInt8 ChgVal
= 60; // increase/decrease the Contrast
1605 Color retCol
= FontCol
;
1606 if ((FontCol
.IsDark() == BackCol
.IsDark()) && (FontCol
.IsBright() == BackCol
.IsBright()))
1608 sal_uInt8 lumi
= retCol
.GetLuminance();
1610 if((lumi
> 120) && (lumi
< 140))
1611 retCol
.DecreaseLuminance(ChgVal
/ 2);
1613 retCol
.DecreaseContrast(ChgVal
);
1619 IMPL_LINK(SvxStyleBox_Base
, DumpAsPropertyTreeHdl
, tools::JsonWriter
&, rJsonWriter
, void)
1625 auto entriesNode
= rJsonWriter
.startNode("entries");
1626 for (int i
= 0, nEntryCount
= m_xWidget
->get_count(); i
< nEntryCount
; ++i
)
1628 auto entryNode
= rJsonWriter
.startNode("");
1629 rJsonWriter
.put("", m_xWidget
->get_text(i
));
1633 int nActive
= m_xWidget
->get_active();
1634 rJsonWriter
.put("selectedCount", static_cast<sal_Int32
>(nActive
== -1 ? 0 : 1));
1637 auto selectedNode
= rJsonWriter
.startNode("selectedEntries");
1640 auto node
= rJsonWriter
.startNode("");
1641 rJsonWriter
.put("", static_cast<sal_Int32
>(nActive
));
1645 rJsonWriter
.put("command", ".uno:StyleApply");
1648 static bool lcl_GetDocFontList(const FontList
** ppFontList
, SvxFontNameBox_Base
* pBox
)
1650 bool bChanged
= false;
1651 const SfxObjectShell
* pDocSh
= SfxObjectShell::Current();
1652 const SvxFontListItem
* pFontListItem
= nullptr;
1656 static_cast<const SvxFontListItem
*>(pDocSh
->GetItem( SID_ATTR_CHAR_FONTLIST
));
1659 ::std::unique_ptr
<FontList
> aFontList(new FontList(Application::GetDefaultDevice()));
1660 *ppFontList
= aFontList
.get();
1661 pBox
->SetOwnFontList(std::move(aFontList
));
1665 if ( pFontListItem
)
1667 const FontList
* pNewFontList
= pFontListItem
->GetFontList();
1668 DBG_ASSERT( pNewFontList
, "Doc-FontList not available!" );
1670 // No old list, but a new list
1671 if ( !*ppFontList
&& pNewFontList
)
1674 *ppFontList
= pNewFontList
;
1679 // Comparing the font lists is not perfect.
1680 // When you change the font list in the Doc, you can track
1681 // changes here only on the Listbox, because ppFontList
1682 // has already been updated.
1683 bChanged
= !pNewFontList
||
1684 *ppFontList
!= pNewFontList
||
1685 pBox
->GetListCount() != pNewFontList
->GetFontNameCount();
1686 // HACK: Comparing is incomplete
1689 *ppFontList
= pNewFontList
;
1693 pBox
->set_sensitive(true);
1695 else if ( pBox
&& ( pDocSh
|| !ppFontList
))
1697 // Disable box only when we have a SfxObjectShell and didn't get a font list OR
1698 // we don't have a SfxObjectShell and no current font list.
1699 // It's possible that we currently have no SfxObjectShell, but a current font list.
1700 // See #i58471: When a user set the focus into the font name combo box and opens
1701 // the help window with F1. After closing the help window, we disable the font name
1702 // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
1703 // font list hasn't changed and therefore the combo box shouldn't be disabled!
1704 pBox
->set_sensitive(false);
1707 // Fill the FontBox, also the new list if necessary
1708 if ( pBox
&& bChanged
)
1710 if (ppFontList
&& *ppFontList
)
1711 pBox
->Fill( *ppFontList
);
1718 SvxFontNameBox_Base::SvxFontNameBox_Base(std::unique_ptr
<weld::ComboBox
> xWidget
,
1719 const Reference
<XFrame
>& rFrame
,
1720 SvxFontNameToolBoxControl
& rCtrl
)
1721 : m_xListener(new comphelper::ConfigurationListener(u
"/org.openoffice.Office.Common/Font/View"_ustr
))
1722 , m_aWYSIWYG(m_xListener
, u
"ShowFontBoxWYSIWYG"_ustr
, *this)
1723 , m_aHistory(m_xListener
, u
"History"_ustr
, *this)
1725 , m_xWidget(new FontNameBox(std::move(xWidget
)))
1726 , pFontList(nullptr)
1730 , mbCheckingUnknownFont(false)
1731 , mbDropDownActive(false)
1735 m_xWidget
->connect_changed(LINK(this, SvxFontNameBox_Base
, SelectHdl
));
1736 m_xWidget
->connect_key_press(LINK(this, SvxFontNameBox_Base
, KeyInputHdl
));
1737 m_xWidget
->connect_entry_activate(LINK(this, SvxFontNameBox_Base
, ActivateHdl
));
1738 m_xWidget
->connect_focus_in(LINK(this, SvxFontNameBox_Base
, FocusInHdl
));
1739 m_xWidget
->connect_focus_out(LINK(this, SvxFontNameBox_Base
, FocusOutHdl
));
1740 m_xWidget
->connect_popup_toggled(LINK(this, SvxFontNameBox_Base
, PopupToggledHdl
));
1741 m_xWidget
->connect_live_preview(LINK(this, SvxFontNameBox_Base
, LivePreviewHdl
));
1742 m_xWidget
->connect_get_property_tree(LINK(this, SvxFontNameBox_Base
, DumpAsPropertyTreeHdl
));
1744 m_xWidget
->set_entry_width_chars(COMBO_WIDTH_IN_CHARS
+ 5);
1747 SvxFontNameBox_Impl::SvxFontNameBox_Impl(vcl::Window
* pParent
, const Reference
<XFrame
>& rFrame
,
1748 SvxFontNameToolBoxControl
& rCtrl
)
1749 : InterimItemWindow(pParent
, u
"svx/ui/fontnamebox.ui"_ustr
, u
"FontNameBox"_ustr
, true, reinterpret_cast<sal_uInt64
>(SfxViewShell::Current()))
1750 , SvxFontNameBox_Base(m_xBuilder
->weld_combo_box(u
"fontnamecombobox"_ustr
), rFrame
, rCtrl
)
1752 set_id(u
"fontnamecombobox"_ustr
);
1756 void SvxFontNameBox_Base::FillList()
1758 if (!m_xWidget
) // e.g. disposed
1760 // Save old Selection, set back in the end
1761 int nStartPos
, nEndPos
;
1762 m_xWidget
->get_entry_selection_bounds(nStartPos
, nEndPos
);
1764 // Did Doc-Fontlist change?
1765 lcl_GetDocFontList(&pFontList
, this);
1767 m_xWidget
->select_entry_region(nStartPos
, nEndPos
);
1770 bool SvxFontNameBox_Base::CheckFontIsAvailable(std::u16string_view fontname
)
1772 lcl_GetDocFontList(&pFontList
, this);
1773 return pFontList
&& pFontList
->IsAvailable(fontname
);
1776 void SvxFontNameBox_Base::CheckAndMarkUnknownFont()
1778 if (mbCheckingUnknownFont
) //tdf#117537 block rentry
1780 mbCheckingUnknownFont
= true;
1781 OUString fontname
= m_xWidget
->get_active_text();
1782 // tdf#154680 If a font is set and that font is unknown, show it in italic.
1783 vcl::Font font
= m_xWidget
->get_entry_font();
1784 if (fontname
.isEmpty() || CheckFontIsAvailable(fontname
))
1786 if( font
.GetItalic() != ITALIC_NONE
)
1788 font
.SetItalic( ITALIC_NONE
);
1789 m_xWidget
->set_entry_font(font
);
1790 m_xWidget
->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME
));
1795 if( font
.GetItalic() != ITALIC_NORMAL
)
1797 font
.SetItalic( ITALIC_NORMAL
);
1798 m_xWidget
->set_entry_font(font
);
1799 m_xWidget
->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE
));
1802 mbCheckingUnknownFont
= false;
1805 void SvxFontNameBox_Base::Update( const css::awt::FontDescriptor
* pFontDesc
)
1809 aCurFont
.SetFamilyName ( pFontDesc
->Name
);
1810 aCurFont
.SetFamily ( FontFamily( pFontDesc
->Family
) );
1811 aCurFont
.SetStyleName ( pFontDesc
->StyleName
);
1812 aCurFont
.SetPitch ( FontPitch( pFontDesc
->Pitch
) );
1813 aCurFont
.SetCharSet ( rtl_TextEncoding( pFontDesc
->CharSet
) );
1815 OUString aCurName
= aCurFont
.GetFamilyName();
1816 OUString aText
= m_xWidget
->get_active_text();
1817 if (aText
!= aCurName
)
1818 set_active_or_entry_text(aCurName
);
1821 void SvxFontNameBox_Base::set_active_or_entry_text(const OUString
& rText
)
1823 m_xWidget
->set_active_or_entry_text(rText
);
1824 CheckAndMarkUnknownFont();
1827 IMPL_LINK_NOARG(SvxFontNameBox_Base
, FocusInHdl
, weld::Widget
&, void)
1832 IMPL_LINK(SvxFontNameBox_Base
, KeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
1834 return DoKeyInput(rKEvt
);
1837 bool SvxFontNameBox_Base::DoKeyInput(const KeyEvent
& rKEvt
)
1839 bool bHandled
= false;
1841 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
1851 set_active_or_entry_text(m_xWidget
->get_saved_value());
1852 if (!m_rCtrl
.IsInSidebar())
1854 ReleaseFocus_Impl();
1863 bool SvxFontNameBox_Impl::DoKeyInput(const KeyEvent
& rKEvt
)
1865 return SvxFontNameBox_Base::DoKeyInput(rKEvt
) || ChildKeyInput(rKEvt
);
1868 IMPL_LINK_NOARG(SvxFontNameBox_Base
, FocusOutHdl
, weld::Widget
&, void)
1870 if (!m_xWidget
->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1872 set_active_or_entry_text(m_xWidget
->get_saved_value());
1878 IMPL_LINK(SvxFontNameBox_Base
, LivePreviewHdl
, const FontMetric
&, rFontMetric
, void)
1880 Sequence
<PropertyValue
> aArgs(1);
1882 SvxFontItem
aFontItem(rFontMetric
.GetFamilyType(),
1883 rFontMetric
.GetFamilyName(),
1884 rFontMetric
.GetStyleName(),
1885 rFontMetric
.GetPitch(),
1886 rFontMetric
.GetCharSet(),
1887 SID_ATTR_CHAR_FONT
);
1888 PropertyValue
* pArgs
= aArgs
.getArray();
1889 aFontItem
.QueryValue(pArgs
[0].Value
);
1890 pArgs
[0].Name
= "CharPreviewFontName";
1891 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
1892 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:CharPreviewFontName"_ustr
, aArgs
);
1895 IMPL_LINK_NOARG(SvxFontNameBox_Base
, PopupToggledHdl
, weld::ComboBox
&, void)
1897 mbDropDownActive
= !mbDropDownActive
;
1898 if (!mbDropDownActive
)
1902 void SvxFontNameBox_Impl::SetOptimalSize()
1904 // set width in chars low so the size request will not be overridden
1905 m_xWidget
->set_entry_width_chars(1);
1906 // tdf#132338 purely using this calculation to keep things their traditional width
1907 Size
aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS
+5) * 4, 0), MapMode(MapUnit::MapAppFont
)));
1908 m_xWidget
->set_size_request(aSize
.Width(), -1);
1910 SetSizePixel(get_preferred_size());
1913 void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent
& rDCEvt
)
1915 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1916 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1920 else if ( ( rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
1921 ( rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) )
1923 // The old font list in shell has likely been destroyed at this point, so we need to get
1924 // the new one before doing anything further.
1925 lcl_GetDocFontList( &pFontList
, this );
1929 void SvxFontNameBox_Base::ReleaseFocus_Impl()
1936 if ( m_xFrame
.is() && m_xFrame
->getContainerWindow().is() )
1937 m_xFrame
->getContainerWindow()->setFocus();
1940 void SvxFontNameBox_Base::EnableControls()
1942 bool bEnableMRU
= m_aHistory
.get();
1943 sal_uInt16 nEntries
= bEnableMRU
? MAX_MRU_FONTNAME_ENTRIES
: 0;
1945 bool bNewWYSIWYG
= m_aWYSIWYG
.get();
1946 bool bOldWYSIWYG
= m_xWidget
->IsWYSIWYGEnabled();
1948 if (m_xWidget
->get_max_mru_count() != nEntries
|| bNewWYSIWYG
!= bOldWYSIWYG
)
1950 // refill in the next GetFocus-Handler
1951 pFontList
= nullptr;
1953 m_xWidget
->set_max_mru_count(nEntries
);
1956 if (bNewWYSIWYG
!= bOldWYSIWYG
)
1957 m_xWidget
->EnableWYSIWYG(bNewWYSIWYG
);
1960 IMPL_LINK(SvxFontNameBox_Base
, SelectHdl
, weld::ComboBox
&, rCombo
, void)
1962 Select(rCombo
.changed_by_direct_pick()); // only when picked from the list
1965 IMPL_LINK_NOARG(SvxFontNameBox_Base
, ActivateHdl
, weld::ComboBox
&, bool)
1971 void SvxFontNameBox_Base::Select(bool bNonTravelSelect
)
1973 Sequence
< PropertyValue
> aArgs( 1 );
1974 auto pArgs
= aArgs
.getArray();
1975 std::unique_ptr
<SvxFontItem
> pFontItem
;
1978 FontMetric
aFontMetric( pFontList
->Get(m_xWidget
->get_active_text(),
1979 aCurFont
.GetWeight(),
1980 aCurFont
.GetItalic() ) );
1981 aCurFont
= aFontMetric
;
1983 pFontItem
.reset( new SvxFontItem( aFontMetric
.GetFamilyType(),
1984 aFontMetric
.GetFamilyName(),
1985 aFontMetric
.GetStyleName(),
1986 aFontMetric
.GetPitch(),
1987 aFontMetric
.GetCharSet(),
1988 SID_ATTR_CHAR_FONT
) );
1991 pFontItem
->QueryValue( a
);
1995 const Reference
<XDispatchProvider
> xProvider(m_xFrame
, UNO_QUERY
);
1996 if (bNonTravelSelect
)
1998 CheckAndMarkUnknownFont();
1999 // #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
2000 // This instance may be deleted in the meantime (i.e. when a dialog is opened
2001 // while in Dispatch()), accessing members will crash in this case.
2002 ReleaseFocus_Impl();
2006 pArgs
[0].Name
= "CharFontName";
2007 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:CharFontName"_ustr
, aArgs
);
2014 pArgs
[0].Name
= "CharPreviewFontName";
2015 SfxToolBoxControl::Dispatch(xProvider
, u
".uno:CharPreviewFontName"_ustr
, aArgs
);
2020 IMPL_LINK(SvxFontNameBox_Base
, DumpAsPropertyTreeHdl
, tools::JsonWriter
&, rJsonWriter
, void)
2023 auto entriesNode
= rJsonWriter
.startNode("entries");
2024 for (int i
= 0, nEntryCount
= m_xWidget
->get_count(); i
< nEntryCount
; ++i
)
2026 auto entryNode
= rJsonWriter
.startNode("");
2027 rJsonWriter
.put("", m_xWidget
->get_text(i
));
2031 int nSelectedEntry
= m_xWidget
->get_active();
2032 rJsonWriter
.put("selectedCount", static_cast<sal_Int32
>(nSelectedEntry
== -1 ? 0 : 1));
2035 auto selectedNode
= rJsonWriter
.startNode("selectedEntries");
2036 if (nSelectedEntry
!= -1)
2038 auto entryNode
= rJsonWriter
.startNode("");
2039 rJsonWriter
.put("", m_xWidget
->get_text(nSelectedEntry
));
2043 rJsonWriter
.put("command", ".uno:CharFontName");
2046 ColorWindow::ColorWindow(OUString rCommand
,
2047 std::shared_ptr
<PaletteManager
> xPaletteManager
,
2048 ColorStatus
& rColorStatus
,
2050 const Reference
< XFrame
>& rFrame
,
2051 const MenuOrToolMenuButton
& rMenuButton
,
2052 TopLevelParentFunction aTopLevelParentFunction
,
2053 ColorSelectFunction aColorSelectFunction
)
2054 : WeldToolbarPopup(rFrame
, rMenuButton
.get_widget(), u
"svx/ui/colorwindow.ui"_ustr
, u
"palette_popup_window"_ustr
)
2055 , theSlotId(nSlotId
)
2056 , maCommand(std::move(rCommand
))
2057 , maMenuButton(rMenuButton
)
2058 , mxPaletteManager(std::move(xPaletteManager
))
2059 , mrColorStatus(rColorStatus
)
2060 , maTopLevelParentFunction(std::move(aTopLevelParentFunction
))
2061 , maColorSelectFunction(std::move(aColorSelectFunction
))
2062 , mxColorSet(new SvxColorValueSet(m_xBuilder
->weld_scrolled_window(u
"colorsetwin"_ustr
, true)))
2063 , mxRecentColorSet(new SvxColorValueSet(nullptr))
2064 , mxPaletteListBox(m_xBuilder
->weld_combo_box(u
"palette_listbox"_ustr
))
2065 , mxButtonAutoColor(m_xBuilder
->weld_button(u
"auto_color_button"_ustr
))
2066 , mxButtonNoneColor(m_xBuilder
->weld_button(u
"none_color_button"_ustr
))
2067 , mxButtonPicker(m_xBuilder
->weld_button(u
"color_picker_button"_ustr
))
2068 , mxAutomaticSeparator(m_xBuilder
->weld_widget(u
"separator4"_ustr
))
2069 , mxColorSetWin(new weld::CustomWeld(*m_xBuilder
, u
"colorset"_ustr
, *mxColorSet
))
2070 , mxRecentColorSetWin(new weld::CustomWeld(*m_xBuilder
, u
"recent_colorset"_ustr
, *mxRecentColorSet
))
2071 , mpDefaultButton(nullptr)
2073 mxColorSet
->SetStyle( WinBits(WB_FLATVALUESET
| WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
| WB_TABSTOP
) );
2074 mxRecentColorSet
->SetStyle( WinBits(WB_FLATVALUESET
| WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
| WB_TABSTOP
) );
2076 switch ( theSlotId
)
2078 case SID_ATTR_CHAR_COLOR_BACKGROUND
:
2079 case SID_BACKGROUND_COLOR
:
2080 case SID_ATTR_CHAR_BACK_COLOR
:
2081 case SID_TABLE_CELL_BACKGROUND_COLOR
:
2083 mxButtonAutoColor
->set_label( SvxResId( RID_SVXSTR_NOFILL
) );
2086 case SID_AUTHOR_COLOR
:
2088 mxButtonAutoColor
->set_label( SvxResId( RID_SVXSTR_BY_AUTHOR
) );
2091 case SID_BMPMASK_COLOR
:
2093 mxButtonAutoColor
->set_label( SvxResId( RID_SVXSTR_TRANSPARENT
) );
2096 case SID_ATTR_CHAR_COLOR
:
2097 case SID_ATTR_CHAR_COLOR2
:
2098 case SID_EXTRUSION_3D_COLOR
:
2100 mxButtonAutoColor
->set_label(EditResId(RID_SVXSTR_AUTOMATIC
));
2103 case SID_FM_CTL_PROPERTIES
:
2105 mxButtonAutoColor
->set_label( SvxResId( RID_SVXSTR_DEFAULT
) );
2110 mxButtonAutoColor
->hide();
2111 mxAutomaticSeparator
->hide();
2116 mxPaletteListBox
->connect_changed(LINK(this, ColorWindow
, SelectPaletteHdl
));
2117 std::vector
<OUString
> aPaletteList
= mxPaletteManager
->GetPaletteList();
2118 mxPaletteListBox
->freeze();
2119 for (const auto& rPalette
: aPaletteList
)
2120 mxPaletteListBox
->append_text(rPalette
);
2121 mxPaletteListBox
->thaw();
2123 // tdf#162104 If the current palette does not exist, select the equivalent to the localized "Standard" palette
2124 // This is required because the names are now localized and in Common.xcs the "Standard" (in English)
2125 // palette is selected by default
2126 OUString
aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get());
2127 auto it
= std::find(aPaletteList
.begin(), aPaletteList
.end(), aPaletteName
);
2128 if (it
== aPaletteList
.end())
2129 aPaletteName
= SvxResId(RID_SVXSTR_COLOR_PALETTE_STANDARD
);
2131 mxPaletteListBox
->set_active_text(aPaletteName
);
2132 const int nSelectedEntry(mxPaletteListBox
->get_active());
2133 if (nSelectedEntry
!= -1)
2134 mxPaletteManager
->SetPalette(nSelectedEntry
);
2136 mxButtonAutoColor
->connect_clicked(LINK(this, ColorWindow
, AutoColorClickHdl
));
2137 mxButtonNoneColor
->connect_clicked(LINK(this, ColorWindow
, AutoColorClickHdl
));
2138 mxButtonPicker
->connect_clicked(LINK(this, ColorWindow
, OpenPickerClickHdl
));
2140 mxColorSet
->SetSelectHdl(LINK( this, ColorWindow
, SelectHdl
));
2141 mxRecentColorSet
->SetSelectHdl(LINK( this, ColorWindow
, SelectHdl
));
2142 m_xTopLevel
->set_help_id(HID_POPUP_COLOR
);
2143 mxColorSet
->SetHelpId(HID_POPUP_COLOR_CTRL
);
2145 mxPaletteManager
->ReloadColorSet(*mxColorSet
);
2146 const sal_uInt32
nMaxItems(SvxColorValueSet::getMaxRowCount() * SvxColorValueSet::getColumnCount());
2147 Size aSize
= mxColorSet
->layoutAllVisible(nMaxItems
);
2148 mxColorSet
->set_size_request(aSize
.Width(), aSize
.Height());
2150 mxPaletteManager
->ReloadRecentColorSet(*mxRecentColorSet
);
2151 aSize
= mxRecentColorSet
->layoutAllVisible(mxPaletteManager
->GetRecentColorCount());
2152 mxRecentColorSet
->set_size_request(aSize
.Width(), aSize
.Height());
2154 AddStatusListener( u
".uno:ColorTableState"_ustr
);
2155 AddStatusListener( maCommand
);
2156 if ( maCommand
== ".uno:FrameLineColor" )
2158 AddStatusListener( u
".uno:BorderTLBR"_ustr
);
2159 AddStatusListener( u
".uno:BorderBLTR"_ustr
);
2163 void ColorWindow::GrabFocus()
2165 if (mxColorSet
->IsNoSelection() && mpDefaultButton
)
2166 mpDefaultButton
->grab_focus();
2168 mxColorSet
->GrabFocus();
2171 void ColorWindow::ShowNoneButton()
2173 mxButtonNoneColor
->show();
2176 ColorWindow::~ColorWindow()
2180 NamedColor
ColorWindow::GetSelectEntryColor(ValueSet
const * pColorSet
)
2182 Color aColor
= pColorSet
->GetItemColor(pColorSet
->GetSelectedItemId());
2183 OUString sColorName
= pColorSet
->GetItemText(pColorSet
->GetSelectedItemId());
2184 return { aColor
, sColorName
};
2189 NamedColor
GetAutoColor(sal_uInt16 nSlotId
)
2192 OUString sColorName
;
2195 case SID_ATTR_CHAR_COLOR_BACKGROUND
:
2196 case SID_BACKGROUND_COLOR
:
2197 case SID_ATTR_CHAR_BACK_COLOR
:
2198 case SID_TABLE_CELL_BACKGROUND_COLOR
:
2199 aColor
= COL_TRANSPARENT
;
2200 sColorName
= SvxResId(RID_SVXSTR_NOFILL
);
2202 case SID_AUTHOR_COLOR
:
2203 aColor
= COL_TRANSPARENT
;
2204 sColorName
= SvxResId(RID_SVXSTR_BY_AUTHOR
);
2206 case SID_BMPMASK_COLOR
:
2207 aColor
= COL_TRANSPARENT
;
2208 sColorName
= SvxResId(RID_SVXSTR_TRANSPARENT
);
2210 case SID_FM_CTL_PROPERTIES
:
2211 aColor
= COL_TRANSPARENT
;
2212 sColorName
= SvxResId(RID_SVXSTR_DEFAULT
);
2214 case SID_ATTR_CHAR_COLOR
:
2215 case SID_ATTR_CHAR_COLOR2
:
2216 case SID_EXTRUSION_3D_COLOR
:
2219 sColorName
= EditResId(RID_SVXSTR_AUTOMATIC
);
2223 return {aColor
, sColorName
};
2226 NamedColor
GetNoneColor()
2228 OUString aName
= comphelper::LibreOfficeKit::isActive()
2229 ? SvxResId(RID_SVXSTR_INVISIBLE
)
2230 : SvxResId(RID_SVXSTR_NONE
);
2231 return { COL_NONE_COLOR
, aName
};
2235 NamedColor
ColorWindow::GetSelectEntryColor() const
2237 if (!mxColorSet
->IsNoSelection())
2238 return GetSelectEntryColor(mxColorSet
.get());
2239 if (!mxRecentColorSet
->IsNoSelection())
2240 return GetSelectEntryColor(mxRecentColorSet
.get());
2241 if (mxButtonNoneColor
.get() == mpDefaultButton
)
2242 return GetNoneColor();
2243 return GetAutoColor();
2246 IMPL_LINK(ColorWindow
, SelectHdl
, ValueSet
*, pColorSet
, void)
2248 NamedColor aNamedColor
= GetSelectEntryColor(pColorSet
);
2250 if (pColorSet
!= mxRecentColorSet
.get())
2252 mxPaletteManager
->AddRecentColor(aNamedColor
.m_aColor
, aNamedColor
.m_aName
);
2253 if (!maMenuButton
.get_active())
2254 mxPaletteManager
->ReloadRecentColorSet(*mxRecentColorSet
);
2257 mxPaletteManager
->SetSplitButtonColor(aNamedColor
);
2259 // deliberate take a copy here in case maMenuButton.set_inactive
2260 // triggers a callback that destroys ourself
2261 ColorSelectFunction
aColorSelectFunction(maColorSelectFunction
);
2262 OUString
sCommand(maCommand
);
2263 // Same for querying IsTheme early.
2264 bool bThemePaletteSelected
= mxPaletteManager
->IsThemePaletteSelected();
2265 sal_uInt16 nSelectedItemId
= pColorSet
->GetSelectedItemId();
2267 if (bThemePaletteSelected
)
2269 sal_uInt16 nThemeIndex
;
2270 sal_uInt16 nEffectIndex
;
2271 if (PaletteManager::GetThemeAndEffectIndex(nSelectedItemId
, nThemeIndex
, nEffectIndex
))
2273 aNamedColor
.m_nThemeIndex
= nThemeIndex
;
2274 mxPaletteManager
->GetLumModOff(nThemeIndex
, nEffectIndex
, aNamedColor
.m_nLumMod
, aNamedColor
.m_nLumOff
);
2278 maMenuButton
.set_inactive();
2279 aColorSelectFunction(sCommand
, aNamedColor
);
2282 IMPL_LINK_NOARG(ColorWindow
, SelectPaletteHdl
, weld::ComboBox
&, void)
2284 int nPos
= mxPaletteListBox
->get_active();
2285 mxPaletteManager
->SetPalette( nPos
);
2286 mxPaletteManager
->ReloadColorSet(*mxColorSet
);
2287 mxColorSet
->layoutToGivenHeight(mxColorSet
->GetOutputSizePixel().Height(), mxPaletteManager
->GetColorCount());
2290 NamedColor
ColorWindow::GetAutoColor() const
2292 return ::GetAutoColor(theSlotId
);
2295 IMPL_LINK(ColorWindow
, AutoColorClickHdl
, weld::Button
&, rButton
, void)
2297 NamedColor aNamedColor
= &rButton
== mxButtonAutoColor
.get() ? GetAutoColor() : GetNoneColor();
2299 mxColorSet
->SetNoSelection();
2300 mxRecentColorSet
->SetNoSelection();
2301 mpDefaultButton
= &rButton
;
2303 mxPaletteManager
->SetSplitButtonColor(aNamedColor
);
2305 // deliberate take a copy here in case maMenuButton.set_inactive
2306 // triggers a callback that destroys ourself
2307 ColorSelectFunction
aColorSelectFunction(maColorSelectFunction
);
2308 OUString
sCommand(maCommand
);
2310 maMenuButton
.set_inactive();
2312 aColorSelectFunction(sCommand
, aNamedColor
);
2315 IMPL_LINK_NOARG(ColorWindow
, OpenPickerClickHdl
, weld::Button
&, void)
2317 // copy before set_inactive
2318 auto nColor
= GetSelectEntryColor().m_aColor
;
2319 auto pParentWindow
= maTopLevelParentFunction();
2320 OUString sCommand
= maCommand
;
2321 std::shared_ptr
<PaletteManager
> xPaletteManager(mxPaletteManager
);
2323 maMenuButton
.set_inactive();
2325 xPaletteManager
->PopupColorPicker(pParentWindow
, sCommand
, nColor
);
2328 void ColorWindow::SetNoSelection()
2330 mxColorSet
->SetNoSelection();
2331 mxRecentColorSet
->SetNoSelection();
2332 mpDefaultButton
= nullptr;
2335 bool ColorWindow::IsNoSelection() const
2337 if (!mxColorSet
->IsNoSelection())
2339 if (!mxRecentColorSet
->IsNoSelection())
2341 return !mxButtonAutoColor
->get_visible() && !mxButtonNoneColor
->get_visible();
2344 void ColorWindow::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
2346 if (rEvent
.FeatureURL
.Complete
== ".uno:ColorTableState")
2348 if (rEvent
.IsEnabled
&& mxPaletteManager
->GetPalette() == 0)
2350 mxPaletteManager
->ReloadColorSet(*mxColorSet
);
2351 mxColorSet
->layoutToGivenHeight(mxColorSet
->GetOutputSizePixel().Height(), mxPaletteManager
->GetColorCount());
2356 mrColorStatus
.statusChanged(rEvent
);
2357 SelectEntry(mrColorStatus
.GetColor());
2361 bool ColorWindow::SelectValueSetEntry(SvxColorValueSet
* pColorSet
, const Color
& rColor
)
2363 for (size_t i
= 1; i
<= pColorSet
->GetItemCount(); ++i
)
2365 if (rColor
== pColorSet
->GetItemColor(i
))
2367 pColorSet
->SelectItem(i
);
2374 void ColorWindow::SelectEntry(const NamedColor
& rNamedColor
)
2378 const Color
&rColor
= rNamedColor
.m_aColor
;
2380 if (mxButtonAutoColor
->get_visible() && rColor
.IsFullyTransparent())
2382 mpDefaultButton
= mxButtonAutoColor
.get();
2386 if (mxButtonNoneColor
->get_visible() && rColor
== COL_NONE_COLOR
)
2388 mpDefaultButton
= mxButtonNoneColor
.get();
2392 // try current palette
2393 bool bFoundColor
= SelectValueSetEntry(mxColorSet
.get(), rColor
);
2394 // try recently used
2396 bFoundColor
= SelectValueSetEntry(mxRecentColorSet
.get(), rColor
);
2397 // if it's not there, add it there now to the end of the recently used
2398 // so its available somewhere handy, but not without trashing the
2399 // whole recently used
2402 const OUString
& rColorName
= rNamedColor
.m_aName
;
2403 mxPaletteManager
->AddRecentColor(rColor
, rColorName
, false);
2404 mxPaletteManager
->ReloadRecentColorSet(*mxRecentColorSet
);
2405 SelectValueSetEntry(mxRecentColorSet
.get(), rColor
);
2409 void ColorWindow::SelectEntry(const Color
& rColor
)
2411 OUString sColorName
= "#" + rColor
.AsRGBHexString().toAsciiUpperCase();
2412 ColorWindow::SelectEntry({rColor
, sColorName
});
2415 ColorStatus::ColorStatus() :
2416 maColor( COL_TRANSPARENT
),
2417 maTLBRColor( COL_TRANSPARENT
),
2418 maBLTRColor( COL_TRANSPARENT
)
2422 void ColorStatus::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
2424 Color
aColor( COL_TRANSPARENT
);
2425 css::table::BorderLine2 aTable
;
2427 if ( rEvent
.State
>>= aTable
)
2429 SvxBorderLine aLine
;
2430 SvxBoxItem::LineToSvxLine( aTable
, aLine
, false );
2431 if ( !aLine
.isEmpty() )
2432 aColor
= aLine
.GetColor();
2435 rEvent
.State
>>= aColor
;
2437 if ( rEvent
.FeatureURL
.Path
== "BorderTLBR" )
2438 maTLBRColor
= aColor
;
2439 else if ( rEvent
.FeatureURL
.Path
== "BorderBLTR" )
2440 maBLTRColor
= aColor
;
2445 Color
ColorStatus::GetColor()
2447 Color
aColor( maColor
);
2449 if ( maTLBRColor
!= COL_TRANSPARENT
)
2451 if ( aColor
!= maTLBRColor
&& aColor
!= COL_TRANSPARENT
)
2452 return COL_TRANSPARENT
;
2453 aColor
= maTLBRColor
;
2456 if ( maBLTRColor
!= COL_TRANSPARENT
)
2458 if ( aColor
!= maBLTRColor
&& aColor
!= COL_TRANSPARENT
)
2459 return COL_TRANSPARENT
;
2467 SvxFrameWindow_Impl::SvxFrameWindow_Impl(SvxFrameToolBoxControl
* pControl
, weld::Widget
* pParent
)
2468 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, u
"svx/ui/floatingframeborder.ui"_ustr
, u
"FloatingFrameBorder"_ustr
)
2469 , mxControl(pControl
)
2470 , mxFrameSet(new SvxFrmValueSet_Impl
)
2471 , mxFrameSetWin(new weld::CustomWeld(*m_xBuilder
, u
"valueset"_ustr
, *mxFrameSet
))
2472 , bParagraphMode(false)
2473 , m_bIsWriter(false)
2476 // check whether the document is Writer or not
2477 if (Reference
<lang::XServiceInfo
> xSI
{ m_xFrame
->getController()->getModel(), UNO_QUERY
})
2478 m_bIsWriter
= xSI
->supportsService(u
"com.sun.star.text.TextDocument"_ustr
);
2480 mxFrameSet
->SetStyle(WB_ITEMBORDER
| WB_DOUBLEBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
);
2481 AddStatusListener(u
".uno:BorderReducedMode"_ustr
);
2486 * ------------------------------------------------------
2487 * NONE LEFT RIGHT LEFTRIGHT DIAGONALDOWN
2488 * TOP BOTTOM TOPBOTTOM OUTER DIAGONALUP
2489 * ------------------------------------------------------
2490 * HOR HORINNER VERINNER ALL CRISSCROSS <- can be switched of via bParagraphMode
2495 // diagonal borders available only for Calc.
2496 // Therefore, Calc uses 10 border types while
2497 // Writer uses 8 of them - for a single cell.
2498 for ( i
=1; i
< (m_bIsWriter
? 9 : 11); i
++ )
2499 mxFrameSet
->InsertItem(i
, Image(aImgVec
[i
-1].first
), aImgVec
[i
-1].second
);
2501 //bParagraphMode should have been set in StateChanged
2502 if ( !bParagraphMode
)
2503 // when multiple cell selected:
2504 // Writer has 12 border types and Calc has 15 of them.
2505 for ( i
= (m_bIsWriter
? 9 : 11); i
< (m_bIsWriter
? 13 : 16); i
++ )
2506 mxFrameSet
->InsertItem(i
, Image(aImgVec
[i
-1].first
), aImgVec
[i
-1].second
);
2508 // adjust frame column for Writer
2509 sal_uInt16 colCount
= m_bIsWriter
? 4 : 5;
2510 mxFrameSet
->SetColCount( colCount
);
2511 mxFrameSet
->SetSelectHdl( LINK( this, SvxFrameWindow_Impl
, SelectHdl
) );
2514 mxFrameSet
->SetHelpId( HID_POPUP_FRAME
);
2515 mxFrameSet
->SetAccessibleName( SvxResId(RID_SVXSTR_FRAME
) );
2520 enum class FrmValidFlags
{
2534 template<> struct typed_flags
<FrmValidFlags
> : is_typed_flags
<FrmValidFlags
, 0x3f> {};
2537 // By default unset lines remain unchanged.
2538 // Via Shift unset lines are reset
2540 IMPL_LINK_NOARG(SvxFrameWindow_Impl
, SelectHdl
, ValueSet
*, void)
2542 SvxBoxItem
aBorderOuter( SID_ATTR_BORDER_OUTER
);
2543 SvxBoxInfoItem
aBorderInner( SID_ATTR_BORDER_INNER
);
2544 SvxBorderLine theDefLine
;
2546 // diagonal down border
2547 SvxBorderLine
dDownBorderLine(nullptr, SvxBorderLineWidth::Hairline
);
2548 SvxLineItem
dDownLineItem(SID_ATTR_BORDER_DIAG_TLBR
);
2550 // diagonal up border
2551 SvxBorderLine
dUpBorderLine(nullptr, SvxBorderLineWidth::Hairline
);
2552 SvxLineItem
dUpLineItem(SID_ATTR_BORDER_DIAG_BLTR
);
2554 bool bIsDiagonalBorder
= false;
2556 SvxBorderLine
*pLeft
= nullptr,
2560 sal_uInt16 nSel
= mxFrameSet
->GetSelectedItemId();
2561 sal_uInt16 nModifier
= mxFrameSet
->GetModifier();
2562 FrmValidFlags nValidFlags
= FrmValidFlags::NONE
;
2564 // tdf#48622, tdf#145828 use correct default to create intended 0.75pt
2565 // cell border using the border formatting tool in the standard toolbar
2566 theDefLine
.GuessLinesWidths(theDefLine
.GetBorderLineStyle(), SvxBorderLineWidth::Thin
);
2568 // nSel has 15 cases which means 15 border
2569 // types for Calc. But Writer uses only 12
2570 // of them - when diagonal borders excluded.
2573 // add appropriate increments
2574 // to match the correct borders.
2575 if (nSel
> 8) { nSel
+= 2; }
2576 else if (nSel
> 4) { nSel
++; }
2581 case 1: nValidFlags
|= FrmValidFlags::AllMask
;
2582 // set nullptr to remove diagonal lines
2583 dDownLineItem
.SetLine(nullptr);
2584 dUpLineItem
.SetLine(nullptr);
2585 SetDiagonalDownBorder(dDownLineItem
);
2586 SetDiagonalUpBorder(dUpLineItem
);
2588 case 2: pLeft
= &theDefLine
;
2589 nValidFlags
|= FrmValidFlags::Left
;
2591 case 3: pRight
= &theDefLine
;
2592 nValidFlags
|= FrmValidFlags::Right
;
2594 case 4: pLeft
= pRight
= &theDefLine
;
2595 nValidFlags
|= FrmValidFlags::Right
|FrmValidFlags::Left
;
2597 case 5: dDownLineItem
.SetLine(&dDownBorderLine
);
2598 SetDiagonalDownBorder(dDownLineItem
);
2599 bIsDiagonalBorder
= true;
2600 break; // DIAGONAL DOWN
2601 case 6: pTop
= &theDefLine
;
2602 nValidFlags
|= FrmValidFlags::Top
;
2604 case 7: pBottom
= &theDefLine
;
2605 nValidFlags
|= FrmValidFlags::Bottom
;
2607 case 8: pTop
= pBottom
= &theDefLine
;
2608 nValidFlags
|= FrmValidFlags::Bottom
|FrmValidFlags::Top
;
2610 case 9: pLeft
= pRight
= pTop
= pBottom
= &theDefLine
;
2611 nValidFlags
|= FrmValidFlags::Left
| FrmValidFlags::Right
| FrmValidFlags::Top
| FrmValidFlags::Bottom
;
2614 dUpLineItem
.SetLine(&dUpBorderLine
);
2615 SetDiagonalUpBorder(dUpLineItem
);
2616 bIsDiagonalBorder
= true;
2617 break; // DIAGONAL UP
2621 pTop
= pBottom
= &theDefLine
;
2622 aBorderInner
.SetLine( &theDefLine
, SvxBoxInfoItemLine::HORI
);
2623 aBorderInner
.SetLine( nullptr, SvxBoxInfoItemLine::VERT
);
2624 nValidFlags
|= FrmValidFlags::HInner
|FrmValidFlags::Top
|FrmValidFlags::Bottom
;
2627 case 12: // HORINNER
2628 pLeft
= pRight
= pTop
= pBottom
= &theDefLine
;
2629 aBorderInner
.SetLine( &theDefLine
, SvxBoxInfoItemLine::HORI
);
2630 aBorderInner
.SetLine( nullptr, SvxBoxInfoItemLine::VERT
);
2631 nValidFlags
|= FrmValidFlags::Right
|FrmValidFlags::Left
|FrmValidFlags::HInner
|FrmValidFlags::Top
|FrmValidFlags::Bottom
;
2634 case 13: // VERINNER
2635 pLeft
= pRight
= pTop
= pBottom
= &theDefLine
;
2636 aBorderInner
.SetLine( nullptr, SvxBoxInfoItemLine::HORI
);
2637 aBorderInner
.SetLine( &theDefLine
, SvxBoxInfoItemLine::VERT
);
2638 nValidFlags
|= FrmValidFlags::Right
|FrmValidFlags::Left
|FrmValidFlags::VInner
|FrmValidFlags::Top
|FrmValidFlags::Bottom
;
2642 pLeft
= pRight
= pTop
= pBottom
= &theDefLine
;
2643 aBorderInner
.SetLine( &theDefLine
, SvxBoxInfoItemLine::HORI
);
2644 aBorderInner
.SetLine( &theDefLine
, SvxBoxInfoItemLine::VERT
);
2645 nValidFlags
|= FrmValidFlags::AllMask
;
2649 // set both diagonal lines to draw criss-cross line
2650 dDownLineItem
.SetLine(&dDownBorderLine
);
2651 dUpLineItem
.SetLine(&dUpBorderLine
);
2653 SetDiagonalDownBorder(dDownLineItem
);
2654 SetDiagonalUpBorder(dUpLineItem
);
2655 bIsDiagonalBorder
= true;
2656 break; // CRISS-CROSS
2662 // if diagonal borders selected,
2663 // no need to execute this block
2664 if (!bIsDiagonalBorder
)
2666 aBorderOuter
.SetLine( pLeft
, SvxBoxItemLine::LEFT
);
2667 aBorderOuter
.SetLine( pRight
, SvxBoxItemLine::RIGHT
);
2668 aBorderOuter
.SetLine( pTop
, SvxBoxItemLine::TOP
);
2669 aBorderOuter
.SetLine( pBottom
, SvxBoxItemLine::BOTTOM
);
2671 if(nModifier
== KEY_SHIFT
)
2672 nValidFlags
|= FrmValidFlags::AllMask
;
2673 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::TOP
, bool(nValidFlags
&FrmValidFlags::Top
));
2674 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::BOTTOM
, bool(nValidFlags
&FrmValidFlags::Bottom
));
2675 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::LEFT
, bool(nValidFlags
&FrmValidFlags::Left
));
2676 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::RIGHT
, bool(nValidFlags
&FrmValidFlags::Right
));
2677 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::HORI
, bool(nValidFlags
&FrmValidFlags::HInner
));
2678 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::VERT
, bool(nValidFlags
&FrmValidFlags::VInner
));
2679 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::DISTANCE
);
2680 aBorderInner
.SetValid( SvxBoxInfoItemValidFlags::DISABLE
, false );
2683 aBorderOuter
.QueryValue( a1
);
2684 aBorderInner
.QueryValue( a2
);
2685 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"OuterBorder"_ustr
, a1
),
2686 comphelper::makePropertyValue(u
"InnerBorder"_ustr
, a2
) };
2688 mxControl
->dispatchCommand( u
".uno:SetBorderStyle"_ustr
, aArgs
);
2691 // coverity[ check_after_deref : FALSE]
2694 /* #i33380# Moved the following line above the Dispatch() call.
2695 This instance may be deleted in the meantime (i.e. when a dialog is opened
2696 while in Dispatch()), accessing members will crash in this case. */
2697 mxFrameSet
->SetNoSelection();
2700 mxControl
->EndPopupMode();
2703 void SvxFrameWindow_Impl::SetDiagonalDownBorder(const SvxLineItem
& dDownLineItem
)
2705 // apply diagonal down border
2707 dDownLineItem
.QueryValue(a
);
2708 Sequence
<PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"BorderTLBR"_ustr
, a
) };
2710 mxControl
->dispatchCommand(u
".uno:BorderTLBR"_ustr
, aArgs
);
2713 void SvxFrameWindow_Impl::SetDiagonalUpBorder(const SvxLineItem
& dUpLineItem
)
2715 // apply diagonal up border
2717 dUpLineItem
.QueryValue(a
);
2718 Sequence
<PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"BorderBLTR"_ustr
, a
) };
2720 mxControl
->dispatchCommand(u
".uno:BorderBLTR"_ustr
, aArgs
);
2723 void SvxFrameWindow_Impl::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
2725 if ( rEvent
.FeatureURL
.Complete
!= ".uno:BorderReducedMode" )
2729 if ( !(rEvent
.State
>>= bValue
) )
2732 bParagraphMode
= bValue
;
2733 //initial calls mustn't insert or remove elements
2734 if(!mxFrameSet
->GetItemCount())
2737 // set 12 border types for Writer, otherwise 15 for Calc.
2738 bool bTableMode
= ( mxFrameSet
->GetItemCount() == static_cast<size_t>(m_bIsWriter
? 12 : 15) );
2739 bool bResize
= false;
2741 if ( bTableMode
&& bParagraphMode
)
2743 for ( sal_uInt16 i
= (m_bIsWriter
? 9 : 11); i
< (m_bIsWriter
? 13 : 16); i
++ )
2744 mxFrameSet
->RemoveItem(i
);
2747 else if ( !bTableMode
&& !bParagraphMode
)
2749 for ( sal_uInt16 i
= (m_bIsWriter
? 9 : 11); i
< (m_bIsWriter
? 13 : 16); i
++ )
2750 mxFrameSet
->InsertItem(i
, Image(aImgVec
[i
-1].first
), aImgVec
[i
-1].second
);
2760 void SvxFrameWindow_Impl::CalcSizeValueSet()
2762 weld::DrawingArea
* pDrawingArea
= mxFrameSet
->GetDrawingArea();
2763 const OutputDevice
& rDevice
= pDrawingArea
->get_ref_device();
2764 Size
aItemSize( 20 * rDevice
.GetDPIScaleFactor(), 20 * rDevice
.GetDPIScaleFactor() );
2765 Size aSize
= mxFrameSet
->CalcWindowSizePixel( aItemSize
);
2766 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
2767 mxFrameSet
->SetOutputSizePixel(aSize
);
2770 void SvxFrameWindow_Impl::InitImageList()
2774 // Writer-specific aImgVec.
2775 // Since Writer doesn't have diagonal borders,
2776 // we have to use 12 border types here.
2778 {BitmapEx(RID_SVXBMP_FRAME1
), SvxResId(RID_SVXSTR_TABLE_PRESET_NONE
)},
2779 {BitmapEx(RID_SVXBMP_FRAME2
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYLEFT
)},
2780 {BitmapEx(RID_SVXBMP_FRAME3
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYRIGHT
)},
2781 {BitmapEx(RID_SVXBMP_FRAME4
), SvxResId(RID_SVXSTR_PARA_PRESET_LEFTRIGHT
)},
2783 {BitmapEx(RID_SVXBMP_FRAME5
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYTOP
)},
2784 {BitmapEx(RID_SVXBMP_FRAME6
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYBOTTOM
)},
2785 {BitmapEx(RID_SVXBMP_FRAME7
), SvxResId(RID_SVXSTR_PARA_PRESET_TOPBOTTOM
)},
2786 {BitmapEx(RID_SVXBMP_FRAME8
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTER
)},
2788 {BitmapEx(RID_SVXBMP_FRAME9
), SvxResId(RID_SVXSTR_PARA_PRESET_TOPBOTTOMHORI
)},
2789 {BitmapEx(RID_SVXBMP_FRAME10
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERHORI
)},
2790 {BitmapEx(RID_SVXBMP_FRAME11
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERVERI
)},
2791 {BitmapEx(RID_SVXBMP_FRAME12
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERALL
)}
2796 // Calc has diagonal borders feature.
2797 // Therefore use additional 3 diagonal border types,
2798 // which make border types 15 in total.
2800 {BitmapEx(RID_SVXBMP_FRAME1
), SvxResId(RID_SVXSTR_TABLE_PRESET_NONE
)},
2801 {BitmapEx(RID_SVXBMP_FRAME2
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYLEFT
)},
2802 {BitmapEx(RID_SVXBMP_FRAME3
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYRIGHT
)},
2803 {BitmapEx(RID_SVXBMP_FRAME4
), SvxResId(RID_SVXSTR_PARA_PRESET_LEFTRIGHT
)},
2804 {BitmapEx(RID_SVXBMP_FRAME14
), SvxResId(RID_SVXSTR_PARA_PRESET_DIAGONALDOWN
)}, // diagonal down border
2806 {BitmapEx(RID_SVXBMP_FRAME5
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYTOP
)},
2807 {BitmapEx(RID_SVXBMP_FRAME6
), SvxResId(RID_SVXSTR_PARA_PRESET_ONLYBOTTOM
)},
2808 {BitmapEx(RID_SVXBMP_FRAME7
), SvxResId(RID_SVXSTR_PARA_PRESET_TOPBOTTOM
)},
2809 {BitmapEx(RID_SVXBMP_FRAME8
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTER
)},
2810 {BitmapEx(RID_SVXBMP_FRAME13
), SvxResId(RID_SVXSTR_PARA_PRESET_DIAGONALUP
)}, // diagonal up border
2812 {BitmapEx(RID_SVXBMP_FRAME9
), SvxResId(RID_SVXSTR_PARA_PRESET_TOPBOTTOMHORI
)},
2813 {BitmapEx(RID_SVXBMP_FRAME10
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERHORI
)},
2814 {BitmapEx(RID_SVXBMP_FRAME11
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERVERI
)},
2815 {BitmapEx(RID_SVXBMP_FRAME12
), SvxResId(RID_SVXSTR_TABLE_PRESET_OUTERALL
)},
2816 {BitmapEx(RID_SVXBMP_FRAME15
), SvxResId(RID_SVXSTR_PARA_PRESET_CRISSCROSS
)} // criss-cross border
2821 static Color
lcl_mediumColor( Color aMain
, Color
/*aDefault*/ )
2823 return SvxBorderLine::threeDMediumColor( aMain
);
2826 SvxLineWindow_Impl::SvxLineWindow_Impl(SvxFrameToolBoxControl
* pControl
, weld::Widget
* pParent
)
2827 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, u
"svx/ui/floatingframeborder.ui"_ustr
, u
"FloatingFrameBorder"_ustr
)
2828 , m_xControl(pControl
)
2829 , m_xLineStyleLb(new LineListBox
)
2830 , m_xLineStyleLbWin(new weld::CustomWeld(*m_xBuilder
, u
"valueset"_ustr
, *m_xLineStyleLb
))
2831 , m_bIsWriter(false)
2835 Reference
< lang::XServiceInfo
> xServices(m_xFrame
->getController()->getModel(), UNO_QUERY
);
2837 m_bIsWriter
= xServices
->supportsService(u
"com.sun.star.text.TextDocument"_ustr
);
2839 catch(const uno::Exception
& )
2843 m_xLineStyleLb
->SetStyle( WinBits(WB_FLATVALUESET
| WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
| WB_TABSTOP
) );
2845 m_xLineStyleLb
->SetSourceUnit( FieldUnit::TWIP
);
2846 m_xLineStyleLb
->SetNone( comphelper::LibreOfficeKit::isActive() ? SvxResId(RID_SVXSTR_INVISIBLE
)
2847 :SvxResId(RID_SVXSTR_NONE
) );
2849 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::SOLID
), SvxBorderLineStyle::SOLID
);
2850 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOTTED
), SvxBorderLineStyle::DOTTED
);
2851 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DASHED
), SvxBorderLineStyle::DASHED
);
2854 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOUBLE
), SvxBorderLineStyle::DOUBLE
);
2855 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_SMALLGAP
), SvxBorderLineStyle::THINTHICK_SMALLGAP
, 20 );
2856 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_MEDIUMGAP
), SvxBorderLineStyle::THINTHICK_MEDIUMGAP
);
2857 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_LARGEGAP
), SvxBorderLineStyle::THINTHICK_LARGEGAP
);
2858 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_SMALLGAP
), SvxBorderLineStyle::THICKTHIN_SMALLGAP
, 20 );
2859 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
), SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
);
2860 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_LARGEGAP
), SvxBorderLineStyle::THICKTHIN_LARGEGAP
);
2862 // Engraved / Embossed
2863 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::EMBOSSED
), SvxBorderLineStyle::EMBOSSED
, 15,
2864 &SvxBorderLine::threeDLightColor
, &SvxBorderLine::threeDDarkColor
,
2866 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::ENGRAVED
), SvxBorderLineStyle::ENGRAVED
, 15,
2867 &SvxBorderLine::threeDDarkColor
, &SvxBorderLine::threeDLightColor
,
2871 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::OUTSET
), SvxBorderLineStyle::OUTSET
, 10,
2872 &SvxBorderLine::lightColor
, &SvxBorderLine::darkColor
);
2873 m_xLineStyleLb
->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::INSET
), SvxBorderLineStyle::INSET
, 10,
2874 &SvxBorderLine::darkColor
, &SvxBorderLine::lightColor
);
2875 Size aSize
= m_xLineStyleLb
->SetWidth( 20 ); // 1pt by default
2877 m_xLineStyleLb
->SetSelectHdl( LINK( this, SvxLineWindow_Impl
, SelectHdl
) );
2879 m_xContainer
->set_help_id(HID_POPUP_LINE
);
2881 aSize
.AdjustWidth(6);
2882 aSize
.AdjustHeight(6);
2883 aSize
= m_xLineStyleLb
->CalcWindowSizePixel(aSize
);
2884 m_xLineStyleLb
->GetDrawingArea()->set_size_request(aSize
.Width(), aSize
.Height());
2885 m_xLineStyleLb
->SetOutputSizePixel(aSize
);
2888 IMPL_LINK_NOARG(SvxLineWindow_Impl
, SelectHdl
, ValueSet
*, void)
2890 SvxLineItem
aLineItem( SID_FRAME_LINESTYLE
);
2891 SvxBorderLineStyle nStyle
= m_xLineStyleLb
->GetSelectEntryStyle();
2893 if ( m_xLineStyleLb
->GetSelectItemPos( ) > 0 )
2896 aTmp
.SetBorderLineStyle( nStyle
);
2897 aTmp
.SetWidth( SvxBorderLineWidth::Thin
); // TODO Make it depend on a width field
2898 aLineItem
.SetLine( &aTmp
);
2901 aLineItem
.SetLine( nullptr );
2904 aLineItem
.QueryValue( a
, m_bIsWriter
? CONVERT_TWIPS
: 0 );
2905 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"LineStyle"_ustr
, a
) };
2907 m_xControl
->dispatchCommand( u
".uno:LineStyle"_ustr
, aArgs
);
2909 m_xControl
->EndPopupMode();
2912 SfxStyleControllerItem_Impl::SfxStyleControllerItem_Impl(
2913 const Reference
< XDispatchProvider
>& rDispatchProvider
,
2914 sal_uInt16 nSlotId
, // Family-ID
2915 const OUString
& rCommand
, // .uno: command bound to this item
2916 SvxStyleToolBoxControl
& rTbxCtl
) // controller instance, which the item is assigned to.
2917 : SfxStatusListener( rDispatchProvider
, nSlotId
, rCommand
),
2922 void SfxStyleControllerItem_Impl::StateChangedAtStatusListener(
2923 SfxItemState eState
, const SfxPoolItem
* pState
)
2927 case SID_STYLE_FAMILY1
:
2928 case SID_STYLE_FAMILY2
:
2929 case SID_STYLE_FAMILY3
:
2930 case SID_STYLE_FAMILY4
:
2931 case SID_STYLE_FAMILY5
:
2933 const sal_uInt16 nIdx
= GetId() - SID_STYLE_FAMILY_START
;
2935 if ( SfxItemState::DEFAULT
== eState
)
2937 const SfxTemplateItem
* pStateItem
=
2938 dynamic_cast<const SfxTemplateItem
*>( pState
);
2939 DBG_ASSERT( pStateItem
!= nullptr, "SfxTemplateItem expected" );
2940 rControl
.SetFamilyState( nIdx
, pStateItem
);
2943 rControl
.SetFamilyState( nIdx
, nullptr );
2949 struct SvxStyleToolBoxControl::Impl
2951 OUString aClearForm
;
2953 ::std::vector
< std::pair
< OUString
, OUString
> > aDefaultStyles
;
2954 bool bSpecModeWriter
;
2957 VclPtr
<SvxStyleBox_Impl
> m_xVclBox
;
2958 std::unique_ptr
<SvxStyleBox_Base
> m_xWeldBox
;
2959 SvxStyleBox_Base
* m_pBox
;
2962 :aClearForm ( SvxResId( RID_SVXSTR_CLEARFORM
) )
2963 ,aMore ( SvxResId( RID_SVXSTR_MORE_STYLES
) )
2964 ,bSpecModeWriter ( false )
2965 ,bSpecModeCalc ( false )
2971 void InitializeStyles(const Reference
< frame::XModel
>& xModel
)
2973 aDefaultStyles
.clear();
2975 //now convert the default style names to the localized names
2978 Reference
< style::XStyleFamiliesSupplier
> xStylesSupplier( xModel
, UNO_QUERY_THROW
);
2979 Reference
< lang::XServiceInfo
> xServices( xModel
, UNO_QUERY_THROW
);
2980 bSpecModeWriter
= xServices
->supportsService(u
"com.sun.star.text.TextDocument"_ustr
);
2983 Reference
<container::XNameAccess
> xParaStyles
;
2984 xStylesSupplier
->getStyleFamilies()->getByName(u
"ParagraphStyles"_ustr
) >>=
2986 static constexpr OUString aWriterStyles
[]
2997 u
"Preformatted Text"_ustr
2999 for( const OUString
& aStyle
: aWriterStyles
)
3003 Reference
< beans::XPropertySet
> xStyle
;
3004 xParaStyles
->getByName( aStyle
) >>= xStyle
;
3006 xStyle
->getPropertyValue(u
"DisplayName"_ustr
) >>= sName
;
3007 if( !sName
.isEmpty() )
3008 aDefaultStyles
.push_back(
3009 std::pair
<OUString
, OUString
>(aStyle
, sName
) );
3011 catch( const uno::Exception
& )
3017 bSpecModeCalc
= xServices
->supportsService(
3018 u
"com.sun.star.sheet.SpreadsheetDocument"_ustr
)))
3020 static constexpr OUString aCalcStyles
[]
3030 Reference
<container::XNameAccess
> xCellStyles
;
3031 xStylesSupplier
->getStyleFamilies()->getByName(u
"CellStyles"_ustr
) >>= xCellStyles
;
3032 for(const OUString
& sStyleName
: aCalcStyles
)
3036 if( xCellStyles
->hasByName( sStyleName
) )
3038 Reference
< beans::XPropertySet
> xStyle( xCellStyles
->getByName( sStyleName
), UNO_QUERY_THROW
);
3040 xStyle
->getPropertyValue(u
"DisplayName"_ustr
) >>= sName
;
3041 if( !sName
.isEmpty() )
3042 aDefaultStyles
.push_back(
3043 std::pair
<OUString
, OUString
>(sStyleName
, sName
) );
3046 catch( const uno::Exception
& )
3051 catch(const uno::Exception
& )
3053 OSL_FAIL("error while initializing style names");
3058 // mapping table from bound items. BE CAREFUL this table must be in the
3059 // same order as the uno commands bound to the slots SID_STYLE_FAMILY1..n
3060 // MAX_FAMILIES must also be correctly set!
3061 constexpr OUString StyleSlotToStyleCommand
[MAX_FAMILIES
] =
3063 u
".uno:CharStyle"_ustr
,
3064 u
".uno:ParaStyle"_ustr
,
3065 u
".uno:FrameStyle"_ustr
,
3066 u
".uno:PageStyle"_ustr
,
3067 u
".uno:TemplateFamily5"_ustr
3070 SvxStyleToolBoxControl::SvxStyleToolBoxControl()
3072 , pStyleSheetPool(nullptr)
3073 , nActFamily(0xffff)
3075 for (sal_uInt16 i
= 0; i
< MAX_FAMILIES
; ++i
)
3077 m_xBoundItems
[i
].clear();
3078 pFamilyState
[i
] = nullptr;
3082 SvxStyleToolBoxControl::~SvxStyleToolBoxControl()
3086 void SAL_CALL
SvxStyleToolBoxControl::initialize(const Sequence
<Any
>& rArguments
)
3088 svt::ToolboxController::initialize(rArguments
);
3090 // After initialize we should have a valid frame member where we can retrieve our
3091 // dispatch provider.
3092 if ( !m_xFrame
.is() )
3095 pImpl
->InitializeStyles(m_xFrame
->getController()->getModel());
3096 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
->getController(), UNO_QUERY
);
3097 for ( sal_uInt16 i
=0; i
<MAX_FAMILIES
; i
++ )
3099 m_xBoundItems
[i
] = new SfxStyleControllerItem_Impl( xDispatchProvider
,
3100 SID_STYLE_FAMILY_START
+ i
,
3101 StyleSlotToStyleCommand
[i
],
3103 pFamilyState
[i
] = nullptr;
3108 void SAL_CALL
SvxStyleToolBoxControl::dispose()
3110 svt::ToolboxController::dispose();
3112 SolarMutexGuard aSolarMutexGuard
;
3113 pImpl
->m_xVclBox
.disposeAndClear();
3114 pImpl
->m_xWeldBox
.reset();
3115 pImpl
->m_pBox
= nullptr;
3117 for (rtl::Reference
<SfxStyleControllerItem_Impl
>& pBoundItem
: m_xBoundItems
)
3121 pBoundItem
->UnBind();
3125 for( sal_uInt16 i
=0; i
<MAX_FAMILIES
; i
++ )
3127 if ( m_xBoundItems
[i
].is() )
3131 m_xBoundItems
[i
]->dispose();
3133 catch ( Exception
& )
3137 m_xBoundItems
[i
].clear();
3139 pFamilyState
[i
].reset();
3141 pStyleSheetPool
= nullptr;
3145 OUString
SvxStyleToolBoxControl::getImplementationName()
3147 return u
"com.sun.star.comp.svx.StyleToolBoxControl"_ustr
;
3150 sal_Bool
SvxStyleToolBoxControl::supportsService( const OUString
& rServiceName
)
3152 return cppu::supportsService( this, rServiceName
);
3155 css::uno::Sequence
< OUString
> SvxStyleToolBoxControl::getSupportedServiceNames()
3157 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
3160 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
3161 com_sun_star_comp_svx_StyleToolBoxControl_get_implementation(
3162 css::uno::XComponentContext
*,
3163 css::uno::Sequence
<css::uno::Any
> const & )
3165 return cppu::acquire( new SvxStyleToolBoxControl() );
3168 void SAL_CALL
SvxStyleToolBoxControl::update()
3170 for (rtl::Reference
<SfxStyleControllerItem_Impl
>& pBoundItem
: m_xBoundItems
)
3171 pBoundItem
->ReBind();
3175 SfxStyleFamily
SvxStyleToolBoxControl::GetActFamily() const
3177 switch ( nActFamily
-1 + SID_STYLE_FAMILY_START
)
3179 case SID_STYLE_FAMILY1
: return SfxStyleFamily::Char
;
3180 case SID_STYLE_FAMILY2
: return SfxStyleFamily::Para
;
3181 case SID_STYLE_FAMILY3
: return SfxStyleFamily::Frame
;
3182 case SID_STYLE_FAMILY4
: return SfxStyleFamily::Page
;
3183 case SID_STYLE_FAMILY5
: return SfxStyleFamily::Pseudo
;
3185 OSL_FAIL( "unknown style family" );
3188 return SfxStyleFamily::Para
;
3191 void SvxStyleToolBoxControl::FillStyleBox()
3193 SvxStyleBox_Base
* pBox
= pImpl
->m_pBox
;
3195 DBG_ASSERT( pStyleSheetPool
, "StyleSheetPool not found!" );
3196 DBG_ASSERT( pBox
, "Control not found!" );
3198 if ( !(pStyleSheetPool
&& pBox
&& nActFamily
!=0xffff) )
3201 const SfxStyleFamily eFamily
= GetActFamily();
3202 SfxStyleSheetBase
* pStyle
= nullptr;
3203 bool bDoFill
= false;
3205 auto xIter
= pStyleSheetPool
->CreateIterator(eFamily
, SfxStyleSearchBits::Used
);
3206 sal_uInt16 nCount
= xIter
->Count();
3208 // Check whether fill is necessary
3209 pStyle
= xIter
->First();
3210 //!!! TODO: This condition isn't right any longer, because we always show some default entries
3211 //!!! so the list doesn't show the count
3212 if ( nCount
!= pBox
->get_count() )
3219 while ( pStyle
&& !bDoFill
)
3221 bDoFill
= ( pBox
->get_text(i
) != pStyle
->GetName() );
3222 pStyle
= xIter
->Next();
3230 OUString
aStrSel(pBox
->get_active_text());
3234 std::vector
<OUString
> aStyles
;
3237 pStyle
= xIter
->Next();
3240 aStyles
.push_back(pStyle
->GetName());
3241 pStyle
= xIter
->Next();
3244 if (pImpl
->bSpecModeWriter
|| pImpl
->bSpecModeCalc
)
3246 pBox
->append_text(pImpl
->aClearForm
);
3247 pBox
->insert_separator(1, u
"separator"_ustr
);
3249 // add default styles if less than 12 items
3250 for( const auto &rStyle
: pImpl
->aDefaultStyles
)
3252 if ( aStyles
.size() + pBox
->get_count() > 12)
3254 // insert default style only if not used (and added to rStyle before)
3255 if (std::find(aStyles
.begin(), aStyles
.end(), rStyle
.second
) >= aStyles
.end())
3256 pBox
->append_text(rStyle
.second
);
3259 std::sort(aStyles
.begin(), aStyles
.end());
3261 for (const auto& rStyle
: aStyles
)
3262 pBox
->append_text(rStyle
);
3264 if ((pImpl
->bSpecModeWriter
|| pImpl
->bSpecModeCalc
) && !comphelper::LibreOfficeKit::isActive())
3265 pBox
->append_text(pImpl
->aMore
);
3268 pBox
->set_active_or_entry_text(aStrSel
);
3269 pBox
->SetFamily( eFamily
);
3272 void SvxStyleToolBoxControl::SelectStyle( const OUString
& rStyleName
)
3274 SvxStyleBox_Base
* pBox
= pImpl
->m_pBox
;
3275 DBG_ASSERT( pBox
, "Control not found!" );
3280 OUString
aStrSel(pBox
->get_active_text());
3282 if ( !rStyleName
.isEmpty() )
3284 OUString aNewStyle
= rStyleName
;
3286 auto aFound
= std::find_if(pImpl
->aDefaultStyles
.begin(), pImpl
->aDefaultStyles
.end(),
3287 [rStyleName
] (auto it
) { return it
.first
== rStyleName
|| it
.second
== rStyleName
; }
3290 if (aFound
!= pImpl
->aDefaultStyles
.end())
3291 aNewStyle
= aFound
->second
;
3293 if ( aNewStyle
!= aStrSel
)
3294 pBox
->set_active_or_entry_text( aNewStyle
);
3297 pBox
->set_active(-1);
3301 void SvxStyleToolBoxControl::Update()
3303 SfxStyleSheetBasePool
* pPool
= nullptr;
3304 SfxObjectShell
* pDocShell
= SfxObjectShell::Current();
3307 pPool
= pDocShell
->GetStyleSheetPool();
3310 for ( i
=0; i
<MAX_FAMILIES
; i
++ )
3311 if( pFamilyState
[i
] )
3314 if ( i
==MAX_FAMILIES
|| !pPool
)
3316 pStyleSheetPool
= pPool
;
3321 const SfxTemplateItem
* pItem
= nullptr;
3323 if ( nActFamily
== 0xffff || nullptr == (pItem
= pFamilyState
[nActFamily
-1].get()) )
3324 // Current range not within allowed ranges or default
3326 pStyleSheetPool
= pPool
;
3329 pItem
= pFamilyState
[nActFamily
-1].get();
3333 pItem
= pFamilyState
[nActFamily
-1].get();
3336 else if ( pPool
!= pStyleSheetPool
)
3337 pStyleSheetPool
= pPool
;
3339 FillStyleBox(); // Decides by itself whether Fill is needed
3342 SelectStyle( pItem
->GetStyleName() );
3345 void SvxStyleToolBoxControl::SetFamilyState( sal_uInt16 nIdx
,
3346 const SfxTemplateItem
* pItem
)
3348 pFamilyState
[nIdx
].reset( pItem
== nullptr ? nullptr : new SfxTemplateItem( *pItem
) );
3352 void SvxStyleToolBoxControl::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
3354 SolarMutexGuard aGuard
;
3357 m_pToolbar
->set_item_sensitive(m_aCommandURL
, rEvent
.IsEnabled
);
3360 ToolBox
* pToolBox
= nullptr;
3362 if (!getToolboxId( nId
, &pToolBox
) )
3364 pToolBox
->EnableItem( nId
, rEvent
.IsEnabled
);
3367 if (rEvent
.IsEnabled
)
3371 css::uno::Reference
<css::awt::XWindow
> SvxStyleToolBoxControl::createItemWindow(const css::uno::Reference
< css::awt::XWindow
>& rParent
)
3373 uno::Reference
< awt::XWindow
> xItemWindow
;
3377 SolarMutexGuard aSolarMutexGuard
;
3379 std::unique_ptr
<weld::ComboBox
> xWidget(m_pBuilder
->weld_combo_box(u
"applystyle"_ustr
));
3381 xItemWindow
= css::uno::Reference
<css::awt::XWindow
>(new weld::TransportAsXWindow(xWidget
.get()));
3383 pImpl
->m_xWeldBox
.reset(new SvxStyleBox_Base(std::move(xWidget
),
3384 u
".uno:StyleApply"_ustr
,
3385 SfxStyleFamily::Para
,
3389 pImpl
->bSpecModeWriter
|| pImpl
->bSpecModeCalc
, *this));
3390 pImpl
->m_pBox
= pImpl
->m_xWeldBox
.get();
3394 VclPtr
<vcl::Window
> pParent
= VCLUnoHelper::GetWindow(rParent
);
3397 SolarMutexGuard aSolarMutexGuard
;
3399 pImpl
->m_xVclBox
= VclPtr
<SvxStyleBox_Impl
>::Create(pParent
,
3401 SfxStyleFamily::Para
,
3405 pImpl
->bSpecModeWriter
|| pImpl
->bSpecModeCalc
, *this);
3406 pImpl
->m_pBox
= pImpl
->m_xVclBox
.get();
3407 xItemWindow
= VCLUnoHelper::GetInterface(pImpl
->m_xVclBox
);
3411 if (pImpl
->m_pBox
&& !pImpl
->aDefaultStyles
.empty())
3412 pImpl
->m_pBox
->SetDefaultStyle(pImpl
->aDefaultStyles
[0].second
);
3417 SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
3422 void SvxFontNameBox_Base::statusChanged_Impl( const css::frame::FeatureStateEvent
& rEvent
)
3424 if ( !rEvent
.IsEnabled
)
3426 set_sensitive(false);
3431 set_sensitive(true);
3433 css::awt::FontDescriptor aFontDesc
;
3434 if ( rEvent
.State
>>= aFontDesc
)
3437 // no active element; delete value in the display
3438 m_xWidget
->set_active(-1);
3439 set_active_or_entry_text(u
""_ustr
);
3441 m_xWidget
->save_value();
3445 void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
3447 SolarMutexGuard aGuard
;
3448 m_pBox
->statusChanged_Impl(rEvent
);
3451 m_pToolbar
->set_item_sensitive(m_aCommandURL
, rEvent
.IsEnabled
);
3454 ToolBox
* pToolBox
= nullptr;
3456 if (!getToolboxId( nId
, &pToolBox
) )
3458 pToolBox
->EnableItem( nId
, rEvent
.IsEnabled
);
3462 css::uno::Reference
<css::awt::XWindow
> SvxFontNameToolBoxControl::createItemWindow(const css::uno::Reference
<css::awt::XWindow
>& rParent
)
3464 uno::Reference
< awt::XWindow
> xItemWindow
;
3468 SolarMutexGuard aSolarMutexGuard
;
3470 std::unique_ptr
<weld::ComboBox
> xWidget(m_pBuilder
->weld_combo_box(u
"fontnamecombobox"_ustr
));
3472 xItemWindow
= css::uno::Reference
<css::awt::XWindow
>(new weld::TransportAsXWindow(xWidget
.get()));
3474 m_xWeldBox
.reset(new SvxFontNameBox_Base(std::move(xWidget
), m_xFrame
, *this));
3475 m_pBox
= m_xWeldBox
.get();
3479 VclPtr
<vcl::Window
> pParent
= VCLUnoHelper::GetWindow(rParent
);
3482 SolarMutexGuard aSolarMutexGuard
;
3483 m_xVclBox
= VclPtr
<SvxFontNameBox_Impl
>::Create(pParent
, m_xFrame
, *this);
3484 m_pBox
= m_xVclBox
.get();
3485 xItemWindow
= VCLUnoHelper::GetInterface(m_xVclBox
);
3492 void SvxFontNameToolBoxControl::dispose()
3494 ToolboxController::dispose();
3496 SolarMutexGuard aSolarMutexGuard
;
3497 m_xVclBox
.disposeAndClear();
3502 OUString
SvxFontNameToolBoxControl::getImplementationName()
3504 return u
"com.sun.star.comp.svx.FontNameToolBoxControl"_ustr
;
3507 sal_Bool
SvxFontNameToolBoxControl::supportsService( const OUString
& rServiceName
)
3509 return cppu::supportsService( this, rServiceName
);
3512 css::uno::Sequence
< OUString
> SvxFontNameToolBoxControl::getSupportedServiceNames()
3514 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
3517 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
3518 com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation(
3519 css::uno::XComponentContext
*,
3520 css::uno::Sequence
<css::uno::Any
> const & )
3522 return cppu::acquire( new SvxFontNameToolBoxControl() );
3525 SvxColorToolBoxControl::SvxColorToolBoxControl( const css::uno::Reference
<css::uno::XComponentContext
>& rContext
) :
3526 ImplInheritanceHelper( rContext
, nullptr, OUString() ),
3527 m_bSplitButton(true),
3529 m_aColorSelectFunction(PaletteManager::DispatchColorCommand
)
3535 sal_uInt16
MapCommandToSlotId(const OUString
& rCommand
)
3537 if (rCommand
== ".uno:Color")
3538 return SID_ATTR_CHAR_COLOR
;
3539 else if (rCommand
== ".uno:FontColor")
3540 return SID_ATTR_CHAR_COLOR2
;
3541 else if (rCommand
== ".uno:BackColor") // deprecated - use CharBackColor
3542 return SID_ATTR_CHAR_COLOR_BACKGROUND
;
3543 else if (rCommand
== ".uno:CharBackColor")
3544 return SID_ATTR_CHAR_BACK_COLOR
;
3545 else if (rCommand
== ".uno:BackgroundColor")
3546 return SID_BACKGROUND_COLOR
;
3547 else if (rCommand
== ".uno:TableCellBackgroundColor")
3548 return SID_TABLE_CELL_BACKGROUND_COLOR
;
3549 else if (rCommand
== ".uno:Extrusion3DColor")
3550 return SID_EXTRUSION_3D_COLOR
;
3551 else if (rCommand
== ".uno:XLineColor")
3552 return SID_ATTR_LINE_COLOR
;
3553 else if (rCommand
== ".uno:FillColor")
3554 return SID_ATTR_FILL_COLOR
;
3555 else if (rCommand
== ".uno:FrameLineColor")
3556 return SID_FRAME_LINECOLOR
;
3558 SAL_WARN("svx.tbxcrtls", "Unknown color command: " << rCommand
);
3564 void SvxColorToolBoxControl::initialize( const css::uno::Sequence
<css::uno::Any
>& rArguments
)
3566 PopupWindowController::initialize( rArguments
);
3568 m_nSlotId
= MapCommandToSlotId( m_aCommandURL
);
3570 if ( m_nSlotId
== SID_ATTR_LINE_COLOR
|| m_nSlotId
== SID_ATTR_FILL_COLOR
||
3571 m_nSlotId
== SID_FRAME_LINECOLOR
|| m_nSlotId
== SID_BACKGROUND_COLOR
)
3573 // Sidebar uses wide buttons for those.
3574 m_bSplitButton
= !m_bSidebar
;
3577 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(getCommandURL(), getModuleName());
3578 OUString aCommandLabel
= vcl::CommandInfoProvider::GetLabelForCommand(aProperties
);
3582 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
3583 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
3584 m_xBtnUpdater
.reset(new svx::ToolboxButtonColorUpdater(m_nSlotId
, m_aCommandURL
, m_pToolbar
, !m_bSplitButton
, aCommandLabel
, m_xFrame
));
3588 ToolBox
* pToolBox
= nullptr;
3590 if (getToolboxId(nId
, &pToolBox
))
3592 m_xBtnUpdater
.reset( new svx::VclToolboxButtonColorUpdater( m_nSlotId
, nId
, pToolBox
, !m_bSplitButton
, aCommandLabel
, m_aCommandURL
, m_xFrame
) );
3593 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ( m_bSplitButton
? ToolBoxItemBits::DROPDOWN
: ToolBoxItemBits::DROPDOWNONLY
) );
3597 void SvxColorToolBoxControl::update()
3599 PopupWindowController::update();
3603 case SID_ATTR_CHAR_COLOR2
:
3604 addStatusListener( u
".uno:CharColorExt"_ustr
);
3607 case SID_ATTR_CHAR_BACK_COLOR
:
3608 case SID_ATTR_CHAR_COLOR_BACKGROUND
:
3609 addStatusListener( u
".uno:CharBackgroundExt"_ustr
);
3612 case SID_FRAME_LINECOLOR
:
3613 addStatusListener( u
".uno:BorderTLBR"_ustr
);
3614 addStatusListener( u
".uno:BorderBLTR"_ustr
);
3619 void SvxColorToolBoxControl::EnsurePaletteManager()
3621 if (!m_xPaletteManager
)
3623 m_xPaletteManager
= std::make_shared
<PaletteManager
>();
3624 m_xPaletteManager
->SetBtnUpdater(m_xBtnUpdater
.get());
3628 SvxColorToolBoxControl::~SvxColorToolBoxControl()
3630 if (m_xPaletteManager
)
3631 m_xPaletteManager
->SetBtnUpdater(nullptr);
3634 void SvxColorToolBoxControl::setColorSelectFunction(const ColorSelectFunction
& aColorSelectFunction
)
3636 m_aColorSelectFunction
= aColorSelectFunction
;
3637 if (m_xPaletteManager
)
3638 m_xPaletteManager
->SetColorSelectFunction(aColorSelectFunction
);
3641 weld::Window
* SvxColorToolBoxControl::GetParentFrame() const
3643 const css::uno::Reference
<css::awt::XWindow
> xParent
= m_xFrame
->getContainerWindow();
3644 return Application::GetFrameWeld(xParent
);
3647 std::unique_ptr
<WeldToolbarPopup
> SvxColorToolBoxControl::weldPopupWindow()
3649 EnsurePaletteManager();
3651 auto xPopover
= std::make_unique
<ColorWindow
>(
3657 MenuOrToolMenuButton(m_pToolbar
, m_aCommandURL
),
3658 [this] { return GetParentFrame(); },
3659 m_aColorSelectFunction
);
3664 VclPtr
<vcl::Window
> SvxColorToolBoxControl::createVclPopupWindow( vcl::Window
* pParent
)
3666 ToolBox
* pToolBox
= nullptr;
3668 if (!getToolboxId(nId
, &pToolBox
))
3671 EnsurePaletteManager();
3673 auto xPopover
= std::make_unique
<ColorWindow
>(
3679 MenuOrToolMenuButton(this, pToolBox
, nId
),
3680 [this] { return GetParentFrame(); },
3681 m_aColorSelectFunction
);
3683 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
3684 std::move(xPopover
), true);
3686 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(m_aCommandURL
, m_sModuleName
);
3687 OUString aWindowTitle
= vcl::CommandInfoProvider::GetLabelForCommand(aProperties
);
3688 mxInterimPopover
->SetText(aWindowTitle
);
3690 mxInterimPopover
->Show();
3692 return mxInterimPopover
;
3695 void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
3697 ToolBox
* pToolBox
= nullptr;
3699 if (!getToolboxId(nId
, &pToolBox
) && !m_pToolbar
)
3702 if ( rEvent
.FeatureURL
.Complete
== m_aCommandURL
)
3705 m_pToolbar
->set_item_sensitive(m_aCommandURL
, rEvent
.IsEnabled
);
3707 pToolBox
->EnableItem( nId
, rEvent
.IsEnabled
);
3711 if ( !m_bSplitButton
)
3713 m_aColorStatus
.statusChanged( rEvent
);
3714 m_xBtnUpdater
->Update( m_aColorStatus
.GetColor() );
3716 else if ( rEvent
.State
>>= bValue
)
3719 m_pToolbar
->set_item_active(m_aCommandURL
, bValue
);
3721 pToolBox
->CheckItem( nId
, bValue
);
3725 void SvxColorToolBoxControl::execute(sal_Int16
/*nSelectModifier*/)
3727 if ( !m_bSplitButton
)
3731 // Toggle the popup also when toolbutton is activated
3732 m_pToolbar
->set_menu_item_active(m_aCommandURL
, !m_pToolbar
->get_menu_item_active(m_aCommandURL
));
3736 // Open the popup also when Enter key is pressed.
3737 createPopupWindow();
3742 OUString aCommand
= m_aCommandURL
;
3743 Color aColor
= m_xBtnUpdater
->GetCurrentColor();
3747 case SID_ATTR_CHAR_COLOR2
:
3748 aCommand
= ".uno:CharColorExt";
3752 auto aArgs( comphelper::InitPropertySequence( {
3753 { m_aCommandURL
.copy(5), css::uno::Any(aColor
) }
3755 dispatchCommand( aCommand
, aArgs
);
3757 EnsurePaletteManager();
3758 OUString sColorName
= m_xBtnUpdater
->GetCurrentColorName();
3759 m_xPaletteManager
->AddRecentColor(aColor
, sColorName
);
3762 sal_Bool
SvxColorToolBoxControl::opensSubToolbar()
3764 // We mark this controller as a sub-toolbar controller, so we get notified
3765 // (through updateImage method) on button image changes, and could redraw
3766 // the last used color on top of it.
3770 void SvxColorToolBoxControl::updateImage()
3772 m_xBtnUpdater
->Update(m_xBtnUpdater
->GetCurrentColor(), true);
3775 OUString
SvxColorToolBoxControl::getSubToolbarName()
3780 void SvxColorToolBoxControl::functionSelected( const OUString
& /*rCommand*/ )
3784 OUString
SvxColorToolBoxControl::getImplementationName()
3786 return u
"com.sun.star.comp.svx.ColorToolBoxControl"_ustr
;
3789 css::uno::Sequence
<OUString
> SvxColorToolBoxControl::getSupportedServiceNames()
3791 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
3794 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
3795 com_sun_star_comp_svx_ColorToolBoxControl_get_implementation(
3796 css::uno::XComponentContext
* rContext
,
3797 css::uno::Sequence
<css::uno::Any
> const & )
3799 return cppu::acquire( new SvxColorToolBoxControl( rContext
) );
3802 SvxFrameToolBoxControl::SvxFrameToolBoxControl( const css::uno::Reference
< css::uno::XComponentContext
>& rContext
)
3803 : svt::PopupWindowController( rContext
, nullptr, OUString() )
3807 void SAL_CALL
SvxFrameToolBoxControl::execute(sal_Int16
/*KeyModifier*/)
3811 // Toggle the popup also when toolbutton is activated
3812 m_pToolbar
->set_menu_item_active(m_aCommandURL
, !m_pToolbar
->get_menu_item_active(m_aCommandURL
));
3816 // Open the popup also when Enter key is pressed.
3817 createPopupWindow();
3821 void SvxFrameToolBoxControl::initialize( const css::uno::Sequence
< css::uno::Any
>& rArguments
)
3823 svt::PopupWindowController::initialize( rArguments
);
3827 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
3828 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
3831 ToolBox
* pToolBox
= nullptr;
3833 if (getToolboxId(nId
, &pToolBox
))
3834 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ToolBoxItemBits::DROPDOWNONLY
);
3837 std::unique_ptr
<WeldToolbarPopup
> SvxFrameToolBoxControl::weldPopupWindow()
3839 if ( m_aCommandURL
== ".uno:LineStyle" )
3840 return std::make_unique
<SvxLineWindow_Impl
>(this, m_pToolbar
);
3841 return std::make_unique
<SvxFrameWindow_Impl
>(this, m_pToolbar
);
3844 VclPtr
<vcl::Window
> SvxFrameToolBoxControl::createVclPopupWindow( vcl::Window
* pParent
)
3846 if ( m_aCommandURL
== ".uno:LineStyle" )
3848 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
3849 std::make_unique
<SvxLineWindow_Impl
>(this, pParent
->GetFrameWeld()), true);
3851 mxInterimPopover
->Show();
3853 mxInterimPopover
->SetText(SvxResId(RID_SVXSTR_FRAME_STYLE
));
3855 return mxInterimPopover
;
3858 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
3859 std::make_unique
<SvxFrameWindow_Impl
>(this, pParent
->GetFrameWeld()), true);
3861 mxInterimPopover
->Show();
3863 mxInterimPopover
->SetText(SvxResId(RID_SVXSTR_FRAME
));
3865 return mxInterimPopover
;
3868 OUString
SvxFrameToolBoxControl::getImplementationName()
3870 return u
"com.sun.star.comp.svx.FrameToolBoxControl"_ustr
;
3873 css::uno::Sequence
< OUString
> SvxFrameToolBoxControl::getSupportedServiceNames()
3875 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
3878 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
3879 com_sun_star_comp_svx_FrameToolBoxControl_get_implementation(
3880 css::uno::XComponentContext
* rContext
,
3881 css::uno::Sequence
<css::uno::Any
> const & )
3883 return cppu::acquire( new SvxFrameToolBoxControl( rContext
) );
3886 SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference
<css::uno::XComponentContext
>& rContext
) :
3887 PopupWindowController( rContext
, nullptr, OUString() ),
3888 m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
3889 m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND
)
3893 SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}
3897 /** Implementation of the currency combo widget **/
3898 class SvxCurrencyList_Impl
: public WeldToolbarPopup
3901 rtl::Reference
<SvxCurrencyToolBoxControl
> m_xControl
;
3902 std::unique_ptr
<weld::Label
> m_xLabel
;
3903 std::unique_ptr
<weld::TreeView
> m_xCurrencyLb
;
3904 std::unique_ptr
<weld::Button
> m_xOkBtn
;
3905 OUString
& m_rSelectedFormat
;
3906 LanguageType
& m_eSelectedLanguage
;
3908 std::vector
<OUString
> m_aFormatEntries
;
3909 LanguageType m_eFormatLanguage
;
3910 DECL_LINK(RowActivatedHdl
, weld::TreeView
&, bool);
3911 DECL_LINK(OKHdl
, weld::Button
&, void);
3913 virtual void GrabFocus() override
;
3916 SvxCurrencyList_Impl(SvxCurrencyToolBoxControl
* pControl
, weld::Widget
* pParent
, OUString
& rSelectedFormat
, LanguageType
& eSelectedLanguage
)
3917 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, u
"svx/ui/currencywindow.ui"_ustr
, u
"CurrencyWindow"_ustr
)
3918 , m_xControl(pControl
)
3919 , m_xLabel(m_xBuilder
->weld_label(u
"label"_ustr
))
3920 , m_xCurrencyLb(m_xBuilder
->weld_tree_view(u
"currency"_ustr
))
3921 , m_xOkBtn(m_xBuilder
->weld_button(u
"ok"_ustr
))
3922 , m_rSelectedFormat(rSelectedFormat
)
3923 , m_eSelectedLanguage(eSelectedLanguage
)
3925 std::vector
< OUString
> aList
;
3926 std::vector
< sal_uInt16
> aCurrencyList
;
3927 const NfCurrencyTable
& rCurrencyTable
= SvNumberFormatter::GetTheCurrencyTable();
3928 sal_uInt16 nLen
= rCurrencyTable
.size();
3930 SvNumberFormatter
aFormatter( m_xControl
->getContext(), LANGUAGE_SYSTEM
);
3931 m_eFormatLanguage
= aFormatter
.GetLanguage();
3933 std::vector
<sfx::CurrencyID
> aCurrencyIDs
;
3935 SfxObjectShell
* pDocShell
= SfxObjectShell::Current();
3936 if (auto pModelAccessor
= pDocShell
->GetDocumentModelAccessor())
3937 aCurrencyIDs
= pModelAccessor
->getDocumentCurrencies();
3939 SvxCurrencyToolBoxControl::GetCurrencySymbols(aList
, true, aCurrencyList
, aCurrencyIDs
);
3941 sal_uInt16 nPos
= 0, nCount
= 0;
3942 sal_Int32 nSelectedPos
= -1;
3944 NfWSStringsDtor aStringsDtor
;
3946 OUString sLongestString
;
3948 m_xCurrencyLb
->freeze();
3949 for( const auto& rItem
: aList
)
3951 sal_uInt16
& rCurrencyIndex
= aCurrencyList
[ nCount
];
3952 if ( rCurrencyIndex
< nLen
)
3954 m_xCurrencyLb
->append_text(rItem
);
3956 if (rItem
.getLength() > sLongestString
.getLength())
3957 sLongestString
= rItem
;
3959 bIsSymbol
= nPos
>= nLen
;
3961 sal_uInt16 nDefaultFormat
;
3962 const NfCurrencyEntry
& rCurrencyEntry
= rCurrencyTable
[ rCurrencyIndex
];
3963 if (rCurrencyIndex
== 0)
3965 // Stored with system locale, but we want the resolved
3966 // full LCID format string. For example
3967 // "[$$-409]#,##0.00" instead of "[$$]#,##0.00".
3968 NfCurrencyEntry
aCurrencyEntry( rCurrencyEntry
);
3969 aCurrencyEntry
.SetLanguage( LanguageTag( aCurrencyEntry
.GetLanguage()).getLanguageType());
3970 nDefaultFormat
= aFormatter
.GetCurrencyFormatStrings( aStringsDtor
, aCurrencyEntry
, bIsSymbol
);
3974 nDefaultFormat
= aFormatter
.GetCurrencyFormatStrings( aStringsDtor
, rCurrencyEntry
, bIsSymbol
);
3976 const OUString
& rFormatStr
= aStringsDtor
[ nDefaultFormat
];
3977 m_aFormatEntries
.push_back( rFormatStr
);
3978 if( rFormatStr
== m_rSelectedFormat
)
3979 nSelectedPos
= nPos
;
3984 m_xCurrencyLb
->thaw();
3985 // enable multiple selection enabled so we can start with nothing selected
3986 m_xCurrencyLb
->set_selection_mode(SelectionMode::Multiple
);
3987 m_xCurrencyLb
->connect_row_activated( LINK( this, SvxCurrencyList_Impl
, RowActivatedHdl
) );
3988 m_xLabel
->set_label(SvxResId(RID_SVXSTR_TBLAFMT_CURRENCY
));
3989 m_xCurrencyLb
->select( nSelectedPos
);
3990 m_xOkBtn
->connect_clicked(LINK(this, SvxCurrencyList_Impl
, OKHdl
));
3992 // gtk will initially make a best guess depending on the first few entries, so copy the probable
3993 // longest entry to the start temporarily and force in the width at this point
3994 m_xCurrencyLb
->insert_text(0, sLongestString
);
3995 m_xCurrencyLb
->set_size_request(m_xCurrencyLb
->get_preferred_size().Width(), m_xCurrencyLb
->get_height_rows(12));
3996 m_xCurrencyLb
->remove(0);
4000 void SvxCurrencyList_Impl::GrabFocus()
4002 m_xCurrencyLb
->grab_focus();
4005 IMPL_LINK_NOARG(SvxCurrencyList_Impl
, OKHdl
, weld::Button
&, void)
4007 RowActivatedHdl(*m_xCurrencyLb
);
4010 IMPL_LINK_NOARG(SvxCurrencyList_Impl
, RowActivatedHdl
, weld::TreeView
&, bool)
4012 if (!m_xControl
.is())
4015 // multiple selection enabled so we can start with nothing selected,
4016 // so force single selection after something is picked
4017 int nSelected
= m_xCurrencyLb
->get_selected_index();
4018 if (nSelected
== -1)
4021 m_xCurrencyLb
->set_selection_mode(SelectionMode::Single
);
4023 m_rSelectedFormat
= m_aFormatEntries
[nSelected
];
4024 m_eSelectedLanguage
= m_eFormatLanguage
;
4026 m_xControl
->execute(nSelected
+ 1);
4028 m_xControl
->EndPopupMode();
4034 void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence
< css::uno::Any
>& rArguments
)
4036 PopupWindowController::initialize(rArguments
);
4040 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
4041 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
4045 ToolBox
* pToolBox
= nullptr;
4047 if (getToolboxId(nId
, &pToolBox
) && pToolBox
->GetItemCommand(nId
) == m_aCommandURL
)
4048 pToolBox
->SetItemBits(nId
, ToolBoxItemBits::DROPDOWN
| pToolBox
->GetItemBits(nId
));
4051 std::unique_ptr
<WeldToolbarPopup
> SvxCurrencyToolBoxControl::weldPopupWindow()
4053 return std::make_unique
<SvxCurrencyList_Impl
>(this, m_pToolbar
, m_aFormatString
, m_eLanguage
);
4056 VclPtr
<vcl::Window
> SvxCurrencyToolBoxControl::createVclPopupWindow( vcl::Window
* pParent
)
4058 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
4059 std::make_unique
<SvxCurrencyList_Impl
>(this, pParent
->GetFrameWeld(), m_aFormatString
, m_eLanguage
));
4061 mxInterimPopover
->Show();
4063 return mxInterimPopover
;
4066 void SvxCurrencyToolBoxControl::execute( sal_Int16 nSelectModifier
)
4068 sal_uInt32 nFormatKey
;
4069 if (m_aFormatString
.isEmpty())
4070 nFormatKey
= NUMBERFORMAT_ENTRY_NOT_FOUND
;
4073 if ( nSelectModifier
> 0 )
4077 uno::Reference
< util::XNumberFormatsSupplier
> xRef( m_xFrame
->getController()->getModel(), uno::UNO_QUERY
);
4078 uno::Reference
< util::XNumberFormats
> rxNumberFormats( xRef
->getNumberFormats(), uno::UNO_SET_THROW
);
4079 css::lang::Locale aLocale
= LanguageTag::convertToLocale( m_eLanguage
);
4080 nFormatKey
= rxNumberFormats
->queryKey( m_aFormatString
, aLocale
, false );
4081 if ( nFormatKey
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
4082 nFormatKey
= rxNumberFormats
->addNew( m_aFormatString
, aLocale
);
4084 catch( const uno::Exception
& )
4086 nFormatKey
= m_nFormatKey
;
4090 nFormatKey
= m_nFormatKey
;
4093 if( nFormatKey
!= NUMBERFORMAT_ENTRY_NOT_FOUND
)
4095 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(u
"NumberFormatCurrency"_ustr
,
4097 dispatchCommand( m_aCommandURL
, aArgs
);
4098 m_nFormatKey
= nFormatKey
;
4101 PopupWindowController::execute( nSelectModifier
);
4104 OUString
SvxCurrencyToolBoxControl::getImplementationName()
4106 return u
"com.sun.star.comp.svx.CurrencyToolBoxControl"_ustr
;
4109 css::uno::Sequence
<OUString
> SvxCurrencyToolBoxControl::getSupportedServiceNames()
4111 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
4114 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
4115 com_sun_star_comp_svx_CurrencyToolBoxControl_get_implementation(
4116 css::uno::XComponentContext
* rContext
,
4117 css::uno::Sequence
<css::uno::Any
> const & )
4119 return cppu::acquire( new SvxCurrencyToolBoxControl( rContext
) );
4122 Reference
< css::accessibility::XAccessible
> SvxFontNameBox_Impl::CreateAccessible()
4125 return InterimItemWindow::CreateAccessible();
4129 void SvxCurrencyToolBoxControl::GetCurrencySymbols(std::vector
<OUString
>& rList
, bool bFlag
,
4130 std::vector
<sal_uInt16
>& rCurrencyList
,
4131 std::vector
<sfx::CurrencyID
> const& rDocumentCurrencyIDs
)
4133 rCurrencyList
.clear();
4135 constexpr OUString aTwoSpace
= u
" "_ustr
;
4136 const NfCurrencyTable
& rCurrencyTable
= SvNumberFormatter::GetTheCurrencyTable();
4137 sal_uInt16 nCount
= rCurrencyTable
.size();
4139 sal_uInt16 nStart
= 1;
4141 LanguageTag eLangTag
= Application::GetSettings().GetLanguageTag();
4142 OUString
aString(ApplyLreOrRleEmbedding(rCurrencyTable
[0].GetBankSymbol()));
4143 aString
+= aTwoSpace
;
4144 aString
+= ApplyLreOrRleEmbedding(rCurrencyTable
[0].GetSymbol());
4145 aString
+= aTwoSpace
;
4146 aString
+= ApplyLreOrRleEmbedding(SvtLanguageTable::GetLanguageString(eLangTag
.getLanguageType()));
4147 aString
+= aTwoSpace
;
4148 aString
+= ApplyLreOrRleEmbedding(SvtLanguageTable::GetLanguageString(rCurrencyTable
[0].GetLanguage()));
4150 rList
.push_back( aString
);
4151 rCurrencyList
.push_back( sal_uInt16(-1) ); // nAuto
4155 rList
.push_back( aString
);
4156 rCurrencyList
.push_back( 0 );
4160 CollatorWrapper
aCollator( ::comphelper::getProcessComponentContext() );
4161 aCollator
.loadDefaultCollator(eLangTag
.getLocale(), 0);
4163 for( sal_uInt16 i
= 1; i
< nCount
; ++i
)
4165 auto& rCurrencyEntry
= rCurrencyTable
[i
];
4167 OUString
aStr( ApplyLreOrRleEmbedding(rCurrencyEntry
.GetBankSymbol()));
4169 aStr
+= ApplyLreOrRleEmbedding(rCurrencyEntry
.GetSymbol());
4171 aStr
+= ApplyLreOrRleEmbedding(SvtLanguageTable::GetLanguageString(rCurrencyEntry
.GetLanguage()));
4173 std::vector
<OUString
>::size_type j
= nStart
;
4175 // Search if the currency is present in the document
4176 auto iter
= std::find_if(rDocumentCurrencyIDs
.begin(), rDocumentCurrencyIDs
.end(), [rCurrencyEntry
](sfx::CurrencyID
const& rCurrency
)
4178 const NfCurrencyEntry
* pEntry
= SvNumberFormatter::GetCurrencyEntry(o3tl::temporary(bool()), rCurrency
.aSymbol
, rCurrency
.aExtension
, rCurrency
.eLanguage
);
4181 return rCurrencyEntry
.GetLanguage() == pEntry
->GetLanguage() && rCurrencyEntry
.GetSymbol() == pEntry
->GetSymbol();
4186 // If currency is in document, insert it on top
4187 if (iter
!= rDocumentCurrencyIDs
.end())
4193 for( ; j
< rList
.size(); ++j
)
4195 if ( aCollator
.compareString( aStr
, rList
[j
] ) < 0 )
4196 break; // insert before first greater than
4200 rList
.insert( rList
.begin() + j
, aStr
);
4201 rCurrencyList
.insert( rCurrencyList
.begin() + j
, i
);
4204 // Append ISO codes to symbol list.
4205 // XXX If this is to be changed, various other places would had to be
4206 // adapted that assume this order!
4207 std::vector
<OUString
>::size_type nCont
= rList
.size();
4209 for ( sal_uInt16 i
= 1; i
< nCount
; ++i
)
4211 bool bInsert
= true;
4212 auto& rCurrencyEntry
= rCurrencyTable
[i
];
4213 OUString
aStr( ApplyLreOrRleEmbedding(rCurrencyEntry
.GetBankSymbol()));
4215 std::vector
<OUString
>::size_type j
= nCont
;
4216 for ( ; j
< rList
.size() && bInsert
; ++j
)
4218 if( rList
[j
] == aStr
)
4220 else if ( aCollator
.compareString( aStr
, rList
[j
] ) < 0 )
4221 break; // insert before first greater than
4225 rList
.insert( rList
.begin() + j
, aStr
);
4226 rCurrencyList
.insert( rCurrencyList
.begin() + j
, i
);
4231 ListBoxColorWrapper::ListBoxColorWrapper(ColorListBox
* pControl
)
4232 : mpControl(pControl
)
4236 void ListBoxColorWrapper::operator()(
4237 [[maybe_unused
]] const OUString
& /*rCommand*/, const NamedColor
& rColor
)
4239 mpControl
->Selected(rColor
);
4242 void ColorListBox::EnsurePaletteManager()
4244 if (!m_xPaletteManager
)
4246 m_xPaletteManager
= std::make_shared
<PaletteManager
>();
4247 m_xPaletteManager
->SetColorSelectFunction(std::ref(m_aColorWrapper
));
4251 void ColorListBox::SetSlotId(sal_uInt16 nSlotId
, bool bShowNoneButton
)
4253 m_nSlotId
= nSlotId
;
4254 m_bShowNoneButton
= bShowNoneButton
;
4255 m_xButton
->set_popover(nullptr);
4256 m_xColorWindow
.reset();
4257 m_aSelectedColor
= bShowNoneButton
? GetNoneColor() : GetAutoColor(m_nSlotId
);
4258 ShowPreview(m_aSelectedColor
);
4259 createColorWindow();
4262 ColorListBox::ColorListBox(std::unique_ptr
<weld::MenuButton
> pControl
,
4263 TopLevelParentFunction aTopLevelParentFunction
,
4264 const ColorListBox
* pCache
)
4265 : m_xButton(std::move(pControl
))
4266 , m_aColorWrapper(this)
4267 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
4269 , m_bShowNoneButton(false)
4270 , m_aTopLevelParentFunction(std::move(aTopLevelParentFunction
))
4272 m_xButton
->connect_toggled(LINK(this, ColorListBox
, ToggleHdl
));
4273 m_aSelectedColor
= GetAutoColor(m_nSlotId
);
4275 LockWidthRequest(CalcBestWidthRequest());
4278 LockWidthRequest(pCache
->m_xButton
->get_size_request().Width());
4279 m_xPaletteManager
.reset(pCache
->m_xPaletteManager
->Clone());
4280 m_xPaletteManager
->SetColorSelectFunction(std::ref(m_aColorWrapper
));
4282 ShowPreview(m_aSelectedColor
);
4285 IMPL_LINK(ColorListBox
, ToggleHdl
, weld::Toggleable
&, rButton
, void)
4287 if (rButton
.get_active())
4289 ColorWindow
* pColorWindow
= getColorWindow();
4290 if (pColorWindow
&& !comphelper::LibreOfficeKit::isActive())
4291 pColorWindow
->GrabFocus();
4295 ColorListBox::~ColorListBox()
4299 ColorWindow
* ColorListBox::getColorWindow() const
4301 if (!m_xColorWindow
)
4302 const_cast<ColorListBox
*>(this)->createColorWindow();
4303 return m_xColorWindow
.get();
4306 void ColorListBox::createColorWindow()
4308 const SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
4309 const SfxFrame
* pFrame
= pViewFrame
? &pViewFrame
->GetFrame() : nullptr;
4310 css::uno::Reference
<css::frame::XFrame
> xFrame(pFrame
? pFrame
->GetFrameInterface() : uno::Reference
<css::frame::XFrame
>());
4312 EnsurePaletteManager();
4314 m_xColorWindow
.reset(new ColorWindow(
4315 OUString() /*m_aCommandURL*/,
4321 m_aTopLevelParentFunction
,
4325 m_xButton
->set_popover(m_xColorWindow
->getTopLevel());
4326 if (m_bShowNoneButton
)
4327 m_xColorWindow
->ShowNoneButton();
4328 m_xColorWindow
->SelectEntry(m_aSelectedColor
);
4331 void ColorListBox::SelectEntry(const NamedColor
& rColor
)
4333 if (o3tl::trim(rColor
.m_aName
).empty())
4335 SelectEntry(rColor
.m_aColor
);
4338 ColorWindow
* pColorWindow
= getColorWindow();
4339 pColorWindow
->SelectEntry(rColor
);
4340 m_aSelectedColor
= pColorWindow
->GetSelectEntryColor();
4341 ShowPreview(m_aSelectedColor
);
4344 void ColorListBox::SelectEntry(const Color
& rColor
)
4346 ColorWindow
* pColorWindow
= getColorWindow();
4347 pColorWindow
->SelectEntry(rColor
);
4348 m_aSelectedColor
= pColorWindow
->GetSelectEntryColor();
4349 ShowPreview(m_aSelectedColor
);
4352 void ColorListBox::Selected(const NamedColor
& rColor
)
4354 ShowPreview(rColor
);
4355 m_aSelectedColor
= rColor
;
4356 if (m_aSelectedLink
.IsSet())
4357 m_aSelectedLink
.Call(*this);
4360 //to avoid the box resizing every time the color is changed to
4361 //the optimal size of the individual color, get the longest
4362 //standard color and stick with that as the size for all
4363 int ColorListBox::CalcBestWidthRequest()
4365 NamedColor aLongestColor
;
4366 tools::Long nMaxStandardColorTextWidth
= 0;
4367 XColorListRef
const xColorTable
= XColorList::CreateStdColorList();
4368 for (tools::Long i
= 0; i
!= xColorTable
->Count(); ++i
)
4370 XColorEntry
& rEntry
= *xColorTable
->GetColor(i
);
4371 auto nColorTextWidth
= m_xButton
->get_pixel_size(rEntry
.GetName()).Width();
4372 if (nColorTextWidth
> nMaxStandardColorTextWidth
)
4374 nMaxStandardColorTextWidth
= nColorTextWidth
;
4375 aLongestColor
.m_aName
= rEntry
.GetName();
4378 ShowPreview(aLongestColor
);
4379 return m_xButton
->get_preferred_size().Width();
4382 void ColorListBox::LockWidthRequest(int nWidth
)
4384 m_xButton
->set_size_request(nWidth
, -1);
4387 void ColorListBox::ShowPreview(const NamedColor
&rColor
)
4389 // ScGridWindow::UpdateAutoFilterFromMenu is similar
4390 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
4391 Size
aImageSize(rStyleSettings
.GetListBoxPreviewDefaultPixelSize());
4393 ScopedVclPtrInstance
<VirtualDevice
> xDevice
;
4394 xDevice
->SetOutputSize(aImageSize
);
4395 const tools::Rectangle
aRect(Point(0, 0), aImageSize
);
4396 if (m_bShowNoneButton
&& rColor
.m_aColor
== COL_NONE_COLOR
)
4398 const Color
aW(COL_WHITE
);
4399 const Color
aG(0xef, 0xef, 0xef);
4400 int nMinDim
= std::min(aImageSize
.Width(), aImageSize
.Height()) + 1;
4401 int nCheckSize
= nMinDim
/ 3;
4402 xDevice
->DrawCheckered(aRect
.TopLeft(), aRect
.GetSize(), std::min(nCheckSize
, 8), aW
, aG
);
4403 xDevice
->SetFillColor();
4407 if (rColor
.m_aColor
== COL_AUTO
)
4408 xDevice
->SetFillColor(m_aAutoDisplayColor
);
4410 xDevice
->SetFillColor(rColor
.m_aColor
);
4413 xDevice
->SetLineColor(rStyleSettings
.GetDisableColor());
4414 xDevice
->DrawRect(aRect
);
4416 m_xButton
->set_image(xDevice
.get());
4417 m_xButton
->set_label(rColor
.m_aName
);
4420 MenuOrToolMenuButton::MenuOrToolMenuButton(weld::MenuButton
* pMenuButton
)
4421 : m_pMenuButton(pMenuButton
)
4422 , m_pToolbar(nullptr)
4423 , m_pControl(nullptr)
4428 MenuOrToolMenuButton::MenuOrToolMenuButton(weld::Toolbar
* pToolbar
, OUString aIdent
)
4429 : m_pMenuButton(nullptr)
4430 , m_pToolbar(pToolbar
)
4431 , m_aIdent(std::move(aIdent
))
4432 , m_pControl(nullptr)
4437 MenuOrToolMenuButton::MenuOrToolMenuButton(SvxColorToolBoxControl
* pControl
, ToolBox
* pToolbar
, ToolBoxItemId nId
)
4438 : m_pMenuButton(nullptr)
4439 , m_pToolbar(nullptr)
4440 , m_pControl(pControl
)
4441 , m_xToolBox(pToolbar
)
4446 MenuOrToolMenuButton::~MenuOrToolMenuButton()
4450 bool MenuOrToolMenuButton::get_active() const
4453 return m_pMenuButton
->get_active();
4455 return m_pToolbar
->get_menu_item_active(m_aIdent
);
4456 return m_xToolBox
->GetDownItemId() == m_nId
;
4459 void MenuOrToolMenuButton::set_inactive() const
4463 if (m_pMenuButton
->get_active())
4464 m_pMenuButton
->set_active(false);
4469 if (m_pToolbar
->get_menu_item_active(m_aIdent
))
4470 m_pToolbar
->set_menu_item_active(m_aIdent
, false);
4473 m_pControl
->EndPopupMode();
4476 weld::Widget
* MenuOrToolMenuButton::get_widget() const
4479 return m_pMenuButton
;
4482 return m_xToolBox
->GetFrameWeld();
4485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */