Adjust includes
[LibreOffice.git] / svx / source / tbxctrls / tbcontrl.cxx
blobd28befe5296a77e36bc90b19392961a363696eb2
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/toolbox.hxx>
31 #include <vcl/bitmapaccess.hxx>
32 #include <vcl/menubtn.hxx>
33 #include <vcl/vclptr.hxx>
34 #include <svtools/valueset.hxx>
35 #include <svtools/ctrlbox.hxx>
36 #include <svl/style.hxx>
37 #include <svtools/ctrltool.hxx>
38 #include <svtools/borderhelper.hxx>
39 #include <svl/stritem.hxx>
40 #include <sfx2/tplpitem.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/viewsh.hxx>
43 #include <sfx2/docfac.hxx>
44 #include <sfx2/templdlg.hxx>
45 #include <svl/isethint.hxx>
46 #include <sfx2/sfxstatuslistener.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
48 #include <tools/urlobj.hxx>
49 #include <sfx2/childwin.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <unotools/fontoptions.hxx>
52 #include <vcl/builderfactory.hxx>
53 #include <vcl/mnemonic.hxx>
54 #include <vcl/svapp.hxx>
55 #include <vcl/settings.hxx>
56 #include <svtools/colorcfg.hxx>
57 #include <com/sun/star/table/BorderLine2.hpp>
58 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
59 #include <com/sun/star/lang/XServiceInfo.hpp>
60 #include <com/sun/star/beans/XPropertySet.hpp>
61 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
62 #include <svx/strings.hrc>
63 #include <svx/svxitems.hrc>
64 #include <svx/svxids.hrc>
65 #include <helpids.h>
66 #include <sfx2/htmlmode.hxx>
67 #include <sfx2/sidebar/Sidebar.hxx>
68 #include <sfx2/sidebar/SidebarToolBox.hxx>
69 #include <svx/xtable.hxx>
70 #include <editeng/editids.hrc>
71 #include <editeng/fontitem.hxx>
72 #include <editeng/fhgtitem.hxx>
73 #include <editeng/boxitem.hxx>
74 #include <editeng/charreliefitem.hxx>
75 #include <editeng/contouritem.hxx>
76 #include <editeng/colritem.hxx>
77 #include <editeng/crossedoutitem.hxx>
78 #include <editeng/emphasismarkitem.hxx>
79 #include <editeng/flstitem.hxx>
80 #include <editeng/lineitem.hxx>
81 #include <editeng/postitem.hxx>
82 #include <editeng/shdditem.hxx>
83 #include <editeng/udlnitem.hxx>
84 #include <editeng/wghtitem.hxx>
85 #include <editeng/svxfont.hxx>
86 #include <editeng/cmapitem.hxx>
87 #include <svx/colorwindow.hxx>
88 #include <svx/colorbox.hxx>
89 #include <svx/drawitem.hxx>
90 #include <svx/tbcontrl.hxx>
91 #include <svx/dlgutil.hxx>
92 #include <svx/dialmgr.hxx>
93 #include <svx/PaletteManager.hxx>
94 #include <memory>
96 #include <svx/framelink.hxx>
97 #include <svx/tbxcolorupdate.hxx>
98 #include <editeng/eerdll.hxx>
99 #include <editeng/editrids.hrc>
100 #include <svx/xlnclit.hxx>
101 #include <svx/xfillit0.hxx>
102 #include <svx/xflclit.hxx>
103 #include <svl/currencytable.hxx>
104 #include <svtools/langtab.hxx>
105 #include <cppu/unotype.hxx>
106 #include <officecfg/Office/Common.hxx>
107 #include <o3tl/typed_flags_set.hxx>
108 #include <bitmaps.hlst>
110 #define MAX_MRU_FONTNAME_ENTRIES 5
112 // don't make more than 15 entries visible at once
113 #define MAX_STYLES_ENTRIES 15
115 // namespaces
116 using namespace ::editeng;
117 using namespace ::com::sun::star;
118 using namespace ::com::sun::star::uno;
119 using namespace ::com::sun::star::frame;
120 using namespace ::com::sun::star::beans;
121 using namespace ::com::sun::star::lang;
123 SFX_IMPL_TOOLBOX_CONTROL( SvxStyleToolBoxControl, SfxTemplateItem );
124 SFX_IMPL_TOOLBOX_CONTROL( SvxSimpleUndoRedoController, SfxStringItem );
126 class SvxStyleBox_Impl : public ComboBox
128 using Window::IsVisible;
129 public:
130 SvxStyleBox_Impl( vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily, const Reference< XDispatchProvider >& rDispatchProvider,
131 const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode );
132 virtual ~SvxStyleBox_Impl() override;
133 virtual void dispose() override;
135 void SetFamily( SfxStyleFamily eNewFamily );
136 bool IsVisible() const { return bVisible; }
138 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
139 virtual bool EventNotify( NotifyEvent& rNEvt ) override;
140 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
141 virtual void StateChanged( StateChangedType nStateChange ) override;
143 virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
145 void SetVisibilityListener( const Link<SvxStyleBox_Impl&,void>& aVisListener ) { aVisibilityListener = aVisListener; }
147 void SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
149 protected:
150 /// Calculate the optimal width of the dropdown. Very expensive operation, triggers lots of font measurement.
151 DECL_LINK(CalcOptimalExtraUserWidth, VclWindowEvent&, void);
153 virtual void Select() override;
155 private:
156 SfxStyleFamily eStyleFamily;
157 sal_Int32 nCurSel;
158 bool bRelease;
159 Size aLogicalSize;
160 Link<SvxStyleBox_Impl&,void> aVisibilityListener;
161 bool bVisible;
162 Reference< XDispatchProvider > m_xDispatchProvider;
163 Reference< XFrame > m_xFrame;
164 OUString m_aCommand;
165 OUString aClearFormatKey;
166 OUString aMoreKey;
167 OUString sDefaultStyle;
168 bool bInSpecialMode;
169 VclPtr<MenuButton> m_pButtons[MAX_STYLES_ENTRIES];
170 VclBuilder m_aBuilder;
171 VclPtr<PopupMenu> m_pMenu;
173 void ReleaseFocus();
174 static Color TestColorsVisible(const Color &FontCol, const Color &BackCol);
175 static void UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName);
176 void SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected);
177 static bool AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle& rTextRect, long nHeight);
178 void SetOptimalSize();
179 DECL_LINK( MenuSelectHdl, Menu *, bool );
182 class SvxFontNameBox_Impl : public FontNameBox
184 using Window::Update;
185 private:
186 const FontList* pFontList;
187 ::std::unique_ptr<FontList> m_aOwnFontList;
188 vcl::Font aCurFont;
189 Size aLogicalSize;
190 OUString aCurText;
191 sal_uInt16 nFtCount;
192 bool bRelease;
193 Reference< XDispatchProvider > m_xDispatchProvider;
194 Reference< XFrame > m_xFrame;
195 bool mbEndPreview;
197 void ReleaseFocus_Impl();
198 void EnableControls_Impl();
200 void EndPreview()
202 Sequence< PropertyValue > aArgs;
203 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
204 ".uno:CharEndPreviewFontName",
205 aArgs );
207 DECL_LINK( CheckAndMarkUnknownFont, VclWindowEvent&, void );
209 void SetOptimalSize();
211 protected:
212 virtual void Select() override;
213 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
215 public:
216 SvxFontNameBox_Impl( vcl::Window* pParent, const Reference< XDispatchProvider >& rDispatchProvider,const Reference< XFrame >& _xFrame
217 , WinBits nStyle
219 virtual ~SvxFontNameBox_Impl() override;
220 virtual void dispose() override;
222 void FillList();
223 void Update( const css::awt::FontDescriptor* pFontDesc );
224 sal_uInt16 GetListCount() { return nFtCount; }
225 void Clear() { FontNameBox::Clear(); nFtCount = 0; }
226 void Fill( const FontList* pList )
227 { FontNameBox::Fill( pList );
228 nFtCount = pList->GetFontNameCount(); }
229 virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
230 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
231 virtual bool EventNotify( NotifyEvent& rNEvt ) override;
232 virtual Reference< css::accessibility::XAccessible > CreateAccessible() override;
233 void SetOwnFontList(::std::unique_ptr<FontList> && _aOwnFontList) { m_aOwnFontList = std::move(_aOwnFontList); }
236 // SelectHdl needs the Modifiers, get them in MouseButtonUp
237 class SvxFrmValueSet_Impl : public ValueSet
239 sal_uInt16 nModifier;
240 virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
241 public:
242 SvxFrmValueSet_Impl(vcl::Window* pParent, WinBits nWinStyle)
243 : ValueSet(pParent, nWinStyle), nModifier(0) {}
244 sal_uInt16 GetModifier() const {return nModifier;}
248 void SvxFrmValueSet_Impl::MouseButtonUp( const MouseEvent& rMEvt )
250 nModifier = rMEvt.GetModifier();
251 ValueSet::MouseButtonUp(rMEvt);
254 class SvxFrameWindow_Impl : public svtools::ToolbarPopup
256 private:
257 VclPtr<SvxFrmValueSet_Impl> aFrameSet;
258 svt::ToolboxController& mrController;
259 std::vector<BitmapEx> aImgVec;
260 bool bParagraphMode;
262 void InitImageList();
263 void CalcSizeValueSet();
264 DECL_LINK( SelectHdl, ValueSet*, void );
266 protected:
267 virtual void GetFocus() override;
268 virtual void KeyInput( const KeyEvent& rKEvt ) override;
270 public:
271 SvxFrameWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow );
272 virtual ~SvxFrameWindow_Impl() override;
273 virtual void dispose() override;
275 virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
276 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
279 class SvxLineWindow_Impl : public svtools::ToolbarPopup
281 private:
282 VclPtr<LineListBox> m_aLineStyleLb;
283 svt::ToolboxController& m_rController;
284 bool m_bIsWriter;
286 DECL_LINK( SelectHdl, ListBox&, void );
288 protected:
289 virtual void Resize() override;
290 virtual void GetFocus() override;
291 public:
292 SvxLineWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow );
293 virtual ~SvxLineWindow_Impl() override { disposeOnce(); }
294 virtual void dispose() override { m_aLineStyleLb.disposeAndClear(); ToolbarPopup::dispose(); }
297 class SvxCurrencyList_Impl : public svtools::ToolbarPopup
299 private:
300 VclPtr<ListBox> m_pCurrencyLb;
301 rtl::Reference<SvxCurrencyToolBoxControl> m_xControl;
302 OUString& m_rSelectedFormat;
303 LanguageType& m_eSelectedLanguage;
305 std::vector<OUString> m_aFormatEntries;
306 LanguageType m_eFormatLanguage;
307 DECL_LINK( SelectHdl, ListBox&, void );
309 public:
310 SvxCurrencyList_Impl( SvxCurrencyToolBoxControl* pControl,
311 vcl::Window* pParentWindow,
312 OUString& rSelectFormat,
313 LanguageType& eSelectLanguage );
314 virtual ~SvxCurrencyList_Impl() override { disposeOnce(); }
315 virtual void dispose() override;
318 class SvxStyleToolBoxControl;
320 class SfxStyleControllerItem_Impl : public SfxStatusListener
322 public:
323 SfxStyleControllerItem_Impl( const Reference< XDispatchProvider >& rDispatchProvider,
324 sal_uInt16 nSlotId,
325 const OUString& rCommand,
326 SvxStyleToolBoxControl& rTbxCtl );
328 protected:
329 virtual void StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState ) override;
331 private:
332 SvxStyleToolBoxControl& rControl;
335 #define BUTTON_WIDTH 20
336 #define BUTTON_PADDING 10
337 #define ITEM_HEIGHT 30
339 SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
340 const OUString& rCommand,
341 SfxStyleFamily eFamily,
342 const Reference< XDispatchProvider >& rDispatchProvider,
343 const Reference< XFrame >& _xFrame,
344 const OUString& rClearFormatKey,
345 const OUString& rMoreKey,
346 bool bInSpec)
347 : ComboBox(pParent, WB_SORT | WB_BORDER | WB_HIDE | WB_DROPDOWN | WB_AUTOHSCROLL)
348 , eStyleFamily( eFamily )
349 , nCurSel(0)
350 , bRelease( true )
351 , aLogicalSize(60, 86)
352 , bVisible(false)
353 , m_xDispatchProvider( rDispatchProvider )
354 , m_xFrame(_xFrame)
355 , m_aCommand( rCommand )
356 , aClearFormatKey( rClearFormatKey )
357 , aMoreKey( rMoreKey )
358 , bInSpecialMode( bInSpec )
359 , m_aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/stylemenu.ui", "")
360 , m_pMenu(m_aBuilder.get_menu("menu"))
362 SetHelpId(HID_STYLE_LISTBOX);
363 m_pMenu->SetSelectHdl( LINK( this, SvxStyleBox_Impl, MenuSelectHdl ) );
364 for(VclPtr<MenuButton> & rpButton : m_pButtons)
365 rpButton = nullptr;
366 SetOptimalSize();
367 EnableAutocomplete( true );
368 EnableUserDraw( true );
369 AddEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));
370 SetUserItemSize( Size( 0, ITEM_HEIGHT ) );
373 SvxStyleBox_Impl::~SvxStyleBox_Impl()
375 disposeOnce();
378 void SvxStyleBox_Impl::dispose()
380 RemoveEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));
382 for (VclPtr<MenuButton>& rButton : m_pButtons)
384 rButton.disposeAndClear();
387 m_pMenu.clear();
388 m_aBuilder.disposeBuilder();
390 ComboBox::dispose();
393 void SvxStyleBox_Impl::ReleaseFocus()
395 if ( !bRelease )
397 bRelease = true;
398 return;
400 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
401 m_xFrame->getContainerWindow()->setFocus();
404 IMPL_LINK( SvxStyleBox_Impl, MenuSelectHdl, Menu*, pMenu, bool)
406 OUString sEntry = GetSelectedEntry();
407 OString sMenuIdent = pMenu->GetCurItemIdent();
408 ReleaseFocus(); // It must be after getting entry pos!
409 if (IsInDropDown())
410 ToggleDropDown();
411 Sequence< PropertyValue > aArgs( 2 );
412 aArgs[0].Name = "Param";
413 aArgs[0].Value <<= sEntry;
414 aArgs[1].Name = "Family";
415 aArgs[1].Value <<= sal_Int16( eStyleFamily );
417 if (sMenuIdent == "update")
419 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
420 ".uno:StyleUpdateByExample", aArgs );
422 else if (sMenuIdent == "edit")
424 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
425 ".uno:EditStyle", aArgs );
428 return false;
431 void SvxStyleBox_Impl::Select()
433 // Tell base class about selection so that AT get informed about it.
434 ComboBox::Select();
436 if ( IsTravelSelect() )
437 return;
439 OUString aSearchEntry( GetText() );
440 bool bDoIt = true, bClear = false;
441 if( bInSpecialMode )
443 if( aSearchEntry == aClearFormatKey && GetSelectedEntryPos() == 0 )
445 aSearchEntry = sDefaultStyle;
446 bClear = true;
447 //not only apply default style but also call 'ClearFormatting'
448 Sequence< PropertyValue > aEmptyVals;
449 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:ResetAttributes",
450 aEmptyVals);
452 else if( aSearchEntry == aMoreKey && GetSelectedEntryPos() == ( GetEntryCount() - 1 ) )
454 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
455 DBG_ASSERT( pViewFrm, "SvxStyleBox_Impl::Select(): no viewframe" );
456 pViewFrm->ShowChildWindow( SID_SIDEBAR );
457 ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel",
458 pViewFrm->GetFrame().GetFrameInterface());
459 //tdf#113214 change text back to previous entry
460 SetText(GetSavedValue());
461 bDoIt = false;
465 //Do we need to create a new style?
466 SfxObjectShell *pShell = SfxObjectShell::Current();
467 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
468 SfxStyleSheetBase* pStyle = nullptr;
470 bool bCreateNew = false;
472 if ( pPool )
474 pPool->SetSearchMask( eStyleFamily );
476 pStyle = pPool->First();
477 while ( pStyle && pStyle->GetName() != aSearchEntry )
478 pStyle = pPool->Next();
481 if ( !pStyle )
483 // cannot find the style for whatever reason
484 // therefore create a new style
485 bCreateNew = true;
488 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
489 This instance may be deleted in the meantime (i.e. when a dialog is opened
490 while in Dispatch()), accessing members will crash in this case. */
491 ReleaseFocus();
493 if( bDoIt )
495 if ( bClear )
496 SetText( aSearchEntry );
497 SaveValue();
499 Sequence< PropertyValue > aArgs( 2 );
500 aArgs[0].Value <<= aSearchEntry;
501 aArgs[1].Name = "Family";
502 aArgs[1].Value <<= sal_Int16( eStyleFamily );
503 if( bCreateNew )
505 aArgs[0].Name = "Param";
506 SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:StyleNewByExample", aArgs);
508 else
510 aArgs[0].Name = "Template";
511 SfxToolBoxControl::Dispatch( m_xDispatchProvider, m_aCommand, aArgs );
516 void SvxStyleBox_Impl::SetFamily( SfxStyleFamily eNewFamily )
518 eStyleFamily = eNewFamily;
521 bool SvxStyleBox_Impl::PreNotify( NotifyEvent& rNEvt )
523 MouseNotifyEvent nType = rNEvt.GetType();
525 if ( MouseNotifyEvent::MOUSEBUTTONDOWN == nType || MouseNotifyEvent::GETFOCUS == nType )
526 nCurSel = GetSelectedEntryPos();
527 else if ( MouseNotifyEvent::LOSEFOCUS == nType )
529 // don't handle before our Select() is called
530 if (!HasFocus() && !HasChildPathFocus() && !IsChild(rNEvt.GetWindow()))
531 SetText( GetSavedValue() );
533 return ComboBox::PreNotify( rNEvt );
536 bool SvxStyleBox_Impl::EventNotify( NotifyEvent& rNEvt )
538 bool bHandled = false;
540 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
542 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
544 switch ( nCode )
546 case KEY_CONTEXTMENU:
548 if(IsInDropDown())
550 const sal_Int32 nItem = GetSelectedEntryPos() - 1;
551 if(nItem < MAX_STYLES_ENTRIES)
552 m_pButtons[nItem]->ExecuteMenu();
553 bHandled = true;
555 break;
557 case KEY_RETURN:
558 case KEY_TAB:
560 if ( KEY_TAB == nCode )
561 bRelease = false;
562 else
563 bHandled = true;
564 Select();
565 break;
568 case KEY_ESCAPE:
569 SelectEntryPos( nCurSel );
570 ReleaseFocus();
571 bHandled = true;
572 break;
575 return bHandled || ComboBox::EventNotify( rNEvt );
578 void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
580 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
581 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
583 SetOptimalSize();
586 ComboBox::DataChanged( rDCEvt );
589 void SvxStyleBox_Impl::StateChanged( StateChangedType nStateChange )
591 ComboBox::StateChanged( nStateChange );
593 if ( nStateChange == StateChangedType::Visible )
595 bVisible = IsReallyVisible();
596 aVisibilityListener.Call( *this );
598 else if ( nStateChange == StateChangedType::InitShow )
600 bVisible = true;
601 aVisibilityListener.Call( *this );
605 bool SvxStyleBox_Impl::AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle& rTextRect, long nHeight)
607 if (rTextRect.Bottom() > nHeight)
609 // the text does not fit, adjust the font size
610 double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
611 vcl::Font aFont(pDevice->GetFont());
612 Size aPixelSize(aFont.GetFontSize());
613 aPixelSize.Width() *= ratio;
614 aPixelSize.Height() *= ratio;
615 aFont.SetFontSize(aPixelSize);
616 pDevice->SetFont(aFont);
617 return true;
619 return false;
622 void SvxStyleBox_Impl::SetOptimalSize()
624 Size aSize(LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont)));
625 set_width_request(aSize.Width());
626 set_height_request(aSize.Height());
627 SetSizePixel(aSize);
630 void SvxStyleBox_Impl::UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName)
632 vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();
634 // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
635 // nBorder, and we are adding 1 in order to look better when
636 // italics is present
637 const int nLeftDistance = 8;
639 tools::Rectangle aTextRect;
640 pDevice->GetTextBoundRect(aTextRect, rStyleName);
642 Point aPos( rUDEvt.GetRect().TopLeft() );
643 aPos.X() += nLeftDistance;
645 if (!AdjustFontForItemHeight(pDevice, aTextRect, rUDEvt.GetRect().GetHeight()))
646 aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aTextRect.Bottom() ) / 2;
648 pDevice->DrawText(aPos, rStyleName);
651 void SvxStyleBox_Impl::SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected)
653 unsigned int nId = rRect.GetHeight() != 0 ? (rRect.getY() / rRect.GetHeight()) : MAX_STYLES_ENTRIES;
654 if (nItem == 0 || nItem == GetEntryCount() - 1)
656 if(nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
657 m_pButtons[nId]->Hide();
659 else
661 SfxObjectShell *pShell = SfxObjectShell::Current();
662 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
663 SfxStyleSheetBase* pStyle = nullptr;
665 if ( pPool )
667 pPool->SetSearchMask( eStyleFamily );
669 pStyle = pPool->First();
670 while (pStyle && pStyle->GetName() != rStyleName)
671 pStyle = pPool->Next();
674 if (pStyle )
676 std::unique_ptr<const SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
677 if (!pItemSet) return;
679 const SvxFontItem * const pFontItem =
680 pItemSet->GetItem<SvxFontItem>(SID_ATTR_CHAR_FONT);
681 const SvxFontHeightItem * const pFontHeightItem =
682 pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
684 if ( pFontItem && pFontHeightItem )
686 Size aFontSize( 0, pFontHeightItem->GetHeight() );
687 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
689 // setup the font properties
690 SvxFont aFont;
691 aFont.SetFamilyName(pFontItem->GetFamilyName());
692 aFont.SetStyleName(pFontItem->GetStyleName());
693 aFont.SetFontSize(aPixelSize);
695 const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_WEIGHT );
696 if ( pItem )
697 aFont.SetWeight( static_cast< const SvxWeightItem* >( pItem )->GetWeight() );
699 pItem = pItemSet->GetItem( SID_ATTR_CHAR_POSTURE );
700 if ( pItem )
701 aFont.SetItalic( static_cast< const SvxPostureItem* >( pItem )->GetPosture() );
703 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
704 if ( pItem )
705 aFont.SetOutline( static_cast< const SvxContourItem* >( pItem )->GetValue() );
707 pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED );
708 if ( pItem )
709 aFont.SetShadow( static_cast< const SvxShadowedItem* >( pItem )->GetValue() );
711 pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF );
712 if ( pItem )
713 aFont.SetRelief( static_cast< const SvxCharReliefItem* >( pItem )->GetValue() );
715 pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE );
716 if ( pItem )
717 aFont.SetUnderline( static_cast< const SvxUnderlineItem* >( pItem )->GetLineStyle() );
719 pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE );
720 if ( pItem )
721 aFont.SetOverline( static_cast< const SvxOverlineItem* >( pItem )->GetValue() );
723 pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT );
724 if ( pItem )
725 aFont.SetStrikeout( static_cast< const SvxCrossedOutItem* >( pItem )->GetStrikeout() );
727 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP );
728 if ( pItem )
729 aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
731 pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK );
732 if ( pItem )
733 aFont.SetEmphasisMark( static_cast< const SvxEmphasisMarkItem* >( pItem )->GetEmphasisMark() );
735 // setup the device & draw
736 vcl::Font aOldFont(rRenderContext.GetFont());
738 Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
740 rRenderContext.SetFont(aFont);
742 pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR );
743 // text color, when nothing is selected
744 if ( (nullptr != pItem) && bIsNotSelected)
745 aFontCol = Color( static_cast< const SvxColorItem* >( pItem )->GetValue() );
747 drawing::FillStyle style = drawing::FillStyle_NONE;
748 // which kind of Fill style is selected
749 pItem = pItemSet->GetItem( XATTR_FILLSTYLE );
750 // only when ok and not selected
751 if ( (nullptr != pItem) && bIsNotSelected)
752 style = static_cast< const XFillStyleItem* >( pItem )->GetValue();
754 switch(style)
756 case drawing::FillStyle_SOLID:
758 // set background color
759 pItem = pItemSet->GetItem( XATTR_FILLCOLOR );
760 if ( nullptr != pItem )
761 aBackCol = Color( static_cast< const XFillColorItem* >( pItem )->GetColorValue() );
763 if ( aBackCol != COL_AUTO )
765 rRenderContext.SetFillColor(aBackCol);
766 rRenderContext.DrawRect(rRect);
769 break;
771 default: break;
772 //TODO Draw the other background styles: gradient, hatching and bitmap
775 // when the font and background color are too similar, adjust the Font-Color
776 if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
777 aFontCol = TestColorsVisible(aFontCol, (aBackCol != COL_AUTO) ? aBackCol : rRenderContext.GetBackground().GetColor());
779 // set text color
780 if ( aFontCol != COL_AUTO )
781 rRenderContext.SetTextColor(aFontCol);
783 // handle the push-button
784 if (bIsNotSelected)
786 if (nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
787 m_pButtons[nId]->Hide();
789 else
791 if (nId < MAX_STYLES_ENTRIES)
793 if (!m_pButtons[nId] && pParent)
795 m_pButtons[nId] = VclPtr<MenuButton>::Create(pParent, WB_FLATBUTTON | WB_NOPOINTERFOCUS);
796 m_pButtons[nId]->SetSizePixel(Size(BUTTON_WIDTH, rRect.GetHeight()));
797 m_pButtons[nId]->SetPopupMenu(m_pMenu);
799 m_pButtons[nId]->SetPosPixel(Point(rRect.GetWidth() - BUTTON_WIDTH, rRect.getY()));
800 m_pButtons[nId]->Show();
808 void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
810 sal_uInt16 nItem = rUDEvt.GetItemId();
811 OUString aStyleName( GetEntry( nItem ) );
813 vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();
814 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
816 const tools::Rectangle& rRect(rUDEvt.GetRect());
817 bool bIsNotSelected = rUDEvt.GetItemId() != GetSelectedEntryPos();
819 SetupEntry(*pDevice, rUDEvt.GetWindow(), nItem, rRect, aStyleName, bIsNotSelected);
821 UserDrawEntry(rUDEvt, aStyleName);
823 pDevice->Pop();
824 // draw separator, if present
825 DrawEntry( rUDEvt, false, false );
828 IMPL_LINK(SvxStyleBox_Impl, CalcOptimalExtraUserWidth, VclWindowEvent&, event, void)
830 // perform the calculation only when we are opening the dropdown
831 if (event.GetId() != VclEventId::DropdownPreOpen)
832 return;
834 long nMaxNormalFontWidth = 0;
835 sal_Int32 nEntryCount = GetEntryCount();
836 for (sal_Int32 i = 0; i < nEntryCount; ++i)
838 OUString sStyleName(GetEntry(i));
839 tools::Rectangle aTextRectForDefaultFont;
840 GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
842 const long nWidth = aTextRectForDefaultFont.GetWidth();
844 nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
847 long nMaxUserDrawFontWidth = nMaxNormalFontWidth;
848 for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
850 OUString sStyleName(GetEntry(i));
852 Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
853 SetupEntry(*this /*FIXME rendercontext*/, this, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
854 tools::Rectangle aTextRectForActualFont;
855 GetTextBoundRect(aTextRectForActualFont, sStyleName);
856 if (AdjustFontForItemHeight(this, aTextRectForActualFont, ITEM_HEIGHT))
858 //Font didn't fit, so it was changed, refetch with final font size
859 GetTextBoundRect(aTextRectForActualFont, sStyleName);
861 Pop();
863 const long nWidth = aTextRectForActualFont.GetWidth() + BUTTON_WIDTH + BUTTON_PADDING;
865 nMaxUserDrawFontWidth = std::max(nWidth, nMaxUserDrawFontWidth);
868 SetUserItemSize(Size(nMaxUserDrawFontWidth - nMaxNormalFontWidth, ITEM_HEIGHT));
871 // test is the color between Font- and background-color to be identify
872 // return is always the Font-Color
873 // when both light or dark, change the Contrast
874 // in other case do not change the origin color
875 // when the color is R=G=B=128 the DecreaseContrast make 128 the need a exception
876 Color SvxStyleBox_Impl::TestColorsVisible(const Color &FontCol, const Color &BackCol)
878 const sal_uInt8 ChgVal = 60; // increase/decrease the Contrast
880 Color retCol = FontCol;
881 if ((FontCol.IsDark() == BackCol.IsDark()) && (FontCol.IsBright() == BackCol.IsBright()))
883 sal_uInt8 lumi = retCol.GetLuminance();
885 if((lumi > 120) && (lumi < 140))
886 retCol.DecreaseLuminance(ChgVal / 2);
887 else
888 retCol.DecreaseContrast(ChgVal);
891 return retCol;
895 static bool lcl_GetDocFontList( const FontList** ppFontList, SvxFontNameBox_Impl* pBox )
897 bool bChanged = false;
898 const SfxObjectShell* pDocSh = SfxObjectShell::Current();
899 const SvxFontListItem* pFontListItem = nullptr;
901 if ( pDocSh )
902 pFontListItem =
903 static_cast<const SvxFontListItem*>(pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
904 else
906 ::std::unique_ptr<FontList> aFontList(new FontList( pBox->GetParent() ));
907 *ppFontList = aFontList.get();
908 pBox->SetOwnFontList(std::move(aFontList));
909 bChanged = true;
912 if ( pFontListItem )
914 const FontList* pNewFontList = pFontListItem->GetFontList();
915 DBG_ASSERT( pNewFontList, "Doc-FontList not available!" );
917 // No old list, but a new list
918 if ( !*ppFontList && pNewFontList )
920 // => take over
921 *ppFontList = pNewFontList;
922 bChanged = true;
924 else
926 // Comparing the font lists is not perfect.
927 // When you change the font list in the Doc, you can track
928 // changes here only on the Listbox, because ppFontList
929 // has already been updated.
930 bChanged =
931 ( ( *ppFontList != pNewFontList ) ||
932 pBox->GetListCount() != pNewFontList->GetFontNameCount() );
933 // HACK: Comparing is incomplete
935 if ( bChanged )
936 *ppFontList = pNewFontList;
939 if ( pBox )
940 pBox->Enable();
942 else if ( pBox && ( pDocSh || !ppFontList ))
944 // Disable box only when we have a SfxObjectShell and didn't get a font list OR
945 // we don't have a SfxObjectShell and no current font list.
946 // It's possible that we currently have no SfxObjectShell, but a current font list.
947 // See #i58471: When a user set the focus into the font name combo box and opens
948 // the help window with F1. After closing the help window, we disable the font name
949 // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
950 // font list hasn't changed and therefore the combo box shouldn't be disabled!
951 pBox->Disable();
954 // Fill the FontBox, also the new list if necessary
955 if ( pBox && bChanged )
957 if ( *ppFontList )
958 pBox->Fill( *ppFontList );
959 else
960 pBox->Clear();
962 return bChanged;
965 SvxFontNameBox_Impl::SvxFontNameBox_Impl( vcl::Window* pParent, const Reference< XDispatchProvider >& rDispatchProvider,const Reference< XFrame >& _xFrame, WinBits nStyle ) :
967 FontNameBox ( pParent, nStyle | WinBits( WB_DROPDOWN | WB_AUTOHSCROLL ) ),
968 pFontList ( nullptr ),
969 aLogicalSize ( 60,160 ),
970 nFtCount ( 0 ),
971 bRelease ( true ),
972 m_xDispatchProvider( rDispatchProvider ),
973 m_xFrame (_xFrame),
974 mbEndPreview(false)
976 SetOptimalSize();
977 EnableControls_Impl();
978 GetSubEdit()->AddEventListener( LINK( this, SvxFontNameBox_Impl, CheckAndMarkUnknownFont ));
981 SvxFontNameBox_Impl::~SvxFontNameBox_Impl()
983 disposeOnce();
986 void SvxFontNameBox_Impl::dispose()
988 GetSubEdit()->RemoveEventListener( LINK( this, SvxFontNameBox_Impl, CheckAndMarkUnknownFont ));
989 FontNameBox::dispose();
992 void SvxFontNameBox_Impl::FillList()
994 // Save old Selection, set back in the end
995 Selection aOldSel = GetSelection();
996 // Did Doc-Fontlist change?
997 lcl_GetDocFontList( &pFontList, this );
998 aCurText = GetText();
999 SetSelection( aOldSel );
1002 IMPL_LINK( SvxFontNameBox_Impl, CheckAndMarkUnknownFont, VclWindowEvent&, event, void )
1004 if( event.GetId() != VclEventId::EditModify )
1005 return;
1006 OUString fontname = GetSubEdit()->GetText();
1007 lcl_GetDocFontList( &pFontList, this );
1008 // If the font is unknown, show it in italic.
1009 vcl::Font font = GetControlFont();
1010 if( pFontList != nullptr && pFontList->IsAvailable( fontname ))
1012 if( font.GetItalic() != ITALIC_NONE )
1014 font.SetItalic( ITALIC_NONE );
1015 SetControlFont( font );
1016 SetQuickHelpText( SvxResId( RID_SVXSTR_CHARFONTNAME ));
1019 else
1021 if( font.GetItalic() != ITALIC_NORMAL )
1023 font.SetItalic( ITALIC_NORMAL );
1024 SetControlFont( font );
1025 SetQuickHelpText( SvxResId( RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE ));
1030 void SvxFontNameBox_Impl::Update( const css::awt::FontDescriptor* pFontDesc )
1032 if ( pFontDesc )
1034 aCurFont.SetFamilyName ( pFontDesc->Name );
1035 aCurFont.SetFamily ( FontFamily( pFontDesc->Family ) );
1036 aCurFont.SetStyleName ( pFontDesc->StyleName );
1037 aCurFont.SetPitch ( FontPitch( pFontDesc->Pitch ) );
1038 aCurFont.SetCharSet ( rtl_TextEncoding( pFontDesc->CharSet ) );
1040 OUString aCurName = aCurFont.GetFamilyName();
1041 if ( GetText() != aCurName )
1042 SetText( aCurName );
1045 bool SvxFontNameBox_Impl::PreNotify( NotifyEvent& rNEvt )
1047 MouseNotifyEvent nType = rNEvt.GetType();
1049 if ( MouseNotifyEvent::MOUSEBUTTONDOWN == nType || MouseNotifyEvent::GETFOCUS == nType )
1051 EnableControls_Impl();
1052 FillList();
1054 return FontNameBox::PreNotify( rNEvt );
1057 bool SvxFontNameBox_Impl::EventNotify( NotifyEvent& rNEvt )
1059 bool bHandled = false;
1060 mbEndPreview = false;
1061 if ( rNEvt.GetType() == MouseNotifyEvent::KEYUP )
1062 mbEndPreview = true;
1064 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
1066 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1068 switch ( nCode )
1070 case KEY_RETURN:
1071 case KEY_TAB:
1073 if ( KEY_TAB == nCode )
1074 bRelease = false;
1075 else
1076 bHandled = true;
1077 Select();
1078 break;
1081 case KEY_ESCAPE:
1082 SetText( aCurText );
1083 ReleaseFocus_Impl();
1084 EndPreview();
1085 break;
1088 else if ( MouseNotifyEvent::LOSEFOCUS == rNEvt.GetType() )
1090 vcl::Window* pFocusWin = Application::GetFocusWindow();
1091 if ( !HasFocus() && GetSubEdit() != pFocusWin )
1092 SetText( GetSavedValue() );
1093 // send EndPreview
1094 EndPreview();
1097 return bHandled || FontNameBox::EventNotify( rNEvt );
1100 void SvxFontNameBox_Impl::SetOptimalSize()
1102 Size aSize(LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont)));
1103 set_width_request(aSize.Width());
1104 set_height_request(aSize.Height());
1105 SetSizePixel(aSize);
1108 void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1110 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1111 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1113 SetOptimalSize();
1115 else if ( ( rDCEvt.GetType() == DataChangedEventType::FONTS ) ||
1116 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) )
1118 // The old font list in shell has likely been destroyed at this point, so we need to get
1119 // the new one before doing anything further.
1120 lcl_GetDocFontList( &pFontList, this );
1123 FontNameBox::DataChanged( rDCEvt );
1126 void SvxFontNameBox_Impl::ReleaseFocus_Impl()
1128 if ( !bRelease )
1130 bRelease = true;
1131 return;
1133 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
1134 m_xFrame->getContainerWindow()->setFocus();
1137 void SvxFontNameBox_Impl::EnableControls_Impl()
1139 SvtFontOptions aFontOpt;
1140 bool bEnable = aFontOpt.IsFontHistoryEnabled();
1141 sal_uInt16 nEntries = bEnable ? MAX_MRU_FONTNAME_ENTRIES : 0;
1142 if ( GetMaxMRUCount() != nEntries )
1144 // refill in the next GetFocus-Handler
1145 pFontList = nullptr;
1146 Clear();
1147 SetMaxMRUCount( nEntries );
1150 bEnable = aFontOpt.IsFontWYSIWYGEnabled();
1151 EnableWYSIWYG( bEnable );
1154 void SvxFontNameBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
1156 FontNameBox::UserDraw( rUDEvt );
1158 // Hack - GetStyle now contains the currently
1159 // selected item in the list box
1160 // ItemId contains the id of the current item to draw
1161 // or select
1162 if ( rUDEvt.GetItemId() == rUDEvt.GetStyle() )
1164 OUString fontName(GetText());
1165 if (IsInDropDown())
1168 * when in dropdown mode the selected item should be
1169 * used and not the current selection
1171 fontName = GetEntry(rUDEvt.GetItemId());
1173 Sequence< PropertyValue > aArgs( 1 );
1174 FontMetric aFontMetric( pFontList->Get( fontName,
1175 aCurFont.GetWeight(),
1176 aCurFont.GetItalic() ) );
1178 SvxFontItem aFontItem( aFontMetric.GetFamilyType(),
1179 aFontMetric.GetFamilyName(),
1180 aFontMetric.GetStyleName(),
1181 aFontMetric.GetPitch(),
1182 aFontMetric.GetCharSet(),
1183 SID_ATTR_CHAR_FONT );
1184 aFontItem.QueryValue( aArgs[0].Value );
1185 aArgs[0].Name = "CharPreviewFontName";
1186 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1187 ".uno:CharPreviewFontName",
1188 aArgs );
1192 void SvxFontNameBox_Impl::Select()
1194 FontNameBox::Select();
1196 Sequence< PropertyValue > aArgs( 1 );
1197 std::unique_ptr<SvxFontItem> pFontItem;
1198 if ( pFontList )
1200 FontMetric aFontMetric( pFontList->Get( GetText(),
1201 aCurFont.GetWeight(),
1202 aCurFont.GetItalic() ) );
1203 aCurFont = aFontMetric;
1205 pFontItem.reset( new SvxFontItem( aFontMetric.GetFamilyType(),
1206 aFontMetric.GetFamilyName(),
1207 aFontMetric.GetStyleName(),
1208 aFontMetric.GetPitch(),
1209 aFontMetric.GetCharSet(),
1210 SID_ATTR_CHAR_FONT ) );
1212 Any a;
1213 pFontItem->QueryValue( a );
1214 aArgs[0].Value = a;
1216 if ( !IsTravelSelect() )
1218 // #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1219 // This instance may be deleted in the meantime (i.e. when a dialog is opened
1220 // while in Dispatch()), accessing members will crash in this case.
1221 ReleaseFocus_Impl();
1222 EndPreview();
1223 if ( pFontItem.get() )
1225 aArgs[0].Name = "CharFontName";
1226 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1227 ".uno:CharFontName",
1228 aArgs );
1231 else
1233 if ( mbEndPreview )
1235 EndPreview();
1236 return;
1238 if ( pFontItem.get() )
1240 aArgs[0].Name = "CharPreviewFontName";
1241 SfxToolBoxControl::Dispatch( m_xDispatchProvider,
1242 ".uno:CharPreviewFontName",
1243 aArgs );
1248 SvxColorWindow::SvxColorWindow(const OUString& rCommand,
1249 std::shared_ptr<PaletteManager> const & rPaletteManager,
1250 BorderColorStatus& rBorderColorStatus,
1251 sal_uInt16 nSlotId,
1252 const Reference< XFrame >& rFrame,
1253 vcl::Window* pParentWindow,
1254 std::function<void(const OUString&, const NamedColor&)> const & aFunction):
1256 ToolbarPopup( rFrame, pParentWindow, "palette_popup_window", "svx/ui/colorwindow.ui" ),
1257 theSlotId( nSlotId ),
1258 maCommand( rCommand ),
1259 mxPaletteManager( rPaletteManager ),
1260 mrBorderColorStatus( rBorderColorStatus ),
1261 maColorSelectFunction(aFunction)
1263 get(mpPaletteListBox, "palette_listbox");
1264 get(mpButtonAutoColor, "auto_color_button");
1265 get(mpButtonNoneColor, "none_color_button");
1266 get(mpButtonPicker, "color_picker_button");
1267 get(mpColorSet, "colorset");
1268 get(mpRecentColorSet, "recent_colorset");
1269 get(mpAutomaticSeparator, "separator4");
1271 mpColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1272 mpRecentColorSet->SetStyle( WinBits(WB_FLATVALUESET | WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_TABSTOP) );
1274 switch ( theSlotId )
1276 case SID_ATTR_CHAR_COLOR_BACKGROUND:
1277 case SID_BACKGROUND_COLOR:
1278 case SID_ATTR_CHAR_BACK_COLOR:
1280 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_NOFILL ) );
1281 break;
1283 case SID_AUTHOR_COLOR:
1285 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_BY_AUTHOR ) );
1286 break;
1288 case SID_BMPMASK_COLOR:
1290 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_TRANSPARENT ) );
1291 break;
1293 case SID_ATTR_CHAR_COLOR:
1294 case SID_ATTR_CHAR_COLOR2:
1295 case SID_EXTRUSION_3D_COLOR:
1297 mpButtonAutoColor->SetText(EditResId(RID_SVXSTR_AUTOMATIC));
1298 break;
1300 case SID_FM_CTL_PROPERTIES:
1302 mpButtonAutoColor->SetText( SvxResId( RID_SVXSTR_DEFAULT ) );
1303 break;
1305 default:
1307 mpButtonAutoColor->Hide();
1308 mpAutomaticSeparator->Hide();
1309 break;
1313 mpColorSet->SetAccessibleName( GetText() );
1315 mpPaletteListBox->SetStyle( mpPaletteListBox->GetStyle() | WB_BORDER );
1316 mpPaletteListBox->SetSelectHdl( LINK( this, SvxColorWindow, SelectPaletteHdl ) );
1317 mpPaletteListBox->AdaptDropDownLineCountToMaximum();
1318 std::vector<OUString> aPaletteList = mxPaletteManager->GetPaletteList();
1319 for( std::vector<OUString>::iterator it = aPaletteList.begin(); it != aPaletteList.end(); ++it )
1321 mpPaletteListBox->InsertEntry( *it );
1323 OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
1324 mpPaletteListBox->SelectEntry( aPaletteName );
1325 const sal_Int32 nSelectedEntry(mpPaletteListBox->GetSelectedEntryPos());
1326 if (nSelectedEntry != LISTBOX_ENTRY_NOTFOUND)
1327 mxPaletteManager->SetPalette(nSelectedEntry);
1329 mpButtonAutoColor->SetClickHdl( LINK( this, SvxColorWindow, AutoColorClickHdl ) );
1330 mpButtonNoneColor->SetClickHdl( LINK( this, SvxColorWindow, AutoColorClickHdl ) );
1331 mpButtonPicker->SetClickHdl( LINK( this, SvxColorWindow, OpenPickerClickHdl ) );
1333 mpColorSet->SetSelectHdl( LINK( this, SvxColorWindow, SelectHdl ) );
1334 mpRecentColorSet->SetSelectHdl( LINK( this, SvxColorWindow, SelectHdl ) );
1335 SetHelpId( HID_POPUP_COLOR );
1336 mpColorSet->SetHelpId( HID_POPUP_COLOR_CTRL );
1338 mxPaletteManager->ReloadColorSet(*mpColorSet);
1339 const sal_uInt32 nMaxItems(SvxColorValueSet::getMaxRowCount() * SvxColorValueSet::getColumnCount());
1340 Size aSize = mpColorSet->layoutAllVisible(nMaxItems);
1341 mpColorSet->set_height_request(aSize.Height());
1342 mpColorSet->set_width_request(aSize.Width());
1344 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
1345 aSize = mpRecentColorSet->layoutAllVisible(mxPaletteManager->GetRecentColorCount());
1346 mpRecentColorSet->set_height_request(aSize.Height());
1347 mpRecentColorSet->set_width_request(aSize.Width());
1349 AddStatusListener( ".uno:ColorTableState" );
1350 AddStatusListener( maCommand );
1351 if ( maCommand == ".uno:FrameLineColor" )
1353 AddStatusListener( ".uno:BorderTLBR" );
1354 AddStatusListener( ".uno:BorderBLTR" );
1358 void SvxColorWindow::ShowNoneButton()
1360 mpButtonNoneColor->Show();
1363 SvxColorWindow::~SvxColorWindow()
1365 disposeOnce();
1368 void SvxColorWindow::dispose()
1370 mpColorSet.clear();
1371 mpRecentColorSet.clear();
1372 mpPaletteListBox.clear();
1373 mpButtonAutoColor.clear();
1374 mpButtonNoneColor.clear();
1375 mpButtonPicker.clear();
1376 mpAutomaticSeparator.clear();
1377 ToolbarPopup::dispose();
1380 void SvxColorWindow::KeyInput( const KeyEvent& rKEvt )
1382 mpColorSet->GrabFocus();
1383 mpColorSet->KeyInput(rKEvt);
1386 NamedColor SvxColorWindow::GetSelectEntryColor(ValueSet const * pColorSet)
1388 Color aColor = pColorSet->GetItemColor(pColorSet->GetSelectItemId());
1389 OUString sColorName = pColorSet->GetItemText(pColorSet->GetSelectItemId());
1390 return std::make_pair(aColor, sColorName);
1393 namespace
1395 NamedColor GetAutoColor(sal_uInt16 nSlotId)
1397 Color aColor;
1398 OUString sColorName;
1399 switch (nSlotId)
1401 case SID_ATTR_CHAR_COLOR_BACKGROUND:
1402 case SID_BACKGROUND_COLOR:
1403 case SID_ATTR_CHAR_BACK_COLOR:
1404 aColor = COL_TRANSPARENT;
1405 sColorName = SvxResId(RID_SVXSTR_NOFILL);
1406 break;
1407 case SID_AUTHOR_COLOR:
1408 aColor = COL_TRANSPARENT;
1409 sColorName = SvxResId(RID_SVXSTR_BY_AUTHOR);
1410 break;
1411 case SID_BMPMASK_COLOR:
1412 aColor = COL_TRANSPARENT;
1413 sColorName = SvxResId(RID_SVXSTR_TRANSPARENT);
1414 break;
1415 case SID_FM_CTL_PROPERTIES:
1416 aColor = COL_TRANSPARENT;
1417 sColorName = SvxResId(RID_SVXSTR_DEFAULT);
1418 break;
1419 case SID_ATTR_CHAR_COLOR:
1420 case SID_ATTR_CHAR_COLOR2:
1421 case SID_EXTRUSION_3D_COLOR:
1422 default:
1423 aColor = COL_AUTO;
1424 sColorName = EditResId(RID_SVXSTR_AUTOMATIC);
1425 break;
1428 return std::make_pair(aColor, sColorName);
1431 NamedColor GetNoneColor()
1433 return std::make_pair(Color(COL_NONE_COLOR), SvxResId(RID_SVXSTR_NONE));
1437 NamedColor SvxColorWindow::GetSelectEntryColor() const
1439 if (!mpColorSet->IsNoSelection())
1440 return GetSelectEntryColor(mpColorSet);
1441 if (!mpRecentColorSet->IsNoSelection())
1442 return GetSelectEntryColor(mpRecentColorSet);
1443 if (mpButtonNoneColor->GetStyle() & WB_DEFBUTTON)
1444 return GetNoneColor();
1445 return GetAutoColor();
1448 IMPL_LINK(SvxColorWindow, SelectHdl, ValueSet*, pColorSet, void)
1450 VclPtr<SvxColorWindow> xThis(this);
1452 NamedColor aNamedColor = GetSelectEntryColor(pColorSet);
1453 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() calls.
1454 This instance may be deleted in the meantime (i.e. when a dialog is opened
1455 while in Dispatch()), accessing members will crash in this case. */
1456 pColorSet->SetNoSelection();
1458 if ( pColorSet != mpRecentColorSet )
1460 mxPaletteManager->AddRecentColor(aNamedColor.first, aNamedColor.second);
1461 if ( !IsInPopupMode() )
1462 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
1465 if ( IsInPopupMode() )
1466 EndPopupMode();
1468 maSelectedLink.Call(aNamedColor);
1470 maColorSelectFunction(maCommand, aNamedColor);
1473 IMPL_LINK_NOARG(SvxColorWindow, SelectPaletteHdl, ListBox&, void)
1475 sal_Int32 nPos = mpPaletteListBox->GetSelectedEntryPos();
1476 mxPaletteManager->SetPalette( nPos );
1477 mxPaletteManager->ReloadColorSet(*mpColorSet);
1478 mpColorSet->layoutToGivenHeight(mpColorSet->GetSizePixel().Height(), mxPaletteManager->GetColorCount());
1481 NamedColor SvxColorWindow::GetAutoColor() const
1483 return ::GetAutoColor(theSlotId);
1486 IMPL_LINK(SvxColorWindow, AutoColorClickHdl, Button*, pButton, void)
1488 VclPtr<SvxColorWindow> xThis(this);
1490 NamedColor aNamedColor = pButton == mpButtonAutoColor ? GetAutoColor() : GetNoneColor();
1492 mpRecentColorSet->SetNoSelection();
1494 if ( IsInPopupMode() )
1495 EndPopupMode();
1497 maSelectedLink.Call(aNamedColor);
1499 maColorSelectFunction(maCommand, aNamedColor);
1502 IMPL_LINK_NOARG(SvxColorWindow, OpenPickerClickHdl, Button*, void)
1504 VclPtr<SvxColorWindow> xThis(this);
1506 if ( IsInPopupMode() )
1507 EndPopupMode();
1508 mxPaletteManager->PopupColorPicker(maCommand, GetSelectEntryColor().first);
1511 void SvxColorWindow::StartSelection()
1513 mpColorSet->StartSelection();
1514 mpRecentColorSet->StartSelection();
1517 void SvxColorWindow::SetNoSelection()
1519 mpColorSet->SetNoSelection();
1520 mpRecentColorSet->SetNoSelection();
1521 mpButtonAutoColor->set_property("has-default", "false");
1522 mpButtonNoneColor->set_property("has-default", "false");
1525 bool SvxColorWindow::IsNoSelection() const
1527 if (!mpColorSet->IsNoSelection())
1528 return false;
1529 if (!mpRecentColorSet->IsNoSelection())
1530 return false;
1531 return !mpButtonAutoColor->IsVisible() && !mpButtonNoneColor->IsVisible();
1534 void SvxColorWindow::statusChanged( const css::frame::FeatureStateEvent& rEvent )
1536 if (rEvent.FeatureURL.Complete == ".uno:ColorTableState")
1538 if (rEvent.IsEnabled && mxPaletteManager->GetPalette() == 0)
1540 mxPaletteManager->ReloadColorSet(*mpColorSet);
1541 mpColorSet->layoutToGivenHeight(mpColorSet->GetSizePixel().Height(), mxPaletteManager->GetColorCount());
1544 else
1546 Color aColor(COL_TRANSPARENT);
1548 if (mrBorderColorStatus.statusChanged(rEvent))
1550 aColor = mrBorderColorStatus.GetColor();
1552 else if (rEvent.IsEnabled)
1554 sal_Int32 nValue;
1555 if (rEvent.State >>= nValue)
1556 aColor = nValue;
1559 SelectEntry(aColor);
1563 bool SvxColorWindow::SelectValueSetEntry(SvxColorValueSet* pColorSet, const Color& rColor)
1565 for (size_t i = 1; i <= pColorSet->GetItemCount(); ++i)
1567 if (rColor == pColorSet->GetItemColor(i))
1569 pColorSet->SelectItem(i);
1570 return true;
1573 return false;
1576 void SvxColorWindow::SelectEntry(const NamedColor& rNamedColor)
1578 SetNoSelection();
1580 const Color &rColor = rNamedColor.first;
1582 if (rColor == COL_TRANSPARENT || rColor == COL_AUTO)
1584 mpButtonAutoColor->set_property("has-default", "true");
1585 return;
1588 if (mpButtonNoneColor->IsVisible() && rColor == COL_NONE_COLOR)
1590 mpButtonNoneColor->set_property("has-default", "true");
1591 return;
1594 // try current palette
1595 bool bFoundColor = SelectValueSetEntry(mpColorSet, rColor);
1596 // try recently used
1597 if (!bFoundColor)
1598 bFoundColor = SelectValueSetEntry(mpRecentColorSet, rColor);
1599 // if its not there, add it there now to the end of the recently used
1600 // so its available somewhere handy, but not without trashing the
1601 // whole recently used
1602 if (!bFoundColor)
1604 const OUString& rColorName = rNamedColor.second;
1605 mxPaletteManager->AddRecentColor(rColor, rColorName, false);
1606 mxPaletteManager->ReloadRecentColorSet(*mpRecentColorSet);
1607 SelectValueSetEntry(mpRecentColorSet, rColor);
1611 void SvxColorWindow::SelectEntry(const Color& rColor)
1613 OUString sColorName = ("#" + rColor.AsRGBHexString().toAsciiUpperCase());
1614 SvxColorWindow::SelectEntry(std::make_pair(rColor, sColorName));
1617 BorderColorStatus::BorderColorStatus() :
1618 maColor( COL_TRANSPARENT ),
1619 maTLBRColor( COL_TRANSPARENT ),
1620 maBLTRColor( COL_TRANSPARENT )
1624 BorderColorStatus::~BorderColorStatus()
1628 bool BorderColorStatus::statusChanged( const css::frame::FeatureStateEvent& rEvent )
1630 Color aColor( COL_TRANSPARENT );
1632 if ( rEvent.FeatureURL.Complete == ".uno:FrameLineColor" )
1634 sal_Int32 nValue;
1635 if ( rEvent.IsEnabled && ( rEvent.State >>= nValue ) )
1636 aColor = nValue;
1638 maColor = aColor;
1639 return true;
1641 else
1643 css::table::BorderLine2 aTable;
1644 if ( rEvent.IsEnabled && ( rEvent.State >>= aTable ) )
1645 aColor = aTable.Color;
1647 if ( rEvent.FeatureURL.Complete == ".uno:BorderTLBR" )
1649 maTLBRColor = aColor;
1650 return true;
1652 else if ( rEvent.FeatureURL.Complete == ".uno:BorderBLTR" )
1654 maBLTRColor = aColor;
1655 return true;
1659 return false;
1662 Color BorderColorStatus::GetColor()
1664 bool bHasColor = maColor != COL_TRANSPARENT;
1665 bool bHasTLBRColor = maTLBRColor != COL_TRANSPARENT;
1666 bool bHasBLTRColor = maBLTRColor != COL_TRANSPARENT;
1668 if ( !bHasColor && bHasTLBRColor && !bHasBLTRColor )
1669 return maTLBRColor;
1670 else if ( !bHasColor && !bHasTLBRColor && bHasBLTRColor )
1671 return maBLTRColor;
1672 else if ( bHasColor && bHasTLBRColor && !bHasBLTRColor )
1674 if ( maColor == maTLBRColor )
1675 return maColor;
1676 else
1677 return maBLTRColor;
1679 else if ( bHasColor && !bHasTLBRColor && bHasBLTRColor )
1681 if ( maColor == maBLTRColor )
1682 return maColor;
1683 else
1684 return maTLBRColor;
1686 else if ( !bHasColor && bHasTLBRColor && bHasBLTRColor )
1688 if ( maTLBRColor == maBLTRColor )
1689 return maTLBRColor;
1690 else
1691 return maColor;
1693 else if ( bHasColor && bHasTLBRColor && bHasBLTRColor )
1695 if ( maColor == maTLBRColor && maColor == maBLTRColor )
1696 return maColor;
1697 else
1698 return COL_TRANSPARENT;
1700 return maColor;
1704 SvxFrameWindow_Impl::SvxFrameWindow_Impl ( svt::ToolboxController& rController, vcl::Window* pParentWindow ) :
1705 ToolbarPopup( rController.getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
1706 aFrameSet ( VclPtr<SvxFrmValueSet_Impl>::Create(this, WinBits( WB_ITEMBORDER | WB_DOUBLEBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT )) ),
1707 mrController( rController ),
1708 bParagraphMode(false)
1710 AddStatusListener(".uno:BorderReducedMode");
1711 InitImageList();
1714 * 1 2 3 4
1715 * -------------------------------------
1716 * NONE LEFT RIGHT LEFTRIGHT
1717 * TOP BOTTOM TOPBOTTOM OUTER
1718 * -------------------------------------
1719 * HOR HORINNER VERINNER ALL <- can be switched of via bParagraphMode
1722 sal_uInt16 i = 0;
1724 for ( i=1; i<9; i++ )
1725 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
1727 //bParagraphMode should have been set in StateChanged
1728 if ( !bParagraphMode )
1729 for ( i = 9; i < 13; i++ )
1730 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
1732 aFrameSet->SetColCount( 4 );
1733 aFrameSet->SetSelectHdl( LINK( this, SvxFrameWindow_Impl, SelectHdl ) );
1734 CalcSizeValueSet();
1736 SetHelpId( HID_POPUP_FRAME );
1737 SetText( SvxResId(RID_SVXSTR_FRAME) );
1738 aFrameSet->SetAccessibleName( SvxResId(RID_SVXSTR_FRAME) );
1739 aFrameSet->Show();
1742 SvxFrameWindow_Impl::~SvxFrameWindow_Impl()
1744 disposeOnce();
1747 void SvxFrameWindow_Impl::dispose()
1749 aFrameSet.disposeAndClear();
1750 ToolbarPopup::dispose();
1753 void SvxFrameWindow_Impl::GetFocus()
1755 if (aFrameSet)
1756 aFrameSet->StartSelection();
1759 void SvxFrameWindow_Impl::KeyInput( const KeyEvent& rKEvt )
1761 aFrameSet->GrabFocus();
1762 aFrameSet->KeyInput( rKEvt );
1765 void SvxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1767 ToolbarPopup::DataChanged( rDCEvt );
1769 if ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) && ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
1771 InitImageList();
1773 sal_uInt16 nNumOfItems = aFrameSet->GetItemCount();
1774 for ( sal_uInt16 i = 1 ; i <= nNumOfItems ; ++i )
1775 aFrameSet->SetItemImage( i, Image(aImgVec[i-1]) );
1779 enum class FrmValidFlags {
1780 NONE = 0x00,
1781 Left = 0x01,
1782 Right = 0x02,
1783 Top = 0x04,
1784 Bottom = 0x08,
1785 HInner = 0x10,
1786 VInner = 0x20,
1787 AllMask = 0x3f,
1789 namespace o3tl {
1790 template<> struct typed_flags<FrmValidFlags> : is_typed_flags<FrmValidFlags, 0x3f> {};
1793 // By default unset lines remain unchanged.
1794 // Via Shift unset lines are reset
1796 IMPL_LINK_NOARG(SvxFrameWindow_Impl, SelectHdl, ValueSet*, void)
1798 VclPtr<SvxFrameWindow_Impl> xThis(this);
1800 SvxBoxItem aBorderOuter( SID_ATTR_BORDER_OUTER );
1801 SvxBoxInfoItem aBorderInner( SID_ATTR_BORDER_INNER );
1802 SvxBorderLine theDefLine;
1803 SvxBorderLine *pLeft = nullptr,
1804 *pRight = nullptr,
1805 *pTop = nullptr,
1806 *pBottom = nullptr;
1807 sal_uInt16 nSel = aFrameSet->GetSelectItemId();
1808 sal_uInt16 nModifier = aFrameSet->GetModifier();
1809 FrmValidFlags nValidFlags = FrmValidFlags::NONE;
1811 theDefLine.GuessLinesWidths(theDefLine.GetBorderLineStyle(),
1812 DEF_LINE_WIDTH_0);
1813 switch ( nSel )
1815 case 1: nValidFlags |= FrmValidFlags::AllMask;
1816 break; // NONE
1817 case 2: pLeft = &theDefLine;
1818 nValidFlags |= FrmValidFlags::Left;
1819 break; // LEFT
1820 case 3: pRight = &theDefLine;
1821 nValidFlags |= FrmValidFlags::Right;
1822 break; // RIGHT
1823 case 4: pLeft = pRight = &theDefLine;
1824 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left;
1825 break; // LEFTRIGHT
1826 case 5: pTop = &theDefLine;
1827 nValidFlags |= FrmValidFlags::Top;
1828 break; // TOP
1829 case 6: pBottom = &theDefLine;
1830 nValidFlags |= FrmValidFlags::Bottom;
1831 break; // BOTTOM
1832 case 7: pTop = pBottom = &theDefLine;
1833 nValidFlags |= FrmValidFlags::Bottom|FrmValidFlags::Top;
1834 break; // TOPBOTTOM
1835 case 8: pLeft = pRight = pTop = pBottom = &theDefLine;
1836 nValidFlags |= FrmValidFlags::Left | FrmValidFlags::Right | FrmValidFlags::Top | FrmValidFlags::Bottom;
1837 break; // OUTER
1839 // Inner Table:
1840 case 9: // HOR
1841 pTop = pBottom = &theDefLine;
1842 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
1843 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
1844 nValidFlags |= FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
1845 break;
1847 case 10: // HORINNER
1848 pLeft = pRight = pTop = pBottom = &theDefLine;
1849 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
1850 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
1851 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::HInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
1852 break;
1854 case 11: // VERINNER
1855 pLeft = pRight = pTop = pBottom = &theDefLine;
1856 aBorderInner.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
1857 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
1858 nValidFlags |= FrmValidFlags::Right|FrmValidFlags::Left|FrmValidFlags::VInner|FrmValidFlags::Top|FrmValidFlags::Bottom;
1859 break;
1861 case 12: // ALL
1862 pLeft = pRight = pTop = pBottom = &theDefLine;
1863 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::HORI );
1864 aBorderInner.SetLine( &theDefLine, SvxBoxInfoItemLine::VERT );
1865 nValidFlags |= FrmValidFlags::AllMask;
1866 break;
1868 default:
1869 break;
1871 aBorderOuter.SetLine( pLeft, SvxBoxItemLine::LEFT );
1872 aBorderOuter.SetLine( pRight, SvxBoxItemLine::RIGHT );
1873 aBorderOuter.SetLine( pTop, SvxBoxItemLine::TOP );
1874 aBorderOuter.SetLine( pBottom, SvxBoxItemLine::BOTTOM );
1876 if(nModifier == KEY_SHIFT)
1877 nValidFlags |= FrmValidFlags::AllMask;
1878 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::TOP, bool(nValidFlags&FrmValidFlags::Top ));
1879 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, bool(nValidFlags&FrmValidFlags::Bottom ));
1880 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::LEFT, bool(nValidFlags&FrmValidFlags::Left));
1881 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::RIGHT, bool(nValidFlags&FrmValidFlags::Right ));
1882 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::HORI, bool(nValidFlags&FrmValidFlags::HInner ));
1883 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::VERT, bool(nValidFlags&FrmValidFlags::VInner));
1884 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
1885 aBorderInner.SetValid( SvxBoxInfoItemValidFlags::DISABLE, false );
1887 if ( IsInPopupMode() )
1888 EndPopupMode();
1890 Any a;
1891 Sequence< PropertyValue > aArgs( 2 );
1892 aArgs[0].Name = "OuterBorder";
1893 aBorderOuter.QueryValue( a );
1894 aArgs[0].Value = a;
1895 aArgs[1].Name = "InnerBorder";
1896 aBorderInner.QueryValue( a );
1897 aArgs[1].Value = a;
1899 if (aFrameSet)
1901 /* #i33380# Moved the following line above the Dispatch() call.
1902 This instance may be deleted in the meantime (i.e. when a dialog is opened
1903 while in Dispatch()), accessing members will crash in this case. */
1904 aFrameSet->SetNoSelection();
1907 mrController.dispatchCommand( ".uno:SetBorderStyle", aArgs );
1910 void SvxFrameWindow_Impl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
1912 if ( rEvent.FeatureURL.Complete == ".uno:BorderReducedMode" )
1914 bool bValue;
1915 if ( rEvent.State >>= bValue )
1917 bParagraphMode = bValue;
1918 //initial calls mustn't insert or remove elements
1919 if(aFrameSet->GetItemCount())
1921 bool bTableMode = ( aFrameSet->GetItemCount() == 12 );
1922 bool bResize = false;
1924 if ( bTableMode && bParagraphMode )
1926 for ( sal_uInt16 i = 9; i < 13; i++ )
1927 aFrameSet->RemoveItem(i);
1928 bResize = true;
1930 else if ( !bTableMode && !bParagraphMode )
1932 for ( sal_uInt16 i = 9; i < 13; i++ )
1933 aFrameSet->InsertItem(i, Image(aImgVec[i-1]));
1934 bResize = true;
1937 if ( bResize )
1939 CalcSizeValueSet();
1946 void SvxFrameWindow_Impl::CalcSizeValueSet()
1948 Size aItemSize( 20 * GetParent()->GetDPIScaleFactor(), 20 * GetParent()->GetDPIScaleFactor() );
1949 Size aSize = aFrameSet->CalcWindowSizePixel( aItemSize );
1950 aFrameSet->SetPosSizePixel( Point( 2, 2 ), aSize );
1951 aSize.Width() += 4;
1952 aSize.Height() += 4;
1953 SetOutputSizePixel( aSize );
1956 void SvxFrameWindow_Impl::InitImageList()
1958 aImgVec.clear();
1959 aImgVec.emplace_back(RID_SVXBMP_FRAME1);
1960 aImgVec.emplace_back(RID_SVXBMP_FRAME2);
1961 aImgVec.emplace_back(RID_SVXBMP_FRAME3);
1962 aImgVec.emplace_back(RID_SVXBMP_FRAME4);
1963 aImgVec.emplace_back(RID_SVXBMP_FRAME5);
1964 aImgVec.emplace_back(RID_SVXBMP_FRAME6);
1965 aImgVec.emplace_back(RID_SVXBMP_FRAME7);
1966 aImgVec.emplace_back(RID_SVXBMP_FRAME8);
1967 aImgVec.emplace_back(RID_SVXBMP_FRAME9);
1968 aImgVec.emplace_back(RID_SVXBMP_FRAME10);
1969 aImgVec.emplace_back(RID_SVXBMP_FRAME11);
1970 aImgVec.emplace_back(RID_SVXBMP_FRAME12);
1972 if (GetParent()->GetDPIScaleFactor() > 1)
1974 for (size_t i = 0; i < aImgVec.size(); ++i)
1976 aImgVec[i].Scale(GetParent()->GetDPIScaleFactor(), GetParent()->GetDPIScaleFactor());
1981 static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
1983 return SvxBorderLine::threeDMediumColor( aMain );
1986 SvxCurrencyList_Impl::SvxCurrencyList_Impl(
1987 SvxCurrencyToolBoxControl* pControl,
1988 vcl::Window* pParentWindow,
1989 OUString& rSelectedFormat,
1990 LanguageType& eSelectedLanguage ) :
1991 ToolbarPopup( pControl->getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
1992 m_pCurrencyLb( VclPtr<ListBox>::Create(this) ),
1993 m_xControl( pControl ),
1994 m_rSelectedFormat( rSelectedFormat ),
1995 m_eSelectedLanguage( eSelectedLanguage )
1997 m_pCurrencyLb->setPosSizePixel( 2, 2, 300, 140 );
1998 SetOutputSizePixel( Size( 304, 144 ) );
2000 std::vector< OUString > aList;
2001 std::vector< sal_uInt16 > aCurrencyList;
2002 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
2003 sal_uInt16 nLen = rCurrencyTable.size();
2005 SvNumberFormatter aFormatter( m_xControl->getContext(), LANGUAGE_SYSTEM );
2006 m_eFormatLanguage = aFormatter.GetLanguage();
2008 SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, aCurrencyList );
2010 sal_uInt16 nPos = 0, nCount = 0;
2011 sal_Int32 nSelectedPos = -1;
2012 bool bIsSymbol;
2013 NfWSStringsDtor aStringsDtor;
2015 for( std::vector< OUString >::iterator i = aList.begin(); i != aList.end(); ++i, ++nCount )
2017 sal_uInt16& rCurrencyIndex = aCurrencyList[ nCount ];
2018 if ( rCurrencyIndex < nLen )
2020 m_pCurrencyLb->InsertEntry( *i );
2021 const NfCurrencyEntry& aCurrencyEntry = rCurrencyTable[ rCurrencyIndex ];
2023 bIsSymbol = nPos >= nLen;
2025 sal_uInt16 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, aCurrencyEntry, bIsSymbol );
2026 const OUString& rFormatStr = aStringsDtor[ nDefaultFormat ];
2027 m_aFormatEntries.push_back( rFormatStr );
2028 if( rFormatStr == m_rSelectedFormat )
2029 nSelectedPos = nPos;
2030 ++nPos;
2033 m_pCurrencyLb->SetSelectHdl( LINK( this, SvxCurrencyList_Impl, SelectHdl ) );
2034 SetText( SvxResId( RID_SVXSTR_TBLAFMT_CURRENCY ) );
2035 if ( nSelectedPos >= 0 )
2036 m_pCurrencyLb->SelectEntryPos( nSelectedPos );
2037 m_pCurrencyLb->Show();
2040 void SvxCurrencyList_Impl::dispose()
2042 m_xControl.clear();
2043 m_pCurrencyLb.disposeAndClear();
2044 ToolbarPopup::dispose();
2047 SvxLineWindow_Impl::SvxLineWindow_Impl( svt::ToolboxController& rController, vcl::Window* pParentWindow ) :
2048 ToolbarPopup( rController.getFrameInterface(), pParentWindow, WB_STDPOPUP | WB_MOVEABLE | WB_CLOSEABLE ),
2049 m_aLineStyleLb( VclPtr<LineListBox>::Create(this) ),
2050 m_rController( rController )
2054 Reference< lang::XServiceInfo > xServices( rController.getFrameInterface()->getController()->getModel(), UNO_QUERY_THROW );
2055 m_bIsWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2057 catch(const uno::Exception& )
2061 m_aLineStyleLb->setPosSizePixel( 2, 2, 110, 140 );
2062 SetOutputSizePixel( Size( 114, 144 ) );
2064 m_aLineStyleLb->SetSourceUnit( FUNIT_TWIP );
2065 m_aLineStyleLb->SetNone( SvxResId(RID_SVXSTR_NONE) );
2067 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::SOLID ), SvxBorderLineStyle::SOLID );
2068 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOTTED ), SvxBorderLineStyle::DOTTED );
2069 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DASHED ), SvxBorderLineStyle::DASHED );
2071 // Double lines
2072 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::DOUBLE ), SvxBorderLineStyle::DOUBLE );
2073 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_SMALLGAP ), SvxBorderLineStyle::THINTHICK_SMALLGAP, 20 );
2074 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_MEDIUMGAP ), SvxBorderLineStyle::THINTHICK_MEDIUMGAP );
2075 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THINTHICK_LARGEGAP ), SvxBorderLineStyle::THINTHICK_LARGEGAP );
2076 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_SMALLGAP ), SvxBorderLineStyle::THICKTHIN_SMALLGAP, 20 );
2077 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_MEDIUMGAP ), SvxBorderLineStyle::THICKTHIN_MEDIUMGAP );
2078 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::THICKTHIN_LARGEGAP ), SvxBorderLineStyle::THICKTHIN_LARGEGAP );
2080 // Engraved / Embossed
2081 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::EMBOSSED ), SvxBorderLineStyle::EMBOSSED, 15,
2082 &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor,
2083 &lcl_mediumColor );
2084 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::ENGRAVED ), SvxBorderLineStyle::ENGRAVED, 15,
2085 &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor,
2086 &lcl_mediumColor );
2088 // Inset / Outset
2089 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::OUTSET ), SvxBorderLineStyle::OUTSET, 10,
2090 &SvxBorderLine::lightColor, &SvxBorderLine::darkColor );
2091 m_aLineStyleLb->InsertEntry( SvxBorderLine::getWidthImpl( SvxBorderLineStyle::INSET ), SvxBorderLineStyle::INSET, 10,
2092 &SvxBorderLine::darkColor, &SvxBorderLine::lightColor );
2093 m_aLineStyleLb->SetWidth( 20 ); // 1pt by default
2095 m_aLineStyleLb->SetSelectHdl( LINK( this, SvxLineWindow_Impl, SelectHdl ) );
2097 SetHelpId( HID_POPUP_LINE );
2098 SetText( SvxResId(RID_SVXSTR_FRAME_STYLE) );
2099 m_aLineStyleLb->Show();
2102 IMPL_LINK_NOARG(SvxCurrencyList_Impl, SelectHdl, ListBox&, void)
2104 VclPtr<SvxCurrencyList_Impl> xThis(this);
2106 if ( IsInPopupMode() )
2107 EndPopupMode();
2109 if (!m_xControl.is())
2110 return;
2112 m_rSelectedFormat = m_aFormatEntries[ m_pCurrencyLb->GetSelectedEntryPos() ];
2113 m_eSelectedLanguage = m_eFormatLanguage;
2115 m_xControl->execute( m_pCurrencyLb->GetSelectedEntryPos() + 1 );
2118 IMPL_LINK_NOARG(SvxLineWindow_Impl, SelectHdl, ListBox&, void)
2120 VclPtr<SvxLineWindow_Impl> xThis(this);
2122 SvxLineItem aLineItem( SID_FRAME_LINESTYLE );
2123 SvxBorderLineStyle nStyle = m_aLineStyleLb->GetSelectEntryStyle();
2125 if ( m_aLineStyleLb->GetSelectedEntryPos( ) > 0 )
2127 SvxBorderLine aTmp;
2128 aTmp.SetBorderLineStyle( nStyle );
2129 aTmp.SetWidth( 20 ); // TODO Make it depend on a width field
2130 aLineItem.SetLine( &aTmp );
2132 else
2133 aLineItem.SetLine( nullptr );
2135 if ( IsInPopupMode() )
2136 EndPopupMode();
2138 Any a;
2139 Sequence< PropertyValue > aArgs( 1 );
2140 aArgs[0].Name = "LineStyle";
2141 aLineItem.QueryValue( a, m_bIsWriter ? CONVERT_TWIPS : 0 );
2142 aArgs[0].Value = a;
2144 m_rController.dispatchCommand( ".uno:LineStyle", aArgs );
2147 void SvxLineWindow_Impl::Resize()
2149 m_aLineStyleLb->Resize();
2152 void SvxLineWindow_Impl::GetFocus()
2154 if ( m_aLineStyleLb )
2155 m_aLineStyleLb->GrabFocus();
2158 SfxStyleControllerItem_Impl::SfxStyleControllerItem_Impl(
2159 const Reference< XDispatchProvider >& rDispatchProvider,
2160 sal_uInt16 nSlotId, // Family-ID
2161 const OUString& rCommand, // .uno: command bound to this item
2162 SvxStyleToolBoxControl& rTbxCtl ) // controller instance, which the item is assigned to.
2163 : SfxStatusListener( rDispatchProvider, nSlotId, rCommand ),
2164 rControl( rTbxCtl )
2168 void SfxStyleControllerItem_Impl::StateChanged(
2169 sal_uInt16, SfxItemState eState, const SfxPoolItem* pState )
2171 switch ( GetId() )
2173 case SID_STYLE_FAMILY1:
2174 case SID_STYLE_FAMILY2:
2175 case SID_STYLE_FAMILY3:
2176 case SID_STYLE_FAMILY4:
2177 case SID_STYLE_FAMILY5:
2179 const sal_uInt16 nIdx = GetId() - SID_STYLE_FAMILY_START;
2181 if ( SfxItemState::DEFAULT == eState )
2183 const SfxTemplateItem* pStateItem =
2184 dynamic_cast<const SfxTemplateItem*>( pState );
2185 DBG_ASSERT( pStateItem != nullptr, "SfxTemplateItem expected" );
2186 rControl.SetFamilyState( nIdx, pStateItem );
2188 else
2189 rControl.SetFamilyState( nIdx, nullptr );
2190 break;
2195 struct SvxStyleToolBoxControl::Impl
2197 OUString aClearForm;
2198 OUString aMore;
2199 ::std::vector< OUString > aDefaultStyles;
2200 bool bSpecModeWriter;
2201 bool bSpecModeCalc;
2203 Impl()
2204 :aClearForm ( SvxResId( RID_SVXSTR_CLEARFORM ) )
2205 ,aMore ( SvxResId( RID_SVXSTR_MORE_STYLES ) )
2206 ,bSpecModeWriter ( false )
2207 ,bSpecModeCalc ( false )
2212 void InitializeStyles(const Reference < frame::XModel >& xModel)
2214 //now convert the default style names to the localized names
2217 Reference< style::XStyleFamiliesSupplier > xStylesSupplier( xModel, UNO_QUERY_THROW );
2218 Reference< lang::XServiceInfo > xServices( xModel, UNO_QUERY_THROW );
2219 bSpecModeWriter = xServices->supportsService("com.sun.star.text.TextDocument");
2220 if(bSpecModeWriter)
2222 Reference<container::XNameAccess> xParaStyles;
2223 xStylesSupplier->getStyleFamilies()->getByName("ParagraphStyles") >>=
2224 xParaStyles;
2225 static const std::vector<OUString> aWriterStyles =
2227 "Text body",
2228 "Quotations",
2229 "Title",
2230 "Subtitle",
2231 "Heading 1",
2232 "Heading 2",
2233 "Heading 3"
2235 for( const OUString& aStyle: aWriterStyles )
2239 Reference< beans::XPropertySet > xStyle;
2240 xParaStyles->getByName( aStyle ) >>= xStyle;
2241 OUString sName;
2242 xStyle->getPropertyValue("DisplayName") >>= sName;
2243 if( !sName.isEmpty() )
2244 aDefaultStyles.push_back(sName);
2246 catch( const uno::Exception& )
2251 else if( (
2252 bSpecModeCalc = xServices->supportsService(
2253 "com.sun.star.sheet.SpreadsheetDocument")))
2255 static const sal_Char* aCalcStyles[] =
2257 "Default",
2258 "Heading1",
2259 "Result",
2260 "Result2"
2262 Reference<container::XNameAccess> xCellStyles;
2263 xStylesSupplier->getStyleFamilies()->getByName("CellStyles") >>= xCellStyles;
2264 for(const char* pCalcStyle : aCalcStyles)
2268 const OUString sStyleName( OUString::createFromAscii( pCalcStyle ) );
2269 if( xCellStyles->hasByName( sStyleName ) )
2271 Reference< beans::XPropertySet > xStyle( xCellStyles->getByName( sStyleName), UNO_QUERY_THROW );
2272 OUString sName;
2273 xStyle->getPropertyValue("DisplayName") >>= sName;
2274 if( !sName.isEmpty() )
2275 aDefaultStyles.push_back(sName);
2278 catch( const uno::Exception& )
2283 catch(const uno::Exception& )
2285 OSL_FAIL("error while initializing style names");
2290 // mapping table from bound items. BE CAREFUL this table must be in the
2291 // same order as the uno commands bound to the slots SID_STYLE_FAMILY1..n
2292 // MAX_FAMILIES must also be correctly set!
2293 static const char* StyleSlotToStyleCommand[MAX_FAMILIES] =
2295 ".uno:CharStyle",
2296 ".uno:ParaStyle",
2297 ".uno:FrameStyle",
2298 ".uno:PageStyle",
2299 ".uno:TemplateFamily5"
2302 SvxStyleToolBoxControl::SvxStyleToolBoxControl(
2303 sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
2304 : SfxToolBoxControl ( nSlotId, nId, rTbx ),
2305 pImpl ( new Impl ),
2306 pStyleSheetPool ( nullptr ),
2307 nActFamily ( 0xffff )
2309 for ( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
2311 pBoundItems[i] = nullptr;
2312 m_xBoundItems[i].clear();
2313 pFamilyState[i] = nullptr;
2317 SvxStyleToolBoxControl::~SvxStyleToolBoxControl()
2321 void SAL_CALL SvxStyleToolBoxControl::initialize( const Sequence< Any >& aArguments )
2323 SfxToolBoxControl::initialize( aArguments );
2325 // After initialize we should have a valid frame member where we can retrieve our
2326 // dispatch provider.
2327 if ( m_xFrame.is() )
2329 pImpl->InitializeStyles(m_xFrame->getController()->getModel());
2330 Reference< XDispatchProvider > xDispatchProvider( m_xFrame->getController(), UNO_QUERY );
2331 for ( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
2333 pBoundItems[i] = new SfxStyleControllerItem_Impl( xDispatchProvider,
2334 SID_STYLE_FAMILY_START + i,
2335 OUString::createFromAscii( StyleSlotToStyleCommand[i] ),
2336 *this );
2337 m_xBoundItems[i].set( static_cast< OWeakObject* >( pBoundItems[i] ), UNO_QUERY );
2338 pFamilyState[i] = nullptr;
2343 // XComponent
2344 void SAL_CALL SvxStyleToolBoxControl::dispose()
2346 SfxToolBoxControl::dispose();
2348 for( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
2350 if ( m_xBoundItems[i].is() )
2354 m_xBoundItems[i]->dispose();
2356 catch ( Exception& )
2360 m_xBoundItems[i].clear();
2361 pBoundItems[i] = nullptr;
2363 delete pFamilyState[i];
2364 pFamilyState[i] = nullptr;
2366 pStyleSheetPool = nullptr;
2367 pImpl.reset();
2370 void SAL_CALL SvxStyleToolBoxControl::update()
2372 // Do nothing, we will start binding our listener when we are visible.
2373 // See link SvxStyleToolBoxControl::VisibilityNotification.
2374 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
2375 if ( pBox->IsVisible() )
2377 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
2378 pBoundItem->ReBind();
2380 bindListener();
2384 SfxStyleFamily SvxStyleToolBoxControl::GetActFamily()
2386 switch ( nActFamily-1 + SID_STYLE_FAMILY_START )
2388 case SID_STYLE_FAMILY1: return SfxStyleFamily::Char;
2389 case SID_STYLE_FAMILY2: return SfxStyleFamily::Para;
2390 case SID_STYLE_FAMILY3: return SfxStyleFamily::Frame;
2391 case SID_STYLE_FAMILY4: return SfxStyleFamily::Page;
2392 case SID_STYLE_FAMILY5: return SfxStyleFamily::Pseudo;
2393 default:
2394 OSL_FAIL( "unknown style family" );
2395 break;
2397 return SfxStyleFamily::Para;
2400 void SvxStyleToolBoxControl::FillStyleBox()
2402 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
2404 DBG_ASSERT( pStyleSheetPool, "StyleSheetPool not found!" );
2405 DBG_ASSERT( pBox, "Control not found!" );
2407 if ( pStyleSheetPool && pBox && nActFamily!=0xffff )
2409 const SfxStyleFamily eFamily = GetActFamily();
2410 sal_uInt16 nCount = pStyleSheetPool->Count();
2411 SfxStyleSheetBase* pStyle = nullptr;
2412 bool bDoFill = false;
2414 pStyleSheetPool->SetSearchMask( eFamily, SFXSTYLEBIT_USED );
2416 // Check whether fill is necessary
2417 pStyle = pStyleSheetPool->First();
2418 //!!! TODO: This condition isn't right any longer, because we always show some default entries
2419 //!!! so the list doesn't show the count
2420 if ( nCount != pBox->GetEntryCount() )
2422 bDoFill = true;
2424 else
2426 sal_uInt16 i= 0;
2427 while ( pStyle && !bDoFill )
2429 bDoFill = ( pBox->GetEntry(i) != pStyle->GetName() );
2430 pStyle = pStyleSheetPool->Next();
2431 i++;
2435 if ( bDoFill )
2437 pBox->SetUpdateMode( false );
2438 pBox->Clear();
2441 pStyle = pStyleSheetPool->First();
2443 if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
2445 while ( pStyle )
2447 // sort out default styles
2448 bool bInsert = true;
2449 OUString aName( pStyle->GetName() );
2450 for( auto const & _i: pImpl->aDefaultStyles )
2452 if( _i == aName )
2454 bInsert = false;
2455 break;
2459 if( bInsert )
2460 pBox->InsertEntry( aName );
2461 pStyle = pStyleSheetPool->Next();
2464 else
2466 while ( pStyle )
2468 pBox->InsertEntry( pStyle->GetName() );
2469 pStyle = pStyleSheetPool->Next();
2474 if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
2476 // disable sort to preserve special order
2477 WinBits nWinBits = pBox->GetStyle();
2478 nWinBits &= ~WB_SORT;
2479 pBox->SetStyle( nWinBits );
2481 // insert default styles
2482 sal_uInt16 nPos = 1;
2483 for( auto const & _i: pImpl->aDefaultStyles )
2485 pBox->InsertEntry( _i, nPos );
2486 ++nPos;
2489 pBox->InsertEntry( pImpl->aClearForm, 0 );
2490 pBox->SetSeparatorPos( 0 );
2492 pBox->InsertEntry( pImpl->aMore );
2494 // enable sort again
2495 nWinBits |= WB_SORT;
2496 pBox->SetStyle( nWinBits );
2499 pBox->SetUpdateMode( true );
2500 pBox->SetFamily( eFamily );
2502 sal_uInt16 nLines = static_cast<sal_uInt16>(
2503 std::min( pBox->GetEntryCount(), static_cast<sal_Int32>(MAX_STYLES_ENTRIES)));
2504 pBox->SetDropDownLineCount( nLines );
2509 void SvxStyleToolBoxControl::SelectStyle( const OUString& rStyleName )
2511 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
2512 DBG_ASSERT( pBox, "Control not found!" );
2514 if ( pBox )
2516 OUString aStrSel( pBox->GetText() );
2518 if ( !rStyleName.isEmpty() )
2520 if ( rStyleName != aStrSel )
2521 pBox->SetText( rStyleName );
2523 else
2524 pBox->SetNoSelection();
2525 pBox->SaveValue();
2529 void SvxStyleToolBoxControl::Update()
2531 SfxStyleSheetBasePool* pPool = nullptr;
2532 SfxObjectShell* pDocShell = SfxObjectShell::Current();
2534 if ( pDocShell )
2535 pPool = pDocShell->GetStyleSheetPool();
2537 sal_uInt16 i;
2538 for ( i=0; i<MAX_FAMILIES; i++ )
2539 if( pFamilyState[i] )
2540 break;
2542 if ( i==MAX_FAMILIES || !pPool )
2544 pStyleSheetPool = pPool;
2545 return;
2549 const SfxTemplateItem* pItem = nullptr;
2551 if ( nActFamily == 0xffff || nullptr == (pItem = pFamilyState[nActFamily-1]) )
2552 // Current range not within allowed ranges or default
2554 pStyleSheetPool = pPool;
2555 nActFamily = 2;
2557 pItem = pFamilyState[nActFamily-1];
2558 if ( !pItem )
2560 nActFamily++;
2561 pItem = pFamilyState[nActFamily-1];
2564 if ( !pItem )
2566 SAL_INFO( "svx", "Unknown Family" ); // can happen
2569 else if ( pPool != pStyleSheetPool )
2570 pStyleSheetPool = pPool;
2572 FillStyleBox(); // Decides by itself whether Fill is needed
2574 if ( pItem )
2575 SelectStyle( pItem->GetStyleName() );
2578 void SvxStyleToolBoxControl::SetFamilyState( sal_uInt16 nIdx,
2579 const SfxTemplateItem* pItem )
2581 delete pFamilyState[nIdx];
2582 pFamilyState[nIdx] = nullptr;
2584 if ( pItem )
2585 pFamilyState[nIdx] = new SfxTemplateItem( *pItem );
2587 Update();
2590 IMPL_LINK_NOARG(SvxStyleToolBoxControl, VisibilityNotification, SvxStyleBox_Impl&, void)
2592 // Call ReBind() && UnBind() according to visibility
2593 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>( GetToolBox().GetItemWindow( GetId() ));
2595 if ( pBox && pBox->IsVisible() && !isBound() )
2597 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
2598 pBoundItem->ReBind();
2600 bindListener();
2602 else if ( (!pBox || !pBox->IsVisible()) && isBound() )
2604 for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
2605 pBoundItem->UnBind();
2606 unbindListener();
2610 void SvxStyleToolBoxControl::StateChanged(
2611 sal_uInt16 , SfxItemState eState, const SfxPoolItem* pState )
2613 sal_uInt16 nId = GetId();
2614 ToolBox& rTbx = GetToolBox();
2615 SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(rTbx.GetItemWindow( nId ));
2616 TriState eTri = TRISTATE_FALSE;
2618 DBG_ASSERT( pBox, "Control not found!" );
2620 if ( SfxItemState::DISABLED == eState )
2621 pBox->Disable();
2622 else
2623 pBox->Enable();
2625 rTbx.EnableItem( nId, SfxItemState::DISABLED != eState );
2627 switch ( eState )
2629 case SfxItemState::DEFAULT:
2630 eTri = static_cast<const SfxTemplateItem*>(pState)->GetValue()
2631 ? TRISTATE_TRUE
2632 : TRISTATE_FALSE;
2633 break;
2635 case SfxItemState::DONTCARE:
2636 eTri = TRISTATE_INDET;
2637 break;
2639 default:
2640 break;
2643 rTbx.SetItemState( nId, eTri );
2645 if ( SfxItemState::DISABLED != eState )
2646 Update();
2649 VclPtr<vcl::Window> SvxStyleToolBoxControl::CreateItemWindow( vcl::Window *pParent )
2651 VclPtrInstance<SvxStyleBox_Impl> pBox( pParent,
2652 OUString( ".uno:StyleApply" ),
2653 SfxStyleFamily::Para,
2654 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
2655 m_xFrame,
2656 pImpl->aClearForm,
2657 pImpl->aMore,
2658 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc );
2659 if( !pImpl->aDefaultStyles.empty())
2660 pBox->SetDefaultStyle( pImpl->aDefaultStyles[0] );
2661 // Set visibility listener to bind/unbind controller
2662 pBox->SetVisibilityListener( LINK( this, SvxStyleToolBoxControl, VisibilityNotification ));
2664 return pBox.get();
2667 class SvxFontNameToolBoxControl : public cppu::ImplInheritanceHelper< svt::ToolboxController,
2668 css::lang::XServiceInfo >
2670 public:
2671 SvxFontNameToolBoxControl();
2673 // XStatusListener
2674 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
2676 // XToolbarController
2677 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent ) override;
2679 // XComponent
2680 virtual void SAL_CALL dispose() override;
2682 // XServiceInfo
2683 virtual OUString SAL_CALL getImplementationName() override;
2684 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
2685 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
2687 private:
2688 VclPtr<SvxFontNameBox_Impl> m_pBox;
2691 SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
2695 void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2697 SolarMutexGuard aGuard;
2698 ToolBox* pToolBox = nullptr;
2699 sal_uInt16 nId = 0;
2700 if ( !getToolboxId( nId, &pToolBox ) )
2701 return;
2703 if ( !rEvent.IsEnabled )
2705 m_pBox->Disable();
2706 m_pBox->Update( nullptr );
2708 else
2710 m_pBox->Enable();
2712 css::awt::FontDescriptor aFontDesc;
2713 if ( rEvent.State >>= aFontDesc )
2714 m_pBox->Update( &aFontDesc );
2715 else
2716 m_pBox->SetText( "" );
2717 m_pBox->SaveValue();
2720 pToolBox->EnableItem( nId, rEvent.IsEnabled );
2723 css::uno::Reference< css::awt::XWindow > SvxFontNameToolBoxControl::createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent )
2725 SolarMutexGuard aGuard;
2726 m_pBox = VclPtr<SvxFontNameBox_Impl>::Create( VCLUnoHelper::GetWindow( rParent ),
2727 Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
2728 m_xFrame, 0);
2729 return VCLUnoHelper::GetInterface( m_pBox );
2732 void SvxFontNameToolBoxControl::dispose()
2734 m_pBox.disposeAndClear();
2735 ToolboxController::dispose();
2738 OUString SvxFontNameToolBoxControl::getImplementationName()
2740 return OUString( "com.sun.star.comp.svx.FontNameToolBoxControl" );
2743 sal_Bool SvxFontNameToolBoxControl::supportsService( const OUString& rServiceName )
2745 return cppu::supportsService( this, rServiceName );
2748 css::uno::Sequence< OUString > SvxFontNameToolBoxControl::getSupportedServiceNames()
2750 return { "com.sun.star.frame.ToolbarController" };
2753 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
2754 com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation(
2755 css::uno::XComponentContext*,
2756 css::uno::Sequence<css::uno::Any> const & )
2758 return cppu::acquire( new SvxFontNameToolBoxControl() );
2761 SvxColorToolBoxControl::SvxColorToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
2762 ImplInheritanceHelper( rContext, nullptr, OUString() ),
2763 m_bSplitButton(true),
2764 m_nSlotId(0),
2765 m_aColorSelectFunction(PaletteManager::DispatchColorCommand)
2769 namespace {
2771 sal_uInt16 MapCommandToSlotId(const OUString& rCommand)
2773 if (rCommand == ".uno:Color")
2774 return SID_ATTR_CHAR_COLOR;
2775 else if (rCommand == ".uno:FontColor")
2776 return SID_ATTR_CHAR_COLOR2;
2777 else if (rCommand == ".uno:BackColor")
2778 return SID_ATTR_CHAR_COLOR_BACKGROUND;
2779 else if (rCommand == ".uno:CharBackColor")
2780 return SID_ATTR_CHAR_BACK_COLOR;
2781 else if (rCommand == ".uno:BackgroundColor")
2782 return SID_BACKGROUND_COLOR;
2783 else if (rCommand == ".uno:Extrusion3DColor")
2784 return SID_EXTRUSION_3D_COLOR;
2785 else if (rCommand == ".uno:XLineColor")
2786 return SID_ATTR_LINE_COLOR;
2787 else if (rCommand == ".uno:FillColor")
2788 return SID_ATTR_FILL_COLOR;
2789 else if (rCommand == ".uno:FrameLineColor")
2790 return SID_FRAME_LINECOLOR;
2792 SAL_WARN("svx.tbxcrtls", "Unknown color command: " << rCommand);
2793 return 0;
2798 void SvxColorToolBoxControl::initialize( const css::uno::Sequence<css::uno::Any>& rArguments )
2800 PopupWindowController::initialize( rArguments );
2802 ToolBox* pToolBox = nullptr;
2803 sal_uInt16 nId = 0;
2804 if ( !getToolboxId( nId, &pToolBox ) )
2806 SAL_WARN("svx.tbxcrtls", "ToolBox not found!");
2807 return;
2810 m_nSlotId = MapCommandToSlotId( m_aCommandURL );
2811 if ( m_nSlotId == SID_ATTR_LINE_COLOR || m_nSlotId == SID_ATTR_FILL_COLOR ||
2812 m_nSlotId == SID_FRAME_LINECOLOR || m_nSlotId == SID_BACKGROUND_COLOR )
2813 // Sidebar uses wide buttons for those.
2814 m_bSplitButton = typeid( *pToolBox ) != typeid( sfx2::sidebar::SidebarToolBox );
2816 m_xBtnUpdater.reset( new svx::ToolboxButtonColorUpdater( m_nSlotId, nId, pToolBox, !m_bSplitButton ) );
2817 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
2820 void SvxColorToolBoxControl::update()
2822 PopupWindowController::update();
2824 switch( m_nSlotId )
2826 case SID_ATTR_CHAR_COLOR2:
2827 addStatusListener( ".uno:CharColorExt");
2828 break;
2830 case SID_ATTR_CHAR_COLOR_BACKGROUND:
2831 addStatusListener( ".uno:CharBackgroundExt");
2832 break;
2834 case SID_FRAME_LINECOLOR:
2835 addStatusListener( ".uno:BorderTLBR");
2836 addStatusListener( ".uno:BorderBLTR");
2837 break;
2841 void SvxColorToolBoxControl::EnsurePaletteManager()
2843 if (!m_xPaletteManager)
2845 m_xPaletteManager.reset(new PaletteManager);
2846 m_xPaletteManager->SetBtnUpdater(m_xBtnUpdater.get());
2847 m_xPaletteManager->SetLastColor(m_xBtnUpdater->GetCurrentColor());
2851 SvxColorToolBoxControl::~SvxColorToolBoxControl()
2853 if (m_xPaletteManager)
2854 m_xPaletteManager->SetBtnUpdater(nullptr);
2857 void SvxColorToolBoxControl::setColorSelectFunction(const ColorSelectFunction& aColorSelectFunction)
2859 m_aColorSelectFunction = aColorSelectFunction;
2860 if (m_xPaletteManager)
2861 m_xPaletteManager->SetColorSelectFunction(aColorSelectFunction);
2864 VclPtr<vcl::Window> SvxColorToolBoxControl::createPopupWindow( vcl::Window* pParent )
2866 EnsurePaletteManager();
2868 VclPtrInstance<SvxColorWindow> pColorWin(
2869 m_aCommandURL,
2870 m_xPaletteManager,
2871 m_aBorderColorStatus,
2872 m_nSlotId,
2873 m_xFrame,
2874 pParent,
2875 m_aColorSelectFunction);
2877 OUString aWindowTitle = vcl::CommandInfoProvider::GetLabelForCommand( m_aCommandURL, m_sModuleName );
2878 pColorWin->SetText( aWindowTitle );
2879 pColorWin->StartSelection();
2880 if ( m_bSplitButton )
2881 pColorWin->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) );
2882 return pColorWin;
2885 IMPL_LINK(SvxColorToolBoxControl, SelectedHdl, const NamedColor&, rColor, void)
2887 m_xBtnUpdater->Update(rColor.first);
2888 if (m_xPaletteManager)
2889 m_xPaletteManager->SetLastColor(rColor.first);
2892 void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
2894 ToolBox* pToolBox = nullptr;
2895 sal_uInt16 nId = 0;
2896 if ( !getToolboxId( nId, &pToolBox ) )
2897 return;
2899 if ( rEvent.FeatureURL.Complete == m_aCommandURL )
2900 pToolBox->EnableItem( nId, rEvent.IsEnabled );
2902 bool bValue;
2903 if ( !m_bSplitButton )
2905 Color aColor( COL_TRANSPARENT );
2907 if ( m_aBorderColorStatus.statusChanged( rEvent ) )
2909 aColor = m_aBorderColorStatus.GetColor();
2911 else if ( rEvent.IsEnabled )
2913 sal_Int32 nValue;
2914 if ( rEvent.State >>= nValue )
2915 aColor = nValue;
2917 m_xBtnUpdater->Update( aColor );
2918 if (m_xPaletteManager)
2919 m_xPaletteManager->SetLastColor(aColor);
2921 else if ( rEvent.State >>= bValue )
2922 pToolBox->CheckItem( nId, bValue );
2925 void SvxColorToolBoxControl::execute(sal_Int16 /*nSelectModifier*/)
2927 if ( !m_bSplitButton )
2929 // Open the popup also when Enter key is pressed.
2930 createPopupWindow();
2931 return;
2934 OUString aCommand = m_aCommandURL;
2936 switch( m_nSlotId )
2938 case SID_ATTR_CHAR_COLOR2 :
2939 aCommand = ".uno:CharColorExt";
2940 break;
2942 case SID_ATTR_CHAR_COLOR_BACKGROUND :
2943 aCommand = ".uno:CharBackgroundExt";
2944 break;
2947 EnsurePaletteManager();
2948 Color aColor = m_xPaletteManager->GetLastColor();
2950 auto aArgs( comphelper::InitPropertySequence( {
2951 { m_aCommandURL.copy(5), css::uno::makeAny( m_xPaletteManager->GetLastColor().GetColor() ) }
2952 } ) );
2953 dispatchCommand( aCommand, aArgs );
2955 OUString sColorName = ("#" + aColor.AsRGBHexString().toAsciiUpperCase());
2956 m_xPaletteManager->AddRecentColor(aColor, sColorName);
2959 sal_Bool SvxColorToolBoxControl::opensSubToolbar()
2961 // For a split button, we mark this controller as a sub-toolbar controller,
2962 // so we get notified (through updateImage method) on button image changes,
2963 // and could redraw the last used color on top of it.
2964 return m_bSplitButton;
2967 void SvxColorToolBoxControl::updateImage()
2969 ToolBox* pToolBox = nullptr;
2970 sal_uInt16 nId = 0;
2971 if ( !getToolboxId( nId, &pToolBox ) )
2972 return;
2974 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(m_aCommandURL, m_xFrame, pToolBox->GetImageSize());
2975 if ( !!aImage )
2977 pToolBox->SetItemImage( nId, aImage );
2978 EnsurePaletteManager();
2979 m_xBtnUpdater->Update(m_xPaletteManager->GetLastColor(), true);
2983 OUString SvxColorToolBoxControl::getSubToolbarName()
2985 return OUString();
2988 void SvxColorToolBoxControl::functionSelected( const OUString& /*rCommand*/ )
2992 OUString SvxColorToolBoxControl::getImplementationName()
2994 return OUString( "com.sun.star.comp.svx.ColorToolBoxControl" );
2997 css::uno::Sequence<OUString> SvxColorToolBoxControl::getSupportedServiceNames()
2999 return { "com.sun.star.frame.ToolbarController" };
3002 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3003 com_sun_star_comp_svx_ColorToolBoxControl_get_implementation(
3004 css::uno::XComponentContext* rContext,
3005 css::uno::Sequence<css::uno::Any> const & )
3007 return cppu::acquire( new SvxColorToolBoxControl( rContext ) );
3010 // class SvxFrameToolBoxControl --------------------------------------------
3012 class SvxFrameToolBoxControl : public svt::PopupWindowController
3014 public:
3015 explicit SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext );
3017 // XInitialization
3018 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) override;
3020 // XServiceInfo
3021 virtual OUString SAL_CALL getImplementationName() override;
3022 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
3024 private:
3025 virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override;
3026 using svt::ToolboxController::createPopupWindow;
3029 SvxFrameToolBoxControl::SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext )
3030 : svt::PopupWindowController( rContext, nullptr, OUString() )
3034 void SvxFrameToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3036 svt::PopupWindowController::initialize( rArguments );
3037 ToolBox* pToolBox = nullptr;
3038 sal_uInt16 nId = 0;
3039 if ( getToolboxId( nId, &pToolBox ) )
3040 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
3043 VclPtr<vcl::Window> SvxFrameToolBoxControl::createPopupWindow( vcl::Window* pParent )
3045 if ( m_aCommandURL == ".uno:LineStyle" )
3046 return VclPtr<SvxLineWindow_Impl>::Create( *this, pParent );
3048 return VclPtr<SvxFrameWindow_Impl>::Create( *this, pParent );
3051 OUString SvxFrameToolBoxControl::getImplementationName()
3053 return OUString( "com.sun.star.comp.svx.FrameToolBoxControl" );
3056 css::uno::Sequence< OUString > SvxFrameToolBoxControl::getSupportedServiceNames()
3058 return { "com.sun.star.frame.ToolbarController" };
3061 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3062 com_sun_star_comp_svx_FrameToolBoxControl_get_implementation(
3063 css::uno::XComponentContext* rContext,
3064 css::uno::Sequence<css::uno::Any> const & )
3066 return cppu::acquire( new SvxFrameToolBoxControl( rContext ) );
3069 SvxSimpleUndoRedoController::SvxSimpleUndoRedoController( sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
3070 :SfxToolBoxControl( nSlotId, nId, rTbx )
3072 aDefaultText = rTbx.GetItemText( nId );
3075 SvxSimpleUndoRedoController::~SvxSimpleUndoRedoController()
3079 void SvxSimpleUndoRedoController::StateChanged( sal_uInt16, SfxItemState eState, const SfxPoolItem* pState )
3081 const SfxStringItem* pItem = dynamic_cast<const SfxStringItem*>( pState );
3082 ToolBox& rBox = GetToolBox();
3083 if ( pItem && eState != SfxItemState::DISABLED )
3085 OUString aNewText( MnemonicGenerator::EraseAllMnemonicChars( pItem->GetValue() ) );
3086 rBox.SetQuickHelpText( GetId(), aNewText );
3088 if ( eState == SfxItemState::DISABLED )
3089 rBox.SetQuickHelpText( GetId(), aDefaultText );
3090 rBox.EnableItem( GetId(), eState != SfxItemState::DISABLED );
3093 SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3094 PopupWindowController( rContext, nullptr, OUString() ),
3095 m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
3096 m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND )
3100 SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}
3102 void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3104 PopupWindowController::initialize(rArguments);
3106 ToolBox* pToolBox = nullptr;
3107 sal_uInt16 nId = 0;
3108 if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL)
3109 pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId));
3112 VclPtr<vcl::Window> SvxCurrencyToolBoxControl::createPopupWindow( vcl::Window* pParent )
3114 return VclPtr<SvxCurrencyList_Impl>::Create(this, pParent, m_aFormatString, m_eLanguage);
3117 void SvxCurrencyToolBoxControl::execute( sal_Int16 nSelectModifier )
3119 sal_uInt32 nFormatKey;
3120 if (m_aFormatString.isEmpty())
3121 nFormatKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
3122 else
3124 if ( nSelectModifier > 0 )
3128 uno::Reference< util::XNumberFormatsSupplier > xRef( m_xFrame->getController()->getModel(), uno::UNO_QUERY );
3129 uno::Reference< util::XNumberFormats > rxNumberFormats( xRef->getNumberFormats(), uno::UNO_QUERY_THROW );
3130 css::lang::Locale aLocale = LanguageTag::convertToLocale( m_eLanguage );
3131 nFormatKey = rxNumberFormats->queryKey( m_aFormatString, aLocale, false );
3132 if ( nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND )
3133 nFormatKey = rxNumberFormats->addNew( m_aFormatString, aLocale );
3135 catch( const uno::Exception& )
3137 nFormatKey = m_nFormatKey;
3140 else
3141 nFormatKey = m_nFormatKey;
3144 if( nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
3146 Sequence< PropertyValue > aArgs( 1 );
3147 aArgs[0].Name = "NumberFormatCurrency";
3148 aArgs[0].Value <<= nFormatKey;
3149 dispatchCommand( m_aCommandURL, aArgs );
3150 m_nFormatKey = nFormatKey;
3152 else
3153 PopupWindowController::execute( nSelectModifier );
3156 OUString SvxCurrencyToolBoxControl::getImplementationName()
3158 return OUString( "com.sun.star.comp.svx.CurrencyToolBoxControl" );
3161 css::uno::Sequence<OUString> SvxCurrencyToolBoxControl::getSupportedServiceNames()
3163 return { "com.sun.star.frame.ToolbarController" };
3166 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3167 com_sun_star_comp_svx_CurrencyToolBoxControl_get_implementation(
3168 css::uno::XComponentContext* rContext,
3169 css::uno::Sequence<css::uno::Any> const & )
3171 return cppu::acquire( new SvxCurrencyToolBoxControl( rContext ) );
3174 Reference< css::accessibility::XAccessible > SvxFontNameBox_Impl::CreateAccessible()
3176 FillList();
3177 return FontNameBox::CreateAccessible();
3180 //static
3181 void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
3182 std::vector<sal_uInt16>& rCurrencyList )
3184 rCurrencyList.clear();
3186 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
3187 sal_uInt16 nCount = rCurrencyTable.size();
3189 sal_uInt16 nStart = 1;
3191 OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) );
3192 aString += " ";
3193 aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3194 rCurrencyTable[0].GetLanguage() ) );
3196 rList.push_back( aString );
3197 rCurrencyList.push_back( sal_uInt16(-1) ); // nAuto
3199 if( bFlag )
3201 rList.push_back( aString );
3202 rCurrencyList.push_back( 0 );
3203 ++nStart;
3206 CollatorWrapper aCollator( ::comphelper::getProcessComponentContext() );
3207 aCollator.loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
3209 const OUString aTwoSpace(" ");
3211 for( sal_uInt16 i = 1; i < nCount; ++i )
3213 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3214 aStr += aTwoSpace;
3215 aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
3216 aStr += aTwoSpace;
3217 aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
3218 rCurrencyTable[i].GetLanguage() ) );
3220 std::vector<OUString>::size_type j = nStart;
3221 for( ; j < rList.size(); ++j )
3222 if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3223 break; // insert before first greater than
3225 rList.insert( rList.begin() + j, aStr );
3226 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3229 // Append ISO codes to symbol list.
3230 // XXX If this is to be changed, various other places would had to be
3231 // adapted that assume this order!
3232 std::vector<OUString>::size_type nCont = rList.size();
3234 for ( sal_uInt16 i = 1; i < nCount; ++i )
3236 bool bInsert = true;
3237 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() ) );
3239 std::vector<OUString>::size_type j = nCont;
3240 for ( ; j < rList.size() && bInsert; ++j )
3242 if( rList[j] == aStr )
3243 bInsert = false;
3244 else if ( aCollator.compareString( aStr, rList[j] ) < 0 )
3245 break; // insert before first greater than
3247 if ( bInsert )
3249 rList.insert( rList.begin() + j, aStr );
3250 rCurrencyList.insert( rCurrencyList.begin() + j, i );
3255 SvxListBoxColorWrapper::SvxListBoxColorWrapper(SvxColorListBox* pControl)
3256 : mxControl(pControl)
3260 void SvxListBoxColorWrapper::operator()(const OUString& /*rCommand*/, const NamedColor& rColor)
3262 if (!mxControl)
3263 return;
3264 mxControl->Selected(rColor);
3267 void SvxListBoxColorWrapper::dispose()
3269 mxControl.clear();
3272 SvxColorListBox::SvxColorListBox(vcl::Window* pParent, WinBits nStyle)
3273 : MenuButton(pParent, nStyle)
3274 , m_aColorWrapper(this)
3275 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
3276 , m_nSlotId(0)
3277 , m_bShowNoneButton(false)
3279 m_aSelectedColor = GetAutoColor(m_nSlotId);
3280 LockWidthRequest();
3281 ShowPreview(m_aSelectedColor);
3282 SetActivateHdl(LINK(this, SvxColorListBox, MenuActivateHdl));
3285 void SvxColorListBox::EnsurePaletteManager()
3287 if (!m_xPaletteManager)
3289 m_xPaletteManager.reset(new PaletteManager);
3290 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
3291 m_xPaletteManager->SetLastColor(m_aSelectedColor.first);
3295 void SvxColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
3297 m_nSlotId = nSlotId;
3298 m_bShowNoneButton = bShowNoneButton;
3299 m_xColorWindow.disposeAndClear();
3300 m_aSelectedColor = bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId);
3301 ShowPreview(m_aSelectedColor);
3302 createColorWindow();
3305 //to avoid the box resizing every time the color is changed to
3306 //the optimal size of the individual color, get the longest
3307 //standard color and stick with that as the size for all
3308 void SvxColorListBox::LockWidthRequest()
3310 if (get_width_request() != -1)
3311 return;
3312 NamedColor aLongestColor;
3313 long nMaxStandardColorTextWidth = 0;
3314 XColorListRef const xColorTable = XColorList::CreateStdColorList();
3315 for (long i = 0; i != xColorTable->Count(); ++i)
3317 XColorEntry& rEntry = *xColorTable->GetColor(i);
3318 long nColorTextWidth = GetTextWidth(rEntry.GetName());
3319 if (nColorTextWidth > nMaxStandardColorTextWidth)
3321 nMaxStandardColorTextWidth = nColorTextWidth;
3322 aLongestColor.second = rEntry.GetName();
3325 ShowPreview(aLongestColor);
3326 set_width_request(get_preferred_size().Width());
3329 void SvxColorListBox::ShowPreview(const NamedColor &rColor)
3331 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3332 Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
3334 ScopedVclPtrInstance<VirtualDevice> xDevice;
3335 xDevice->SetOutputSize(aImageSize);
3336 const tools::Rectangle aRect(Point(0, 0), aImageSize);
3337 if (m_bShowNoneButton && rColor.first == COL_NONE_COLOR)
3339 const Color aW(COL_WHITE);
3340 const Color aG(0xef, 0xef, 0xef);
3341 xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 8, aW, aG);
3342 xDevice->SetFillColor();
3344 else
3346 if (rColor.first == COL_AUTO)
3347 xDevice->SetFillColor(m_aAutoDisplayColor);
3348 else
3349 xDevice->SetFillColor(rColor.first);
3352 xDevice->SetLineColor(rStyleSettings.GetDisableColor());
3353 xDevice->DrawRect(aRect);
3355 Bitmap aBitmap(xDevice->GetBitmap(Point(0, 0), xDevice->GetOutputSize()));
3356 SetImageAlign(ImageAlign::Left);
3357 SetModeImage(Image(aBitmap));
3358 SetText(rColor.second);
3361 IMPL_LINK(SvxColorListBox, WindowEventListener, VclWindowEvent&, rWindowEvent, void)
3363 if (rWindowEvent.GetId() == VclEventId::WindowEndPopupMode)
3365 m_xColorWindow.disposeAndClear();
3366 SetPopover(nullptr);
3370 IMPL_LINK_NOARG(SvxColorListBox, MenuActivateHdl, MenuButton *, void)
3372 if (!m_xColorWindow || m_xColorWindow->isDisposed())
3373 createColorWindow();
3376 void SvxColorListBox::createColorWindow()
3378 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
3379 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
3380 css::uno::Reference<css::frame::XFrame> xFrame(pFrame ? pFrame->GetFrameInterface() : uno::Reference<css::frame::XFrame>());
3382 EnsurePaletteManager();
3384 m_xColorWindow = VclPtr<SvxColorWindow>::Create(
3385 OUString() /*m_aCommandURL*/,
3386 m_xPaletteManager,
3387 m_aBorderColorStatus,
3388 m_nSlotId,
3389 xFrame,
3390 this,
3391 m_aColorWrapper);
3393 m_xColorWindow->AddEventListener(LINK(this, SvxColorListBox, WindowEventListener));
3395 SetNoSelection();
3396 if (m_bShowNoneButton)
3397 m_xColorWindow->ShowNoneButton();
3398 m_xColorWindow->SelectEntry(m_aSelectedColor);
3399 SetPopover(m_xColorWindow);
3402 void SvxColorListBox::Selected(const NamedColor& rColor)
3404 ShowPreview(rColor);
3405 if (m_xPaletteManager)
3406 m_xPaletteManager->SetLastColor(rColor.first);
3407 m_aSelectedColor = rColor;
3408 if (m_aSelectedLink.IsSet())
3409 m_aSelectedLink.Call(*this);
3412 VCL_BUILDER_FACTORY(SvxColorListBox)
3414 SvxColorListBox::~SvxColorListBox()
3416 disposeOnce();
3419 void SvxColorListBox::dispose()
3421 m_xColorWindow.disposeAndClear();
3422 m_aColorWrapper.dispose();
3423 MenuButton::dispose();
3426 VclPtr<SvxColorWindow> SvxColorListBox::getColorWindow() const
3428 if (!m_xColorWindow || m_xColorWindow->isDisposed())
3429 const_cast<SvxColorListBox*>(this)->createColorWindow();
3430 return m_xColorWindow;
3433 void SvxColorListBox::SelectEntry(const NamedColor& rColor)
3435 if (rColor.second.trim().isEmpty())
3437 SelectEntry(rColor.first);
3438 return;
3440 VclPtr<SvxColorWindow> xColorWindow = getColorWindow();
3441 xColorWindow->SelectEntry(rColor);
3442 m_aSelectedColor = xColorWindow->GetSelectEntryColor();
3443 ShowPreview(m_aSelectedColor);
3446 void SvxColorListBox::SelectEntry(const Color& rColor)
3448 VclPtr<SvxColorWindow> xColorWindow = getColorWindow();
3449 xColorWindow->SelectEntry(rColor);
3450 m_aSelectedColor = xColorWindow->GetSelectEntryColor();
3451 ShowPreview(m_aSelectedColor);
3454 SvxColorListBoxWrapper::SvxColorListBoxWrapper(SvxColorListBox& rListBox)
3455 : sfx::SingleControlWrapper<SvxColorListBox, Color>(rListBox)
3459 SvxColorListBoxWrapper::~SvxColorListBoxWrapper()
3463 bool SvxColorListBoxWrapper::IsControlDontKnow() const
3465 return GetControl().IsNoSelection();
3468 void SvxColorListBoxWrapper::SetControlDontKnow( bool bSet )
3470 if( bSet ) GetControl().SetNoSelection();
3473 Color SvxColorListBoxWrapper::GetControlValue() const
3475 return GetControl().GetSelectEntryColor();
3478 void SvxColorListBoxWrapper::SetControlValue( Color aColor )
3480 GetControl().SelectEntry( aColor );
3483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */