Bump version to 6.4-15
[LibreOffice.git] / svx / source / tbxctrls / tbcontrl.cxx
blob50e3f6760867abdee07c8ccde5eb745df7303ced
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 .
20 #include <string>
21 #include <typeinfo>
22 #include <utility>
24 #include <comphelper/propertysequence.hxx>
25 #include <tools/color.hxx>
26 #include <svl/poolitem.hxx>
27 #include <svl/eitem.hxx>
28 #include <svl/itemset.hxx>
29 #include <vcl/commandinfoprovider.hxx>
30 #include <vcl/event.hxx>
31 #include <vcl/toolbox.hxx>
32 #include <vcl/bitmapaccess.hxx>
33 #include <vcl/menubtn.hxx>
34 #include <vcl/vclptr.hxx>
35 #include <svtools/valueset.hxx>
36 #include <svtools/ctrlbox.hxx>
37 #include <svl/style.hxx>
38 #include <svtools/ctrltool.hxx>
39 #include <svtools/borderhelper.hxx>
40 #include <svl/stritem.hxx>
41 #include <sfx2/tplpitem.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <sfx2/viewsh.hxx>
44 #include <sfx2/docfac.hxx>
45 #include <sfx2/templdlg.hxx>
46 #include <svl/isethint.hxx>
47 #include <sfx2/sfxstatuslistener.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <tools/urlobj.hxx>
50 #include <sfx2/childwin.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <unotools/fontoptions.hxx>
53 #include <vcl/builderfactory.hxx>
54 #include <vcl/mnemonic.hxx>
55 #include <vcl/svapp.hxx>
56 #include <vcl/settings.hxx>
57 #include <vcl/virdev.hxx>
58 #include <svtools/colorcfg.hxx>
59 #include <com/sun/star/awt/FontDescriptor.hpp>
60 #include <com/sun/star/table/BorderLine2.hpp>
61 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
62 #include <com/sun/star/lang/XServiceInfo.hpp>
63 #include <com/sun/star/beans/XPropertySet.hpp>
64 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
65 #include <com/sun/star/frame/XDispatchProvider.hpp>
66 #include <com/sun/star/frame/XFrame.hpp>
67 #include <svx/strings.hrc>
68 #include <svx/svxitems.hrc>
69 #include <svx/svxids.hrc>
70 #include <helpids.h>
71 #include <sfx2/htmlmode.hxx>
72 #include <sfx2/sidebar/Sidebar.hxx>
73 #include <sfx2/sidebar/SidebarToolBox.hxx>
74 #include <svx/xtable.hxx>
75 #include <editeng/editids.hrc>
76 #include <editeng/fontitem.hxx>
77 #include <editeng/fhgtitem.hxx>
78 #include <editeng/boxitem.hxx>
79 #include <editeng/charreliefitem.hxx>
80 #include <editeng/contouritem.hxx>
81 #include <editeng/colritem.hxx>
82 #include <editeng/crossedoutitem.hxx>
83 #include <editeng/emphasismarkitem.hxx>
84 #include <editeng/flstitem.hxx>
85 #include <editeng/lineitem.hxx>
86 #include <editeng/postitem.hxx>
87 #include <editeng/shdditem.hxx>
88 #include <editeng/udlnitem.hxx>
89 #include <editeng/wghtitem.hxx>
90 #include <editeng/svxfont.hxx>
91 #include <editeng/cmapitem.hxx>
92 #include <svx/colorwindow.hxx>
93 #include <svx/colorbox.hxx>
94 #include <svx/drawitem.hxx>
95 #include <svx/tbcontrl.hxx>
96 #include <svx/dlgutil.hxx>
97 #include <svx/dialmgr.hxx>
98 #include <svx/PaletteManager.hxx>
99 #include <memory>
101 #include <svx/framelink.hxx>
102 #include <svx/tbxcolorupdate.hxx>
103 #include <editeng/eerdll.hxx>
104 #include <editeng/editrids.hrc>
105 #include <svx/xdef.hxx>
106 #include <svx/xlnclit.hxx>
107 #include <svx/xfillit0.hxx>
108 #include <svx/xflclit.hxx>
109 #include <svl/currencytable.hxx>
110 #include <svtools/langtab.hxx>
111 #include <cppu/unotype.hxx>
112 #include <cppuhelper/supportsservice.hxx>
113 #include <officecfg/Office/Common.hxx>
114 #include <o3tl/typed_flags_set.hxx>
115 #include <bitmaps.hlst>
116 #include <sal/log.hxx>
117 #include <unotools/collatorwrapper.hxx>
118 #include <boost/property_tree/ptree.hpp>
120 #include <comphelper/lok.hxx>
122 #define MAX_MRU_FONTNAME_ENTRIES 5
124 // don't make more than 15 entries visible at once
125 #define MAX_STYLES_ENTRIES 15
127 // namespaces
128 using namespace ::editeng;
129 using namespace ::com::sun::star;
130 using namespace ::com::sun::star::uno;
131 using namespace ::com::sun::star::frame;
132 using namespace ::com::sun::star::beans;
133 using namespace ::com::sun::star::lang;
135 SFX_IMPL_TOOLBOX_CONTROL( SvxStyleToolBoxControl, SfxTemplateItem );
136 SFX_IMPL_TOOLBOX_CONTROL( SvxSimpleUndoRedoController, SfxStringItem );
138 class SvxStyleBox_Impl : public ComboBox
140 using Window::IsVisible;
141 public:
142 SvxStyleBox_Impl( vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily, const Reference< XDispatchProvider >& rDispatchProvider,
143 const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode );
144 virtual ~SvxStyleBox_Impl() override;
145 virtual void dispose() override;
147 void SetFamily( SfxStyleFamily eNewFamily );
148 bool IsVisible() const { return bVisible; }
150 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
151 virtual bool EventNotify( NotifyEvent& rNEvt ) override;
152 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
153 virtual void StateChanged( StateChangedType nStateChange ) override;
155 virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
157 void SetVisibilityListener( const Link<SvxStyleBox_Impl&,void>& aVisListener ) { aVisibilityListener = aVisListener; }
159 void SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
160 virtual boost::property_tree::ptree DumpAsPropertyTree() override;
162 protected:
163 /// Calculate the optimal width of the dropdown. Very expensive operation, triggers lots of font measurement.
164 DECL_LINK(CalcOptimalExtraUserWidth, VclWindowEvent&, void);
166 virtual void Select() override;
168 private:
169 SfxStyleFamily eStyleFamily;
170 sal_Int32 nCurSel;
171 bool bRelease;
172 Size const aLogicalSize;
173 Link<SvxStyleBox_Impl&,void> aVisibilityListener;
174 bool bVisible;
175 Reference< XDispatchProvider > m_xDispatchProvider;
176 Reference< XFrame > m_xFrame;
177 OUString const m_aCommand;
178 OUString const aClearFormatKey;
179 OUString const aMoreKey;
180 OUString sDefaultStyle;
181 bool const bInSpecialMode;
182 VclPtr<MenuButton> m_pButtons[MAX_STYLES_ENTRIES];
183 VclBuilder m_aBuilder;
184 VclPtr<PopupMenu> m_pMenu;
186 void ReleaseFocus();
187 static Color TestColorsVisible(const Color &FontCol, const Color &BackCol);
188 static void UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName);
189 void SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected);
190 static bool AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle const & rTextRect, long nHeight);
191 void SetOptimalSize();
192 DECL_LINK( MenuSelectHdl, Menu *, bool );
193 DECL_STATIC_LINK(SvxStyleBox_Impl, ShowMoreHdl, void*, void);
196 class SvxFontNameBox_Impl : public FontNameBox
198 using Window::Update;
199 private:
200 const FontList* pFontList;
201 ::std::unique_ptr<FontList> m_aOwnFontList;
202 vcl::Font aCurFont;
203 Size const aLogicalSize;
204 OUString aCurText;
205 sal_uInt16 nFtCount;
206 bool bRelease;
207 Reference< XDispatchProvider > m_xDispatchProvider;
208 Reference< XFrame > m_xFrame;
209 bool mbEndPreview;
210 bool mbCheckingUnknownFont;
212 void ReleaseFocus_Impl();
213 void EnableControls_Impl();
215 void EndPreview()
217 Sequence< PropertyValue > aArgs;
218 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
219 ".uno:CharEndPreviewFontName",
220 aArgs );
222 DECL_LINK( CheckAndMarkUnknownFont, VclWindowEvent&, void );
224 void SetOptimalSize();
226 protected:
227 virtual void Select() override;
228 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
230 public:
231 SvxFontNameBox_Impl( vcl::Window* pParent, const Reference< XDispatchProvider >& rDispatchProvider,const Reference< XFrame >& _xFrame
232 , WinBits nStyle
234 virtual ~SvxFontNameBox_Impl() override;
235 virtual void dispose() override;
237 void FillList();
238 void Update( const css::awt::FontDescriptor* pFontDesc );
239 sal_uInt16 GetListCount() const { return nFtCount; }
240 void Clear() { FontNameBox::Clear(); nFtCount = 0; }
241 void Fill( const FontList* pList )
242 { FontNameBox::Fill( pList );
243 nFtCount = pList->GetFontNameCount(); }
244 virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
245 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
246 virtual bool EventNotify( NotifyEvent& rNEvt ) override;
247 virtual Reference< css::accessibility::XAccessible > CreateAccessible() override;
248 void SetOwnFontList(::std::unique_ptr<FontList> && _aOwnFontList) { m_aOwnFontList = std::move(_aOwnFontList); }
249 virtual boost::property_tree::ptree DumpAsPropertyTree() override;
252 // SelectHdl needs the Modifiers, get them in MouseButtonUp
253 class SvxFrmValueSet_Impl : public ValueSet
255 sal_uInt16 nModifier;
256 virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
257 public:
258 SvxFrmValueSet_Impl(vcl::Window* pParent, WinBits nWinStyle)
259 : ValueSet(pParent, nWinStyle), nModifier(0) {}
260 sal_uInt16 GetModifier() const {return nModifier;}
264 void SvxFrmValueSet_Impl::MouseButtonUp( const MouseEvent& rMEvt )
266 nModifier = rMEvt.GetModifier();
267 ValueSet::MouseButtonUp(rMEvt);
270 class SvxFrameWindow_Impl : public svtools::ToolbarPopup
272 private:
273 VclPtr<SvxFrmValueSet_Impl> aFrameSet;
274 svt::ToolboxController& mrController;
275 std::vector<BitmapEx> aImgVec;
276 bool bParagraphMode;
278 void InitImageList();
279 void CalcSizeValueSet();
280 DECL_LINK( SelectHdl, ValueSet*, void );
282 protected:
283 virtual void GetFocus() override;
284 virtual void KeyInput( const KeyEvent& rKEvt ) override;
286 public:
287 SvxFrameWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow );
288 virtual ~SvxFrameWindow_Impl() override;
289 virtual void dispose() override;
291 virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
292 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
295 namespace
297 class LineListBox final : public ListBox
299 public:
300 typedef Color (*ColorFunc)(Color);
301 typedef Color (*ColorDistFunc)(Color, Color);
303 LineListBox( vcl::Window* pParent );
304 virtual ~LineListBox() override;
305 virtual void dispose() override;
307 /** Set the width in Twips */
308 void SetWidth( long nWidth )
310 long nOldWidth = m_nWidth;
311 m_nWidth = nWidth;
312 UpdateEntries( nOldWidth );
315 void SetNone( const OUString& sNone )
317 m_sNone = sNone;
320 using ListBox::InsertEntry;
321 /** Insert a listbox entry with all widths in Twips. */
322 void InsertEntry(const BorderWidthImpl& rWidthImpl,
323 SvxBorderLineStyle nStyle, long nMinWidth = 0,
324 ColorFunc pColor1Fn = &sameColor,
325 ColorFunc pColor2Fn = &sameColor,
326 ColorDistFunc pColorDistFn = &sameDistColor);
328 SvxBorderLineStyle GetEntryStyle( sal_Int32 nPos ) const;
330 SvxBorderLineStyle GetSelectEntryStyle() const;
332 void SetSourceUnit( FieldUnit eNewUnit ) { eSourceUnit = eNewUnit; }
334 const Color& GetColor() const { return aColor; }
336 private:
338 void ImpGetLine(long nLine1, long nLine2, long nDistance,
339 Color nColor1, Color nColor2, Color nColorDist,
340 SvxBorderLineStyle nStyle, BitmapEx& rBmp);
341 using Window::ImplInit;
342 void UpdatePaintLineColor(); // returns sal_True if maPaintCol has changed
343 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
345 void UpdateEntries( long nOldWidth );
346 sal_Int32 GetStylePos( sal_Int32 nListPos, long nWidth );
348 const Color& GetPaintColor() const
350 return maPaintCol;
353 Color GetColorLine1( sal_Int32 nPos );
354 Color GetColorLine2( sal_Int32 nPos );
355 Color GetColorDist( sal_Int32 nPos );
357 LineListBox( const LineListBox& ) = delete;
358 LineListBox& operator =( const LineListBox& ) = delete;
360 std::vector<std::unique_ptr<ImpLineListData>> m_vLineList;
361 long m_nWidth;
362 OUString m_sNone;
363 ScopedVclPtr<VirtualDevice> aVirDev;
364 Size aTxtSize;
365 Color const aColor;
366 Color maPaintCol;
367 FieldUnit eSourceUnit;
370 SvxBorderLineStyle LineListBox::GetSelectEntryStyle() const
372 SvxBorderLineStyle nStyle = SvxBorderLineStyle::SOLID;
373 sal_Int32 nPos = GetSelectedEntryPos();
374 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
376 if (!m_sNone.isEmpty())
377 nPos--;
378 nStyle = GetEntryStyle( nPos );
381 return nStyle;
384 void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
385 Color aColor1, Color aColor2, Color aColorDist,
386 SvxBorderLineStyle nStyle, BitmapEx& rBmp )
388 //TODO, rather than including the " " text to force
389 //the line height, better would be do drop
390 //this calculation and draw a bitmap of height
391 //equal to normal text line and center the
392 //line within that
393 long nMinWidth = GetTextWidth("----------");
394 Size aSize = CalcSubEditSize();
395 aSize.setWidth( std::max(nMinWidth, aSize.Width()) );
396 aSize.AdjustWidth( -(aTxtSize.Width()) );
397 aSize.AdjustWidth( -6 );
398 aSize.setHeight( aTxtSize.Height() );
400 // SourceUnit to Twips
401 if ( eSourceUnit == FieldUnit::POINT )
403 nLine1 /= 5;
404 nLine2 /= 5;
405 nDistance /= 5;
408 // Paint the lines
409 aSize = aVirDev->PixelToLogic( aSize );
410 long nPix = aVirDev->PixelToLogic( Size( 0, 1 ) ).Height();
411 sal_uInt32 n1 = nLine1;
412 sal_uInt32 n2 = nLine2;
413 long nDist = nDistance;
414 n1 += nPix-1;
415 n1 -= n1%nPix;
416 if ( n2 )
418 nDist += nPix-1;
419 nDist -= nDist%nPix;
420 n2 += nPix-1;
421 n2 -= n2%nPix;
423 long nVirHeight = n1+nDist+n2;
424 if ( nVirHeight > aSize.Height() )
425 aSize.setHeight( nVirHeight );
426 // negative width should not be drawn
427 if ( aSize.Width() <= 0 )
428 return;
430 Size aVirSize = aVirDev->LogicToPixel( aSize );
431 if ( aVirDev->GetOutputSizePixel() != aVirSize )
432 aVirDev->SetOutputSizePixel( aVirSize );
433 aVirDev->SetFillColor( aColorDist );
434 aVirDev->DrawRect( tools::Rectangle( Point(), aSize ) );
436 aVirDev->SetFillColor( aColor1 );
438 double y1 = double( n1 ) / 2;
439 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y1 ), basegfx::B2DPoint( aSize.Width( ), y1 ), n1, nStyle );
441 if ( n2 )
443 double y2 = n1 + nDist + double( n2 ) / 2;
444 aVirDev->SetFillColor( aColor2 );
445 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, SvxBorderLineStyle::SOLID );
447 rBmp = aVirDev->GetBitmapEx( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
450 LineListBox::LineListBox( vcl::Window* pParent ) :
451 ListBox( pParent, WB_BORDER ),
452 m_nWidth( 5 ),
453 m_sNone( ),
454 aVirDev( VclPtr<VirtualDevice>::Create() ),
455 aColor( COL_BLACK ),
456 maPaintCol( COL_BLACK )
458 aTxtSize.setWidth( GetTextWidth( " " ) );
459 aTxtSize.setHeight( GetTextHeight() );
460 eSourceUnit = FieldUnit::POINT;
462 aVirDev->SetLineColor();
463 aVirDev->SetMapMode( MapMode( MapUnit::MapTwip ) );
465 UpdatePaintLineColor();
468 LineListBox::~LineListBox()
470 disposeOnce();
473 void LineListBox::dispose()
475 m_vLineList.clear();
476 ListBox::dispose();
479 sal_Int32 LineListBox::GetStylePos( sal_Int32 nListPos, long nWidth )
481 sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
482 if (!m_sNone.isEmpty())
483 nListPos--;
485 sal_Int32 n = 0;
486 size_t i = 0;
487 size_t nCount = m_vLineList.size();
488 while ( nPos == LISTBOX_ENTRY_NOTFOUND && i < nCount )
490 auto& pData = m_vLineList[ i ];
491 if ( pData->GetMinWidth() <= nWidth )
493 if ( nListPos == n )
494 nPos = static_cast<sal_Int32>(i);
495 n++;
497 i++;
500 return nPos;
503 void LineListBox::InsertEntry(
504 const BorderWidthImpl& rWidthImpl, SvxBorderLineStyle nStyle, long nMinWidth,
505 ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
507 m_vLineList.emplace_back(new ImpLineListData(
508 rWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn));
511 SvxBorderLineStyle LineListBox::GetEntryStyle( sal_Int32 nPos ) const
513 ImpLineListData* pData = (0 <= nPos && static_cast<size_t>(nPos) < m_vLineList.size()) ? m_vLineList[ nPos ].get() : nullptr;
514 return pData ? pData->GetStyle() : SvxBorderLineStyle::NONE;
517 void LineListBox::UpdatePaintLineColor()
519 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
520 Color aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
522 bool bRet = aNewCol != maPaintCol;
524 if( bRet )
525 maPaintCol = aNewCol;
528 void LineListBox::UpdateEntries( long nOldWidth )
530 SetUpdateMode( false );
532 UpdatePaintLineColor( );
534 sal_Int32 nSelEntry = GetSelectedEntryPos();
535 sal_Int32 nTypePos = GetStylePos( nSelEntry, nOldWidth );
537 // Remove the old entries
538 while ( GetEntryCount( ) > 0 )
539 ListBox::RemoveEntry( 0 );
541 // Add the new entries based on the defined width
542 if (!m_sNone.isEmpty())
543 ListBox::InsertEntry( m_sNone );
545 sal_uInt16 n = 0;
546 sal_uInt16 nCount = m_vLineList.size( );
547 while ( n < nCount )
549 auto& pData = m_vLineList[ n ];
550 if ( pData->GetMinWidth() <= m_nWidth )
552 BitmapEx aBmp;
553 ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
554 pData->GetLine2ForWidth( m_nWidth ),
555 pData->GetDistForWidth( m_nWidth ),
556 GetColorLine1( GetEntryCount( ) ),
557 GetColorLine2( GetEntryCount( ) ),
558 GetColorDist( GetEntryCount( ) ),
559 pData->GetStyle(), aBmp );
560 ListBox::InsertEntry(" ", Image(aBmp));
561 if ( n == nTypePos )
562 SelectEntryPos( GetEntryCount() - 1 );
564 else if ( n == nTypePos )
565 SetNoSelection();
566 n++;
569 SetUpdateMode( true );
570 Invalidate();
573 Color LineListBox::GetColorLine1( sal_Int32 nPos )
575 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
576 if (nStyle == LISTBOX_ENTRY_NOTFOUND)
577 return GetPaintColor( );
578 auto& pData = m_vLineList[ nStyle ];
579 return pData->GetColorLine1( GetColor( ) );
582 Color LineListBox::GetColorLine2( sal_Int32 nPos )
584 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
585 if (nStyle == LISTBOX_ENTRY_NOTFOUND)
586 return GetPaintColor( );
587 auto& pData = m_vLineList[ nStyle ];
588 return pData->GetColorLine2( GetColor( ) );
591 Color LineListBox::GetColorDist( sal_Int32 nPos )
593 Color rResult = GetSettings().GetStyleSettings().GetFieldColor();
595 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
596 if (nStyle == LISTBOX_ENTRY_NOTFOUND)
597 return rResult;
598 auto& pData = m_vLineList[ nStyle ];
599 return pData->GetColorDist( GetColor( ), rResult );
602 void LineListBox::DataChanged( const DataChangedEvent& rDCEvt )
604 ListBox::DataChanged( rDCEvt );
606 if( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) && ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
607 UpdateEntries( m_nWidth );
611 class SvxLineWindow_Impl : public svtools::ToolbarPopup
613 private:
614 VclPtr<LineListBox> m_aLineStyleLb;
615 svt::ToolboxController& m_rController;
616 bool m_bIsWriter;
618 DECL_LINK( SelectHdl, ListBox&, void );
620 protected:
621 virtual void Resize() override;
622 virtual void GetFocus() override;
623 public:
624 SvxLineWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow );
625 virtual ~SvxLineWindow_Impl() override { disposeOnce(); }
626 virtual void dispose() override { m_aLineStyleLb.disposeAndClear(); ToolbarPopup::dispose(); }
629 class SvxCurrencyList_Impl : public svtools::ToolbarPopup
631 private:
632 VclPtr<ListBox> m_pCurrencyLb;
633 rtl::Reference<SvxCurrencyToolBoxControl> m_xControl;
634 OUString& m_rSelectedFormat;
635 LanguageType& m_eSelectedLanguage;
637 std::vector<OUString> m_aFormatEntries;
638 LanguageType m_eFormatLanguage;
639 DECL_LINK( SelectHdl, ListBox&, void );
641 public:
642 SvxCurrencyList_Impl( SvxCurrencyToolBoxControl* pControl,
643 vcl::Window* pParentWindow,
644 OUString& rSelectFormat,
645 LanguageType& eSelectLanguage );
646 virtual ~SvxCurrencyList_Impl() override { disposeOnce(); }
647 virtual void dispose() override;
650 class SvxStyleToolBoxControl;
652 class SfxStyleControllerItem_Impl : public SfxStatusListener
654 public:
655 SfxStyleControllerItem_Impl( const Reference< XDispatchProvider >& rDispatchProvider,
656 sal_uInt16 nSlotId,
657 const OUString& rCommand,
658 SvxStyleToolBoxControl& rTbxCtl );
660 protected:
661 virtual void StateChanged( SfxItemState eState, const SfxPoolItem* pState ) override;
663 private:
664 SvxStyleToolBoxControl& rControl;
667 #define BUTTON_WIDTH 20
668 #define BUTTON_PADDING 10
669 #define ITEM_HEIGHT 30
671 SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
672 const OUString& rCommand,
673 SfxStyleFamily eFamily,
674 const Reference< XDispatchProvider >& rDispatchProvider,
675 const Reference< XFrame >& _xFrame,
676 const OUString& rClearFormatKey,
677 const OUString& rMoreKey,
678 bool bInSpec)
679 : ComboBox(pParent, WB_SORT | WB_BORDER | WB_HIDE | WB_DROPDOWN | WB_AUTOHSCROLL)
680 , eStyleFamily( eFamily )
681 , nCurSel(0)
682 , bRelease( true )
683 , aLogicalSize(60, 86)
684 , bVisible(false)
685 , m_xDispatchProvider( rDispatchProvider )
686 , m_xFrame(_xFrame)
687 , m_aCommand( rCommand )
688 , aClearFormatKey( rClearFormatKey )
689 , aMoreKey( rMoreKey )
690 , bInSpecialMode( bInSpec )
691 , m_aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/stylemenu.ui", "")
692 , m_pMenu(m_aBuilder.get_menu("menu"))
694 SetHelpId(HID_STYLE_LISTBOX);
695 m_pMenu->SetSelectHdl( LINK( this, SvxStyleBox_Impl, MenuSelectHdl ) );
696 for(VclPtr<MenuButton> & rpButton : m_pButtons)
697 rpButton = nullptr;
698 SetOptimalSize();
699 EnableAutocomplete( true );
700 EnableUserDraw( true );
701 AddEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));
702 SetUserItemSize( Size( 0, ITEM_HEIGHT ) );
703 set_id("applystyle");
706 SvxStyleBox_Impl::~SvxStyleBox_Impl()
708 disposeOnce();
711 void SvxStyleBox_Impl::dispose()
713 RemoveEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));
715 for (VclPtr<MenuButton>& rButton : m_pButtons)
717 rButton.disposeAndClear();
720 m_pMenu.clear();
721 m_aBuilder.disposeBuilder();
723 ComboBox::dispose();
726 void SvxStyleBox_Impl::ReleaseFocus()
728 if ( !bRelease )
730 bRelease = true;
731 return;
733 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
734 m_xFrame->getContainerWindow()->setFocus();
737 IMPL_LINK( SvxStyleBox_Impl, MenuSelectHdl, Menu*, pMenu, bool)
739 OUString sEntry = GetSelectedEntry();
740 OString sMenuIdent = pMenu->GetCurItemIdent();
741 ReleaseFocus(); // It must be after getting entry pos!
742 if (IsInDropDown())
743 ToggleDropDown();
744 Sequence< PropertyValue > aArgs( 2 );
745 aArgs[0].Name = "Param";
746 aArgs[0].Value <<= sEntry;
747 aArgs[1].Name = "Family";
748 aArgs[1].Value <<= sal_Int16( eStyleFamily );
750 if (sMenuIdent == "update")
752 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
753 ".uno:StyleUpdateByExample", aArgs );
755 else if (sMenuIdent == "edit")
757 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
758 ".uno:EditStyle", aArgs );
761 return false;
764 IMPL_STATIC_LINK_NOARG(SvxStyleBox_Impl, ShowMoreHdl, void*, void)
766 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
767 DBG_ASSERT( pViewFrm, "SvxStyleBox_Impl::Select(): no viewframe" );
768 if (!pViewFrm)
769 return;
770 pViewFrm->ShowChildWindow(SID_SIDEBAR);
771 ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel", pViewFrm->GetFrame().GetFrameInterface(), true);
774 void SvxStyleBox_Impl::Select()
776 // Tell base class about selection so that AT get informed about it.
777 ComboBox::Select();
779 if ( IsTravelSelect() )
780 return;
782 OUString aSearchEntry( GetText() );
783 bool bDoIt = true, bClear = false;
784 if( bInSpecialMode )
786 if( aSearchEntry == aClearFormatKey && GetSelectedEntryPos() == 0 )
788 aSearchEntry = sDefaultStyle;
789 bClear = true;
790 //not only apply default style but also call 'ClearFormatting'
791 Sequence< PropertyValue > aEmptyVals;
792 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:ResetAttributes",
793 aEmptyVals);
795 else if( aSearchEntry == aMoreKey && GetSelectedEntryPos() == ( GetEntryCount() - 1 ) )
797 Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Impl, ShowMoreHdl));
798 //tdf#113214 change text back to previous entry
799 SetText(GetSavedValue());
800 bDoIt = false;
804 //Do we need to create a new style?
805 SfxObjectShell *pShell = SfxObjectShell::Current();
806 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
807 SfxStyleSheetBase* pStyle = nullptr;
809 bool bCreateNew = false;
811 if ( pPool )
813 pPool->SetSearchMask( eStyleFamily );
815 pStyle = pPool->First();
816 while ( pStyle && pStyle->GetName() != aSearchEntry )
817 pStyle = pPool->Next();
820 if ( !pStyle )
822 // cannot find the style for whatever reason
823 // therefore create a new style
824 bCreateNew = true;
827 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
828 This instance may be deleted in the meantime (i.e. when a dialog is opened
829 while in Dispatch()), accessing members will crash in this case. */
830 ReleaseFocus();
832 if( bDoIt )
834 if ( bClear )
835 SetText( aSearchEntry );
836 SaveValue();
838 Sequence< PropertyValue > aArgs( 2 );
839 aArgs[0].Value <<= aSearchEntry;
840 aArgs[1].Name = "Family";
841 aArgs[1].Value <<= sal_Int16( eStyleFamily );
842 if( bCreateNew )
844 aArgs[0].Name = "Param";
845 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:StyleNewByExample", aArgs);
847 else
849 aArgs[0].Name = "Template";
850 SfxToolBoxControl::Dispatch( m_xDispatchProvider, m_aCommand, aArgs );
855 void SvxStyleBox_Impl::SetFamily( SfxStyleFamily eNewFamily )
857 eStyleFamily = eNewFamily;
860 bool SvxStyleBox_Impl::PreNotify( NotifyEvent& rNEvt )
862 MouseNotifyEvent nType = rNEvt.GetType();
864 if ( MouseNotifyEvent::MOUSEBUTTONDOWN == nType || MouseNotifyEvent::GETFOCUS == nType )
865 nCurSel = GetSelectedEntryPos();
866 else if ( MouseNotifyEvent::LOSEFOCUS == nType )
868 // don't handle before our Select() is called
869 if (!HasFocus() && !HasChildPathFocus() && !IsChild(rNEvt.GetWindow()))
870 SetText( GetSavedValue() );
872 return ComboBox::PreNotify( rNEvt );
875 bool SvxStyleBox_Impl::EventNotify( NotifyEvent& rNEvt )
877 bool bHandled = false;
879 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
881 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
883 switch ( nCode )
885 case KEY_CONTEXTMENU:
887 if(IsInDropDown())
889 const sal_Int32 nItem = GetSelectedEntryPos() - 1;
890 if(nItem < MAX_STYLES_ENTRIES)
891 m_pButtons[nItem]->ExecuteMenu();
892 bHandled = true;
894 break;
896 case KEY_RETURN:
897 case KEY_TAB:
899 if ( KEY_TAB == nCode )
900 bRelease = false;
901 else
902 bHandled = true;
903 Select();
904 break;
907 case KEY_ESCAPE:
908 SelectEntryPos( nCurSel );
909 if ( typeid( *GetParent() ) != typeid( sfx2::sidebar::SidebarToolBox ) )
910 ReleaseFocus();
911 bHandled = true;
912 break;
915 return bHandled || ComboBox::EventNotify( rNEvt );
918 void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
920 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
921 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
923 SetOptimalSize();
926 ComboBox::DataChanged( rDCEvt );
929 void SvxStyleBox_Impl::StateChanged( StateChangedType nStateChange )
931 ComboBox::StateChanged( nStateChange );
933 if ( nStateChange == StateChangedType::Visible )
935 bVisible = IsReallyVisible();
936 aVisibilityListener.Call( *this );
938 else if ( nStateChange == StateChangedType::InitShow )
940 bVisible = true;
941 aVisibilityListener.Call( *this );
945 bool SvxStyleBox_Impl::AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle const & rTextRect, long nHeight)
947 if (rTextRect.Bottom() > nHeight)
949 // the text does not fit, adjust the font size
950 double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
951 vcl::Font aFont(pDevice->GetFont());
952 Size aPixelSize(aFont.GetFontSize());
953 aPixelSize.setWidth( aPixelSize.Width() * ratio );
954 aPixelSize.setHeight( aPixelSize.Height() * ratio );
955 aFont.SetFontSize(aPixelSize);
956 pDevice->SetFont(aFont);
957 return true;
959 return false;
962 void SvxStyleBox_Impl::SetOptimalSize()
964 Size aSize(LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont)));
965 set_width_request(aSize.Width());
966 set_height_request(aSize.Height());
967 SetSizePixel(aSize);
970 void SvxStyleBox_Impl::UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName)
972 vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();
974 // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
975 // nBorder, and we are adding 1 in order to look better when
976 // italics is present
977 const int nLeftDistance = 8;
979 tools::Rectangle aTextRect;
980 pDevice->GetTextBoundRect(aTextRect, rStyleName);
982 Point aPos( rUDEvt.GetRect().TopLeft() );
983 aPos.AdjustX(nLeftDistance );
985 if (!AdjustFontForItemHeight(pDevice, aTextRect, rUDEvt.GetRect().GetHeight()))
986 aPos.AdjustY(( rUDEvt.GetRect().GetHeight() - aTextRect.Bottom() ) / 2 );
988 pDevice->DrawText(aPos, rStyleName);
991 void SvxStyleBox_Impl::SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected)
993 unsigned int nId = rRect.GetHeight() != 0 ? (rRect.getY() / rRect.GetHeight()) : MAX_STYLES_ENTRIES;
994 if (nItem == 0 || nItem == GetEntryCount() - 1)
996 if(nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
997 m_pButtons[nId]->Hide();
999 else
1001 SfxObjectShell *pShell = SfxObjectShell::Current();
1002 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
1003 SfxStyleSheetBase* pStyle = nullptr;
1005 if ( pPool )
1007 pPool->SetSearchMask( eStyleFamily );
1009 pStyle = pPool->First();
1010 while (pStyle && pStyle->GetName() != rStyleName)
1011 pStyle = pPool->Next();
1014 if (pStyle )
1016 std::unique_ptr<const SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
1017 if (!pItemSet) return;
1019 const SvxFontItem * const pFontItem =
1020 pItemSet->GetItem<SvxFontItem>(SID_ATTR_CHAR_FONT);
1021 const SvxFontHeightItem * const pFontHeightItem =
1022 pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
1024 if ( pFontItem && pFontHeightItem )
1026 Size aFontSize( 0, pFontHeightItem->GetHeight() );
1027 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
1029 // setup the font properties
1030 SvxFont aFont;
1031 aFont.SetFamilyName(pFontItem->GetFamilyName());
1032 aFont.SetStyleName(pFontItem->GetStyleName());
1033 aFont.SetFontSize(aPixelSize);
1035 const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_WEIGHT );
1036 if ( pItem )
1037 aFont.SetWeight( static_cast< const SvxWeightItem* >( pItem )->GetWeight() );
1039 pItem = pItemSet->GetItem( SID_ATTR_CHAR_POSTURE );
1040 if ( pItem )
1041 aFont.SetItalic( static_cast< const SvxPostureItem* >( pItem )->GetPosture() );
1043 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
1044 if ( pItem )
1045 aFont.SetOutline( static_cast< const SvxContourItem* >( pItem )->GetValue() );
1047 pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED );
1048 if ( pItem )
1049 aFont.SetShadow( static_cast< const SvxShadowedItem* >( pItem )->GetValue() );
1051 pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF );
1052 if ( pItem )
1053 aFont.SetRelief( static_cast< const SvxCharReliefItem* >( pItem )->GetValue() );
1055 pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE );
1056 if ( pItem )
1057 aFont.SetUnderline( static_cast< const SvxUnderlineItem* >( pItem )->GetLineStyle() );
1059 pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE );
1060 if ( pItem )
1061 aFont.SetOverline( static_cast< const SvxOverlineItem* >( pItem )->GetValue() );
1063 pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT );
1064 if ( pItem )
1065 aFont.SetStrikeout( static_cast< const SvxCrossedOutItem* >( pItem )->GetStrikeout() );
1067 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP );
1068 if ( pItem )
1069 aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
1071 pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK );
1072 if ( pItem )
1073 aFont.SetEmphasisMark( static_cast< const SvxEmphasisMarkItem* >( pItem )->GetEmphasisMark() );
1075 // setup the device & draw
1076 vcl::Font aOldFont(rRenderContext.GetFont());
1078 Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
1080 rRenderContext.SetFont(aFont);
1082 pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR );
1083 // text color, when nothing is selected
1084 if ( (nullptr != pItem) && bIsNotSelected)
1085 aFontCol = static_cast< const SvxColorItem* >( pItem )->GetValue();
1087 drawing::FillStyle style = drawing::FillStyle_NONE;
1088 // which kind of Fill style is selected
1089 pItem = pItemSet->GetItem( XATTR_FILLSTYLE );
1090 // only when ok and not selected
1091 if ( (nullptr != pItem) && bIsNotSelected)
1092 style = static_cast< const XFillStyleItem* >( pItem )->GetValue();
1094 switch(style)
1096 case drawing::FillStyle_SOLID:
1098 // set background color
1099 pItem = pItemSet->GetItem( XATTR_FILLCOLOR );
1100 if ( nullptr != pItem )
1101 aBackCol = static_cast< const XFillColorItem* >( pItem )->GetColorValue();
1103 if ( aBackCol != COL_AUTO )
1105 rRenderContext.SetFillColor(aBackCol);
1106 rRenderContext.DrawRect(rRect);
1109 break;
1111 default: break;
1112 //TODO Draw the other background styles: gradient, hatching and bitmap
1115 // when the font and background color are too similar, adjust the Font-Color
1116 if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
1117 aFontCol = TestColorsVisible(aFontCol, (aBackCol != COL_AUTO) ? aBackCol : rRenderContext.GetBackground().GetColor());
1119 // set text color
1120 if ( aFontCol != COL_AUTO )
1121 rRenderContext.SetTextColor(aFontCol);
1123 // handle the push-button
1124 if (bIsNotSelected)
1126 if (nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
1127 m_pButtons[nId]->Hide();
1129 else
1131 if (nId < MAX_STYLES_ENTRIES)
1133 if (!m_pButtons[nId] && pParent)
1135 m_pButtons[nId] = VclPtr<MenuButton>::Create(pParent, WB_FLATBUTTON | WB_NOPOINTERFOCUS);
1136 m_pButtons[nId]->SetSizePixel(Size(BUTTON_WIDTH, rRect.GetHeight()));
1137 m_pButtons[nId]->SetPopupMenu(m_pMenu);
1139 m_pButtons[nId]->SetPosPixel(Point(rRect.GetWidth() - BUTTON_WIDTH, rRect.getY()));
1140 m_pButtons[nId]->Show();
1148 void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
1150 sal_uInt16 nItem = rUDEvt.GetItemId();
1151 OUString aStyleName( GetEntry( nItem ) );
1153 vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();
1154 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
1156 const tools::Rectangle& rRect(rUDEvt.GetRect());
1157 bool bIsNotSelected = rUDEvt.GetItemId() != GetSelectedEntryPos();
1159 SetupEntry(*pDevice, rUDEvt.GetWindow(), nItem, rRect, aStyleName, bIsNotSelected);
1161 UserDrawEntry(rUDEvt, aStyleName);
1163 pDevice->Pop();
1164 // draw separator, if present
1165 DrawEntry( rUDEvt, false, false );
1168 IMPL_LINK(SvxStyleBox_Impl, CalcOptimalExtraUserWidth, VclWindowEvent&, event, void)
1170 // perform the calculation only when we are opening the dropdown
1171 if (event.GetId() != VclEventId::DropdownPreOpen)
1172 return;
1174 long nMaxNormalFontWidth = 0;
1175 sal_Int32 nEntryCount = GetEntryCount();
1176 for (sal_Int32 i = 0; i < nEntryCount; ++i)
1178 OUString sStyleName(GetEntry(i));
1179 tools::Rectangle aTextRectForDefaultFont;
1180 GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
1182 const long nWidth = aTextRectForDefaultFont.GetWidth();
1184 nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
1187 long nMaxUserDrawFontWidth = nMaxNormalFontWidth;
1188 for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
1190 OUString sStyleName(GetEntry(i));
1192 Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
1193 SetupEntry(*this /*FIXME rendercontext*/, this, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
1194 tools::Rectangle aTextRectForActualFont;
1195 GetTextBoundRect(aTextRectForActualFont, sStyleName);
1196 if (AdjustFontForItemHeight(this, aTextRectForActualFont, ITEM_HEIGHT))
1198 //Font didn't fit, so it was changed, refetch with final font size
1199 GetTextBoundRect(aTextRectForActualFont, sStyleName);
1201 Pop();
1203 const long nWidth = aTextRectForActualFont.GetWidth() + BUTTON_WIDTH + BUTTON_PADDING;
1205 nMaxUserDrawFontWidth = std::max(nWidth, nMaxUserDrawFontWidth);
1208 SetUserItemSize(Size(nMaxUserDrawFontWidth - nMaxNormalFontWidth, ITEM_HEIGHT));
1211 // test is the color between Font- and background-color to be identify
1212 // return is always the Font-Color
1213 // when both light or dark, change the Contrast
1214 // in other case do not change the origin color
1215 // when the color is R=G=B=128 the DecreaseContrast make 128 the need an exception
1216 Color SvxStyleBox_Impl::TestColorsVisible(const Color &FontCol, const Color &BackCol)
1218 const sal_uInt8 ChgVal = 60; // increase/decrease the Contrast
1220 Color retCol = FontCol;
1221 if ((FontCol.IsDark() == BackCol.IsDark()) && (FontCol.IsBright() == BackCol.IsBright()))
1223 sal_uInt8 lumi = retCol.GetLuminance();
1225 if((lumi > 120) && (lumi < 140))
1226 retCol.DecreaseLuminance(ChgVal / 2);
1227 else
1228 retCol.DecreaseContrast(ChgVal);
1231 return retCol;
1234 boost::property_tree::ptree SvxStyleBox_Impl::DumpAsPropertyTree()
1236 boost::property_tree::ptree aTree(ComboBox::DumpAsPropertyTree());
1238 boost::property_tree::ptree aEntries;
1240 for (int i = 0; i < GetEntryCount(); ++i)
1242 boost::property_tree::ptree aEntry;
1243 aEntry.put("", GetEntry(i));
1244 aEntries.push_back(std::make_pair("", aEntry));
1247 aTree.add_child("entries", aEntries);
1249 boost::property_tree::ptree aSelected;
1251 for (int i = 0; i < GetSelectedEntryCount(); ++i)
1253 boost::property_tree::ptree aEntry;
1254 aEntry.put("", GetSelectedEntryPos(i));
1255 aSelected.push_back(std::make_pair("", aEntry));
1258 aTree.put("selectedCount", GetSelectedEntryCount());
1259 aTree.add_child("selectedEntries", aSelected);
1260 aTree.put("command", ".uno:StyleApply");
1262 return aTree;
1266 static bool lcl_GetDocFontList( const FontList** ppFontList, SvxFontNameBox_Impl* pBox )
1268 bool bChanged = false;
1269 const SfxObjectShell* pDocSh = SfxObjectShell::Current();
1270 const SvxFontListItem* pFontListItem = nullptr;
1272 if ( pDocSh )
1273 pFontListItem =
1274 static_cast<const SvxFontListItem*>(pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
1275 else
1277 ::std::unique_ptr<FontList> aFontList(new FontList( pBox->GetParent() ));
1278 *ppFontList = aFontList.get();
1279 pBox->SetOwnFontList(std::move(aFontList));
1280 bChanged = true;
1283 if ( pFontListItem )
1285 const FontList* pNewFontList = pFontListItem->GetFontList();
1286 DBG_ASSERT( pNewFontList, "Doc-FontList not available!" );
1288 // No old list, but a new list
1289 if ( !*ppFontList && pNewFontList )
1291 // => take over
1292 *ppFontList = pNewFontList;
1293 bChanged = true;
1295 else
1297 // Comparing the font lists is not perfect.
1298 // When you change the font list in the Doc, you can track
1299 // changes here only on the Listbox, because ppFontList
1300 // has already been updated.
1301 bChanged =
1302 ( ( *ppFontList != pNewFontList ) ||
1303 pBox->GetListCount() != pNewFontList->GetFontNameCount() );
1304 // HACK: Comparing is incomplete
1306 if ( bChanged )
1307 *ppFontList = pNewFontList;
1310 if ( pBox )
1311 pBox->Enable();
1313 else if ( pBox && ( pDocSh || !ppFontList ))
1315 // Disable box only when we have a SfxObjectShell and didn't get a font list OR
1316 // we don't have a SfxObjectShell and no current font list.
1317 // It's possible that we currently have no SfxObjectShell, but a current font list.
1318 // See #i58471: When a user set the focus into the font name combo box and opens
1319 // the help window with F1. After closing the help window, we disable the font name
1320 // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
1321 // font list hasn't changed and therefore the combo box shouldn't be disabled!
1322 pBox->Disable();
1325 // Fill the FontBox, also the new list if necessary
1326 if ( pBox && bChanged )
1328 if ( *ppFontList )
1329 pBox->Fill( *ppFontList );
1330 else
1331 pBox->Clear();
1333 return bChanged;
1336 SvxFontNameBox_Impl::SvxFontNameBox_Impl( vcl::Window* pParent, const Reference< XDispatchProvider >& rDispatchProvider,const Reference< XFrame >& _xFrame, WinBits nStyle ) :
1338 FontNameBox ( pParent, nStyle | WinBits( WB_DROPDOWN | WB_AUTOHSCROLL ) ),
1339 pFontList ( nullptr ),
1340 aLogicalSize ( 60,160 ),
1341 nFtCount ( 0 ),
1342 bRelease ( true ),
1343 m_xDispatchProvider( rDispatchProvider ),
1344 m_xFrame (_xFrame),
1345 mbEndPreview(false),
1346 mbCheckingUnknownFont(false)
1348 SetOptimalSize();
1349 EnableControls_Impl();
1350 GetSubEdit()->AddEventListener( LINK( this, SvxFontNameBox_Impl, CheckAndMarkUnknownFont ));
1351 set_id("fontnamecombobox");
1354 SvxFontNameBox_Impl::~SvxFontNameBox_Impl()
1356 disposeOnce();
1359 void SvxFontNameBox_Impl::dispose()
1361 GetSubEdit()->RemoveEventListener( LINK( this, SvxFontNameBox_Impl, CheckAndMarkUnknownFont ));
1362 FontNameBox::dispose();
1365 void SvxFontNameBox_Impl::FillList()
1367 // Save old Selection, set back in the end
1368 Selection aOldSel = GetSelection();
1369 // Did Doc-Fontlist change?
1370 lcl_GetDocFontList( &pFontList, this );
1371 aCurText = GetText();
1372 SetSelection( aOldSel );
1375 IMPL_LINK( SvxFontNameBox_Impl, CheckAndMarkUnknownFont, VclWindowEvent&, event, void )
1377 if( event.GetId() != VclEventId::EditModify )
1378 return;
1379 if (mbCheckingUnknownFont) //tdf#117537 block rentry
1380 return;
1381 mbCheckingUnknownFont = true;
1382 OUString fontname = GetSubEdit()->GetText();
1383 lcl_GetDocFontList( &pFontList, this );
1384 // If the font is unknown, show it in italic.
1385 vcl::Font font = GetControlFont();
1386 if( pFontList != nullptr && pFontList->IsAvailable( fontname ))
1388 if( font.GetItalic() != ITALIC_NONE )
1390 font.SetItalic( ITALIC_NONE );
1391 SetControlFont( font );
1392 SetQuickHelpText( SvxResId( RID_SVXSTR_CHARFONTNAME ));
1395 else
1397 if( font.GetItalic() != ITALIC_NORMAL )
1399 font.SetItalic( ITALIC_NORMAL );
1400 SetControlFont( font );
1401 SetQuickHelpText( SvxResId( RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE ));
1404 mbCheckingUnknownFont = false;
1407 void SvxFontNameBox_Impl::Update( const css::awt::FontDescriptor* pFontDesc )
1409 if ( pFontDesc )
1411 aCurFont.SetFamilyName ( pFontDesc->Name );
1412 aCurFont.SetFamily ( FontFamily( pFontDesc->Family ) );
1413 aCurFont.SetStyleName ( pFontDesc->StyleName );
1414 aCurFont.SetPitch ( FontPitch( pFontDesc->Pitch ) );
1415 aCurFont.SetCharSet ( rtl_TextEncoding( pFontDesc->CharSet ) );
1417 OUString aCurName = aCurFont.GetFamilyName();
1418 if ( GetText() != aCurName )
1419 SetText( aCurName );
1422 bool SvxFontNameBox_Impl::PreNotify( NotifyEvent& rNEvt )
1424 MouseNotifyEvent nType = rNEvt.GetType();
1426 if ( MouseNotifyEvent::MOUSEBUTTONDOWN == nType || MouseNotifyEvent::GETFOCUS == nType )
1428 EnableControls_Impl();
1429 FillList();
1431 return FontNameBox::PreNotify( rNEvt );
1434 bool SvxFontNameBox_Impl::EventNotify( NotifyEvent& rNEvt )
1436 bool bHandled = false;
1437 mbEndPreview = false;
1438 if ( rNEvt.GetType() == MouseNotifyEvent::KEYUP )
1439 mbEndPreview = true;
1441 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
1443 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1445 switch ( nCode )
1447 case KEY_RETURN:
1448 case KEY_TAB:
1450 if ( KEY_TAB == nCode )
1451 bRelease = false;
1452 else
1453 bHandled = true;
1454 Select();
1455 break;
1458 case KEY_ESCAPE:
1459 SetText( aCurText );
1460 if ( typeid( *GetParent() ) != typeid( sfx2::sidebar::SidebarToolBox ) )
1461 ReleaseFocus_Impl();
1462 EndPreview();
1463 break;
1466 else if ( MouseNotifyEvent::LOSEFOCUS == rNEvt.GetType() )
1468 vcl::Window* pFocusWin = Application::GetFocusWindow();
1469 if ( !HasFocus() && GetSubEdit() != pFocusWin )
1470 SetText( GetSavedValue() );
1471 // send EndPreview
1472 EndPreview();
1475 return bHandled || FontNameBox::EventNotify( rNEvt );
1478 void SvxFontNameBox_Impl::SetOptimalSize()
1480 Size aSize(LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont)));
1481 set_width_request(aSize.Width());
1482 set_height_request(aSize.Height());
1483 SetSizePixel(aSize);
1486 void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1488 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1489 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1491 SetOptimalSize();
1493 else if ( ( rDCEvt.GetType() == DataChangedEventType::FONTS ) ||
1494 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) )
1496 // The old font list in shell has likely been destroyed at this point, so we need to get
1497 // the new one before doing anything further.
1498 lcl_GetDocFontList( &pFontList, this );
1501 FontNameBox::DataChanged( rDCEvt );
1504 void SvxFontNameBox_Impl::ReleaseFocus_Impl()
1506 if ( !bRelease )
1508 bRelease = true;
1509 return;
1511 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
1512 m_xFrame->getContainerWindow()->setFocus();
1515 void SvxFontNameBox_Impl::EnableControls_Impl()
1517 SvtFontOptions aFontOpt;
1518 bool bEnable = aFontOpt.IsFontHistoryEnabled();
1519 sal_uInt16 nEntries = bEnable ? MAX_MRU_FONTNAME_ENTRIES : 0;
1520 if ( GetMaxMRUCount() != nEntries )
1522 // refill in the next GetFocus-Handler
1523 pFontList = nullptr;
1524 Clear();
1525 SetMaxMRUCount( nEntries );
1528 bEnable = aFontOpt.IsFontWYSIWYGEnabled();
1529 EnableWYSIWYG( bEnable );
1532 void SvxFontNameBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
1534 FontNameBox::UserDraw( rUDEvt );
1536 // Hack - GetStyle now contains the currently
1537 // selected item in the list box
1538 // ItemId contains the id of the current item to draw
1539 // or select
1540 if ( rUDEvt.GetItemId() == rUDEvt.GetStyle() )
1542 OUString fontName(GetText());
1543 if (IsInDropDown())
1546 * when in dropdown mode the selected item should be
1547 * used and not the current selection
1549 fontName = GetEntry(rUDEvt.GetItemId());
1551 Sequence< PropertyValue > aArgs( 1 );
1552 FontMetric aFontMetric( pFontList->Get( fontName,
1553 aCurFont.GetWeight(),
1554 aCurFont.GetItalic() ) );
1556 SvxFontItem aFontItem( aFontMetric.GetFamilyType(),
1557 aFontMetric.GetFamilyName(),
1558 aFontMetric.GetStyleName(),
1559 aFontMetric.GetPitch(),
1560 aFontMetric.GetCharSet(),
1561 SID_ATTR_CHAR_FONT );
1562 aFontItem.QueryValue( aArgs[0].Value );
1563 aArgs[0].Name = "CharPreviewFontName";
1564 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1565 ".uno:CharPreviewFontName",
1566 aArgs );
1570 void SvxFontNameBox_Impl::Select()
1572 FontNameBox::Select();
1574 Sequence< PropertyValue > aArgs( 1 );
1575 std::unique_ptr<SvxFontItem> pFontItem;
1576 if ( pFontList )
1578 FontMetric aFontMetric( pFontList->Get( GetText(),
1579 aCurFont.GetWeight(),
1580 aCurFont.GetItalic() ) );
1581 aCurFont = aFontMetric;
1583 pFontItem.reset( new SvxFontItem( aFontMetric.GetFamilyType(),
1584 aFontMetric.GetFamilyName(),
1585 aFontMetric.GetStyleName(),
1586 aFontMetric.GetPitch(),
1587 aFontMetric.GetCharSet(),
1588 SID_ATTR_CHAR_FONT ) );
1590 Any a;
1591 pFontItem->QueryValue( a );
1592 aArgs[0].Value = a;
1594 if ( !IsTravelSelect() )
1596 // #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1597 // This instance may be deleted in the meantime (i.e. when a dialog is opened
1598 // while in Dispatch()), accessing members will crash in this case.
1599 ReleaseFocus_Impl();
1600 EndPreview();
1601 if (pFontItem)
1603 aArgs[0].Name = "CharFontName";
1604 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1605 ".uno:CharFontName",
1606 aArgs );
1609 else
1611 if ( mbEndPreview )
1613 EndPreview();
1614 return;
1616 if (pFontItem)
1618 aArgs[0].Name = "CharPreviewFontName";
1619 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1620 ".uno:CharPreviewFontName",
1621 aArgs );
1626 boost::property_tree::ptree SvxFontNameBox_Impl::DumpAsPropertyTree()
1628 boost::property_tree::ptree aTree(FontNameBox::DumpAsPropertyTree());
1630 boost::property_tree::ptree aEntries;
1632 for (int i = 0; i < GetEntryCount(); ++i)
1634 boost::property_tree::ptree aEntry;
1635 aEntry.put("", GetEntry(i));
1636 aEntries.push_back(std::make_pair("", aEntry));
1639 aTree.add_child("entries", aEntries);
1641 boost::property_tree::ptree aSelected;
1643 for (int i = 0; i < GetSelectedEntryCount(); ++i)
1645 boost::property_tree::ptree aEntry;
1646 aEntry.put("", GetSelectedEntryPos(i));
1647 aSelected.push_back(std::make_pair("", aEntry));
1650 aTree.put("selectedCount", GetSelectedEntryCount());
1651 aTree.add_child("selectedEntries", aSelected);
1652 aTree.put("command", ".uno:CharFontName");
1654 return aTree;
1657 SvxColorWindow::SvxColorWindow(const OUString& rCommand,
1658 std::shared_ptr<PaletteManager> const & rPaletteManager,
1659 ColorStatus& rColorStatus,
1660 sal_uInt16 nSlotId,
1661 const Reference< XFrame >& rFrame,
1662 vcl::Window* pParentWindow,
1663 bool bReuseParentForPicker,
1664 ColorSelectFunction const & aFunction):
1666 ToolbarPopup( rFrame, pParentWindow, "palette_popup_window", "svx/ui/oldcolorwindow.ui" ),
1667 theSlotId( nSlotId ),
1668 maCommand( rCommand ),
1669 mxParentWindow(pParentWindow),
1670 mxPaletteManager( rPaletteManager ),
1671 mrColorStatus( rColorStatus ),
1672 maColorSelectFunction(aFunction),
1673 mbReuseParentForPicker(bReuseParentForPicker)
1675 get(mpPaletteListBox, "palette_listbox");
1676 get(mpButtonAutoColor, "auto_color_button");
1677 get(mpButtonNoneColor, "none_color_button");
1678 get(mpButtonPicker, "color_picker_button");
1679 get(mpColorSet, "colorset");
1680 get(mpRecentColorSet, "recent_colorset");
1681 get(mpAutomaticSeparator, "separator4");
1683 mpColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1684 mpRecentColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1686 switch ( theSlotId )
1688 case SID_ATTR_CHAR_COLOR_BACKGROUND:
1689 case SID_BACKGROUND_COLOR:
1690 case SID_ATTR_CHAR_BACK_COLOR:
1691 case SID_TABLE_CELL_BACKGROUND_COLOR:
1693 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_NOFILL ) );
1694 break;
1696 case SID_AUTHOR_COLOR:
1698 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_BY_AUTHOR ) );
1699 break;
1701 case SID_BMPMASK_COLOR:
1703 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_TRANSPARENT ) );
1704 break;
1706 case SID_ATTR_CHAR_COLOR:
1707 case SID_ATTR_CHAR_COLOR2:
1708 case SID_EXTRUSION_3D_COLOR:
1710 mpButtonAutoColor->SetText(EditResId(RID_SVXSTR_AUTOMATIC));
1711 break;
1713 case SID_FM_CTL_PROPERTIES:
1715 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_DEFAULT ) );
1716 break;
1718 default:
1720 mpButtonAutoColor->Hide();
1721 mpAutomaticSeparator->Hide();
1722 break;
1726 mpColorSet->SetAccessibleName( GetText() );
1728 mpPaletteListBox->SetStyle( mpPaletteListBox->GetStyle() | WB_BORDER );
1729 mpPaletteListBox->SetSelectHdl( LINK( this, SvxColorWindow, SelectPaletteHdl ) );
1730 mpPaletteListBox->AdaptDropDownLineCountToMaximum();
1731 std::vector<OUString> aPaletteList = mxPaletteManager->GetPaletteList();
1732 for (const auto& rPalette : aPaletteList )
1734 mpPaletteListBox->InsertEntry( rPalette );
1736 OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
1737 mpPaletteListBox->SelectEntry( aPaletteName );
1738 const sal_Int32 nSelectedEntry(mpPaletteListBox->GetSelectedEntryPos());
1739 if (nSelectedEntry != LISTBOX_ENTRY_NOTFOUND)
1740 mxPaletteManager->SetPalette(nSelectedEntry);
1742 mpButtonAutoColor->SetClickHdl( LINK( this, SvxColorWindow, AutoColorClickHdl ) );
1743 mpButtonNoneColor->SetClickHdl( LINK( this, SvxColorWindow, AutoColorClickHdl ) );
1744 mpButtonPicker->SetClickHdl( LINK( this, SvxColorWindow, OpenPickerClickHdl ) );
1746 mpColorSet->SetSelectHdl( LINK( this, SvxColorWindow, SelectHdl ) );
1747 mpRecentColorSet->SetSelectHdl( LINK( this, SvxColorWindow, SelectHdl ) );
1748 SetHelpId( HID_POPUP_COLOR );
1749 mpColorSet->SetHelpId( HID_POPUP_COLOR_CTRL );
1751 mxPaletteManager->ReloadColorSet(*mpColorSet);
1752 const sal_uInt32 nMaxItems(SvxColorValueSet::getMaxRowCount() * SvxColorValueSet::getColumnCount());
1753 Size aSize = mpColorSet->layoutAllVisible(nMaxItems);
1754 mpColorSet->set_height_request(aSize.Height());
1755 mpColorSet->set_width_request(aSize.Width());
1757 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
1758 aSize = mpRecentColorSet->layoutAllVisible(mxPaletteManager->GetRecentColorCount());
1759 mpRecentColorSet->set_height_request(aSize.Height());
1760 mpRecentColorSet->set_width_request(aSize.Width());
1762 AddStatusListener( ".uno:ColorTableState" );
1763 AddStatusListener( maCommand );
1764 if ( maCommand == ".uno:FrameLineColor" )
1766 AddStatusListener( ".uno:BorderTLBR" );
1767 AddStatusListener( ".uno:BorderBLTR" );
1771 ColorWindow::ColorWindow(std::shared_ptr<PaletteManager> const & rPaletteManager,
1772 ColorStatus& rColorStatus,
1773 sal_uInt16 nSlotId,
1774 const Reference< XFrame >& rFrame,
1775 weld::Window* pParentWindow,
1776 const MenuOrToolMenuButton& rMenuButton,
1777 ColorSelectFunction const & aFunction)
1778 : ToolbarPopupBase(rFrame)
1779 , m_xBuilder(Application::CreateBuilder(rMenuButton.get_widget(), "svx/ui/colorwindow.ui"))
1780 , theSlotId(nSlotId)
1781 , mpParentWindow(pParentWindow)
1782 , maMenuButton(rMenuButton)
1783 , mxPaletteManager(rPaletteManager)
1784 , mrColorStatus(rColorStatus)
1785 , maColorSelectFunction(aFunction)
1786 , mxColorSet(new ColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin")))
1787 , mxRecentColorSet(new ColorValueSet(nullptr))
1788 , mxTopLevel(m_xBuilder->weld_container("palette_popup_window"))
1789 , mxPaletteListBox(m_xBuilder->weld_combo_box("palette_listbox"))
1790 , mxButtonAutoColor(m_xBuilder->weld_button("auto_color_button"))
1791 , mxButtonNoneColor(m_xBuilder->weld_button("none_color_button"))
1792 , mxButtonPicker(m_xBuilder->weld_button("color_picker_button"))
1793 , mxAutomaticSeparator(m_xBuilder->weld_widget("separator4"))
1794 , mxColorSetWin(new weld::CustomWeld(*m_xBuilder, "colorset", *mxColorSet))
1795 , mxRecentColorSetWin(new weld::CustomWeld(*m_xBuilder, "recent_colorset", *mxRecentColorSet))
1796 , mpDefaultButton(nullptr)
1798 mxColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1799 mxRecentColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1801 switch ( theSlotId )
1803 case SID_ATTR_CHAR_COLOR_BACKGROUND:
1804 case SID_BACKGROUND_COLOR:
1805 case SID_ATTR_CHAR_BACK_COLOR:
1806 case SID_TABLE_CELL_BACKGROUND_COLOR:
1808 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_NOFILL ) );
1809 break;
1811 case SID_AUTHOR_COLOR:
1813 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_BY_AUTHOR ) );
1814 break;
1816 case SID_BMPMASK_COLOR:
1818 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_TRANSPARENT ) );
1819 break;
1821 case SID_ATTR_CHAR_COLOR:
1822 case SID_ATTR_CHAR_COLOR2:
1823 case SID_EXTRUSION_3D_COLOR:
1825 mxButtonAutoColor->set_label(EditResId(RID_SVXSTR_AUTOMATIC));
1826 break;
1828 case SID_FM_CTL_PROPERTIES:
1830 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_DEFAULT ) );
1831 break;
1833 default:
1835 mxButtonAutoColor->hide();
1836 mxAutomaticSeparator->hide();
1837 break;
1841 mxPaletteListBox->connect_changed(LINK(this, ColorWindow, SelectPaletteHdl));
1842 std::vector<OUString> aPaletteList = mxPaletteManager->GetPaletteList();
1843 mxPaletteListBox->freeze();
1844 for (const auto& rPalette : aPaletteList)
1845 mxPaletteListBox->append_text(rPalette);
1846 mxPaletteListBox->thaw();
1847 OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
1848 mxPaletteListBox->set_active_text(aPaletteName);
1849 const int nSelectedEntry(mxPaletteListBox->get_active());
1850 if (nSelectedEntry != -1)
1851 mxPaletteManager->SetPalette(nSelectedEntry);
1853 mxButtonAutoColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl));
1854 mxButtonNoneColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl));
1855 mxButtonPicker->connect_clicked(LINK(this, ColorWindow, OpenPickerClickHdl));
1857 mxColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl));
1858 mxRecentColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl));
1859 mxTopLevel->set_help_id(HID_POPUP_COLOR);
1860 mxTopLevel->connect_focus_in(LINK(this, ColorWindow, FocusHdl));
1861 mxColorSet->SetHelpId(HID_POPUP_COLOR_CTRL);
1863 mxPaletteManager->ReloadColorSet(*mxColorSet);
1864 const sal_uInt32 nMaxItems(SvxColorValueSet::getMaxRowCount() * SvxColorValueSet::getColumnCount());
1865 Size aSize = mxColorSet->layoutAllVisible(nMaxItems);
1866 mxColorSet->set_size_request(aSize.Width(), aSize.Height());
1868 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
1869 aSize = mxRecentColorSet->layoutAllVisible(mxPaletteManager->GetRecentColorCount());
1870 mxRecentColorSet->set_size_request(aSize.Width(), aSize.Height());
1872 AddStatusListener( ".uno:ColorTableState" );
1875 IMPL_LINK_NOARG(ColorWindow, FocusHdl, weld::Widget&, void)
1877 if (mxColorSet->IsNoSelection() && mpDefaultButton)
1878 mpDefaultButton->grab_focus();
1879 else
1880 mxColorSet->GrabFocus();
1883 void SvxColorWindow::ShowNoneButton()
1885 mpButtonNoneColor->Show();
1888 void ColorWindow::ShowNoneButton()
1890 mxButtonNoneColor->show();
1893 SvxColorWindow::~SvxColorWindow()
1895 disposeOnce();
1898 ColorWindow::~ColorWindow()
1902 void SvxColorWindow::dispose()
1904 mpColorSet.clear();
1905 mpRecentColorSet.clear();
1906 mpPaletteListBox.clear();
1907 mpButtonAutoColor.clear();
1908 mpButtonNoneColor.clear();
1909 mpButtonPicker.clear();
1910 mpAutomaticSeparator.clear();
1911 mxParentWindow.clear();
1912 ToolbarPopup::dispose();
1915 void SvxColorWindow::KeyInput( const KeyEvent& rKEvt )
1917 mpColorSet->GrabFocus();
1918 mpColorSet->KeyInput(rKEvt);
1921 NamedColor SvxColorWindow::GetSelectEntryColor(ValueSet const * pColorSet)
1923 Color aColor = pColorSet->GetItemColor(pColorSet->GetSelectedItemId());
1924 OUString sColorName = pColorSet->GetItemText(pColorSet->GetSelectedItemId());
1925 return std::make_pair(aColor, sColorName);
1928 NamedColor ColorWindow::GetSelectEntryColor(SvtValueSet const * pColorSet)
1930 Color aColor = pColorSet->GetItemColor(pColorSet->GetSelectedItemId());
1931 OUString sColorName = pColorSet->GetItemText(pColorSet->GetSelectedItemId());
1932 return std::make_pair(aColor, sColorName);
1935 namespace
1937 NamedColor GetAutoColor(sal_uInt16 nSlotId)
1939 Color aColor;
1940 OUString sColorName;
1941 switch (nSlotId)
1943 case SID_ATTR_CHAR_COLOR_BACKGROUND:
1944 case SID_BACKGROUND_COLOR:
1945 case SID_ATTR_CHAR_BACK_COLOR:
1946 case SID_TABLE_CELL_BACKGROUND_COLOR:
1947 aColor = COL_TRANSPARENT;
1948 sColorName = SvxResId(RID_SVXSTR_NOFILL);
1949 break;
1950 case SID_AUTHOR_COLOR:
1951 aColor = COL_TRANSPARENT;
1952 sColorName = SvxResId(RID_SVXSTR_BY_AUTHOR);
1953 break;
1954 case SID_BMPMASK_COLOR:
1955 aColor = COL_TRANSPARENT;
1956 sColorName = SvxResId(RID_SVXSTR_TRANSPARENT);
1957 break;
1958 case SID_FM_CTL_PROPERTIES:
1959 aColor = COL_TRANSPARENT;
1960 sColorName = SvxResId(RID_SVXSTR_DEFAULT);
1961 break;
1962 case SID_ATTR_CHAR_COLOR:
1963 case SID_ATTR_CHAR_COLOR2:
1964 case SID_EXTRUSION_3D_COLOR:
1965 default:
1966 aColor = COL_AUTO;
1967 sColorName = EditResId(RID_SVXSTR_AUTOMATIC);
1968 break;
1971 return std::make_pair(aColor, sColorName);
1974 NamedColor GetNoneColor()
1976 return std::make_pair(COL_NONE_COLOR, comphelper::LibreOfficeKit::isActive() ? SvxResId(RID_SVXSTR_INVISIBLE)
1977 : SvxResId(RID_SVXSTR_NONE));
1981 NamedColor SvxColorWindow::GetSelectEntryColor() const
1983 if (!mpColorSet->IsNoSelection())
1984 return GetSelectEntryColor(mpColorSet);
1985 if (!mpRecentColorSet->IsNoSelection())
1986 return GetSelectEntryColor(mpRecentColorSet);
1987 if (mpButtonNoneColor->GetStyle() & WB_DEFBUTTON)
1988 return GetNoneColor();
1989 return GetAutoColor();
1992 NamedColor ColorWindow::GetSelectEntryColor() const
1994 if (!mxColorSet->IsNoSelection())
1995 return GetSelectEntryColor(mxColorSet.get());
1996 if (!mxRecentColorSet->IsNoSelection())
1997 return GetSelectEntryColor(mxRecentColorSet.get());
1998 if (mxButtonNoneColor.get() == mpDefaultButton)
1999 return GetNoneColor();
2000 return GetAutoColor();
2003 IMPL_LINK(SvxColorWindow, SelectHdl, ValueSet*, pColorSet, void)
2005 VclPtr<SvxColorWindow> xThis(this);
2007 NamedColor aNamedColor = GetSelectEntryColor(pColorSet);
2009 if ( pColorSet != mpRecentColorSet )
2011 mxPaletteManager->AddRecentColor(aNamedColor.first, aNamedColor.second);
2012 if ( !IsInPopupMode() )
2013 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
2016 if ( IsInPopupMode() )
2017 EndPopupMode();
2019 maSelectedLink.Call(aNamedColor);
2021 maColorSelectFunction(maCommand, aNamedColor);
2024 IMPL_LINK(ColorWindow, SelectHdl, SvtValueSet*, pColorSet, void)
2026 NamedColor aNamedColor = GetSelectEntryColor(pColorSet);
2028 if (pColorSet != mxRecentColorSet.get())
2030 mxPaletteManager->AddRecentColor(aNamedColor.first, aNamedColor.second);
2031 if (!maMenuButton.get_active())
2032 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2035 if (maMenuButton.get_active())
2036 maMenuButton.set_active(false);
2038 maColorSelectFunction(OUString(), aNamedColor);
2041 IMPL_LINK_NOARG(SvxColorWindow, SelectPaletteHdl, ListBox&, void)
2043 sal_Int32 nPos = mpPaletteListBox->GetSelectedEntryPos();
2044 mxPaletteManager->SetPalette( nPos );
2045 mxPaletteManager->ReloadColorSet(*mpColorSet);
2046 mpColorSet->layoutToGivenHeight(mpColorSet->GetSizePixel().Height(), mxPaletteManager->GetColorCount());
2049 IMPL_LINK_NOARG(ColorWindow, SelectPaletteHdl, weld::ComboBox&, void)
2051 int nPos = mxPaletteListBox->get_active();
2052 mxPaletteManager->SetPalette( nPos );
2053 mxPaletteManager->ReloadColorSet(*mxColorSet);
2054 mxColorSet->layoutToGivenHeight(mxColorSet->GetOutputSizePixel().Height(), mxPaletteManager->GetColorCount());
2057 NamedColor SvxColorWindow::GetAutoColor() const
2059 return ::GetAutoColor(theSlotId);
2062 NamedColor ColorWindow::GetAutoColor() const
2064 return ::GetAutoColor(theSlotId);
2067 IMPL_LINK(SvxColorWindow, AutoColorClickHdl, Button*, pButton, void)
2069 VclPtr<SvxColorWindow> xThis(this);
2071 NamedColor aNamedColor = pButton == mpButtonAutoColor ? GetAutoColor() : GetNoneColor();
2073 mpRecentColorSet->SetNoSelection();
2075 if ( IsInPopupMode() )
2076 EndPopupMode();
2078 maSelectedLink.Call(aNamedColor);
2080 maColorSelectFunction(maCommand, aNamedColor);
2083 IMPL_LINK(ColorWindow, AutoColorClickHdl, weld::Button&, rButton, void)
2085 NamedColor aNamedColor = &rButton == mxButtonAutoColor.get() ? GetAutoColor() : GetNoneColor();
2087 mxColorSet->SetNoSelection();
2088 mxRecentColorSet->SetNoSelection();
2089 mpDefaultButton = &rButton;
2091 if (maMenuButton.get_active())
2092 maMenuButton.set_active(false);
2094 maColorSelectFunction(OUString(), aNamedColor);
2097 IMPL_LINK_NOARG(SvxColorWindow, OpenPickerClickHdl, Button*, void)
2099 VclPtr<SvxColorWindow> xThis(this);
2101 if ( IsInPopupMode() )
2102 EndPopupMode();
2104 weld::Window* pParentFrame;
2105 if (mbReuseParentForPicker)
2107 pParentFrame = mxParentWindow->GetFrameWeld();
2109 else
2111 const css::uno::Reference<css::awt::XWindow> xParent = mxFrame->getContainerWindow();
2112 pParentFrame = Application::GetFrameWeld(xParent);
2114 mxPaletteManager->PopupColorPicker(pParentFrame, maCommand, GetSelectEntryColor().first);
2117 IMPL_LINK_NOARG(ColorWindow, OpenPickerClickHdl, weld::Button&, void)
2119 if (maMenuButton.get_active())
2120 maMenuButton.set_active(false);
2121 mxPaletteManager->PopupColorPicker(mpParentWindow, OUString(), GetSelectEntryColor().first);
2124 void SvxColorWindow::StartSelection()
2126 mpColorSet->StartSelection();
2127 mpRecentColorSet->StartSelection();
2130 void SvxColorWindow::SetNoSelection()
2132 mpColorSet->SetNoSelection();
2133 mpRecentColorSet->SetNoSelection();
2134 mpButtonAutoColor->set_property("has-default", "false");
2135 mpButtonNoneColor->set_property("has-default", "false");
2138 void ColorWindow::SetNoSelection()
2140 mxColorSet->SetNoSelection();
2141 mxRecentColorSet->SetNoSelection();
2142 mpDefaultButton = nullptr;
2145 bool SvxColorWindow::IsNoSelection() const
2147 if (!mpColorSet->IsNoSelection())
2148 return false;
2149 if (!mpRecentColorSet->IsNoSelection())
2150 return false;
2151 return !mpButtonAutoColor->IsVisible() && !mpButtonNoneColor->IsVisible();
2154 bool ColorWindow::IsNoSelection() const
2156 if (!mxColorSet->IsNoSelection())
2157 return false;
2158 if (!mxRecentColorSet->IsNoSelection())
2159 return false;
2160 return !mxButtonAutoColor->get_visible() && !mxButtonNoneColor->get_visible();
2163 void SvxColorWindow::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2165 if (rEvent.FeatureURL.Complete == ".uno:ColorTableState")
2167 if (rEvent.IsEnabled && mxPaletteManager->GetPalette() == 0)
2169 mxPaletteManager->ReloadColorSet(*mpColorSet);
2170 mpColorSet->layoutToGivenHeight(mpColorSet->GetSizePixel().Height(), mxPaletteManager->GetColorCount());
2173 else
2175 mrColorStatus.statusChanged(rEvent);
2176 SelectEntry(mrColorStatus.GetColor());
2180 void ColorWindow::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2182 if (rEvent.FeatureURL.Complete == ".uno:ColorTableState")
2184 if (rEvent.IsEnabled && mxPaletteManager->GetPalette() == 0)
2186 mxPaletteManager->ReloadColorSet(*mxColorSet);
2187 mxColorSet->layoutToGivenHeight(mxColorSet->GetOutputSizePixel().Height(), mxPaletteManager->GetColorCount());
2190 else
2192 mrColorStatus.statusChanged(rEvent);
2193 SelectEntry(mrColorStatus.GetColor());
2197 bool SvxColorWindow::SelectValueSetEntry(SvxColorValueSet* pColorSet, const Color& rColor)
2199 for (size_t i = 1; i <= pColorSet->GetItemCount(); ++i)
2201 if (rColor == pColorSet->GetItemColor(i))
2203 pColorSet->SelectItem(i);
2204 return true;
2207 return false;
2210 bool ColorWindow::SelectValueSetEntry(ColorValueSet* pColorSet, const Color& rColor)
2212 for (size_t i = 1; i <= pColorSet->GetItemCount(); ++i)
2214 if (rColor == pColorSet->GetItemColor(i))
2216 pColorSet->SelectItem(i);
2217 return true;
2220 return false;
2223 void SvxColorWindow::SelectEntry(const NamedColor& rNamedColor)
2225 SetNoSelection();
2227 const Color &rColor = rNamedColor.first;
2229 if (rColor == COL_TRANSPARENT || rColor == COL_AUTO)
2231 mpButtonAutoColor->set_property("has-default", "true");
2232 return;
2235 if (mpButtonNoneColor->IsVisible() && rColor == COL_NONE_COLOR)
2237 mpButtonNoneColor->set_property("has-default", "true");
2238 return;
2241 // try current palette
2242 bool bFoundColor = SelectValueSetEntry(mpColorSet, rColor);
2243 // try recently used
2244 if (!bFoundColor)
2245 bFoundColor = SelectValueSetEntry(mpRecentColorSet, rColor);
2246 // if it's not there, add it there now to the end of the recently used
2247 // so its available somewhere handy, but not without trashing the
2248 // whole recently used
2249 if (!bFoundColor)
2251 const OUString& rColorName = rNamedColor.second;
2252 mxPaletteManager->AddRecentColor(rColor, rColorName, false);
2253 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
2254 SelectValueSetEntry(mpRecentColorSet, rColor);
2258 void SvxColorWindow::SelectEntry(const Color& rColor)
2260 OUString sColorName = "#" + rColor.AsRGBHexString().toAsciiUpperCase();
2261 SvxColorWindow::SelectEntry(std::make_pair(rColor, sColorName));
2264 void ColorWindow::SelectEntry(const NamedColor& rNamedColor)
2266 SetNoSelection();
2268 const Color &rColor = rNamedColor.first;
2270 if (mxButtonAutoColor->get_visible() && (rColor == COL_TRANSPARENT || rColor == COL_AUTO))
2272 mpDefaultButton = mxButtonAutoColor.get();
2273 return;
2276 if (mxButtonNoneColor->get_visible() && rColor == COL_NONE_COLOR)
2278 mpDefaultButton = mxButtonNoneColor.get();
2279 return;
2282 // try current palette
2283 bool bFoundColor = SelectValueSetEntry(mxColorSet.get(), rColor);
2284 // try recently used
2285 if (!bFoundColor)
2286 bFoundColor = SelectValueSetEntry(mxRecentColorSet.get(), rColor);
2287 // if it's not there, add it there now to the end of the recently used
2288 // so its available somewhere handy, but not without trashing the
2289 // whole recently used
2290 if (!bFoundColor)
2292 const OUString& rColorName = rNamedColor.second;
2293 mxPaletteManager->AddRecentColor(rColor, rColorName, false);
2294 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2295 SelectValueSetEntry(mxRecentColorSet.get(), rColor);
2299 void ColorWindow::SelectEntry(const Color& rColor)
2301 OUString sColorName = "#" + rColor.AsRGBHexString().toAsciiUpperCase();
2302 ColorWindow::SelectEntry(std::make_pair(rColor, sColorName));
2305 ColorStatus::ColorStatus() :
2306 maColor( COL_TRANSPARENT ),
2307 maTLBRColor( COL_TRANSPARENT ),
2308 maBLTRColor( COL_TRANSPARENT )
2312 ColorStatus::~ColorStatus()
2316 void ColorStatus::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2318 Color aColor( COL_TRANSPARENT );
2319 css::table::BorderLine2 aTable;
2321 if ( rEvent.State >>= aTable )
2323 SvxBorderLine aLine;
2324 SvxBoxItem::LineToSvxLine( aTable, aLine, false );
2325 if ( !aLine.isEmpty() )
2326 aColor = aLine.GetColor();
2328 else
2329 rEvent.State >>= aColor;
2331 if ( rEvent.FeatureURL.Path == "BorderTLBR" )
2332 maTLBRColor = aColor;
2333 else if ( rEvent.FeatureURL.Path == "BorderBLTR" )
2334 maBLTRColor = aColor;
2335 else
2336 maColor = aColor;
2339 Color ColorStatus::GetColor()
2341 Color aColor( maColor );
2343 if ( maTLBRColor != COL_TRANSPARENT )
2345 if ( aColor != maTLBRColor && aColor != COL_TRANSPARENT )
2346 return COL_TRANSPARENT;
2347 aColor = maTLBRColor;
2350 if ( maBLTRColor != COL_TRANSPARENT )
2352 if ( aColor != maBLTRColor && aColor != COL_TRANSPARENT )
2353 return COL_TRANSPARENT;
2354 return maBLTRColor;
2357 return aColor;
2361 SvxFrameWindow_Impl::SvxFrameWindow_Impl ( svt::ToolboxController& rController, vcl::Window* pParentWindow ) :
2362 ToolbarPopup( rController.getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
2363 aFrameSet ( VclPtr<SvxFrmValueSet_Impl>::Create(this, WinBits( WB_ITEMBORDER | WB_DOUBLEBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT )) ),
2364 mrController( rController ),
2365 bParagraphMode(false)
2367 AddStatusListener(".uno:BorderReducedMode");
2368 InitImageList();
2371 * 1 2 3 4
2372 * -------------------------------------
2373 * NONE LEFT RIGHT LEFTRIGHT
2374 * TOP BOTTOM TOPBOTTOM OUTER
2375 * -------------------------------------
2376 * HOR HORINNER VERINNER ALL <- can be switched of via bParagraphMode
2379 sal_uInt16 i = 0;
2381 for ( i=1; i<9; i++ )
2382 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2384 //bParagraphMode should have been set in StateChanged
2385 if ( !bParagraphMode )
2386 for ( i = 9; i < 13; i++ )
2387 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2389 aFrameSet->SetColCount( 4 );
2390 aFrameSet->SetSelectHdl( LINK( this, SvxFrameWindow_Impl, SelectHdl ) );
2391 CalcSizeValueSet();
2393 SetHelpId( HID_POPUP_FRAME );
2394 SetText( SvxResId(RID_SVXSTR_FRAME) );
2395 aFrameSet->SetAccessibleName( SvxResId(RID_SVXSTR_FRAME) );
2396 aFrameSet->Show();
2399 SvxFrameWindow_Impl::~SvxFrameWindow_Impl()
2401 disposeOnce();
2404 void SvxFrameWindow_Impl::dispose()
2406 aFrameSet.disposeAndClear();
2407 ToolbarPopup::dispose();
2410 void SvxFrameWindow_Impl::GetFocus()
2412 if (aFrameSet)
2413 aFrameSet->StartSelection();
2416 void SvxFrameWindow_Impl::KeyInput( const KeyEvent& rKEvt )
2418 aFrameSet->GrabFocus();
2419 aFrameSet->KeyInput( rKEvt );
2422 void SvxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2424 ToolbarPopup::DataChanged( rDCEvt );
2426 if ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) && ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
2428 InitImageList();
2430 sal_uInt16 nNumOfItems = aFrameSet->GetItemCount();
2431 for ( sal_uInt16 i = 1 ; i <= nNumOfItems ; ++i )
2432 aFrameSet->SetItemImage( i, Image(aImgVec[i-1]) );
2436 enum class FrmValidFlags {
2437 NONE = 0x00,
2438 Left = 0x01,
2439 Right = 0x02,
2440 Top = 0x04,
2441 Bottom = 0x08,
2442 HInner = 0x10,
2443 VInner = 0x20,
2444 AllMask = 0x3f,
2446 namespace o3tl {
2447 template<> struct typed_flags<FrmValidFlags> : is_typed_flags<FrmValidFlags, 0x3f> {};
2450 // By default unset lines remain unchanged.
2451 // Via Shift unset lines are reset
2453 IMPL_LINK_NOARG(SvxFrameWindow_Impl, SelectHdl, ValueSet*, void)
2455 VclPtr<SvxFrameWindow_Impl> xThis(this);
2457 SvxBoxItem aBorderOuter( SID_ATTR_BORDER_OUTER );
2458 SvxBoxInfoItem aBorderInner( SID_ATTR_BORDER_INNER );
2459 SvxBorderLine theDefLine;
2460 SvxBorderLine *pLeft = nullptr,
2461 *pRight = nullptr,
2462 *pTop = nullptr,
2463 *pBottom = nullptr;
2464 sal_uInt16 nSel = aFrameSet->GetSelectedItemId();
2465 sal_uInt16 nModifier = aFrameSet->GetModifier();
2466 FrmValidFlags nValidFlags = FrmValidFlags::NONE;
2468 theDefLine.GuessLinesWidths(theDefLine.GetBorderLineStyle(),
2469 DEF_LINE_WIDTH_0);
2470 switch ( nSel )
2472 case 1: nValidFlags |= FrmValidFlags::AllMask;
2473 break; // NONE
2474 case 2: pLeft = &theDefLine;
2475 nValidFlags |= FrmValidFlags::Left;
2476 break; // LEFT
2477 case 3: pRight = &theDefLine;
2478 nValidFlags |= FrmValidFlags::Right;
2479 break; // RIGHT
2480 case 4: pLeft = pRight = &theDefLine;
2481 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left;
2482 break; // LEFTRIGHT
2483 case 5: pTop = &theDefLine;
2484 nValidFlags |= FrmValidFlags::Top;
2485 break; // TOP
2486 case 6: pBottom = &theDefLine;
2487 nValidFlags |= FrmValidFlags::Bottom;
2488 break; // BOTTOM
2489 case 7: pTop = pBottom = &theDefLine;
2490 nValidFlags |= FrmValidFlags::Bottom|FrmValidFlags::Top;
2491 break; // TOPBOTTOM
2492 case 8: pLeft = pRight = pTop = pBottom = &theDefLine;
2493 nValidFlags |= FrmValidFlags::Left | FrmValidFlags::Right | FrmValidFlags::Top | FrmValidFlags::Bottom;
2494 break; // OUTER
2496 // Inner Table:
2497 case 9: // HOR
2498 pTop = pBottom = &theDefLine;
2499 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2500 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
2501 nValidFlags |= FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2502 break;
2504 case 10: // HORINNER
2505 pLeft = pRight = pTop = pBottom = &theDefLine;
2506 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2507 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
2508 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2509 break;
2511 case 11: // VERINNER
2512 pLeft = pRight = pTop = pBottom = &theDefLine;
2513 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
2514 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
2515 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::VInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
2516 break;
2518 case 12: // ALL
2519 pLeft = pRight = pTop = pBottom = &theDefLine;
2520 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
2521 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
2522 nValidFlags |= FrmValidFlags::AllMask;
2523 break;
2525 default:
2526 break;
2528 aBorderOuter.SetLine( pLeft, SvxBoxItemLine::LEFT );
2529 aBorderOuter.SetLine( pRight, SvxBoxItemLine::RIGHT );
2530 aBorderOuter.SetLine( pTop, SvxBoxItemLine::TOP );
2531 aBorderOuter.SetLine( pBottom, SvxBoxItemLine::BOTTOM );
2533 if(nModifier == KEY_SHIFT)
2534 nValidFlags |= FrmValidFlags::AllMask;
2535 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::TOP, bool(nValidFlags&FrmValidFlags::Top ));
2536 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, bool(nValidFlags&FrmValidFlags::Bottom ));
2537 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::LEFT, bool(nValidFlags&FrmValidFlags::Left));
2538 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::RIGHT, bool(nValidFlags&FrmValidFlags::Right ));
2539 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::HORI, bool(nValidFlags&FrmValidFlags::HInner ));
2540 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::VERT, bool(nValidFlags&FrmValidFlags::VInner));
2541 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
2542 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISABLE, false );
2544 if ( IsInPopupMode() )
2545 EndPopupMode();
2547 Any a;
2548 Sequence< PropertyValue > aArgs( 2 );
2549 aArgs[0].Name = "OuterBorder";
2550 aBorderOuter.QueryValue( a );
2551 aArgs[0].Value = a;
2552 aArgs[1].Name = "InnerBorder";
2553 aBorderInner.QueryValue( a );
2554 aArgs[1].Value = a;
2556 if (aFrameSet)
2558 /* #i33380# Moved the following line above the Dispatch() call.
2559 This instance may be deleted in the meantime (i.e. when a dialog is opened
2560 while in Dispatch()), accessing members will crash in this case. */
2561 aFrameSet->SetNoSelection();
2564 mrController.dispatchCommand( ".uno:SetBorderStyle", aArgs );
2567 void SvxFrameWindow_Impl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2569 if ( rEvent.FeatureURL.Complete == ".uno:BorderReducedMode" )
2571 bool bValue;
2572 if ( rEvent.State >>= bValue )
2574 bParagraphMode = bValue;
2575 //initial calls mustn't insert or remove elements
2576 if(aFrameSet->GetItemCount())
2578 bool bTableMode = ( aFrameSet->GetItemCount() == 12 );
2579 bool bResize = false;
2581 if ( bTableMode && bParagraphMode )
2583 for ( sal_uInt16 i = 9; i < 13; i++ )
2584 aFrameSet->RemoveItem(i);
2585 bResize = true;
2587 else if ( !bTableMode && !bParagraphMode )
2589 for ( sal_uInt16 i = 9; i < 13; i++ )
2590 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
2591 bResize = true;
2594 if ( bResize )
2596 CalcSizeValueSet();
2603 void SvxFrameWindow_Impl::CalcSizeValueSet()
2605 Size aItemSize( 20 * GetParent()->GetDPIScaleFactor(), 20 * GetParent()->GetDPIScaleFactor() );
2606 Size aSize = aFrameSet->CalcWindowSizePixel( aItemSize );
2607 aFrameSet->SetPosSizePixel( Point( 2, 2 ), aSize );
2608 aSize.AdjustWidth(4 );
2609 aSize.AdjustHeight(4 );
2610 SetOutputSizePixel( aSize );
2613 void SvxFrameWindow_Impl::InitImageList()
2615 aImgVec.clear();
2616 aImgVec.emplace_back(RID_SVXBMP_FRAME1);
2617 aImgVec.emplace_back(RID_SVXBMP_FRAME2);
2618 aImgVec.emplace_back(RID_SVXBMP_FRAME3);
2619 aImgVec.emplace_back(RID_SVXBMP_FRAME4);
2620 aImgVec.emplace_back(RID_SVXBMP_FRAME5);
2621 aImgVec.emplace_back(RID_SVXBMP_FRAME6);
2622 aImgVec.emplace_back(RID_SVXBMP_FRAME7);
2623 aImgVec.emplace_back(RID_SVXBMP_FRAME8);
2624 aImgVec.emplace_back(RID_SVXBMP_FRAME9);
2625 aImgVec.emplace_back(RID_SVXBMP_FRAME10);
2626 aImgVec.emplace_back(RID_SVXBMP_FRAME11);
2627 aImgVec.emplace_back(RID_SVXBMP_FRAME12);
2630 static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
2632 return SvxBorderLine::threeDMediumColor( aMain );
2635 SvxCurrencyList_Impl::SvxCurrencyList_Impl(
2636 SvxCurrencyToolBoxControl* pControl,
2637 vcl::Window* pParentWindow,
2638 OUString& rSelectedFormat,
2639 LanguageType& eSelectedLanguage ) :
2640 ToolbarPopup( pControl->getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
2641 m_pCurrencyLb( VclPtr<ListBox>::Create(this) ),
2642 m_xControl( pControl ),
2643 m_rSelectedFormat( rSelectedFormat ),
2644 m_eSelectedLanguage( eSelectedLanguage )
2646 m_pCurrencyLb->setPosSizePixel( 2, 2, 300, 140 );
2647 SetOutputSizePixel( Size( 304, 144 ) );
2649 std::vector< OUString > aList;
2650 std::vector< sal_uInt16 > aCurrencyList;
2651 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
2652 sal_uInt16 nLen = rCurrencyTable.size();
2654 SvNumberFormatter aFormatter( m_xControl->getContext(), LANGUAGE_SYSTEM );
2655 m_eFormatLanguage = aFormatter.GetLanguage();
2657 SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, aCurrencyList );
2659 sal_uInt16 nPos = 0, nCount = 0;
2660 sal_Int32 nSelectedPos = -1;
2661 bool bIsSymbol;
2662 NfWSStringsDtor aStringsDtor;
2664 for( const auto& rItem : aList )
2666 sal_uInt16& rCurrencyIndex = aCurrencyList[ nCount ];
2667 if ( rCurrencyIndex < nLen )
2669 m_pCurrencyLb->InsertEntry( rItem );
2670 const NfCurrencyEntry& aCurrencyEntry = rCurrencyTable[ rCurrencyIndex ];
2672 bIsSymbol = nPos >= nLen;
2674 sal_uInt16 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, aCurrencyEntry, bIsSymbol );
2675 const OUString& rFormatStr = aStringsDtor[ nDefaultFormat ];
2676 m_aFormatEntries.push_back( rFormatStr );
2677 if( rFormatStr == m_rSelectedFormat )
2678 nSelectedPos = nPos;
2679 ++nPos;
2681 ++nCount;
2683 m_pCurrencyLb->SetSelectHdl( LINK( this, SvxCurrencyList_Impl, SelectHdl ) );
2684 SetText( SvxResId( RID_SVXSTR_TBLAFMT_CURRENCY ) );
2685 if ( nSelectedPos >= 0 )
2686 m_pCurrencyLb->SelectEntryPos( nSelectedPos );
2687 m_pCurrencyLb->Show();
2690 void SvxCurrencyList_Impl::dispose()
2692 m_xControl.clear();
2693 m_pCurrencyLb.disposeAndClear();
2694 ToolbarPopup::dispose();
2697 SvxLineWindow_Impl::SvxLineWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow ) :
2698 ToolbarPopup( rController.getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
2699 m_aLineStyleLb( VclPtr<LineListBox>::Create(this) ),
2700 m_rController( rController )
2704 Reference< lang::XServiceInfo > xServices( rController.getFrameInterface()->getController()->getModel(), UNO_QUERY_THROW );
2705 m_bIsWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2707 catch(const uno::Exception& )
2711 m_aLineStyleLb->setPosSizePixel( 2, 2, 110, 140 );
2712 SetOutputSizePixel( Size( 114, 144 ) );
2714 m_aLineStyleLb->SetSourceUnit( FieldUnit::TWIP );
2715 m_aLineStyleLb->SetNone( comphelper::LibreOfficeKit::isActive() ? SvxResId(RID_SVXSTR_INVISIBLE)
2716 :SvxResId(RID_SVXSTR_NONE) );
2718 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::SOLID ), SvxBorderLineStyle::SOLID );
2719 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOTTED ), SvxBorderLineStyle::DOTTED );
2720 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DASHED ), SvxBorderLineStyle::DASHED );
2722 // Double lines
2723 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOUBLE ), SvxBorderLineStyle::DOUBLE );
2724 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_SMALLGAP ), SvxBorderLineStyle::THINTHICK_SMALLGAP, 20 );
2725 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_MEDIUMGAP ), SvxBorderLineStyle::THINTHICK_MEDIUMGAP );
2726 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_LARGEGAP ), SvxBorderLineStyle::THINTHICK_LARGEGAP );
2727 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_SMALLGAP ), SvxBorderLineStyle::THICKTHIN_SMALLGAP, 20 );
2728 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_MEDIUMGAP ), SvxBorderLineStyle::THICKTHIN_MEDIUMGAP );
2729 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_LARGEGAP ), SvxBorderLineStyle::THICKTHIN_LARGEGAP );
2731 // Engraved / Embossed
2732 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::EMBOSSED ), SvxBorderLineStyle::EMBOSSED, 15,
2733 &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor,
2734 &lcl_mediumColor );
2735 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::ENGRAVED ), SvxBorderLineStyle::ENGRAVED, 15,
2736 &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor,
2737 &lcl_mediumColor );
2739 // Inset / Outset
2740 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::OUTSET ), SvxBorderLineStyle::OUTSET, 10,
2741 &SvxBorderLine::lightColor, &SvxBorderLine::darkColor );
2742 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::INSET ), SvxBorderLineStyle::INSET, 10,
2743 &SvxBorderLine::darkColor, &SvxBorderLine::lightColor );
2744 m_aLineStyleLb->SetWidth( 20 ); // 1pt by default
2746 m_aLineStyleLb->SetSelectHdl( LINK( this, SvxLineWindow_Impl, SelectHdl ) );
2748 SetHelpId( HID_POPUP_LINE );
2749 SetText( SvxResId(RID_SVXSTR_FRAME_STYLE) );
2750 m_aLineStyleLb->Show();
2753 IMPL_LINK_NOARG(SvxCurrencyList_Impl, SelectHdl, ListBox&, void)
2755 VclPtr<SvxCurrencyList_Impl> xThis(this);
2757 if ( IsInPopupMode() )
2758 EndPopupMode();
2760 if (!m_xControl.is())
2761 return;
2763 m_rSelectedFormat = m_aFormatEntries[ m_pCurrencyLb->GetSelectedEntryPos() ];
2764 m_eSelectedLanguage = m_eFormatLanguage;
2766 m_xControl->execute( m_pCurrencyLb->GetSelectedEntryPos() + 1 );
2769 IMPL_LINK_NOARG(SvxLineWindow_Impl, SelectHdl, ListBox&, void)
2771 VclPtr<SvxLineWindow_Impl> xThis(this);
2773 SvxLineItem aLineItem( SID_FRAME_LINESTYLE );
2774 SvxBorderLineStyle nStyle = m_aLineStyleLb->GetSelectEntryStyle();
2776 if ( m_aLineStyleLb->GetSelectedEntryPos( ) > 0 )
2778 SvxBorderLine aTmp;
2779 aTmp.SetBorderLineStyle( nStyle );
2780 aTmp.SetWidth( 20 ); // TODO Make it depend on a width field
2781 aLineItem.SetLine( &aTmp );
2783 else
2784 aLineItem.SetLine( nullptr );
2786 if ( IsInPopupMode() )
2787 EndPopupMode();
2789 Any a;
2790 Sequence< PropertyValue > aArgs( 1 );
2791 aArgs[0].Name = "LineStyle";
2792 aLineItem.QueryValue( a, m_bIsWriter ? CONVERT_TWIPS : 0 );
2793 aArgs[0].Value = a;
2795 m_rController.dispatchCommand( ".uno:LineStyle", aArgs );
2798 void SvxLineWindow_Impl::Resize()
2800 m_aLineStyleLb->Resize();
2803 void SvxLineWindow_Impl::GetFocus()
2805 if ( m_aLineStyleLb )
2806 m_aLineStyleLb->GrabFocus();
2809 SfxStyleControllerItem_Impl::SfxStyleControllerItem_Impl(
2810 const Reference< XDispatchProvider >& rDispatchProvider,
2811 sal_uInt16 nSlotId, // Family-ID
2812 const OUString& rCommand, // .uno: command bound to this item
2813 SvxStyleToolBoxControl& rTbxCtl ) // controller instance, which the item is assigned to.
2814 : SfxStatusListener( rDispatchProvider, nSlotId, rCommand ),
2815 rControl( rTbxCtl )
2819 void SfxStyleControllerItem_Impl::StateChanged(
2820 SfxItemState eState, const SfxPoolItem* pState )
2822 switch ( GetId() )
2824 case SID_STYLE_FAMILY1:
2825 case SID_STYLE_FAMILY2:
2826 case SID_STYLE_FAMILY3:
2827 case SID_STYLE_FAMILY4:
2828 case SID_STYLE_FAMILY5:
2830 const sal_uInt16 nIdx = GetId() - SID_STYLE_FAMILY_START;
2832 if ( SfxItemState::DEFAULT == eState )
2834 const SfxTemplateItem* pStateItem =
2835 dynamic_cast<const SfxTemplateItem*>( pState );
2836 DBG_ASSERT( pStateItem != nullptr, "SfxTemplateItem expected" );
2837 rControl.SetFamilyState( nIdx, pStateItem );
2839 else
2840 rControl.SetFamilyState( nIdx, nullptr );
2841 break;
2846 struct SvxStyleToolBoxControl::Impl
2848 OUString aClearForm;
2849 OUString aMore;
2850 ::std::vector< std::pair< OUString, OUString > > aDefaultStyles;
2851 bool bSpecModeWriter;
2852 bool bSpecModeCalc;
2854 Impl()
2855 :aClearForm ( SvxResId( RID_SVXSTR_CLEARFORM ) )
2856 ,aMore ( SvxResId( RID_SVXSTR_MORE_STYLES ) )
2857 ,bSpecModeWriter ( false )
2858 ,bSpecModeCalc ( false )
2863 void InitializeStyles(const Reference < frame::XModel >& xModel)
2865 //now convert the default style names to the localized names
2868 Reference< style::XStyleFamiliesSupplier > xStylesSupplier( xModel, UNO_QUERY_THROW );
2869 Reference< lang::XServiceInfo > xServices( xModel, UNO_QUERY_THROW );
2870 bSpecModeWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2871 if(bSpecModeWriter)
2873 Reference<container::XNameAccess> xParaStyles;
2874 xStylesSupplier->getStyleFamilies()->getByName("ParagraphStyles") >>=
2875 xParaStyles;
2876 static const std::vector<OUString> aWriterStyles =
2878 "Standard",
2879 "Text body",
2880 "Title",
2881 "Subtitle",
2882 "Heading 1",
2883 "Heading 2",
2884 "Heading 3",
2885 "Quotations"
2887 for( const OUString& aStyle: aWriterStyles )
2891 Reference< beans::XPropertySet > xStyle;
2892 xParaStyles->getByName( aStyle ) >>= xStyle;
2893 OUString sName;
2894 xStyle->getPropertyValue("DisplayName") >>= sName;
2895 if( !sName.isEmpty() )
2896 aDefaultStyles.push_back(
2897 std::pair<OUString, OUString>(aStyle, sName) );
2899 catch( const uno::Exception& )
2904 else if( (
2905 bSpecModeCalc = xServices->supportsService(
2906 "com.sun.star.sheet.SpreadsheetDocument")))
2908 static const sal_Char* aCalcStyles[] =
2910 "Default",
2911 "Heading1",
2912 "Result",
2913 "Result2"
2915 Reference<container::XNameAccess> xCellStyles;
2916 xStylesSupplier->getStyleFamilies()->getByName("CellStyles") >>= xCellStyles;
2917 for(const char* pCalcStyle : aCalcStyles)
2921 const OUString sStyleName( OUString::createFromAscii( pCalcStyle ) );
2922 if( xCellStyles->hasByName( sStyleName ) )
2924 Reference< beans::XPropertySet > xStyle( xCellStyles->getByName( sStyleName), UNO_QUERY_THROW );
2925 OUString sName;
2926 xStyle->getPropertyValue("DisplayName") >>= sName;
2927 if( !sName.isEmpty() )
2928 aDefaultStyles.push_back(
2929 std::pair<OUString, OUString>(sStyleName, sName) );
2932 catch( const uno::Exception& )
2937 catch(const uno::Exception& )
2939 OSL_FAIL("error while initializing style names");
2944 // mapping table from bound items. BE CAREFUL this table must be in the
2945 // same order as the uno commands bound to the slots SID_STYLE_FAMILY1..n
2946 // MAX_FAMILIES must also be correctly set!
2947 static const char* StyleSlotToStyleCommand[MAX_FAMILIES] =
2949 ".uno:CharStyle",
2950 ".uno:ParaStyle",
2951 ".uno:FrameStyle",
2952 ".uno:PageStyle",
2953 ".uno:TemplateFamily5"
2956 SvxStyleToolBoxControl::SvxStyleToolBoxControl(
2957 sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
2958 : SfxToolBoxControl ( nSlotId, nId, rTbx ),
2959 pImpl ( new Impl ),
2960 pStyleSheetPool ( nullptr ),
2961 nActFamily ( 0xffff )
2963 for ( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
2965 pBoundItems[i] = nullptr;
2966 m_xBoundItems[i].clear();
2967 pFamilyState[i] = nullptr;
2971 SvxStyleToolBoxControl::~SvxStyleToolBoxControl()
2975 void SAL_CALL SvxStyleToolBoxControl::initialize( const Sequence< Any >& aArguments )
2977 SfxToolBoxControl::initialize( aArguments );
2979 // After initialize we should have a valid frame member where we can retrieve our
2980 // dispatch provider.
2981 if ( m_xFrame.is() )
2983 pImpl->InitializeStyles(m_xFrame->getController()->getModel());
2984 Reference< XDispatchProvider > xDispatchProvider( m_xFrame->getController(), UNO_QUERY );
2985 for ( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
2987 pBoundItems[i] = new SfxStyleControllerItem_Impl( xDispatchProvider,
2988 SID_STYLE_FAMILY_START + i,
2989 OUString::createFromAscii( StyleSlotToStyleCommand[i] ),
2990 *this );
2991 m_xBoundItems[i].set( static_cast< OWeakObject* >( pBoundItems[i] ), UNO_QUERY );
2992 pFamilyState[i] = nullptr;
2997 // XComponent
2998 void SAL_CALL SvxStyleToolBoxControl::dispose()
3000 SfxToolBoxControl::dispose();
3002 for( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
3004 if ( m_xBoundItems[i].is() )
3008 m_xBoundItems[i]->dispose();
3010 catch ( Exception& )
3014 m_xBoundItems[i].clear();
3015 pBoundItems[i] = nullptr;
3017 pFamilyState[i].reset();
3019 pStyleSheetPool = nullptr;
3020 pImpl.reset();
3023 void SAL_CALL SvxStyleToolBoxControl::update()
3025 // Do nothing, we will start binding our listener when we are visible.
3026 // See link SvxStyleToolBoxControl::VisibilityNotification.
3027 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
3028 if ( pBox->IsVisible() )
3030 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
3031 pBoundItem->ReBind();
3033 bindListener();
3037 SfxStyleFamily SvxStyleToolBoxControl::GetActFamily() const
3039 switch ( nActFamily-1 + SID_STYLE_FAMILY_START )
3041 case SID_STYLE_FAMILY1: return SfxStyleFamily::Char;
3042 case SID_STYLE_FAMILY2: return SfxStyleFamily::Para;
3043 case SID_STYLE_FAMILY3: return SfxStyleFamily::Frame;
3044 case SID_STYLE_FAMILY4: return SfxStyleFamily::Page;
3045 case SID_STYLE_FAMILY5: return SfxStyleFamily::Pseudo;
3046 default:
3047 OSL_FAIL( "unknown style family" );
3048 break;
3050 return SfxStyleFamily::Para;
3053 void SvxStyleToolBoxControl::FillStyleBox()
3055 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
3057 DBG_ASSERT( pStyleSheetPool, "StyleSheetPool not found!" );
3058 DBG_ASSERT( pBox, "Control not found!" );
3060 if ( pStyleSheetPool && pBox && nActFamily!=0xffff )
3062 const SfxStyleFamily eFamily = GetActFamily();
3063 sal_uInt16 nCount = pStyleSheetPool->Count();
3064 SfxStyleSheetBase* pStyle = nullptr;
3065 bool bDoFill = false;
3067 pStyleSheetPool->SetSearchMask( eFamily, SfxStyleSearchBits::Used );
3069 // Check whether fill is necessary
3070 pStyle = pStyleSheetPool->First();
3071 //!!! TODO: This condition isn't right any longer, because we always show some default entries
3072 //!!! so the list doesn't show the count
3073 if ( nCount != pBox->GetEntryCount() )
3075 bDoFill = true;
3077 else
3079 sal_uInt16 i= 0;
3080 while ( pStyle && !bDoFill )
3082 bDoFill = ( pBox->GetEntry(i) != pStyle->GetName() );
3083 pStyle = pStyleSheetPool->Next();
3084 i++;
3088 if ( bDoFill )
3090 pBox->SetUpdateMode( false );
3091 pBox->Clear();
3094 pStyle = pStyleSheetPool->Next();
3096 if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
3098 while ( pStyle )
3100 // sort out default styles
3101 bool bInsert = true;
3102 OUString aName( pStyle->GetName() );
3103 for( auto const & _i: pImpl->aDefaultStyles )
3105 if( _i.first == aName || _i.second == aName )
3107 bInsert = false;
3108 break;
3112 if( bInsert )
3113 pBox->InsertEntry( aName );
3114 pStyle = pStyleSheetPool->Next();
3117 else
3119 while ( pStyle )
3121 pBox->InsertEntry( pStyle->GetName() );
3122 pStyle = pStyleSheetPool->Next();
3127 if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
3129 // disable sort to preserve special order
3130 WinBits nWinBits = pBox->GetStyle();
3131 nWinBits &= ~WB_SORT;
3132 pBox->SetStyle( nWinBits );
3134 // insert default styles
3135 sal_uInt16 nPos = 1;
3136 for( auto const & _i: pImpl->aDefaultStyles )
3138 pBox->InsertEntry( _i.second, nPos );
3139 ++nPos;
3142 pBox->InsertEntry( pImpl->aClearForm, 0 );
3143 pBox->SetSeparatorPos( 0 );
3145 if (!comphelper::LibreOfficeKit::isActive())
3146 pBox->InsertEntry( pImpl->aMore );
3148 // enable sort again
3149 nWinBits |= WB_SORT;
3150 pBox->SetStyle( nWinBits );
3153 pBox->SetUpdateMode( true );
3154 pBox->SetFamily( eFamily );
3156 sal_uInt16 nLines = static_cast<sal_uInt16>(
3157 std::min( pBox->GetEntryCount(), static_cast<sal_Int32>(MAX_STYLES_ENTRIES)));
3158 pBox->SetDropDownLineCount( nLines );
3163 void SvxStyleToolBoxControl::SelectStyle( const OUString& rStyleName )
3165 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
3166 DBG_ASSERT( pBox, "Control not found!" );
3168 if ( pBox )
3170 OUString aStrSel( pBox->GetText() );
3172 if ( !rStyleName.isEmpty() )
3174 OUString aNewStyle = rStyleName;
3176 auto aFound = std::find_if(pImpl->aDefaultStyles.begin(), pImpl->aDefaultStyles.end(),
3177 [rStyleName] (auto it) { return it.first == rStyleName || it.second == rStyleName; }
3180 if (aFound != pImpl->aDefaultStyles.end())
3181 aNewStyle = aFound->second;
3183 if ( aNewStyle != aStrSel )
3184 pBox->SetText( aNewStyle );
3186 else
3187 pBox->SetNoSelection();
3188 pBox->SaveValue();
3192 void SvxStyleToolBoxControl::Update()
3194 SfxStyleSheetBasePool* pPool = nullptr;
3195 SfxObjectShell* pDocShell = SfxObjectShell::Current();
3197 if ( pDocShell )
3198 pPool = pDocShell->GetStyleSheetPool();
3200 sal_uInt16 i;
3201 for ( i=0; i<MAX_FAMILIES; i++ )
3202 if( pFamilyState[i] )
3203 break;
3205 if ( i==MAX_FAMILIES || !pPool )
3207 pStyleSheetPool = pPool;
3208 return;
3212 const SfxTemplateItem* pItem = nullptr;
3214 if ( nActFamily == 0xffff || nullptr == (pItem = pFamilyState[nActFamily-1].get()) )
3215 // Current range not within allowed ranges or default
3217 pStyleSheetPool = pPool;
3218 nActFamily = 2;
3220 pItem = pFamilyState[nActFamily-1].get();
3221 if ( !pItem )
3223 nActFamily++;
3224 pItem = pFamilyState[nActFamily-1].get();
3227 if ( !pItem )
3229 SAL_INFO( "svx", "Unknown Family" ); // can happen
3232 else if ( pPool != pStyleSheetPool )
3233 pStyleSheetPool = pPool;
3235 FillStyleBox(); // Decides by itself whether Fill is needed
3237 if ( pItem )
3238 SelectStyle( pItem->GetStyleName() );
3241 void SvxStyleToolBoxControl::SetFamilyState( sal_uInt16 nIdx,
3242 const SfxTemplateItem* pItem )
3244 pFamilyState[nIdx].reset( pItem == nullptr ? nullptr : new SfxTemplateItem( *pItem ) );
3245 Update();
3248 IMPL_LINK_NOARG(SvxStyleToolBoxControl, VisibilityNotification, SvxStyleBox_Impl&, void)
3250 // Call ReBind() && UnBind() according to visibility
3251 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>( GetToolBox().GetItemWindow( GetId() ));
3253 if ( pBox && pBox->IsVisible() && !isBound() )
3255 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
3256 pBoundItem->ReBind();
3258 bindListener();
3260 else if ( (!pBox || !pBox->IsVisible()) && isBound() )
3262 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
3263 pBoundItem->UnBind();
3264 unbindListener();
3268 void SvxStyleToolBoxControl::StateChanged(
3269 sal_uInt16 , SfxItemState eState, const SfxPoolItem* pState )
3271 sal_uInt16 nId = GetId();
3272 ToolBox& rTbx = GetToolBox();
3273 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(rTbx.GetItemWindow( nId ));
3274 TriState eTri = TRISTATE_FALSE;
3276 DBG_ASSERT( pBox, "Control not found!" );
3278 if ( SfxItemState::DISABLED == eState )
3279 pBox->Disable();
3280 else
3281 pBox->Enable();
3283 rTbx.EnableItem( nId, SfxItemState::DISABLED != eState );
3285 switch ( eState )
3287 case SfxItemState::DEFAULT:
3288 eTri = static_cast<const SfxTemplateItem*>(pState)->GetValue() != SfxStyleSearchBits::Auto
3289 ? TRISTATE_TRUE
3290 : TRISTATE_FALSE;
3291 break;
3293 case SfxItemState::DONTCARE:
3294 eTri = TRISTATE_INDET;
3295 break;
3297 default:
3298 break;
3301 rTbx.SetItemState( nId, eTri );
3303 if ( SfxItemState::DISABLED != eState )
3304 Update();
3307 VclPtr<vcl::Window> SvxStyleToolBoxControl::CreateItemWindow( vcl::Window *pParent )
3309 VclPtrInstance<SvxStyleBox_Impl> pBox( pParent,
3310 OUString( ".uno:StyleApply" ),
3311 SfxStyleFamily::Para,
3312 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
3313 m_xFrame,
3314 pImpl->aClearForm,
3315 pImpl->aMore,
3316 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc );
3317 if( !pImpl->aDefaultStyles.empty())
3318 pBox->SetDefaultStyle( pImpl->aDefaultStyles[0].second );
3319 // Set visibility listener to bind/unbind controller
3320 pBox->SetVisibilityListener( LINK( this, SvxStyleToolBoxControl, VisibilityNotification ));
3322 return pBox.get();
3325 class SvxFontNameToolBoxControl : public cppu::ImplInheritanceHelper< svt::ToolboxController,
3326 css::lang::XServiceInfo >
3328 public:
3329 SvxFontNameToolBoxControl();
3331 // XStatusListener
3332 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
3334 // XToolbarController
3335 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent ) override;
3337 // XComponent
3338 virtual void SAL_CALL dispose() override;
3340 // XServiceInfo
3341 virtual OUString SAL_CALL getImplementationName() override;
3342 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
3343 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
3345 private:
3346 VclPtr<SvxFontNameBox_Impl> m_pBox;
3349 SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
3353 void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3355 SolarMutexGuard aGuard;
3356 ToolBox* pToolBox = nullptr;
3357 sal_uInt16 nId = 0;
3358 if ( !getToolboxId( nId, &pToolBox ) )
3359 return;
3361 if ( !rEvent.IsEnabled )
3363 m_pBox->Disable();
3364 m_pBox->Update( nullptr );
3366 else
3368 m_pBox->Enable();
3370 css::awt::FontDescriptor aFontDesc;
3371 if ( rEvent.State >>= aFontDesc )
3372 m_pBox->Update( &aFontDesc );
3373 else
3374 m_pBox->SetText( "" );
3375 m_pBox->SaveValue();
3378 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3381 css::uno::Reference< css::awt::XWindow > SvxFontNameToolBoxControl::createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent )
3383 SolarMutexGuard aGuard;
3384 m_pBox = VclPtr<SvxFontNameBox_Impl>::Create( VCLUnoHelper::GetWindow( rParent ),
3385 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
3386 m_xFrame, 0);
3387 return VCLUnoHelper::GetInterface( m_pBox );
3390 void SvxFontNameToolBoxControl::dispose()
3392 m_pBox.disposeAndClear();
3393 ToolboxController::dispose();
3396 OUString SvxFontNameToolBoxControl::getImplementationName()
3398 return "com.sun.star.comp.svx.FontNameToolBoxControl";
3401 sal_Bool SvxFontNameToolBoxControl::supportsService( const OUString& rServiceName )
3403 return cppu::supportsService( this, rServiceName );
3406 css::uno::Sequence< OUString > SvxFontNameToolBoxControl::getSupportedServiceNames()
3408 return { "com.sun.star.frame.ToolbarController" };
3411 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3412 com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation(
3413 css::uno::XComponentContext*,
3414 css::uno::Sequence<css::uno::Any> const & )
3416 return cppu::acquire( new SvxFontNameToolBoxControl() );
3419 SvxColorToolBoxControl::SvxColorToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3420 ImplInheritanceHelper( rContext, nullptr, OUString() ),
3421 m_bSplitButton(true),
3422 m_nSlotId(0),
3423 m_aColorSelectFunction(PaletteManager::DispatchColorCommand)
3427 namespace {
3429 sal_uInt16 MapCommandToSlotId(const OUString& rCommand)
3431 if (rCommand == ".uno:Color")
3432 return SID_ATTR_CHAR_COLOR;
3433 else if (rCommand == ".uno:FontColor")
3434 return SID_ATTR_CHAR_COLOR2;
3435 else if (rCommand == ".uno:BackColor")
3436 return SID_ATTR_CHAR_COLOR_BACKGROUND;
3437 else if (rCommand == ".uno:CharBackColor")
3438 return SID_ATTR_CHAR_BACK_COLOR;
3439 else if (rCommand == ".uno:BackgroundColor")
3440 return SID_BACKGROUND_COLOR;
3441 else if (rCommand == ".uno:TableCellBackgroundColor")
3442 return SID_TABLE_CELL_BACKGROUND_COLOR;
3443 else if (rCommand == ".uno:Extrusion3DColor")
3444 return SID_EXTRUSION_3D_COLOR;
3445 else if (rCommand == ".uno:XLineColor")
3446 return SID_ATTR_LINE_COLOR;
3447 else if (rCommand == ".uno:FillColor")
3448 return SID_ATTR_FILL_COLOR;
3449 else if (rCommand == ".uno:FrameLineColor")
3450 return SID_FRAME_LINECOLOR;
3452 SAL_WARN("svx.tbxcrtls", "Unknown color command: " << rCommand);
3453 return 0;
3458 void SvxColorToolBoxControl::initialize( const css::uno::Sequence<css::uno::Any>& rArguments )
3460 PopupWindowController::initialize( rArguments );
3462 ToolBox* pToolBox = nullptr;
3463 sal_uInt16 nId = 0;
3464 if ( !getToolboxId( nId, &pToolBox ) )
3466 SAL_WARN("svx.tbxcrtls", "ToolBox not found!");
3467 return;
3470 m_nSlotId = MapCommandToSlotId( m_aCommandURL );
3471 if ( m_nSlotId == SID_ATTR_LINE_COLOR || m_nSlotId == SID_ATTR_FILL_COLOR ||
3472 m_nSlotId == SID_FRAME_LINECOLOR || m_nSlotId == SID_BACKGROUND_COLOR )
3473 // Sidebar uses wide buttons for those.
3474 m_bSplitButton = typeid( *pToolBox ) != typeid( sfx2::sidebar::SidebarToolBox );
3476 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(getCommandURL(), getModuleName());
3477 OUString aCommandLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
3479 m_xBtnUpdater.reset( new svx::ToolboxButtonColorUpdater( m_nSlotId, nId, pToolBox, !m_bSplitButton, aCommandLabel ) );
3480 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
3483 void SvxColorToolBoxControl::update()
3485 PopupWindowController::update();
3487 switch( m_nSlotId )
3489 case SID_ATTR_CHAR_COLOR2:
3490 addStatusListener( ".uno:CharColorExt");
3491 break;
3493 case SID_ATTR_CHAR_COLOR_BACKGROUND:
3494 addStatusListener( ".uno:CharBackgroundExt");
3495 break;
3497 case SID_FRAME_LINECOLOR:
3498 addStatusListener( ".uno:BorderTLBR");
3499 addStatusListener( ".uno:BorderBLTR");
3500 break;
3504 void SvxColorToolBoxControl::EnsurePaletteManager()
3506 if (!m_xPaletteManager)
3508 m_xPaletteManager.reset(new PaletteManager);
3509 m_xPaletteManager->SetBtnUpdater(m_xBtnUpdater.get());
3513 SvxColorToolBoxControl::~SvxColorToolBoxControl()
3515 if (m_xPaletteManager)
3516 m_xPaletteManager->SetBtnUpdater(nullptr);
3519 void SvxColorToolBoxControl::setColorSelectFunction(const ColorSelectFunction& aColorSelectFunction)
3521 m_aColorSelectFunction = aColorSelectFunction;
3522 if (m_xPaletteManager)
3523 m_xPaletteManager->SetColorSelectFunction(aColorSelectFunction);
3526 VclPtr<vcl::Window> SvxColorToolBoxControl::createPopupWindow( vcl::Window* pParent )
3528 EnsurePaletteManager();
3530 VclPtrInstance<SvxColorWindow> pColorWin(
3531 m_aCommandURL,
3532 m_xPaletteManager,
3533 m_aColorStatus,
3534 m_nSlotId,
3535 m_xFrame,
3536 pParent,
3537 false,
3538 m_aColorSelectFunction);
3540 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(m_aCommandURL, m_sModuleName);
3541 OUString aWindowTitle = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
3542 pColorWin->SetText( aWindowTitle );
3543 pColorWin->StartSelection();
3544 if ( m_bSplitButton )
3545 pColorWin->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) );
3546 return pColorWin;
3549 IMPL_LINK(SvxColorToolBoxControl, SelectedHdl, const NamedColor&, rColor, void)
3551 m_xBtnUpdater->Update(rColor);
3554 void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3556 ToolBox* pToolBox = nullptr;
3557 sal_uInt16 nId = 0;
3558 if ( !getToolboxId( nId, &pToolBox ) )
3559 return;
3561 if ( rEvent.FeatureURL.Complete == m_aCommandURL )
3562 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3564 bool bValue;
3565 if ( !m_bSplitButton )
3567 m_aColorStatus.statusChanged( rEvent );
3568 m_xBtnUpdater->Update( m_aColorStatus.GetColor() );
3570 else if ( rEvent.State >>= bValue )
3571 pToolBox->CheckItem( nId, bValue );
3574 void SvxColorToolBoxControl::execute(sal_Int16 /*nSelectModifier*/)
3576 if ( !m_bSplitButton )
3578 // Open the popup also when Enter key is pressed.
3579 createPopupWindow();
3580 return;
3583 OUString aCommand = m_aCommandURL;
3584 Color aColor = m_xBtnUpdater->GetCurrentColor();
3586 switch( m_nSlotId )
3588 case SID_ATTR_CHAR_COLOR2 :
3589 aCommand = ".uno:CharColorExt";
3590 break;
3592 case SID_ATTR_CHAR_COLOR_BACKGROUND :
3593 aCommand = ".uno:CharBackgroundExt";
3594 break;
3597 auto aArgs( comphelper::InitPropertySequence( {
3598 { m_aCommandURL.copy(5), css::uno::makeAny(aColor) }
3599 } ) );
3600 dispatchCommand( aCommand, aArgs );
3602 EnsurePaletteManager();
3603 OUString sColorName = m_xBtnUpdater->GetCurrentColorName();
3604 m_xPaletteManager->AddRecentColor(aColor, sColorName);
3607 sal_Bool SvxColorToolBoxControl::opensSubToolbar()
3609 // For a split button, we mark this controller as a sub-toolbar controller,
3610 // so we get notified (through updateImage method) on button image changes,
3611 // and could redraw the last used color on top of it.
3612 return m_bSplitButton;
3615 void SvxColorToolBoxControl::updateImage()
3617 ToolBox* pToolBox = nullptr;
3618 sal_uInt16 nId = 0;
3619 if ( !getToolboxId( nId, &pToolBox ) )
3620 return;
3622 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(m_aCommandURL, m_xFrame, pToolBox->GetImageSize());
3623 if ( !!aImage )
3625 pToolBox->SetItemImage( nId, aImage );
3626 m_xBtnUpdater->Update(m_xBtnUpdater->GetCurrentColor(), true);
3630 OUString SvxColorToolBoxControl::getSubToolbarName()
3632 return OUString();
3635 void SvxColorToolBoxControl::functionSelected( const OUString& /*rCommand*/ )
3639 OUString SvxColorToolBoxControl::getImplementationName()
3641 return "com.sun.star.comp.svx.ColorToolBoxControl";
3644 css::uno::Sequence<OUString> SvxColorToolBoxControl::getSupportedServiceNames()
3646 return { "com.sun.star.frame.ToolbarController" };
3649 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3650 com_sun_star_comp_svx_ColorToolBoxControl_get_implementation(
3651 css::uno::XComponentContext* rContext,
3652 css::uno::Sequence<css::uno::Any> const & )
3654 return cppu::acquire( new SvxColorToolBoxControl( rContext ) );
3657 // class SvxFrameToolBoxControl --------------------------------------------
3659 class SvxFrameToolBoxControl : public svt::PopupWindowController
3661 public:
3662 explicit SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext );
3664 // XInitialization
3665 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) override;
3667 // XServiceInfo
3668 virtual OUString SAL_CALL getImplementationName() override;
3669 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
3671 private:
3672 virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override;
3673 using svt::ToolboxController::createPopupWindow;
3676 SvxFrameToolBoxControl::SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext )
3677 : svt::PopupWindowController( rContext, nullptr, OUString() )
3681 void SvxFrameToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3683 svt::PopupWindowController::initialize( rArguments );
3684 ToolBox* pToolBox = nullptr;
3685 sal_uInt16 nId = 0;
3686 if ( getToolboxId( nId, &pToolBox ) )
3687 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
3690 VclPtr<vcl::Window> SvxFrameToolBoxControl::createPopupWindow( vcl::Window* pParent )
3692 if ( m_aCommandURL == ".uno:LineStyle" )
3693 return VclPtr<SvxLineWindow_Impl>::Create( *this, pParent );
3695 return VclPtr<SvxFrameWindow_Impl>::Create( *this, pParent );
3698 OUString SvxFrameToolBoxControl::getImplementationName()
3700 return "com.sun.star.comp.svx.FrameToolBoxControl";
3703 css::uno::Sequence< OUString > SvxFrameToolBoxControl::getSupportedServiceNames()
3705 return { "com.sun.star.frame.ToolbarController" };
3708 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3709 com_sun_star_comp_svx_FrameToolBoxControl_get_implementation(
3710 css::uno::XComponentContext* rContext,
3711 css::uno::Sequence<css::uno::Any> const & )
3713 return cppu::acquire( new SvxFrameToolBoxControl( rContext ) );
3716 SvxSimpleUndoRedoController::SvxSimpleUndoRedoController( sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
3717 :SfxToolBoxControl( nSlotId, nId, rTbx )
3719 aDefaultText = rTbx.GetItemText( nId );
3722 SvxSimpleUndoRedoController::~SvxSimpleUndoRedoController()
3726 void SvxSimpleUndoRedoController::StateChanged( sal_uInt16, SfxItemState eState, const SfxPoolItem* pState )
3728 const SfxStringItem* pItem = dynamic_cast<const SfxStringItem*>( pState );
3729 ToolBox& rBox = GetToolBox();
3730 if ( pItem && eState != SfxItemState::DISABLED )
3732 OUString aNewText( MnemonicGenerator::EraseAllMnemonicChars( pItem->GetValue() ) );
3733 rBox.SetQuickHelpText( GetId(), aNewText );
3735 if ( eState == SfxItemState::DISABLED )
3736 rBox.SetQuickHelpText( GetId(), aDefaultText );
3737 rBox.EnableItem( GetId(), eState != SfxItemState::DISABLED );
3740 SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3741 PopupWindowController( rContext, nullptr, OUString() ),
3742 m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
3743 m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND )
3747 SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}
3749 void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3751 PopupWindowController::initialize(rArguments);
3753 ToolBox* pToolBox = nullptr;
3754 sal_uInt16 nId = 0;
3755 if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL)
3756 pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId));
3759 VclPtr<vcl::Window> SvxCurrencyToolBoxControl::createPopupWindow( vcl::Window* pParent )
3761 return VclPtr<SvxCurrencyList_Impl>::Create(this, pParent, m_aFormatString, m_eLanguage);
3764 void SvxCurrencyToolBoxControl::execute( sal_Int16 nSelectModifier )
3766 sal_uInt32 nFormatKey;
3767 if (m_aFormatString.isEmpty())
3768 nFormatKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
3769 else
3771 if ( nSelectModifier > 0 )
3775 uno::Reference< util::XNumberFormatsSupplier > xRef( m_xFrame->getController()->getModel(), uno::UNO_QUERY );
3776 uno::Reference< util::XNumberFormats > rxNumberFormats( xRef->getNumberFormats(), uno::UNO_SET_THROW );
3777 css::lang::Locale aLocale = LanguageTag::convertToLocale( m_eLanguage );
3778 nFormatKey = rxNumberFormats->queryKey( m_aFormatString, aLocale, false );
3779 if ( nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND )
3780 nFormatKey = rxNumberFormats->addNew( m_aFormatString, aLocale );
3782 catch( const uno::Exception& )
3784 nFormatKey = m_nFormatKey;
3787 else
3788 nFormatKey = m_nFormatKey;
3791 if( nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
3793 Sequence< PropertyValue > aArgs( 1 );
3794 aArgs[0].Name = "NumberFormatCurrency";
3795 aArgs[0].Value <<= nFormatKey;
3796 dispatchCommand( m_aCommandURL, aArgs );
3797 m_nFormatKey = nFormatKey;
3799 else
3800 PopupWindowController::execute( nSelectModifier );
3803 OUString SvxCurrencyToolBoxControl::getImplementationName()
3805 return "com.sun.star.comp.svx.CurrencyToolBoxControl";
3808 css::uno::Sequence<OUString> SvxCurrencyToolBoxControl::getSupportedServiceNames()
3810 return { "com.sun.star.frame.ToolbarController" };
3813 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3814 com_sun_star_comp_svx_CurrencyToolBoxControl_get_implementation(
3815 css::uno::XComponentContext* rContext,
3816 css::uno::Sequence<css::uno::Any> const & )
3818 return cppu::acquire( new SvxCurrencyToolBoxControl( rContext ) );
3821 Reference< css::accessibility::XAccessible > SvxFontNameBox_Impl::CreateAccessible()
3823 FillList();
3824 return FontNameBox::CreateAccessible();
3827 //static
3828 void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
3829 std::vector<sal_uInt16>& rCurrencyList )
3831 rCurrencyList.clear();
3833 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
3834 sal_uInt16 nCount = rCurrencyTable.size();
3836 sal_uInt16 nStart = 1;
3838 OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) + " " );
3839 aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3840 rCurrencyTable[0].GetLanguage() ) );
3842 rList.push_back( aString );
3843 rCurrencyList.push_back( sal_uInt16(-1) ); // nAuto
3845 if( bFlag )
3847 rList.push_back( aString );
3848 rCurrencyList.push_back( 0 );
3849 ++nStart;
3852 CollatorWrapper aCollator( ::comphelper::getProcessComponentContext() );
3853 aCollator.loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
3855 const OUString aTwoSpace(" ");
3857 for( sal_uInt16 i = 1; i < nCount; ++i )
3859 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3860 aStr += aTwoSpace;
3861 aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
3862 aStr += aTwoSpace;
3863 aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3864 rCurrencyTable[i].GetLanguage() ) );
3866 std::vector<OUString>::size_type j = nStart;
3867 for( ; j < rList.size(); ++j )
3868 if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3869 break; // insert before first greater than
3871 rList.insert( rList.begin() + j, aStr );
3872 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3875 // Append ISO codes to symbol list.
3876 // XXX If this is to be changed, various other places would had to be
3877 // adapted that assume this order!
3878 std::vector<OUString>::size_type nCont = rList.size();
3880 for ( sal_uInt16 i = 1; i < nCount; ++i )
3882 bool bInsert = true;
3883 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3885 std::vector<OUString>::size_type j = nCont;
3886 for ( ; j < rList.size() && bInsert; ++j )
3888 if( rList[j] == aStr )
3889 bInsert = false;
3890 else if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3891 break; // insert before first greater than
3893 if ( bInsert )
3895 rList.insert( rList.begin() + j, aStr );
3896 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3901 SvxListBoxColorWrapper::SvxListBoxColorWrapper(SvxColorListBox* pControl)
3902 : mxControl(pControl)
3906 void SvxListBoxColorWrapper::operator()(const OUString& /*rCommand*/, const NamedColor& rColor)
3908 if (!mxControl)
3909 return;
3910 mxControl->Selected(rColor);
3913 void SvxListBoxColorWrapper::dispose()
3915 mxControl.clear();
3918 ListBoxColorWrapper::ListBoxColorWrapper(ColorListBox* pControl)
3919 : mpControl(pControl)
3923 void ListBoxColorWrapper::operator()(const OUString& /*rCommand*/, const NamedColor& rColor)
3925 mpControl->Selected(rColor);
3928 SvxColorListBox::SvxColorListBox(vcl::Window* pParent, WinBits nStyle)
3929 : MenuButton(pParent, nStyle)
3930 , m_aColorWrapper(this)
3931 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
3932 , m_nSlotId(0)
3933 , m_bShowNoneButton(false)
3935 m_aSelectedColor = GetAutoColor(m_nSlotId);
3936 LockWidthRequest();
3937 ShowPreview(m_aSelectedColor);
3938 SetActivateHdl(LINK(this, SvxColorListBox, MenuActivateHdl));
3941 void SvxColorListBox::EnsurePaletteManager()
3943 if (!m_xPaletteManager)
3945 m_xPaletteManager.reset(new PaletteManager);
3946 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
3950 void ColorListBox::EnsurePaletteManager()
3952 if (!m_xPaletteManager)
3954 m_xPaletteManager.reset(new PaletteManager);
3955 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
3959 void SvxColorListBox::SetSlotId(sal_uInt16 nSlotId)
3961 m_nSlotId = nSlotId;
3962 m_bShowNoneButton = false;
3963 m_xColorWindow.disposeAndClear();
3964 m_aSelectedColor = GetAutoColor(m_nSlotId);
3965 ShowPreview(m_aSelectedColor);
3966 createColorWindow();
3969 void ColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
3971 m_nSlotId = nSlotId;
3972 m_bShowNoneButton = bShowNoneButton;
3973 m_xButton->set_popover(nullptr);
3974 m_xColorWindow.reset();
3975 m_aSelectedColor = bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId);
3976 ShowPreview(m_aSelectedColor);
3977 createColorWindow();
3980 //to avoid the box resizing every time the color is changed to
3981 //the optimal size of the individual color, get the longest
3982 //standard color and stick with that as the size for all
3983 void SvxColorListBox::LockWidthRequest()
3985 if (get_width_request() != -1)
3986 return;
3987 NamedColor aLongestColor;
3988 long nMaxStandardColorTextWidth = 0;
3989 XColorListRef const xColorTable = XColorList::CreateStdColorList();
3990 for (long i = 0; i != xColorTable->Count(); ++i)
3992 XColorEntry& rEntry = *xColorTable->GetColor(i);
3993 long nColorTextWidth = GetTextWidth(rEntry.GetName());
3994 if (nColorTextWidth > nMaxStandardColorTextWidth)
3996 nMaxStandardColorTextWidth = nColorTextWidth;
3997 aLongestColor.second = rEntry.GetName();
4000 ShowPreview(aLongestColor);
4001 set_width_request(get_preferred_size().Width());
4004 void SvxColorListBox::ShowPreview(const NamedColor &rColor)
4006 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
4007 Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
4009 ScopedVclPtrInstance<VirtualDevice> xDevice;
4010 xDevice->SetOutputSize(aImageSize);
4011 const tools::Rectangle aRect(Point(0, 0), aImageSize);
4012 if (m_bShowNoneButton && rColor.first == COL_NONE_COLOR)
4014 const Color aW(COL_WHITE);
4015 const Color aG(0xef, 0xef, 0xef);
4016 xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 8, aW, aG);
4017 xDevice->SetFillColor();
4019 else
4021 if (rColor.first == COL_AUTO)
4022 xDevice->SetFillColor(m_aAutoDisplayColor);
4023 else
4024 xDevice->SetFillColor(rColor.first);
4027 xDevice->SetLineColor(rStyleSettings.GetDisableColor());
4028 xDevice->DrawRect(aRect);
4030 BitmapEx aBitmap(xDevice->GetBitmapEx(Point(0, 0), xDevice->GetOutputSize()));
4031 SetImageAlign(ImageAlign::Left);
4032 SetModeImage(Image(aBitmap));
4033 SetText(rColor.second);
4036 IMPL_LINK(SvxColorListBox, WindowEventListener, VclWindowEvent&, rWindowEvent, void)
4038 if (rWindowEvent.GetId() == VclEventId::WindowEndPopupMode)
4040 m_xColorWindow.disposeAndClear();
4041 SetPopover(nullptr);
4045 IMPL_LINK_NOARG(SvxColorListBox, MenuActivateHdl, MenuButton *, void)
4047 if (!m_xColorWindow || m_xColorWindow->isDisposed())
4048 createColorWindow();
4051 void SvxColorListBox::createColorWindow()
4053 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
4054 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
4055 css::uno::Reference<css::frame::XFrame> xFrame(pFrame ? pFrame->GetFrameInterface() : uno::Reference<css::frame::XFrame>());
4057 EnsurePaletteManager();
4059 m_xColorWindow = VclPtr<SvxColorWindow>::Create(
4060 OUString() /*m_aCommandURL*/,
4061 m_xPaletteManager,
4062 m_aColorStatus,
4063 m_nSlotId,
4064 xFrame,
4065 this,
4066 true,
4067 m_aColorWrapper);
4069 m_xColorWindow->AddEventListener(LINK(this, SvxColorListBox, WindowEventListener));
4071 SetNoSelection();
4072 if (m_bShowNoneButton)
4073 m_xColorWindow->ShowNoneButton();
4074 m_xColorWindow->SelectEntry(m_aSelectedColor);
4075 SetPopover(m_xColorWindow);
4078 void SvxColorListBox::Selected(const NamedColor& rColor)
4080 ShowPreview(rColor);
4081 m_aSelectedColor = rColor;
4082 if (m_aSelectedLink.IsSet())
4083 m_aSelectedLink.Call(*this);
4086 VCL_BUILDER_FACTORY(SvxColorListBox)
4088 SvxColorListBox::~SvxColorListBox()
4090 disposeOnce();
4093 void SvxColorListBox::dispose()
4095 m_xColorWindow.disposeAndClear();
4096 m_aColorWrapper.dispose();
4097 MenuButton::dispose();
4100 VclPtr<SvxColorWindow> const & SvxColorListBox::getColorWindow() const
4102 if (!m_xColorWindow || m_xColorWindow->isDisposed())
4103 const_cast<SvxColorListBox*>(this)->createColorWindow();
4104 return m_xColorWindow;
4107 void SvxColorListBox::SelectEntry(const NamedColor& rColor)
4109 if (rColor.second.trim().isEmpty())
4111 SelectEntry(rColor.first);
4112 return;
4114 VclPtr<SvxColorWindow> xColorWindow = getColorWindow();
4115 xColorWindow->SelectEntry(rColor);
4116 m_aSelectedColor = xColorWindow->GetSelectEntryColor();
4117 ShowPreview(m_aSelectedColor);
4120 void SvxColorListBox::SelectEntry(const Color& rColor)
4122 VclPtr<SvxColorWindow> xColorWindow = getColorWindow();
4123 xColorWindow->SelectEntry(rColor);
4124 m_aSelectedColor = xColorWindow->GetSelectEntryColor();
4125 ShowPreview(m_aSelectedColor);
4128 boost::property_tree::ptree SvxColorListBox::DumpAsPropertyTree()
4130 boost::property_tree::ptree aTree = MenuButton::DumpAsPropertyTree();
4131 aTree.put("type", "colorlistbox");
4132 return aTree;
4135 ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl, weld::Window* pTopLevel)
4136 : m_xButton(std::move(pControl))
4137 , m_pTopLevel(pTopLevel)
4138 , m_aColorWrapper(this)
4139 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
4140 , m_nSlotId(0)
4141 , m_bShowNoneButton(false)
4143 m_xButton->connect_toggled(LINK(this, ColorListBox, ToggleHdl));
4144 m_aSelectedColor = GetAutoColor(m_nSlotId);
4145 LockWidthRequest();
4146 ShowPreview(m_aSelectedColor);
4149 IMPL_LINK(ColorListBox, ToggleHdl, weld::ToggleButton&, rButton, void)
4151 if (rButton.get_active())
4152 getColorWindow()->FocusHdl(*m_xButton);
4155 ColorListBox::~ColorListBox()
4159 ColorWindow* ColorListBox::getColorWindow() const
4161 if (!m_xColorWindow)
4162 const_cast<ColorListBox*>(this)->createColorWindow();
4163 return m_xColorWindow.get();
4166 void ColorListBox::createColorWindow()
4168 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
4169 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
4170 css::uno::Reference<css::frame::XFrame> xFrame(pFrame ? pFrame->GetFrameInterface() : uno::Reference<css::frame::XFrame>());
4172 EnsurePaletteManager();
4174 m_xColorWindow.reset(new ColorWindow(
4175 m_xPaletteManager,
4176 m_aColorStatus,
4177 m_nSlotId,
4178 xFrame,
4179 m_pTopLevel,
4180 m_xButton.get(),
4181 m_aColorWrapper));
4183 SetNoSelection();
4184 m_xButton->set_popover(m_xColorWindow->GetWidget());
4185 if (m_bShowNoneButton)
4186 m_xColorWindow->ShowNoneButton();
4187 m_xColorWindow->SelectEntry(m_aSelectedColor);
4190 void ColorListBox::SelectEntry(const NamedColor& rColor)
4192 if (rColor.second.trim().isEmpty())
4194 SelectEntry(rColor.first);
4195 return;
4197 ColorWindow* pColorWindow = getColorWindow();
4198 pColorWindow->SelectEntry(rColor);
4199 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
4200 ShowPreview(m_aSelectedColor);
4203 void ColorListBox::SelectEntry(const Color& rColor)
4205 ColorWindow* pColorWindow = getColorWindow();
4206 pColorWindow->SelectEntry(rColor);
4207 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
4208 ShowPreview(m_aSelectedColor);
4211 void ColorListBox::Selected(const NamedColor& rColor)
4213 ShowPreview(rColor);
4214 m_aSelectedColor = rColor;
4215 if (m_aSelectedLink.IsSet())
4216 m_aSelectedLink.Call(*this);
4219 //to avoid the box resizing every time the color is changed to
4220 //the optimal size of the individual color, get the longest
4221 //standard color and stick with that as the size for all
4222 void ColorListBox::LockWidthRequest()
4224 NamedColor aLongestColor;
4225 long nMaxStandardColorTextWidth = 0;
4226 XColorListRef const xColorTable = XColorList::CreateStdColorList();
4227 for (long i = 0; i != xColorTable->Count(); ++i)
4229 XColorEntry& rEntry = *xColorTable->GetColor(i);
4230 auto nColorTextWidth = m_xButton->get_pixel_size(rEntry.GetName()).Width();
4231 if (nColorTextWidth > nMaxStandardColorTextWidth)
4233 nMaxStandardColorTextWidth = nColorTextWidth;
4234 aLongestColor.second = rEntry.GetName();
4237 ShowPreview(aLongestColor);
4238 m_xButton->set_size_request(m_xButton->get_preferred_size().Width(), -1);
4241 void ColorListBox::ShowPreview(const NamedColor &rColor)
4243 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
4244 Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
4246 ScopedVclPtrInstance<VirtualDevice> xDevice;
4247 xDevice->SetOutputSize(aImageSize);
4248 const tools::Rectangle aRect(Point(0, 0), aImageSize);
4249 if (m_bShowNoneButton && rColor.first == COL_NONE_COLOR)
4251 const Color aW(COL_WHITE);
4252 const Color aG(0xef, 0xef, 0xef);
4253 xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 8, aW, aG);
4254 xDevice->SetFillColor();
4256 else
4258 if (rColor.first == COL_AUTO)
4259 xDevice->SetFillColor(m_aAutoDisplayColor);
4260 else
4261 xDevice->SetFillColor(rColor.first);
4264 xDevice->SetLineColor(rStyleSettings.GetDisableColor());
4265 xDevice->DrawRect(aRect);
4267 m_xButton->set_image(xDevice.get());
4268 m_xButton->set_label(rColor.second);
4271 MenuOrToolMenuButton::MenuOrToolMenuButton(weld::MenuButton* pMenuButton)
4272 : m_pMenuButton(pMenuButton)
4273 , m_pToolbar(nullptr)
4277 MenuOrToolMenuButton::MenuOrToolMenuButton(weld::Toolbar* pToolbar, const OString& rIdent)
4278 : m_pMenuButton(nullptr)
4279 , m_pToolbar(pToolbar)
4280 , m_aIdent(rIdent)
4284 bool MenuOrToolMenuButton::get_active() const
4286 if (m_pMenuButton)
4287 return m_pMenuButton->get_active();
4288 return m_pToolbar->get_item_active(m_aIdent);
4291 void MenuOrToolMenuButton::set_active(bool bActive) const
4293 if (m_pMenuButton)
4295 m_pMenuButton->set_active(bActive);
4296 return;
4298 m_pToolbar->set_item_active(m_aIdent, bActive);
4301 weld::Widget* MenuOrToolMenuButton::get_widget() const
4303 if (m_pMenuButton)
4304 return m_pMenuButton;
4305 return m_pToolbar;
4308 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */