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