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>
99#include <o3tl/string_view.hxx>
101#include <bitmaps.hlst>
102#include <sal/log.hxx>
104
105#include <comphelper/lok.hxx>
106#include <tools/json_writer.hxx>
107
108#include <editeng/editeng.hxx>
109
110#define MAX_MRU_FONTNAME_ENTRIES 5
111
112#define COMBO_WIDTH_IN_CHARS 18
113
114#define MAX_MRU_CURRENCIES 5
115
116#define INVALID_CURRENCY sal_uInt16(-2)
117
118// namespaces
119using namespace ::editeng;
120using namespace ::com::sun::star;
121using namespace ::com::sun::star::uno;
122using namespace ::com::sun::star::frame;
123using namespace ::com::sun::star::beans;
124using namespace ::com::sun::star::lang;
125
126namespace
127{
128struct ScriptInfo
129{
130 tools::Long textWidth;
131 SvtScriptType scriptType;
132 sal_Int32 changePos;
133 ScriptInfo(SvtScriptType scrptType, sal_Int32 position)
134 : textWidth(0)
135 , scriptType(scrptType)
136 , changePos(position)
137 {
138 }
139};
140
141class SvxStyleBox_Base
142{
143public:
144 SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget, OUString rCommand, SfxStyleFamily eFamily,
145 const Reference<XFrame>& _xFrame, OUString aClearFormatKey,
146 OUString aMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);
147
148 virtual ~SvxStyleBox_Base()
149 {
150 }
151
152 void SetFamily( SfxStyleFamily eNewFamily );
153
154 void SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
155
156 int get_count() const { return m_xWidget->get_count(); }
157 OUString get_text(int nIndex) const { return m_xWidget->get_text(nIndex); }
158 OUString get_active_text() const { return m_xWidget->get_active_text(); }
159
160 void append_text(const OUString& rStr)
161 {
162 OUString sId(OUString::number(m_xWidget->get_count()));
163 m_xWidget->append(sId, rStr);
164 }
165
166 void insert_separator(int pos, const OUString& rId)
167 {
168 m_xWidget->insert_separator(pos, rId);
169 }
170
171 void set_active_or_entry_text(const OUString& rText)
172 {
173 const int nFound = m_xWidget->find_text(rText);
174 if (nFound != -1)
175 m_xWidget->set_active(nFound);
176 else
177 m_xWidget->set_entry_text(rText);
178 }
179
180 void set_active(int nActive)
181 {
182 m_xWidget->set_active(nActive);
183 }
184
185 void freeze()
186 {
187 m_xWidget->freeze();
188 }
189
190 void save_value()
191 {
192 m_xWidget->save_value();
193 }
194
195 void clear()
196 {
197 m_xWidget->clear();
198 m_nMaxUserDrawFontWidth = 0;
199 }
200
201 void thaw()
202 {
203 m_xWidget->thaw();
204 }
205
206 virtual bool DoKeyInput(const KeyEvent& rKEvt);
207
208private:
209 std::optional<SvxFont> m_oFont;
210 std::optional<SvxFont> m_oCJKFont;
211 std::optional<SvxFont> m_oCTLFont;
212
213 DECL_LINK(SelectHdl, weld::ComboBox&, void);
214 DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
215 DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
216 DECL_LINK(FocusOutHdl, weld::Widget&, void);
217 DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
218 DECL_LINK(CustomRenderHdl, weld::ComboBox::render_args, void);
219 DECL_LINK(CustomGetSizeHdl, OutputDevice&, Size);
220
222 void CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext);
223
224 void Select(bool bNonTravelSelect);
225
226 tools::Rectangle CalcBoundRect(vcl::RenderContext& rRenderContext, const OUString &rStyleName, std::vector<ScriptInfo>& rScriptChanges, double fRatio = 1);
227
228protected:
229 SvxStyleToolBoxControl& m_rCtrl;
230
231 std::unique_ptr<weld::Builder> m_xMenuBuilder;
232 std::unique_ptr<weld::Menu> m_xMenu;
233 std::unique_ptr<weld::ComboBox> m_xWidget;
234
235 SfxStyleFamily eStyleFamily;
236 int m_nMaxUserDrawFontWidth;
237 int m_nLastItemWithMenu;
238 bool bRelease;
239 Reference< XFrame > m_xFrame;
240 OUString m_aCommand;
241 OUString aClearFormatKey;
242 OUString aMoreKey;
243 OUString sDefaultStyle;
244 bool bInSpecialMode;
245
246 void ReleaseFocus();
247 static Color TestColorsVisible(const Color &FontCol, const Color &BackCol);
248 void UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const tools::Rectangle& rTextRect, const OUString &rStyleName, const std::vector<ScriptInfo>& rScriptChanges);
249 void SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, bool bIsNotSelected);
250 DECL_LINK(MenuSelectHdl, const OUString&, void);
251 DECL_STATIC_LINK(SvxStyleBox_Base, ShowMoreHdl, void*, void);
252};
253
254class SvxStyleBox_Impl final : public InterimItemWindow
255 , public SvxStyleBox_Base
256{
257public:
258 SvxStyleBox_Impl(vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily,
259 const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);
260
261 virtual ~SvxStyleBox_Impl() override
262 {
263 disposeOnce();
264 }
265
266 virtual void dispose() override
267 {
268 m_xWidget.reset();
269 m_xMenu.reset();
270 m_xMenuBuilder.reset();
272 }
273
274 virtual bool DoKeyInput(const KeyEvent& rKEvt) override;
275
276private:
277
278 virtual void DataChanged(const DataChangedEvent& rDCEvt) override;
279 void SetOptimalSize();
280};
281
282class SvxFontNameBox_Impl;
283class SvxFontNameBox_Base;
284
285class SvxFontNameToolBoxControl final : public cppu::ImplInheritanceHelper<svt::ToolboxController,
286 css::lang::XServiceInfo>
287{
288public:
289 SvxFontNameToolBoxControl();
290
291 // XStatusListener
292 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
293
294 // XToolbarController
295 virtual css::uno::Reference<css::awt::XWindow> SAL_CALL createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent) override;
296
297 // XComponent
298 virtual void SAL_CALL dispose() override;
299
300 // XServiceInfo
301 virtual OUString SAL_CALL getImplementationName() override;
302 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
303 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
304
305private:
307 std::unique_ptr<SvxFontNameBox_Base> m_xWeldBox;
308 SvxFontNameBox_Base* m_pBox;
309};
310
311class FontOptionsListener final : public comphelper::ConfigurationListenerProperty<bool>
312{
313private:
314 SvxFontNameBox_Base& m_rBox;
315
316 virtual void setProperty(const css::uno::Any &rProperty) override;
317public:
318 FontOptionsListener(const rtl::Reference<comphelper::ConfigurationListener>& rListener, const OUString& rProp, SvxFontNameBox_Base& rBox)
320 , m_rBox(rBox)
321 {
322 }
323};
324
325class SvxFontNameBox_Base
326{
327private:
329 FontOptionsListener m_aWYSIWYG;
330 FontOptionsListener m_aHistory;
331
332protected:
333 SvxFontNameToolBoxControl& m_rCtrl;
334
335 std::unique_ptr<FontNameBox> m_xWidget;
336 const FontList* pFontList;
337 ::std::unique_ptr<FontList> m_aOwnFontList;
338 vcl::Font aCurFont;
339 sal_uInt16 nFtCount;
340 bool bRelease;
341 Reference< XFrame > m_xFrame;
342 bool mbCheckingUnknownFont;
343
344 void ReleaseFocus_Impl();
345
346 void Select(bool bNonTravelSelect);
347
348 void EndPreview()
349 {
350 Sequence< PropertyValue > aArgs;
351 const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
352 SfxToolBoxControl::Dispatch(xProvider, ".uno:CharEndPreviewFontName", aArgs);
353 }
354
355 bool CheckFontIsAvailable(std::u16string_view fontname);
356 void CheckAndMarkUnknownFont();
357
358public:
359 SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget, const Reference<XFrame>& rFrame,
360 SvxFontNameToolBoxControl& rCtrl);
361 virtual ~SvxFontNameBox_Base()
362 {
363 m_xListener->dispose();
364 }
365
366 void FillList();
367 void Update( const css::awt::FontDescriptor* pFontDesc );
368 sal_uInt16 GetListCount() const { return nFtCount; }
369 void Clear() { m_xWidget->clear(); nFtCount = 0; }
370 void Fill( const FontList* pList )
371 {
372 m_xWidget->Fill(pList);
373 nFtCount = pList->GetFontNameCount();
374 }
375
376 void SetOwnFontList(::std::unique_ptr<FontList> && _aOwnFontList) { m_aOwnFontList = std::move(_aOwnFontList); }
377
378 virtual void set_sensitive(bool bSensitive)
379 {
380 m_xWidget->set_sensitive(bSensitive);
381 }
382
383 void set_active_or_entry_text(const OUString& rText);
384
385 void statusChanged_Impl(const css::frame::FeatureStateEvent& rEvent);
386
387 virtual bool DoKeyInput(const KeyEvent& rKEvt);
388
389 void EnableControls();
390
391 DECL_LINK(SelectHdl, weld::ComboBox&, void);
392 DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
393 DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
394 DECL_LINK(FocusInHdl, weld::Widget&, void);
395 DECL_LINK(FocusOutHdl, weld::Widget&, void);
396 DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
397};
398
399void FontOptionsListener::setProperty(const css::uno::Any &rProperty)
400{
402 m_rBox.EnableControls();
403}
404
405class SvxFontNameBox_Impl final : public InterimItemWindow
406 , public SvxFontNameBox_Base
407{
408private:
409 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
410 virtual void GetFocus() override
411 {
412 if (m_xWidget)
413 m_xWidget->grab_focus();
415 }
416
417 void SetOptimalSize();
418
419 virtual bool DoKeyInput(const KeyEvent& rKEvt) override;
420
421public:
422 SvxFontNameBox_Impl(vcl::Window* pParent,
423 const Reference<XFrame>& rFrame, SvxFontNameToolBoxControl& rCtrl);
424
425 virtual void dispose() override
426 {
427 m_xWidget.reset();
429 }
430
431 virtual ~SvxFontNameBox_Impl() override
432 {
433 disposeOnce();
434 }
435
436 virtual Reference< css::accessibility::XAccessible > CreateAccessible() override;
437
438 virtual void set_sensitive(bool bSensitive) override
439 {
440 m_xWidget->set_sensitive(bSensitive);
441 if (bSensitive)
443 else
445 }
446};
447
448
449// SelectHdl needs the Modifiers, get them in MouseButtonUp
450class SvxFrmValueSet_Impl final : public ValueSet
451{
452private:
453 sal_uInt16 nModifier;
454
455 virtual bool MouseButtonUp(const MouseEvent& rMEvt) override
456 {
457 nModifier = rMEvt.GetModifier();
458 return ValueSet::MouseButtonUp(rMEvt);
459 }
460
461public:
462 SvxFrmValueSet_Impl()
463 : ValueSet(nullptr)
464 , nModifier(0)
465 {
466 }
467 sal_uInt16 GetModifier() const {return nModifier;}
468};
469
470}
471
472namespace {
473
474class SvxFrameToolBoxControl;
475
476class SvxFrameWindow_Impl final : public WeldToolbarPopup
477{
478private:
480 std::unique_ptr<SvxFrmValueSet_Impl> mxFrameSet;
481 std::unique_ptr<weld::CustomWeld> mxFrameSetWin;
482 std::vector<std::pair<BitmapEx, OUString>> aImgVec;
483 bool bParagraphMode;
484 bool m_bIsWriter;
485
486 void InitImageList();
487 void CalcSizeValueSet();
488 DECL_LINK( SelectHdl, ValueSet*, void );
489
490 void SetDiagonalDownBorder(const SvxLineItem& dDownLineItem);
491 void SetDiagonalUpBorder(const SvxLineItem& dUpLineItem);
492
493public:
494 SvxFrameWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
495 virtual void GrabFocus() override
496 {
497 mxFrameSet->GrabFocus();
498 }
499
500 virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
501};
502
503class SvxFrameToolBoxControl : public svt::PopupWindowController
504{
505public:
506 explicit SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext );
507
508 // XInitialization
509 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) override;
510
511 // XServiceInfo
512 virtual OUString SAL_CALL getImplementationName() override;
513 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
514
515 virtual void SAL_CALL execute(sal_Int16 nKeyModifier) override;
516private:
517 virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
518 virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
519};
520
521 class LineListBox final : public ValueSet
522 {
523 public:
524 typedef Color (*ColorFunc)(Color);
525 typedef Color (*ColorDistFunc)(Color, Color);
526
527 LineListBox();
528
530 Size SetWidth( tools::Long nWidth )
531 {
532 tools::Long nOldWidth = m_nWidth;
533 m_nWidth = nWidth;
534 return UpdateEntries( nOldWidth );
535 }
536
537 void SetNone( const OUString& sNone )
538 {
539 m_sNone = sNone;
540 }
541
543 void InsertEntry(const BorderWidthImpl& rWidthImpl,
544 SvxBorderLineStyle nStyle, tools::Long nMinWidth = 0,
545 ColorFunc pColor1Fn = &sameColor,
546 ColorFunc pColor2Fn = &sameColor,
547 ColorDistFunc pColorDistFn = &sameDistColor);
548
549 SvxBorderLineStyle GetEntryStyle( sal_Int32 nPos ) const;
550
551 SvxBorderLineStyle GetSelectEntryStyle() const;
552
553 void SetSourceUnit( FieldUnit eNewUnit ) { eSourceUnit = eNewUnit; }
554
555 const Color& GetColor() const { return aColor; }
556
557 virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
558 private:
559
560 void ImpGetLine(tools::Long nLine1, tools::Long nLine2, tools::Long nDistance,
561 Color nColor1, Color nColor2, Color nColorDist,
562 SvxBorderLineStyle nStyle, BitmapEx& rBmp);
563
564 void UpdatePaintLineColor(); // returns sal_True if maPaintCol has changed
565
566 Size UpdateEntries( tools::Long nOldWidth );
567 sal_Int32 GetStylePos( sal_Int32 nListPos, tools::Long nWidth );
568
569 const Color& GetPaintColor() const
570 {
571 return maPaintCol;
572 }
573
574 Color GetColorLine1( sal_Int32 nPos );
575 Color GetColorLine2( sal_Int32 nPos );
576 Color GetColorDist( sal_Int32 nPos );
577
578 LineListBox( const LineListBox& ) = delete;
579 LineListBox& operator =( const LineListBox& ) = delete;
580
581 std::vector<std::unique_ptr<ImpLineListData>> m_vLineList;
582 tools::Long m_nWidth;
583 OUString m_sNone;
585 Size aTxtSize;
586 Color const aColor;
587 Color maPaintCol;
588 FieldUnit eSourceUnit;
589 };
590
591 SvxBorderLineStyle LineListBox::GetSelectEntryStyle() const
592 {
593 SvxBorderLineStyle nStyle = SvxBorderLineStyle::SOLID;
594 size_t nPos = GetSelectItemPos();
595 if (nPos != VALUESET_ITEM_NOTFOUND)
596 {
597 if (!m_sNone.isEmpty())
598 --nPos;
599 nStyle = GetEntryStyle( nPos );
600 }
601
602 return nStyle;
603 }
604
605 void LineListBox::ImpGetLine( tools::Long nLine1, tools::Long nLine2, tools::Long nDistance,
606 Color aColor1, Color aColor2, Color aColorDist,
607 SvxBorderLineStyle nStyle, BitmapEx& rBmp )
608 {
609 auto nMinWidth = GetDrawingArea()->get_ref_device().approximate_digit_width() * COMBO_WIDTH_IN_CHARS;
610 Size aSize(nMinWidth, aTxtSize.Height());
611 aSize.AdjustWidth( -(aTxtSize.Width()) );
612 aSize.AdjustWidth( -6 );
613
614 // SourceUnit to Twips
615 if ( eSourceUnit == FieldUnit::POINT )
616 {
617 nLine1 /= 5;
618 nLine2 /= 5;
619 nDistance /= 5;
620 }
621
622 // Paint the lines
623 aSize = aVirDev->PixelToLogic( aSize );
624 tools::Long nPix = aVirDev->PixelToLogic( Size( 0, 1 ) ).Height();
625 sal_uInt32 n1 = nLine1;
626 sal_uInt32 n2 = nLine2;
627 tools::Long nDist = nDistance;
628 n1 += nPix-1;
629 n1 -= n1%nPix;
630 if ( n2 )
631 {
632 nDist += nPix-1;
633 nDist -= nDist%nPix;
634 n2 += nPix-1;
635 n2 -= n2%nPix;
636 }
637 tools::Long nVirHeight = n1+nDist+n2;
638 if ( nVirHeight > aSize.Height() )
639 aSize.setHeight( nVirHeight );
640 // negative width should not be drawn
641 if ( aSize.Width() <= 0 )
642 return;
643
644 Size aVirSize = aVirDev->LogicToPixel( aSize );
645 if ( aVirDev->GetOutputSizePixel() != aVirSize )
646 aVirDev->SetOutputSizePixel( aVirSize );
647 aVirDev->SetFillColor( aColorDist );
648 aVirDev->DrawRect( tools::Rectangle( Point(), aSize ) );
649
650 aVirDev->SetFillColor( aColor1 );
651
652 double y1 = double( n1 ) / 2;
653 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y1 ), basegfx::B2DPoint( aSize.Width( ), y1 ), n1, nStyle );
654
655 if ( n2 )
656 {
657 double y2 = n1 + nDist + double( n2 ) / 2;
658 aVirDev->SetFillColor( aColor2 );
659 svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, SvxBorderLineStyle::SOLID );
660 }
661 rBmp = aVirDev->GetBitmapEx( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
662 }
663
664 LineListBox::LineListBox()
665 : ValueSet(nullptr)
666 , m_nWidth( 5 )
667 , aVirDev(VclPtr<VirtualDevice>::Create())
668 , aColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor())
669 , maPaintCol(COL_BLACK)
670 , eSourceUnit(FieldUnit::POINT)
671 {
672 aVirDev->SetLineColor();
673 aVirDev->SetMapMode( MapMode( MapUnit::MapTwip ) );
674 }
675
676 void LineListBox::SetDrawingArea(weld::DrawingArea* pDrawingArea)
677 {
678 ValueSet::SetDrawingArea(pDrawingArea);
679
680 OutputDevice& rDevice = pDrawingArea->get_ref_device();
681
682 aTxtSize.setWidth( rDevice.approximate_digit_width() );
683 aTxtSize.setHeight( rDevice.GetTextHeight() );
684
685 UpdatePaintLineColor();
686 }
687
688 sal_Int32 LineListBox::GetStylePos( sal_Int32 nListPos, tools::Long nWidth )
689 {
690 sal_Int32 nPos = -1;
691 if (!m_sNone.isEmpty())
692 nListPos--;
693
694 sal_Int32 n = 0;
695 size_t i = 0;
696 size_t nCount = m_vLineList.size();
697 while ( nPos == -1 && i < nCount )
698 {
699 auto& pData = m_vLineList[ i ];
700 if ( pData->GetMinWidth() <= nWidth )
701 {
702 if ( nListPos == n )
703 nPos = static_cast<sal_Int32>(i);
704 n++;
705 }
706 i++;
707 }
708
709 return nPos;
710 }
711
712 void LineListBox::InsertEntry(
713 const BorderWidthImpl& rWidthImpl, SvxBorderLineStyle nStyle, tools::Long nMinWidth,
714 ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
715 {
716 m_vLineList.emplace_back(new ImpLineListData(
717 rWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn));
718 }
719
720 SvxBorderLineStyle LineListBox::GetEntryStyle( sal_Int32 nPos ) const
721 {
722 ImpLineListData* pData = (0 <= nPos && o3tl::make_unsigned(nPos) < m_vLineList.size()) ? m_vLineList[ nPos ].get() : nullptr;
723 return pData ? pData->GetStyle() : SvxBorderLineStyle::NONE;
724 }
725
726 void LineListBox::UpdatePaintLineColor()
727 {
729 Color aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
730
731 bool bRet = aNewCol != maPaintCol;
732
733 if( bRet )
734 maPaintCol = aNewCol;
735 }
736
737 Size LineListBox::UpdateEntries( tools::Long nOldWidth )
738 {
739 Size aSize;
740
741 UpdatePaintLineColor( );
742
743 sal_Int32 nSelEntry = GetSelectItemPos();
744 sal_Int32 nTypePos = GetStylePos( nSelEntry, nOldWidth );
745
746 // Remove the old entries
747 Clear();
748
749 sal_uInt16 nId(1);
750
751 // Add the new entries based on the defined width
752 if (!m_sNone.isEmpty())
753 InsertItem(nId++, Image(), m_sNone);
754
755 sal_uInt16 n = 0;
756 sal_uInt16 nCount = m_vLineList.size( );
757 while ( n < nCount )
758 {
759 auto& pData = m_vLineList[ n ];
760 if ( pData->GetMinWidth() <= m_nWidth )
761 {
762 BitmapEx aBmp;
763 ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
764 pData->GetLine2ForWidth( m_nWidth ),
765 pData->GetDistForWidth( m_nWidth ),
766 GetColorLine1( GetItemCount( ) ),
767 GetColorLine2( GetItemCount( ) ),
768 GetColorDist( GetItemCount( ) ),
769 pData->GetStyle(), aBmp );
770 InsertItem(nId, Image(aBmp), SvtLineListBox::GetLineStyleName(pData->GetStyle()));
771 Size aBmpSize = aBmp.GetSizePixel();
772 if (aBmpSize.Width() > aSize.Width())
773 aSize.setWidth(aBmpSize.getWidth());
774 if (aBmpSize.Height() > aSize.Height())
775 aSize.setHeight(aBmpSize.getHeight());
776 if ( n == nTypePos )
777 SelectItem(nId);
778 }
779 else if ( n == nTypePos )
780 SetNoSelection();
781 n++;
782 ++nId;
783 }
784
785 Invalidate();
786
787 return aSize;
788 }
789
790 Color LineListBox::GetColorLine1( sal_Int32 nPos )
791 {
792 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
793 if (nStyle == -1)
794 return GetPaintColor( );
795 auto& pData = m_vLineList[ nStyle ];
796 return pData->GetColorLine1( GetColor( ) );
797 }
798
799 Color LineListBox::GetColorLine2( sal_Int32 nPos )
800 {
801 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
802 if (nStyle == -1)
803 return GetPaintColor( );
804 auto& pData = m_vLineList[ nStyle ];
805 return pData->GetColorLine2( GetColor( ) );
806 }
807
808 Color LineListBox::GetColorDist( sal_Int32 nPos )
809 {
811
812 sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
813 if (nStyle == -1)
814 return rResult;
815 auto& pData = m_vLineList[ nStyle ];
816 return pData->GetColorDist( GetColor( ), rResult );
817 }
818}
819
820namespace {
821
822class SvxLineWindow_Impl final : public WeldToolbarPopup
823{
824private:
826 std::unique_ptr<LineListBox> m_xLineStyleLb;
827 std::unique_ptr<weld::CustomWeld> m_xLineStyleLbWin;
828 bool m_bIsWriter;
829
830 DECL_LINK( SelectHdl, ValueSet*, void );
831
832public:
833 SvxLineWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
834 virtual void GrabFocus() override
835 {
836 m_xLineStyleLb->GrabFocus();
837 }
838};
839
840}
841
843
845{
846 public:
847 SfxStyleControllerItem_Impl( const Reference< XDispatchProvider >& rDispatchProvider,
848 sal_uInt16 nSlotId,
849 const OUString& rCommand,
850 SvxStyleToolBoxControl& rTbxCtl );
851
852 protected:
853 virtual void StateChangedAtStatusListener( SfxItemState eState, const SfxPoolItem* pState ) override;
854
855 private:
857};
858
859#define BUTTON_PADDING 10
860#define ITEM_HEIGHT 30
861
862SvxStyleBox_Base::SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
863 OUString aCommand,
864 SfxStyleFamily eFamily,
865 const Reference< XFrame >& _xFrame,
866 OUString _aClearFormatKey,
867 OUString _aMoreKey,
868 bool bInSpec, SvxStyleToolBoxControl& rCtrl)
869 : m_rCtrl(rCtrl)
870 , m_xMenuBuilder(Application::CreateBuilder(nullptr, "svx/ui/stylemenu.ui"))
871 , m_xMenu(m_xMenuBuilder->weld_menu("menu"))
872 , m_xWidget(std::move(xWidget))
873 , eStyleFamily( eFamily )
874 , m_nMaxUserDrawFontWidth(0)
875 , m_nLastItemWithMenu(-1)
876 , bRelease( true )
877 , m_xFrame(_xFrame)
878 , m_aCommand(std::move( aCommand ))
879 , aClearFormatKey(std::move( _aClearFormatKey ))
880 , aMoreKey(std::move( _aMoreKey ))
881 , bInSpecialMode( bInSpec )
882{
883 m_xWidget->connect_changed(LINK(this, SvxStyleBox_Base, SelectHdl));
884 m_xWidget->connect_key_press(LINK(this, SvxStyleBox_Base, KeyInputHdl));
885 m_xWidget->connect_entry_activate(LINK(this, SvxStyleBox_Base, ActivateHdl));
886 m_xWidget->connect_focus_out(LINK(this, SvxStyleBox_Base, FocusOutHdl));
887 m_xWidget->connect_get_property_tree(LINK(this, SvxStyleBox_Base, DumpAsPropertyTreeHdl));
888 m_xWidget->set_help_id(HID_STYLE_LISTBOX);
889 m_xWidget->set_entry_completion(true);
890 m_xMenu->connect_activate(LINK(this, SvxStyleBox_Base, MenuSelectHdl));
891
892 m_xWidget->connect_custom_get_size(LINK(this, SvxStyleBox_Base, CustomGetSizeHdl));
893 m_xWidget->connect_custom_render(LINK(this, SvxStyleBox_Base, CustomRenderHdl));
894 m_xWidget->set_custom_renderer(true);
895
896 m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS + 3);
897}
898
899IMPL_LINK(SvxStyleBox_Base, CustomGetSizeHdl, OutputDevice&, rArg, Size)
900{
901 CalcOptimalExtraUserWidth(rArg);
902 return Size(m_nMaxUserDrawFontWidth, ITEM_HEIGHT);
903}
904
905SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
906 const OUString& rCommand,
907 SfxStyleFamily eFamily,
908 const Reference< XFrame >& _xFrame,
909 const OUString& rClearFormatKey,
910 const OUString& rMoreKey,
911 bool bInSpec, SvxStyleToolBoxControl& rCtrl)
912 : InterimItemWindow(pParent, "svx/ui/applystylebox.ui", "ApplyStyleBox")
913 , SvxStyleBox_Base(m_xBuilder->weld_combo_box("applystyle"), rCommand, eFamily, _xFrame,
914 rClearFormatKey, rMoreKey, bInSpec, rCtrl)
915{
916 InitControlBase(m_xWidget.get());
917
918 set_id("applystyle");
919 SetOptimalSize();
920}
921
922void SvxStyleBox_Base::ReleaseFocus()
923{
924 if ( !bRelease )
925 {
926 bRelease = true;
927 return;
928 }
929 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
930 m_xFrame->getContainerWindow()->setFocus();
931}
932
933IMPL_LINK(SvxStyleBox_Base, MenuSelectHdl, const OUString&, rMenuIdent, void)
934{
935 if (m_nLastItemWithMenu < 0 || m_nLastItemWithMenu >= m_xWidget->get_count())
936 return;
937
938 OUString sEntry = m_xWidget->get_text(m_nLastItemWithMenu);
939
940 ReleaseFocus(); // It must be after getting entry pos!
941 Sequence<PropertyValue> aArgs{ comphelper::makePropertyValue("Param", sEntry),
943 sal_Int16( eStyleFamily )) };
944
945 const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
946 if (rMenuIdent == "update")
947 {
948 SfxToolBoxControl::Dispatch(xProvider, ".uno:StyleUpdateByExample", aArgs);
949 }
950 else if (rMenuIdent == "edit")
951 {
952 SfxToolBoxControl::Dispatch(xProvider, ".uno:EditStyle", aArgs);
953 }
954}
955
956IMPL_STATIC_LINK_NOARG(SvxStyleBox_Base, ShowMoreHdl, void*, void)
957{
959 DBG_ASSERT( pViewFrm, "SvxStyleBox_Base::Select(): no viewframe" );
960 if (!pViewFrm)
961 return;
962 pViewFrm->ShowChildWindow(SID_SIDEBAR);
963 ::sfx2::sidebar::Sidebar::ShowPanel(u"StyleListPanel", pViewFrm->GetFrame().GetFrameInterface(), true);
964}
965
966IMPL_LINK(SvxStyleBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
967{
968 Select(rCombo.changed_by_direct_pick()); // only when picked from the list
969}
970
971IMPL_LINK_NOARG(SvxStyleBox_Base, ActivateHdl, weld::ComboBox&, bool)
972{
973 Select(true);
974 return true;
975}
976
977void SvxStyleBox_Base::Select(bool bNonTravelSelect)
978{
979 if (!bNonTravelSelect)
980 return;
981
982 OUString aSearchEntry(m_xWidget->get_active_text());
983 bool bDoIt = true, bClear = false;
984 if( bInSpecialMode )
985 {
986 if( aSearchEntry == aClearFormatKey && m_xWidget->get_active() == 0 )
987 {
988 aSearchEntry = sDefaultStyle;
989 bClear = true;
990 //not only apply default style but also call 'ClearFormatting'
991 Sequence< PropertyValue > aEmptyVals;
992 const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
993 SfxToolBoxControl::Dispatch(xProvider, ".uno:ResetAttributes", aEmptyVals);
994 }
995 else if (aSearchEntry == aMoreKey && m_xWidget->get_active() == (m_xWidget->get_count() - 1))
996 {
997 Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Base, ShowMoreHdl));
998 //tdf#113214 change text back to previous entry
999 set_active_or_entry_text(m_xWidget->get_saved_value());
1000 bDoIt = false;
1001 }
1002 }
1003
1004 //Do we need to create a new style?
1006 if (!pShell)
1007 return;
1008
1009 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
1010 SfxStyleSheetBase* pStyle = nullptr;
1011
1012 bool bCreateNew = false;
1013
1014 if ( pPool )
1015 {
1016 pStyle = pPool->First(eStyleFamily);
1017 while ( pStyle && pStyle->GetName() != aSearchEntry )
1018 pStyle = pPool->Next();
1019 }
1020
1021 if ( !pStyle )
1022 {
1023 // cannot find the style for whatever reason
1024 // therefore create a new style
1025 bCreateNew = true;
1026 }
1027
1028 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1029 This instance may be deleted in the meantime (i.e. when a dialog is opened
1030 while in Dispatch()), accessing members will crash in this case. */
1031 ReleaseFocus();
1032
1033 if( !bDoIt )
1034 return;
1035
1036 if ( bClear )
1037 set_active_or_entry_text(aSearchEntry);
1038 m_xWidget->save_value();
1039
1040 Sequence< PropertyValue > aArgs( 2 );
1041 auto pArgs = aArgs.getArray();
1042 pArgs[0].Value <<= aSearchEntry;
1043 pArgs[1].Name = "Family";
1044 pArgs[1].Value <<= sal_Int16( eStyleFamily );
1045
1046 const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
1047 if( bCreateNew )
1048 {
1049 pArgs[0].Name = "Param";
1050 SfxToolBoxControl::Dispatch(xProvider, ".uno:StyleNewByExample", aArgs);
1051 }
1052 else
1053 {
1054 pArgs[0].Name = "Template";
1055 SfxToolBoxControl::Dispatch(xProvider, m_aCommand, aArgs);
1056 }
1057}
1058
1059void SvxStyleBox_Base::SetFamily( SfxStyleFamily eNewFamily )
1060{
1061 eStyleFamily = eNewFamily;
1062}
1063
1064IMPL_LINK_NOARG(SvxStyleBox_Base, FocusOutHdl, weld::Widget&, void)
1065{
1066 if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1067 set_active_or_entry_text(m_xWidget->get_saved_value());
1068}
1069
1070IMPL_LINK(SvxStyleBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1071{
1072 return DoKeyInput(rKEvt);
1073}
1074
1075bool SvxStyleBox_Base::DoKeyInput(const KeyEvent& rKEvt)
1076{
1077 bool bHandled = false;
1078
1079 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1080
1081 switch (nCode)
1082 {
1083 case KEY_TAB:
1084 bRelease = false;
1085 Select(true);
1086 break;
1087 case KEY_ESCAPE:
1088 set_active_or_entry_text(m_xWidget->get_saved_value());
1089 if (!m_rCtrl.IsInSidebar())
1090 {
1091 ReleaseFocus();
1092 bHandled = true;
1093 }
1094 break;
1095 }
1096
1097 return bHandled;
1098}
1099
1100bool SvxStyleBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
1101{
1102 return SvxStyleBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
1103}
1104
1105void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1106{
1107 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1108 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1109 {
1110 SetOptimalSize();
1111 }
1112
1114}
1115
1116void SvxStyleBox_Impl::SetOptimalSize()
1117{
1118 // set width in chars low so the size request will not be overridden
1119 m_xWidget->set_entry_width_chars(1);
1120 // tdf#132338 purely using this calculation to keep things their traditional width
1121 Size aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS + 3) * 4, 0), MapMode(MapUnit::MapAppFont)));
1122 m_xWidget->set_size_request(aSize.Width(), -1);
1123
1124 SetSizePixel(get_preferred_size());
1125}
1126
1127namespace
1128{
1129std::vector<ScriptInfo> CheckScript(const OUString &rStyleName)
1130{
1131 assert(!rStyleName.isEmpty()); // must have a preview text here!
1132
1133 std::vector<ScriptInfo> aScriptChanges;
1134
1135 auto aEditEngine = EditEngine(nullptr);
1136 aEditEngine.SetText(rStyleName);
1137
1138 auto aScript = aEditEngine.GetScriptType({ 0, 0, 0, 0 });
1139 for (sal_Int32 i = 1; i <= rStyleName.getLength(); i++)
1140 {
1141 auto aNextScript = aEditEngine.GetScriptType({ 0, i, 0, i });
1142 if (aNextScript != aScript || i == rStyleName.getLength())
1143 aScriptChanges.emplace_back(aScript, i);
1144 aScript = aNextScript;
1145 }
1146
1147 return aScriptChanges;
1148}
1149}
1150
1151tools::Rectangle SvxStyleBox_Base::CalcBoundRect(vcl::RenderContext& rRenderContext, const OUString &rStyleName, std::vector<ScriptInfo>& rScriptChanges, double fRatio)
1152{
1153 tools::Rectangle aTextRect;
1154
1155 SvtScriptType aScript;
1156 sal_uInt16 nIdx = 0;
1157 sal_Int32 nStart = 0;
1158 sal_Int32 nEnd;
1159 size_t nCnt = rScriptChanges.size();
1160
1161 if (nCnt)
1162 {
1163 nEnd = rScriptChanges[nIdx].changePos;
1164 aScript = rScriptChanges[nIdx].scriptType;
1165 }
1166 else
1167 {
1168 nEnd = rStyleName.getLength();
1169 aScript = SvtScriptType::LATIN;
1170 }
1171
1172 do
1173 {
1174 auto oFont = (aScript == SvtScriptType::ASIAN) ?
1175 m_oCJKFont :
1176 ((aScript == SvtScriptType::COMPLEX) ?
1177 m_oCTLFont :
1178 m_oFont);
1179
1180 rRenderContext.Push(vcl::PushFlags::FONT);
1181
1182 if (oFont)
1183 rRenderContext.SetFont(*oFont);
1184
1185 if (fRatio != 1)
1186 {
1187 vcl::Font aFont(rRenderContext.GetFont());
1188 Size aPixelSize(aFont.GetFontSize());
1189 aPixelSize.setWidth(aPixelSize.Width() * fRatio);
1190 aPixelSize.setHeight(aPixelSize.Height() * fRatio);
1191 aFont.SetFontSize(aPixelSize);
1192 rRenderContext.SetFont(aFont);
1193 }
1194
1195 tools::Rectangle aRect;
1196 rRenderContext.GetTextBoundRect(aRect, rStyleName, nStart, nStart, nEnd - nStart);
1197 aTextRect = aTextRect.Union(aRect);
1198
1199 tools::Long nWidth = rRenderContext.GetTextWidth(rStyleName, nStart, nEnd - nStart);
1200
1201 rRenderContext.Pop();
1202
1203 if (nIdx >= rScriptChanges.size())
1204 break;
1205
1206 rScriptChanges[nIdx++].textWidth = nWidth;
1207
1208 if (nEnd < rStyleName.getLength() && nIdx < nCnt)
1209 {
1210 nStart = nEnd;
1211 nEnd = rScriptChanges[nIdx].changePos;
1212 aScript = rScriptChanges[nIdx].scriptType;
1213 }
1214 else
1215 break;
1216 }
1217 while(true);
1218
1219 return aTextRect;
1220}
1221
1222void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const tools::Rectangle& rTextRect, const OUString &rStyleName, const std::vector<ScriptInfo>& rScriptChanges)
1223{
1224 // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
1225 // nBorder, and we are adding 1 in order to look better when
1226 // italics is present
1227 const int nLeftDistance = 8;
1228
1229 Point aPos(rRect.TopLeft());
1230 aPos.AdjustX(nLeftDistance );
1231
1232 double fRatio = 1;
1233 if (rTextRect.Bottom() > rRect.GetHeight())
1234 fRatio = static_cast<double>(rRect.GetHeight()) / rTextRect.Bottom();
1235 else
1236 aPos.AdjustY((rRect.GetHeight() - rTextRect.Bottom()) / 2);
1237
1238 SvtScriptType aScript;
1239 sal_uInt16 nIdx = 0;
1240 sal_Int32 nStart = 0;
1241 sal_Int32 nEnd;
1242 size_t nCnt = rScriptChanges.size();
1243
1244 if (nCnt)
1245 {
1246 nEnd = rScriptChanges[nIdx].changePos;
1247 aScript = rScriptChanges[nIdx].scriptType;
1248 }
1249 else
1250 {
1251 nEnd = rStyleName.getLength();
1252 aScript = SvtScriptType::LATIN;
1253 }
1254
1255
1256 do
1257 {
1258 auto oFont = (aScript == SvtScriptType::ASIAN) ?
1259 m_oCJKFont :
1260 ((aScript == SvtScriptType::COMPLEX) ?
1261 m_oCTLFont :
1262 m_oFont);
1263
1264 rRenderContext.Push(vcl::PushFlags::FONT);
1265
1266 if (oFont)
1267 rRenderContext.SetFont(*oFont);
1268
1269 if (fRatio != 1)
1270 {
1271 vcl::Font aFont(rRenderContext.GetFont());
1272 Size aPixelSize(aFont.GetFontSize());
1273 aPixelSize.setWidth(aPixelSize.Width() * fRatio);
1274 aPixelSize.setHeight(aPixelSize.Height() * fRatio);
1275 aFont.SetFontSize(aPixelSize);
1276 rRenderContext.SetFont(aFont);
1277 }
1278
1279 rRenderContext.DrawText(aPos, rStyleName, nStart, nEnd - nStart);
1280
1281 rRenderContext.Pop();
1282
1283 aPos.AdjustX(rScriptChanges[nIdx++].textWidth * fRatio);
1284 if (nEnd < rStyleName.getLength() && nIdx < nCnt)
1285 {
1286 nStart = nEnd;
1287 nEnd = rScriptChanges[nIdx].changePos;
1288 aScript = rScriptChanges[nIdx].scriptType;
1289 }
1290 else
1291 break;
1292 }
1293 while(true);
1294}
1295
1296static bool GetWhich(const SfxItemSet& rSet, sal_uInt16 nSlot, sal_uInt16& rWhich)
1297{
1298 rWhich = rSet.GetPool()->GetWhich(nSlot);
1299 return rSet.GetItemState(rWhich) >= SfxItemState::DEFAULT;
1300}
1301
1302static bool SetFont(const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont)
1303{
1304 sal_uInt16 nWhich;
1305 if (GetWhich(rSet, nSlot, nWhich))
1306 {
1307 const auto& rFontItem = static_cast<const SvxFontItem&>(rSet.Get(nWhich));
1308 rFont.SetFamilyName(rFontItem.GetFamilyName());
1309 rFont.SetStyleName(rFontItem.GetStyleName());
1310 return true;
1311 }
1312 return false;
1313}
1314
1315static bool SetFontSize(vcl::RenderContext& rRenderContext, const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont)
1316{
1317 sal_uInt16 nWhich;
1318 if (GetWhich(rSet, nSlot, nWhich))
1319 {
1320 const auto& rFontHeightItem = static_cast<const SvxFontHeightItem&>(rSet.Get(nWhich));
1322 {
1323 Size aFontSize(0, rFontHeightItem.GetHeight());
1324 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
1325 rFont.SetFontSize(aPixelSize);
1326 return true;
1327 }
1328 }
1329 return false;
1330}
1331
1332static void SetFontStyle(const SfxItemSet& rSet, sal_uInt16 nPosture, sal_uInt16 nWeight, SvxFont& rFont)
1333{
1334 sal_uInt16 nWhich;
1335 if (GetWhich(rSet, nPosture, nWhich))
1336 {
1337 const auto& rItem = static_cast<const SvxPostureItem&>(rSet.Get(nWhich));
1338 rFont.SetItalic(rItem.GetPosture());
1339 }
1340
1341 if (GetWhich(rSet, nWeight, nWhich))
1342 {
1343 const auto& rItem = static_cast<const SvxWeightItem&>(rSet.Get(nWhich));
1344 rFont.SetWeight(rItem.GetWeight());
1345 }
1346}
1347
1348void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, bool bIsNotSelected)
1349{
1350 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1351 if (!bIsNotSelected)
1352 rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
1353 else
1354 rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
1355
1356 // handle the push-button
1357 if (!bIsNotSelected)
1358 {
1359 if (nItem == 0 || nItem == m_xWidget->get_count() - 1)
1360 m_xWidget->set_item_menu(OUString::number(nItem), nullptr);
1361 else
1362 {
1363 m_nLastItemWithMenu = nItem;
1364 m_xWidget->set_item_menu(OUString::number(nItem), m_xMenu.get());
1365 }
1366 }
1367
1368 if (nItem <= 0 || nItem >= m_xWidget->get_count() - 1)
1369 return;
1370
1372 if (!pShell)
1373 return;
1374
1375 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
1376 if (!pPool)
1377 return;
1378
1379 SfxStyleSheetBase* pStyle = pPool->First(eStyleFamily);
1380 while (pStyle && pStyle->GetName() != rStyleName)
1381 pStyle = pPool->Next();
1382
1383 if (!pStyle )
1384 return;
1385
1386 std::optional<SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
1387 if (!pItemSet) return;
1388
1389 SvxFont aFont;
1390 SvxFont aCJKFont;
1391 SvxFont aCTLFont;
1392
1393 SetFontStyle(*pItemSet, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, aFont);
1394 SetFontStyle(*pItemSet, SID_ATTR_CHAR_CJK_POSTURE, SID_ATTR_CHAR_CJK_WEIGHT, aCJKFont);
1395 SetFontStyle(*pItemSet, SID_ATTR_CHAR_CTL_POSTURE, SID_ATTR_CHAR_CTL_WEIGHT, aCTLFont);
1396
1397 const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
1398 if ( pItem )
1399 {
1400 auto aVal = static_cast< const SvxContourItem* >( pItem )->GetValue();
1401 aFont.SetOutline(aVal);
1402 aCJKFont.SetOutline(aVal);
1403 aCTLFont.SetOutline(aVal);
1404 }
1405
1406 pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED );
1407 if ( pItem )
1408 {
1409 auto aVal = static_cast< const SvxShadowedItem* >( pItem )->GetValue();
1410 aFont.SetShadow(aVal);
1411 aCJKFont.SetShadow(aVal);
1412 aCTLFont.SetShadow(aVal);
1413 }
1414
1415 pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF );
1416 if ( pItem )
1417 {
1418 auto aVal = static_cast< const SvxCharReliefItem* >( pItem )->GetValue();
1419 aFont.SetRelief(aVal);
1420 aCJKFont.SetRelief(aVal);
1421 aCTLFont.SetRelief(aVal);
1422 }
1423
1424 pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE );
1425 if ( pItem )
1426 {
1427 auto aVal = static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle();
1428 aFont.SetUnderline(aVal);
1429 aCJKFont.SetUnderline(aVal);
1430 aCTLFont.SetUnderline(aVal);
1431 }
1432
1433 pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE );
1434 if ( pItem )
1435 {
1436 auto aVal = static_cast< const SvxOverlineItem* >( pItem )->GetValue();
1437 aFont.SetOverline(aVal);
1438 aCJKFont.SetOverline(aVal);
1439 aCTLFont.SetOverline(aVal);
1440 }
1441
1442 pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT );
1443 if ( pItem )
1444 {
1445 auto aVal = static_cast< const SvxCrossedOutItem* >( pItem )->GetStrikeout();
1446 aFont.SetStrikeout(aVal);
1447 aCJKFont.SetStrikeout(aVal);
1448 aCTLFont.SetStrikeout(aVal);
1449 }
1450
1451 pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP );
1452 if ( pItem )
1453 {
1454 auto aVal = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap();
1455 aFont.SetCaseMap(aVal);
1456 aCJKFont.SetCaseMap(aVal);
1457 aCTLFont.SetCaseMap(aVal);
1458 }
1459
1460 pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK );
1461 if ( pItem )
1462 {
1463 auto aVal = static_cast< const SvxEmphasisMarkItem* >( pItem )->GetEmphasisMark();
1464 aFont.SetEmphasisMark(aVal);
1465 aCJKFont.SetEmphasisMark(aVal);
1466 aCTLFont.SetEmphasisMark(aVal);
1467 }
1468
1469 // setup the device & draw
1470 Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
1471
1472 pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR );
1473 // text color, when nothing is selected
1474 if ( (nullptr != pItem) && bIsNotSelected)
1475 aFontCol = static_cast< const SvxColorItem* >( pItem )->GetValue();
1476
1477 drawing::FillStyle style = drawing::FillStyle_NONE;
1478 // which kind of Fill style is selected
1479 pItem = pItemSet->GetItem( XATTR_FILLSTYLE );
1480 // only when ok and not selected
1481 if ( (nullptr != pItem) && bIsNotSelected)
1482 style = static_cast< const XFillStyleItem* >( pItem )->GetValue();
1483
1484 switch(style)
1485 {
1486 case drawing::FillStyle_SOLID:
1487 {
1488 // set background color
1489 pItem = pItemSet->GetItem( XATTR_FILLCOLOR );
1490 if ( nullptr != pItem )
1491 aBackCol = static_cast< const XFillColorItem* >( pItem )->GetColorValue();
1492
1493 if ( aBackCol != COL_AUTO )
1494 {
1495 rRenderContext.SetFillColor(aBackCol);
1496 rRenderContext.DrawRect(rRect);
1497 }
1498 }
1499 break;
1500
1501 default: break;
1502 //TODO Draw the other background styles: gradient, hatching and bitmap
1503 }
1504
1505 // when the font and background color are too similar, adjust the Font-Color
1506 if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
1507 aFontCol = TestColorsVisible(aFontCol, (aBackCol != COL_AUTO) ? aBackCol : rRenderContext.GetBackground().GetColor());
1508
1509 // set text color
1510 if ( aFontCol != COL_AUTO )
1511 rRenderContext.SetTextColor(aFontCol);
1512
1513 if (SetFont(*pItemSet, SID_ATTR_CHAR_FONT, aFont) &&
1514 SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_FONTHEIGHT, aFont))
1515 m_oFont = aFont;
1516
1517 if (SetFont(*pItemSet, SID_ATTR_CHAR_CJK_FONT, aCJKFont) &&
1518 SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CJK_FONTHEIGHT, aCJKFont))
1519 m_oCJKFont = aCJKFont;
1520
1521 if (SetFont(*pItemSet, SID_ATTR_CHAR_CTL_FONT, aCTLFont) &&
1522 SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CTL_FONTHEIGHT, aCTLFont))
1523 m_oCTLFont = aCTLFont;
1524}
1525
1526IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, weld::ComboBox::render_args, aPayload, void)
1527{
1528 vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
1529 const ::tools::Rectangle& rRect = std::get<1>(aPayload);
1530 bool bSelected = std::get<2>(aPayload);
1531 const OUString& rId = std::get<3>(aPayload);
1532
1533 sal_uInt32 nIndex = rId.toUInt32();
1534
1535 OUString aStyleName(m_xWidget->get_text(nIndex));
1536
1538
1539 SetupEntry(rRenderContext, nIndex, rRect, aStyleName, !bSelected);
1540 auto aScriptChanges = CheckScript(aStyleName);
1541 auto aTextRect = CalcBoundRect(rRenderContext, aStyleName, aScriptChanges);
1542 UserDrawEntry(rRenderContext, rRect, aTextRect, aStyleName, aScriptChanges);
1543
1544 rRenderContext.Pop();
1545}
1546
1547void SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext)
1548{
1549 if (m_nMaxUserDrawFontWidth)
1550 return;
1551
1552 tools::Long nMaxNormalFontWidth = 0;
1553 sal_Int32 nEntryCount = m_xWidget->get_count();
1554 for (sal_Int32 i = 0; i < nEntryCount; ++i)
1555 {
1556 OUString sStyleName(get_text(i));
1557 tools::Rectangle aTextRectForDefaultFont;
1558 rRenderContext.GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
1559
1560 const tools::Long nWidth = aTextRectForDefaultFont.GetWidth();
1561
1562 nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
1563 }
1564
1565 m_nMaxUserDrawFontWidth = nMaxNormalFontWidth;
1566 for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
1567 {
1568 OUString sStyleName(get_text(i));
1569
1570 if (sStyleName.isEmpty())
1571 continue;
1572
1574 SetupEntry(rRenderContext, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
1575 auto aScriptChanges = CheckScript(sStyleName);
1576 tools::Rectangle aTextRectForActualFont = CalcBoundRect(rRenderContext, sStyleName, aScriptChanges);
1577 if (aTextRectForActualFont.Bottom() > ITEM_HEIGHT)
1578 {
1579 //Font didn't fit, re-calculate with adjustment ratio.
1580 double fRatio = static_cast<double>(ITEM_HEIGHT) / aTextRectForActualFont.Bottom();
1581 aTextRectForActualFont = CalcBoundRect(rRenderContext, sStyleName, aScriptChanges, fRatio);
1582 }
1583 rRenderContext.Pop();
1584
1585 const int nWidth = aTextRectForActualFont.GetWidth() + m_xWidget->get_menu_button_width() + BUTTON_PADDING;
1586
1587 m_nMaxUserDrawFontWidth = std::max(nWidth, m_nMaxUserDrawFontWidth);
1588 }
1589}
1590
1591// test is the color between Font- and background-color to be identify
1592// return is always the Font-Color
1593// when both light or dark, change the Contrast
1594// in other case do not change the origin color
1595// when the color is R=G=B=128 the DecreaseContrast make 128 the need an exception
1596Color SvxStyleBox_Base::TestColorsVisible(const Color &FontCol, const Color &BackCol)
1597{
1598 constexpr sal_uInt8 ChgVal = 60; // increase/decrease the Contrast
1599
1600 Color retCol = FontCol;
1601 if ((FontCol.IsDark() == BackCol.IsDark()) && (FontCol.IsBright() == BackCol.IsBright()))
1602 {
1603 sal_uInt8 lumi = retCol.GetLuminance();
1604
1605 if((lumi > 120) && (lumi < 140))
1606 retCol.DecreaseLuminance(ChgVal / 2);
1607 else
1608 retCol.DecreaseContrast(ChgVal);
1609 }
1610
1611 return retCol;
1612}
1613
1614IMPL_LINK(SvxStyleBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
1615{
1616 if (!m_xWidget)
1617 return;
1618
1619 {
1620 auto entriesNode = rJsonWriter.startNode("entries");
1621 for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
1622 {
1623 auto entryNode = rJsonWriter.startNode("");
1624 rJsonWriter.put("", m_xWidget->get_text(i));
1625 }
1626 }
1627
1628 int nActive = m_xWidget->get_active();
1629 rJsonWriter.put("selectedCount", static_cast<sal_Int32>(nActive == -1 ? 0 : 1));
1630
1631 {
1632 auto selectedNode = rJsonWriter.startNode("selectedEntries");
1633 if (nActive != -1)
1634 {
1635 auto node = rJsonWriter.startNode("");
1636 rJsonWriter.put("", static_cast<sal_Int32>(nActive));
1637 }
1638 }
1639
1640 rJsonWriter.put("command", ".uno:StyleApply");
1641}
1642
1643static bool lcl_GetDocFontList(const FontList** ppFontList, SvxFontNameBox_Base* pBox)
1644{
1645 bool bChanged = false;
1646 const SfxObjectShell* pDocSh = SfxObjectShell::Current();
1647 const SvxFontListItem* pFontListItem = nullptr;
1648
1649 if ( pDocSh )
1650 pFontListItem =
1651 static_cast<const SvxFontListItem*>(pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
1652 else
1653 {
1654 ::std::unique_ptr<FontList> aFontList(new FontList(Application::GetDefaultDevice()));
1655 *ppFontList = aFontList.get();
1656 pBox->SetOwnFontList(std::move(aFontList));
1657 bChanged = true;
1658 }
1659
1660 if ( pFontListItem )
1661 {
1662 const FontList* pNewFontList = pFontListItem->GetFontList();
1663 DBG_ASSERT( pNewFontList, "Doc-FontList not available!" );
1664
1665 // No old list, but a new list
1666 if ( !*ppFontList && pNewFontList )
1667 {
1668 // => take over
1669 *ppFontList = pNewFontList;
1670 bChanged = true;
1671 }
1672 else
1673 {
1674 // Comparing the font lists is not perfect.
1675 // When you change the font list in the Doc, you can track
1676 // changes here only on the Listbox, because ppFontList
1677 // has already been updated.
1678 bChanged =
1679 ( ( *ppFontList != pNewFontList ) ||
1680 pBox->GetListCount() != pNewFontList->GetFontNameCount() );
1681 // HACK: Comparing is incomplete
1682
1683 if ( bChanged )
1684 *ppFontList = pNewFontList;
1685 }
1686
1687 if ( pBox )
1688 pBox->set_sensitive(true);
1689 }
1690 else if ( pBox && ( pDocSh || !ppFontList ))
1691 {
1692 // Disable box only when we have a SfxObjectShell and didn't get a font list OR
1693 // we don't have a SfxObjectShell and no current font list.
1694 // It's possible that we currently have no SfxObjectShell, but a current font list.
1695 // See #i58471: When a user set the focus into the font name combo box and opens
1696 // the help window with F1. After closing the help window, we disable the font name
1697 // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
1698 // font list hasn't changed and therefore the combo box shouldn't be disabled!
1699 pBox->set_sensitive(false);
1700 }
1701
1702 // Fill the FontBox, also the new list if necessary
1703 if ( pBox && bChanged )
1704 {
1705 if ( *ppFontList )
1706 pBox->Fill( *ppFontList );
1707 else
1708 pBox->Clear();
1709 }
1710 return bChanged;
1711}
1712
1713SvxFontNameBox_Base::SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
1714 const Reference<XFrame>& rFrame,
1715 SvxFontNameToolBoxControl& rCtrl)
1716 : m_xListener(new comphelper::ConfigurationListener("/org.openoffice.Office.Common/Font/View"))
1717 , m_aWYSIWYG(m_xListener, "ShowFontBoxWYSIWYG", *this)
1718 , m_aHistory(m_xListener, "History", *this)
1719 , m_rCtrl(rCtrl)
1720 , m_xWidget(new FontNameBox(std::move(xWidget)))
1721 , pFontList(nullptr)
1722 , nFtCount(0)
1723 , bRelease(true)
1724 , m_xFrame(rFrame)
1725 , mbCheckingUnknownFont(false)
1726{
1727 EnableControls();
1728
1729 m_xWidget->connect_changed(LINK(this, SvxFontNameBox_Base, SelectHdl));
1730 m_xWidget->connect_key_press(LINK(this, SvxFontNameBox_Base, KeyInputHdl));
1731 m_xWidget->connect_entry_activate(LINK(this, SvxFontNameBox_Base, ActivateHdl));
1732 m_xWidget->connect_focus_in(LINK(this, SvxFontNameBox_Base, FocusInHdl));
1733 m_xWidget->connect_focus_out(LINK(this, SvxFontNameBox_Base, FocusOutHdl));
1734 m_xWidget->connect_get_property_tree(LINK(this, SvxFontNameBox_Base, DumpAsPropertyTreeHdl));
1735
1736 m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS + 5);
1737}
1738
1739SvxFontNameBox_Impl::SvxFontNameBox_Impl(vcl::Window* pParent, const Reference<XFrame>& rFrame,
1740 SvxFontNameToolBoxControl& rCtrl)
1741 : InterimItemWindow(pParent, "svx/ui/fontnamebox.ui", "FontNameBox")
1742 , SvxFontNameBox_Base(m_xBuilder->weld_combo_box("fontnamecombobox"), rFrame, rCtrl)
1743{
1744 set_id("fontnamecombobox");
1745 SetOptimalSize();
1746}
1747
1748void SvxFontNameBox_Base::FillList()
1749{
1750 if (!m_xWidget) // e.g. disposed
1751 return;
1752 // Save old Selection, set back in the end
1753 int nStartPos, nEndPos;
1754 m_xWidget->get_entry_selection_bounds(nStartPos, nEndPos);
1755
1756 // Did Doc-Fontlist change?
1757 lcl_GetDocFontList(&pFontList, this);
1758
1759 m_xWidget->select_entry_region(nStartPos, nEndPos);
1760}
1761
1762bool SvxFontNameBox_Base::CheckFontIsAvailable(std::u16string_view fontname)
1763{
1764 lcl_GetDocFontList(&pFontList, this);
1765 return pFontList && pFontList->IsAvailable(fontname);
1766}
1767
1768void SvxFontNameBox_Base::CheckAndMarkUnknownFont()
1769{
1770 if (mbCheckingUnknownFont) //tdf#117537 block rentry
1771 return;
1772 mbCheckingUnknownFont = true;
1773 OUString fontname = m_xWidget->get_active_text();
1774 // tdf#154680 If a font is set and that font is unknown, show it in italic.
1775 vcl::Font font = m_xWidget->get_entry_font();
1776 if (fontname.isEmpty() || CheckFontIsAvailable(fontname))
1777 {
1778 if( font.GetItalic() != ITALIC_NONE )
1779 {
1780 font.SetItalic( ITALIC_NONE );
1781 m_xWidget->set_entry_font(font);
1782 m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME));
1783 }
1784 }
1785 else
1786 {
1787 if( font.GetItalic() != ITALIC_NORMAL )
1788 {
1789 font.SetItalic( ITALIC_NORMAL );
1790 m_xWidget->set_entry_font(font);
1791 m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE));
1792 }
1793 }
1794 mbCheckingUnknownFont = false;
1795}
1796
1797void SvxFontNameBox_Base::Update( const css::awt::FontDescriptor* pFontDesc )
1798{
1799 if ( pFontDesc )
1800 {
1801 aCurFont.SetFamilyName ( pFontDesc->Name );
1802 aCurFont.SetFamily ( FontFamily( pFontDesc->Family ) );
1803 aCurFont.SetStyleName ( pFontDesc->StyleName );
1804 aCurFont.SetPitch ( FontPitch( pFontDesc->Pitch ) );
1805 aCurFont.SetCharSet ( rtl_TextEncoding( pFontDesc->CharSet ) );
1806 }
1807 OUString aCurName = aCurFont.GetFamilyName();
1808 OUString aText = m_xWidget->get_active_text();
1809 if (aText != aCurName)
1810 set_active_or_entry_text(aCurName);
1811}
1812
1813void SvxFontNameBox_Base::set_active_or_entry_text(const OUString& rText)
1814{
1815 m_xWidget->set_active_or_entry_text(rText);
1816 CheckAndMarkUnknownFont();
1817}
1818
1819IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusInHdl, weld::Widget&, void)
1820{
1821 FillList();
1822}
1823
1824IMPL_LINK(SvxFontNameBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1825{
1826 return DoKeyInput(rKEvt);
1827}
1828
1829bool SvxFontNameBox_Base::DoKeyInput(const KeyEvent& rKEvt)
1830{
1831 bool bHandled = false;
1832
1833 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1834
1835 switch (nCode)
1836 {
1837 case KEY_TAB:
1838 bRelease = false;
1839 Select(true);
1840 break;
1841
1842 case KEY_ESCAPE:
1843 set_active_or_entry_text(m_xWidget->get_saved_value());
1844 if (!m_rCtrl.IsInSidebar())
1845 {
1846 ReleaseFocus_Impl();
1847 bHandled = true;
1848 }
1849 EndPreview();
1850 break;
1851 }
1852
1853 return bHandled;
1854}
1855
1856bool SvxFontNameBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
1857{
1858 return SvxFontNameBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
1859}
1860
1861IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusOutHdl, weld::Widget&, void)
1862{
1863 if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
1864 {
1865 set_active_or_entry_text(m_xWidget->get_saved_value());
1866 // send EndPreview
1867 EndPreview();
1868 }
1869}
1870
1871void SvxFontNameBox_Impl::SetOptimalSize()
1872{
1873 // set width in chars low so the size request will not be overridden
1874 m_xWidget->set_entry_width_chars(1);
1875 // tdf#132338 purely using this calculation to keep things their traditional width
1876 Size aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS +5) * 4, 0), MapMode(MapUnit::MapAppFont)));
1877 m_xWidget->set_size_request(aSize.Width(), -1);
1878
1879 SetSizePixel(get_preferred_size());
1880}
1881
1882void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1883{
1884 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1885 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1886 {
1887 SetOptimalSize();
1888 }
1889 else if ( ( rDCEvt.GetType() == DataChangedEventType::FONTS ) ||
1890 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) )
1891 {
1892 // The old font list in shell has likely been destroyed at this point, so we need to get
1893 // the new one before doing anything further.
1894 lcl_GetDocFontList( &pFontList, this );
1895 }
1896}
1897
1898void SvxFontNameBox_Base::ReleaseFocus_Impl()
1899{
1900 if ( !bRelease )
1901 {
1902 bRelease = true;
1903 return;
1904 }
1905 if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
1906 m_xFrame->getContainerWindow()->setFocus();
1907}
1908
1909void SvxFontNameBox_Base::EnableControls()
1910{
1911 bool bEnableMRU = m_aHistory.get();
1912 sal_uInt16 nEntries = bEnableMRU ? MAX_MRU_FONTNAME_ENTRIES : 0;
1913
1914 bool bNewWYSIWYG = m_aWYSIWYG.get();
1915 bool bOldWYSIWYG = m_xWidget->IsWYSIWYGEnabled();
1916
1917 if (m_xWidget->get_max_mru_count() != nEntries || bNewWYSIWYG != bOldWYSIWYG)
1918 {
1919 // refill in the next GetFocus-Handler
1920 pFontList = nullptr;
1921 Clear();
1922 m_xWidget->set_max_mru_count(nEntries);
1923 }
1924
1925 if (bNewWYSIWYG != bOldWYSIWYG)
1926 m_xWidget->EnableWYSIWYG(bNewWYSIWYG);
1927}
1928
1929IMPL_LINK(SvxFontNameBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
1930{
1931 Select(rCombo.changed_by_direct_pick()); // only when picked from the list
1932}
1933
1934IMPL_LINK_NOARG(SvxFontNameBox_Base, ActivateHdl, weld::ComboBox&, bool)
1935{
1936 Select(true);
1937 return true;
1938}
1939
1940void SvxFontNameBox_Base::Select(bool bNonTravelSelect)
1941{
1942 Sequence< PropertyValue > aArgs( 1 );
1943 auto pArgs = aArgs.getArray();
1944 std::unique_ptr<SvxFontItem> pFontItem;
1945 if ( pFontList )
1946 {
1947 FontMetric aFontMetric( pFontList->Get(m_xWidget->get_active_text(),
1948 aCurFont.GetWeight(),
1949 aCurFont.GetItalic() ) );
1950 aCurFont = aFontMetric;
1951
1952 pFontItem.reset( new SvxFontItem( aFontMetric.GetFamilyType(),
1953 aFontMetric.GetFamilyName(),
1954 aFontMetric.GetStyleName(),
1955 aFontMetric.GetPitch(),
1956 aFontMetric.GetCharSet(),
1957 SID_ATTR_CHAR_FONT ) );
1958
1959 Any a;
1960 pFontItem->QueryValue( a );
1961 pArgs[0].Value = a;
1962 }
1963
1964 const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
1965 if (bNonTravelSelect)
1966 {
1967 CheckAndMarkUnknownFont();
1968 // #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
1969 // This instance may be deleted in the meantime (i.e. when a dialog is opened
1970 // while in Dispatch()), accessing members will crash in this case.
1971 ReleaseFocus_Impl();
1972 EndPreview();
1973 if (pFontItem)
1974 {
1975 pArgs[0].Name = "CharFontName";
1976 SfxToolBoxControl::Dispatch(xProvider, ".uno:CharFontName", aArgs);
1977 }
1978 }
1979 else
1980 {
1981 if (pFontItem)
1982 {
1983 pArgs[0].Name = "CharPreviewFontName";
1984 SfxToolBoxControl::Dispatch(xProvider, ".uno:CharPreviewFontName", aArgs);
1985 }
1986 }
1987}
1988
1989IMPL_LINK(SvxFontNameBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
1990{
1991 {
1992 auto entriesNode = rJsonWriter.startNode("entries");
1993 for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
1994 {
1995 auto entryNode = rJsonWriter.startNode("");
1996 rJsonWriter.put("", m_xWidget->get_text(i));
1997 }
1998 }
1999
2000 int nSelectedEntry = m_xWidget->get_active();
2001 rJsonWriter.put("selectedCount", static_cast<sal_Int32>(nSelectedEntry == -1 ? 0 : 1));
2002
2003 {
2004 auto selectedNode = rJsonWriter.startNode("selectedEntries");
2005 if (nSelectedEntry != -1)
2006 {
2007 auto entryNode = rJsonWriter.startNode("");
2008 rJsonWriter.put("", m_xWidget->get_text(nSelectedEntry));
2009 }
2010 }
2011
2012 rJsonWriter.put("command", ".uno:CharFontName");
2013}
2014
2016 std::shared_ptr<PaletteManager> xPaletteManager,
2017 ColorStatus& rColorStatus,
2018 sal_uInt16 nSlotId,
2019 const Reference< XFrame >& rFrame,
2020 const MenuOrToolMenuButton& rMenuButton,
2021 TopLevelParentFunction aTopLevelParentFunction,
2022 ColorSelectFunction aColorSelectFunction)
2023 : WeldToolbarPopup(rFrame, rMenuButton.get_widget(), "svx/ui/colorwindow.ui", "palette_popup_window")
2024 , theSlotId(nSlotId)
2025 , maCommand(std::move(rCommand))
2026 , maMenuButton(rMenuButton)
2027 , mxPaletteManager(std::move(xPaletteManager))
2028 , mrColorStatus(rColorStatus)
2029 , maTopLevelParentFunction(std::move(aTopLevelParentFunction))
2030 , maColorSelectFunction(std::move(aColorSelectFunction))
2031 , mxColorSet(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin", true)))
2032 , mxRecentColorSet(new SvxColorValueSet(nullptr))
2033 , mxPaletteListBox(m_xBuilder->weld_combo_box("palette_listbox"))
2034 , mxButtonAutoColor(m_xBuilder->weld_button("auto_color_button"))
2035 , mxButtonNoneColor(m_xBuilder->weld_button("none_color_button"))
2036 , mxButtonPicker(m_xBuilder->weld_button("color_picker_button"))
2037 , mxAutomaticSeparator(m_xBuilder->weld_widget("separator4"))
2038 , mxColorSetWin(new weld::CustomWeld(*m_xBuilder, "colorset", *mxColorSet))
2039 , mxRecentColorSetWin(new weld::CustomWeld(*m_xBuilder, "recent_colorset", *mxRecentColorSet))
2040 , mpDefaultButton(nullptr)
2041{
2044
2045 switch ( theSlotId )
2046 {
2047 case SID_ATTR_CHAR_COLOR_BACKGROUND:
2048 case SID_BACKGROUND_COLOR:
2049 case SID_ATTR_CHAR_BACK_COLOR:
2050 case SID_TABLE_CELL_BACKGROUND_COLOR:
2051 {
2052 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_NOFILL ) );
2053 break;
2054 }
2055 case SID_AUTHOR_COLOR:
2056 {
2057 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_BY_AUTHOR ) );
2058 break;
2059 }
2060 case SID_BMPMASK_COLOR:
2061 {
2062 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_TRANSPARENT ) );
2063 break;
2064 }
2065 case SID_ATTR_CHAR_COLOR:
2066 case SID_ATTR_CHAR_COLOR2:
2067 case SID_EXTRUSION_3D_COLOR:
2068 {
2069 mxButtonAutoColor->set_label(EditResId(RID_SVXSTR_AUTOMATIC));
2070 break;
2071 }
2072 case SID_FM_CTL_PROPERTIES:
2073 {
2074 mxButtonAutoColor->set_label( SvxResId( RID_SVXSTR_DEFAULT ) );
2075 break;
2076 }
2077 default:
2078 {
2079 mxButtonAutoColor->hide();
2080 mxAutomaticSeparator->hide();
2081 break;
2082 }
2083 }
2084
2085 mxPaletteListBox->connect_changed(LINK(this, ColorWindow, SelectPaletteHdl));
2086 std::vector<OUString> aPaletteList = mxPaletteManager->GetPaletteList();
2087 mxPaletteListBox->freeze();
2088 for (const auto& rPalette : aPaletteList)
2089 mxPaletteListBox->append_text(rPalette);
2090 mxPaletteListBox->thaw();
2091 OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
2092 mxPaletteListBox->set_active_text(aPaletteName);
2093 const int nSelectedEntry(mxPaletteListBox->get_active());
2094 if (nSelectedEntry != -1)
2095 mxPaletteManager->SetPalette(nSelectedEntry);
2096
2097 mxButtonAutoColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl));
2098 mxButtonNoneColor->connect_clicked(LINK(this, ColorWindow, AutoColorClickHdl));
2099 mxButtonPicker->connect_clicked(LINK(this, ColorWindow, OpenPickerClickHdl));
2100
2101 mxColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl));
2102 mxRecentColorSet->SetSelectHdl(LINK( this, ColorWindow, SelectHdl));
2103 m_xTopLevel->set_help_id(HID_POPUP_COLOR);
2104 mxColorSet->SetHelpId(HID_POPUP_COLOR_CTRL);
2105
2106 mxPaletteManager->ReloadColorSet(*mxColorSet);
2108 Size aSize = mxColorSet->layoutAllVisible(nMaxItems);
2109 mxColorSet->set_size_request(aSize.Width(), aSize.Height());
2110
2111 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2112 aSize = mxRecentColorSet->layoutAllVisible(mxPaletteManager->GetRecentColorCount());
2113 mxRecentColorSet->set_size_request(aSize.Width(), aSize.Height());
2114
2115 AddStatusListener( ".uno:ColorTableState" );
2117 if ( maCommand == ".uno:FrameLineColor" )
2118 {
2119 AddStatusListener( ".uno:BorderTLBR" );
2120 AddStatusListener( ".uno:BorderBLTR" );
2121 }
2122}
2123
2125{
2126 if (mxColorSet->IsNoSelection() && mpDefaultButton)
2128 else
2129 mxColorSet->GrabFocus();
2130}
2131
2133{
2134 mxButtonNoneColor->show();
2135}
2136
2138{
2139}
2140
2142{
2143 Color aColor = pColorSet->GetItemColor(pColorSet->GetSelectedItemId());
2144 OUString sColorName = pColorSet->GetItemText(pColorSet->GetSelectedItemId());
2145 return { aColor, sColorName };
2146}
2147
2148namespace
2149{
2150 NamedColor GetAutoColor(sal_uInt16 nSlotId)
2151 {
2152 Color aColor;
2153 OUString sColorName;
2154 switch (nSlotId)
2155 {
2156 case SID_ATTR_CHAR_COLOR_BACKGROUND:
2157 case SID_BACKGROUND_COLOR:
2158 case SID_ATTR_CHAR_BACK_COLOR:
2159 case SID_TABLE_CELL_BACKGROUND_COLOR:
2160 aColor = COL_TRANSPARENT;
2161 sColorName = SvxResId(RID_SVXSTR_NOFILL);
2162 break;
2163 case SID_AUTHOR_COLOR:
2164 aColor = COL_TRANSPARENT;
2165 sColorName = SvxResId(RID_SVXSTR_BY_AUTHOR);
2166 break;
2167 case SID_BMPMASK_COLOR:
2168 aColor = COL_TRANSPARENT;
2169 sColorName = SvxResId(RID_SVXSTR_TRANSPARENT);
2170 break;
2171 case SID_FM_CTL_PROPERTIES:
2172 aColor = COL_TRANSPARENT;
2173 sColorName = SvxResId(RID_SVXSTR_DEFAULT);
2174 break;
2175 case SID_ATTR_CHAR_COLOR:
2176 case SID_ATTR_CHAR_COLOR2:
2177 case SID_EXTRUSION_3D_COLOR:
2178 default:
2179 aColor = COL_AUTO;
2180 sColorName = EditResId(RID_SVXSTR_AUTOMATIC);
2181 break;
2182 }
2183
2184 return {aColor, sColorName};
2185 }
2186
2187 NamedColor GetNoneColor()
2188 {
2190 ? SvxResId(RID_SVXSTR_INVISIBLE)
2191 : SvxResId(RID_SVXSTR_NONE);
2192 return { COL_NONE_COLOR, aName };
2193 }
2194}
2195
2197{
2198 if (!mxColorSet->IsNoSelection())
2199 return GetSelectEntryColor(mxColorSet.get());
2200 if (!mxRecentColorSet->IsNoSelection())
2203 return GetNoneColor();
2204 return GetAutoColor();
2205}
2206
2207IMPL_LINK(ColorWindow, SelectHdl, ValueSet*, pColorSet, void)
2208{
2209 NamedColor aNamedColor = GetSelectEntryColor(pColorSet);
2210
2211 if (pColorSet != mxRecentColorSet.get())
2212 {
2213 mxPaletteManager->AddRecentColor(aNamedColor.m_aColor, aNamedColor.m_aName);
2214 if (!maMenuButton.get_active())
2215 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2216 }
2217
2218 mxPaletteManager->SetSplitButtonColor(aNamedColor);
2219
2220 // deliberate take a copy here in case maMenuButton.set_inactive
2221 // triggers a callback that destroys ourself
2222 ColorSelectFunction aColorSelectFunction(maColorSelectFunction);
2223 OUString sCommand(maCommand);
2224 // Same for querying IsTheme early.
2225 bool bThemePaletteSelected = mxPaletteManager->IsThemePaletteSelected();
2226 sal_uInt16 nSelectedItemId = pColorSet->GetSelectedItemId();
2227
2228 if (bThemePaletteSelected)
2229 {
2230 sal_uInt16 nThemeIndex;
2231 sal_uInt16 nEffectIndex;
2232 if (PaletteManager::GetThemeAndEffectIndex(nSelectedItemId, nThemeIndex, nEffectIndex))
2233 {
2234 aNamedColor.m_nThemeIndex = nThemeIndex;
2235 mxPaletteManager->GetLumModOff(nThemeIndex, nEffectIndex, aNamedColor.m_nLumMod, aNamedColor.m_nLumOff);
2236 }
2237 }
2238
2239 maMenuButton.set_inactive();
2240 aColorSelectFunction(sCommand, aNamedColor);
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 mxPaletteManager->SetSplitButtonColor(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, aNamedColor);
2274}
2275
2276IMPL_LINK_NOARG(ColorWindow, OpenPickerClickHdl, weld::Button&, void)
2277{
2278 // copy before set_inactive
2279 auto nColor = GetSelectEntryColor().m_aColor;
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.m_aColor;
2340
2341 if (mxButtonAutoColor->get_visible() && rColor.IsFullyTransparent())
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.m_aName;
2364 mxPaletteManager->AddRecentColor(rColor, rColorName, false);
2365 mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet);
2367 }
2368}
2369
2371{
2372 OUString sColorName = "#" + rColor.AsRGBHexString().toAsciiUpperCase();
2373 ColorWindow::SelectEntry({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[ check_after_deref : 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 // add used styles
3198 pStyle = xIter->Next();
3199 while ( pStyle )
3200 {
3201 aStyles.push_back(pStyle->GetName());
3202 pStyle = xIter->Next();
3203 }
3204
3205 if (pImpl->bSpecModeWriter || pImpl->bSpecModeCalc)
3206 {
3207 pBox->append_text(pImpl->aClearForm);
3208 pBox->insert_separator(1, "separator");
3209
3210 // add default styles if less than 12 items
3211 for( const auto &rStyle : pImpl->aDefaultStyles )
3212 {
3213 if ( aStyles.size() + pBox->get_count() > 12)
3214 break;
3215 // insert default style only if not used (and added to rStyle before)
3216 if (std::find(aStyles.begin(), aStyles.end(), rStyle.second) >= aStyles.end())
3217 pBox->append_text(rStyle.second);
3218 }
3219 }
3220 std::sort(aStyles.begin(), aStyles.end());
3221
3222 for (const auto& rStyle : aStyles)
3223 pBox->append_text(rStyle);
3224
3225 if ((pImpl->bSpecModeWriter || pImpl->bSpecModeCalc) && !comphelper::LibreOfficeKit::isActive())
3226 pBox->append_text(pImpl->aMore);
3227
3228 pBox->thaw();
3229 pBox->set_active_or_entry_text(aStrSel);
3230 pBox->SetFamily( eFamily );
3231}
3232
3233void SvxStyleToolBoxControl::SelectStyle( const OUString& rStyleName )
3234{
3235 SvxStyleBox_Base* pBox = pImpl->m_pBox;
3236 DBG_ASSERT( pBox, "Control not found!" );
3237
3238 if ( !pBox )
3239 return;
3240
3241 OUString aStrSel(pBox->get_active_text());
3242
3243 if ( !rStyleName.isEmpty() )
3244 {
3245 OUString aNewStyle = rStyleName;
3246
3247 auto aFound = std::find_if(pImpl->aDefaultStyles.begin(), pImpl->aDefaultStyles.end(),
3248 [rStyleName] (auto it) { return it.first == rStyleName || it.second == rStyleName; }
3249 );
3250
3251 if (aFound != pImpl->aDefaultStyles.end())
3252 aNewStyle = aFound->second;
3253
3254 if ( aNewStyle != aStrSel )
3255 pBox->set_active_or_entry_text( aNewStyle );
3256 }
3257 else
3258 pBox->set_active(-1);
3259 pBox->save_value();
3260}
3261
3263{
3264 SfxStyleSheetBasePool* pPool = nullptr;
3266
3267 if ( pDocShell )
3268 pPool = pDocShell->GetStyleSheetPool();
3269
3270 sal_uInt16 i;
3271 for ( i=0; i<MAX_FAMILIES; i++ )
3272 if( pFamilyState[i] )
3273 break;
3274
3275 if ( i==MAX_FAMILIES || !pPool )
3276 {
3277 pStyleSheetPool = pPool;
3278 return;
3279 }
3280
3281
3282 const SfxTemplateItem* pItem = nullptr;
3283
3284 if ( nActFamily == 0xffff || nullptr == (pItem = pFamilyState[nActFamily-1].get()) )
3285 // Current range not within allowed ranges or default
3286 {
3287 pStyleSheetPool = pPool;
3288 nActFamily = 2;
3289
3290 pItem = pFamilyState[nActFamily-1].get();
3291 if ( !pItem )
3292 {
3293 nActFamily++;
3294 pItem = pFamilyState[nActFamily-1].get();
3295 }
3296 }
3297 else if ( pPool != pStyleSheetPool )
3298 pStyleSheetPool = pPool;
3299
3300 FillStyleBox(); // Decides by itself whether Fill is needed
3301
3302 if ( pItem )
3303 SelectStyle( pItem->GetStyleName() );
3304}
3305
3307 const SfxTemplateItem* pItem )
3308{
3309 pFamilyState[nIdx].reset( pItem == nullptr ? nullptr : new SfxTemplateItem( *pItem ) );
3310 Update();
3311}
3312
3313void SvxStyleToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3314{
3315 SolarMutexGuard aGuard;
3316
3317 if (m_pToolbar)
3318 m_pToolbar->set_item_sensitive(m_aCommandURL, rEvent.IsEnabled);
3319 else
3320 {
3321 ToolBox* pToolBox = nullptr;
3323 if (!getToolboxId( nId, &pToolBox ) )
3324 return;
3325 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3326 }
3327
3328 if (rEvent.IsEnabled)
3329 Update();
3330}
3331
3332css::uno::Reference<css::awt::XWindow> SvxStyleToolBoxControl::createItemWindow(const css::uno::Reference< css::awt::XWindow>& rParent)
3333{
3334 uno::Reference< awt::XWindow > xItemWindow;
3335
3336 if (m_pBuilder)
3337 {
3338 SolarMutexGuard aSolarMutexGuard;
3339
3340 std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("applystyle"));
3341
3342 xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
3343
3344 pImpl->m_xWeldBox.reset(new SvxStyleBox_Base(std::move(xWidget),
3345 ".uno:StyleApply",
3346 SfxStyleFamily::Para,
3347 m_xFrame,
3348 pImpl->aClearForm,
3349 pImpl->aMore,
3350 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this));
3351 pImpl->m_pBox = pImpl->m_xWeldBox.get();
3352 }
3353 else
3354 {
3356 if ( pParent )
3357 {
3358 SolarMutexGuard aSolarMutexGuard;
3359
3360 pImpl->m_xVclBox = VclPtr<SvxStyleBox_Impl>::Create(pParent,
3361 ".uno:StyleApply",
3362 SfxStyleFamily::Para,
3363 m_xFrame,
3364 pImpl->aClearForm,
3365 pImpl->aMore,
3366 pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this);
3367 pImpl->m_pBox = pImpl->m_xVclBox.get();
3368 xItemWindow = VCLUnoHelper::GetInterface(pImpl->m_xVclBox);
3369 }
3370 }
3371
3372 if (pImpl->m_pBox && !pImpl->aDefaultStyles.empty())
3373 pImpl->m_pBox->SetDefaultStyle(pImpl->aDefaultStyles[0].second);
3374
3375 return xItemWindow;
3376}
3377
3378SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
3379 : m_pBox(nullptr)
3380{
3381}
3382
3383void SvxFontNameBox_Base::statusChanged_Impl( const css::frame::FeatureStateEvent& rEvent )
3384{
3385 if ( !rEvent.IsEnabled )
3386 {
3387 set_sensitive(false);
3388 Update( nullptr );
3389 }
3390 else
3391 {
3392 set_sensitive(true);
3393
3394 css::awt::FontDescriptor aFontDesc;
3395 if ( rEvent.State >>= aFontDesc )
3396 Update(&aFontDesc);
3397 else {
3398 // no active element; delete value in the display
3399 m_xWidget->set_active(-1);
3400 set_active_or_entry_text("");
3401 }
3402 m_xWidget->save_value();
3403 }
3404}
3405
3406void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3407{
3408 SolarMutexGuard aGuard;
3409 m_pBox->statusChanged_Impl(rEvent);
3410
3411 if (m_pToolbar)
3412 m_pToolbar->set_item_sensitive(m_aCommandURL, rEvent.IsEnabled);
3413 else
3414 {
3415 ToolBox* pToolBox = nullptr;
3417 if (!getToolboxId( nId, &pToolBox ) )
3418 return;
3419 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3420 }
3421}
3422
3423css::uno::Reference<css::awt::XWindow> SvxFontNameToolBoxControl::createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent)
3424{
3425 uno::Reference< awt::XWindow > xItemWindow;
3426
3427 if (m_pBuilder)
3428 {
3429 SolarMutexGuard aSolarMutexGuard;
3430
3431 std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("fontnamecombobox"));
3432
3433 xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
3434
3435 m_xWeldBox.reset(new SvxFontNameBox_Base(std::move(xWidget), m_xFrame, *this));
3436 m_pBox = m_xWeldBox.get();
3437 }
3438 else
3439 {
3441 if ( pParent )
3442 {
3443 SolarMutexGuard aSolarMutexGuard;
3444 m_xVclBox = VclPtr<SvxFontNameBox_Impl>::Create(pParent, m_xFrame, *this);
3445 m_pBox = m_xVclBox.get();
3446 xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox);
3447 }
3448 }
3449
3450 return xItemWindow;
3451}
3452
3453void SvxFontNameToolBoxControl::dispose()
3454{
3455 ToolboxController::dispose();
3456
3457 SolarMutexGuard aSolarMutexGuard;
3458 m_xVclBox.disposeAndClear();
3459 m_xWeldBox.reset();
3460 m_pBox = nullptr;
3461}
3462
3463OUString SvxFontNameToolBoxControl::getImplementationName()
3464{
3465 return "com.sun.star.comp.svx.FontNameToolBoxControl";
3466}
3467
3468sal_Bool SvxFontNameToolBoxControl::supportsService( const OUString& rServiceName )
3469{
3470 return cppu::supportsService( this, rServiceName );
3471}
3472
3473css::uno::Sequence< OUString > SvxFontNameToolBoxControl::getSupportedServiceNames()
3474{
3475 return { "com.sun.star.frame.ToolbarController" };
3476}
3477
3478extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3480 css::uno::XComponentContext*,
3481 css::uno::Sequence<css::uno::Any> const & )
3482{
3483 return cppu::acquire( new SvxFontNameToolBoxControl() );
3484}
3485
3486SvxColorToolBoxControl::SvxColorToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3487 ImplInheritanceHelper( rContext, nullptr, OUString() ),
3488 m_bSplitButton(true),
3489 m_nSlotId(0),
3490 m_aColorSelectFunction(PaletteManager::DispatchColorCommand)
3491{
3492}
3493
3494namespace {
3495
3496sal_uInt16 MapCommandToSlotId(const OUString& rCommand)
3497{
3498 if (rCommand == ".uno:Color")
3499 return SID_ATTR_CHAR_COLOR;
3500 else if (rCommand == ".uno:FontColor")
3501 return SID_ATTR_CHAR_COLOR2;
3502 else if (rCommand == ".uno:BackColor") // deprecated - use CharBackColor
3503 return SID_ATTR_CHAR_COLOR_BACKGROUND;
3504 else if (rCommand == ".uno:CharBackColor")
3505 return SID_ATTR_CHAR_BACK_COLOR;
3506 else if (rCommand == ".uno:BackgroundColor")
3507 return SID_BACKGROUND_COLOR;
3508 else if (rCommand == ".uno:TableCellBackgroundColor")
3509 return SID_TABLE_CELL_BACKGROUND_COLOR;
3510 else if (rCommand == ".uno:Extrusion3DColor")
3511 return SID_EXTRUSION_3D_COLOR;
3512 else if (rCommand == ".uno:XLineColor")
3513 return SID_ATTR_LINE_COLOR;
3514 else if (rCommand == ".uno:FillColor")
3515 return SID_ATTR_FILL_COLOR;
3516 else if (rCommand == ".uno:FrameLineColor")
3517 return SID_FRAME_LINECOLOR;
3518
3519 SAL_WARN("svx.tbxcrtls", "Unknown color command: " << rCommand);
3520 return 0;
3521}
3522
3523}
3524
3525void SvxColorToolBoxControl::initialize( const css::uno::Sequence<css::uno::Any>& rArguments )
3526{
3527 PopupWindowController::initialize( rArguments );
3528
3529 m_nSlotId = MapCommandToSlotId( m_aCommandURL );
3530
3531 if ( m_nSlotId == SID_ATTR_LINE_COLOR || m_nSlotId == SID_ATTR_FILL_COLOR ||
3532 m_nSlotId == SID_FRAME_LINECOLOR || m_nSlotId == SID_BACKGROUND_COLOR )
3533 {
3534 // Sidebar uses wide buttons for those.
3535 m_bSplitButton = !m_bSidebar;
3536 }
3537
3538 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(getCommandURL(), getModuleName());
3540
3541 if (m_pToolbar)
3542 {
3543 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3544 m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
3545 m_xBtnUpdater.reset(new svx::ToolboxButtonColorUpdater(m_nSlotId, m_aCommandURL, m_pToolbar, !m_bSplitButton, aCommandLabel, m_xFrame));
3546 return;
3547 }
3548
3549 ToolBox* pToolBox = nullptr;
3551 if (getToolboxId(nId, &pToolBox))
3552 {
3553 m_xBtnUpdater.reset( new svx::VclToolboxButtonColorUpdater( m_nSlotId, nId, pToolBox, !m_bSplitButton, aCommandLabel, m_aCommandURL, m_xFrame ) );
3554 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
3555 }
3556}
3557
3559{
3560 PopupWindowController::update();
3561
3562 switch( m_nSlotId )
3563 {
3564 case SID_ATTR_CHAR_COLOR2:
3565 addStatusListener( ".uno:CharColorExt");
3566 break;
3567
3568 case SID_ATTR_CHAR_BACK_COLOR:
3569 case SID_ATTR_CHAR_COLOR_BACKGROUND:
3570 addStatusListener( ".uno:CharBackgroundExt");
3571 break;
3572
3573 case SID_FRAME_LINECOLOR:
3574 addStatusListener( ".uno:BorderTLBR");
3575 addStatusListener( ".uno:BorderBLTR");
3576 break;
3577 }
3578}
3579
3581{
3582 if (!m_xPaletteManager)
3583 {
3584 m_xPaletteManager = std::make_shared<PaletteManager>();
3585 m_xPaletteManager->SetBtnUpdater(m_xBtnUpdater.get());
3586 }
3587}
3588
3590{
3592 m_xPaletteManager->SetBtnUpdater(nullptr);
3593}
3594
3596{
3597 m_aColorSelectFunction = aColorSelectFunction;
3599 m_xPaletteManager->SetColorSelectFunction(aColorSelectFunction);
3600}
3601
3603{
3604 const css::uno::Reference<css::awt::XWindow> xParent = m_xFrame->getContainerWindow();
3605 return Application::GetFrameWeld(xParent);
3606}
3607
3608std::unique_ptr<WeldToolbarPopup> SvxColorToolBoxControl::weldPopupWindow()
3609{
3611
3612 auto xPopover = std::make_unique<ColorWindow>(
3613 m_aCommandURL,
3616 m_nSlotId,
3617 m_xFrame,
3618 MenuOrToolMenuButton(m_pToolbar, m_aCommandURL),
3619 [this] { return GetParentFrame(); },
3621
3622 return xPopover;
3623}
3624
3626{
3627 ToolBox* pToolBox = nullptr;
3629 if (!getToolboxId(nId, &pToolBox))
3630 return nullptr;
3631
3633
3634 auto xPopover = std::make_unique<ColorWindow>(
3635 m_aCommandURL,
3638 m_nSlotId,
3639 m_xFrame,
3640 MenuOrToolMenuButton(this, pToolBox, nId),
3641 [this] { return GetParentFrame(); },
3643
3644 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3645 std::move(xPopover), true);
3646
3647 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(m_aCommandURL, m_sModuleName);
3649 mxInterimPopover->SetText(aWindowTitle);
3650
3651 mxInterimPopover->Show();
3652
3653 return mxInterimPopover;
3654}
3655
3656void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
3657{
3658 ToolBox* pToolBox = nullptr;
3660 if (!getToolboxId(nId, &pToolBox) && !m_pToolbar)
3661 return;
3662
3663 if ( rEvent.FeatureURL.Complete == m_aCommandURL )
3664 {
3665 if (m_pToolbar)
3666 m_pToolbar->set_item_sensitive(m_aCommandURL, rEvent.IsEnabled);
3667 else
3668 pToolBox->EnableItem( nId, rEvent.IsEnabled );
3669 }
3670
3671 bool bValue;
3672 if ( !m_bSplitButton )
3673 {
3674 m_aColorStatus.statusChanged( rEvent );
3676 }
3677 else if ( rEvent.State >>= bValue )
3678 {
3679 if (m_pToolbar)
3680 m_pToolbar->set_item_active(m_aCommandURL, bValue);
3681 else if (pToolBox)
3682 pToolBox->CheckItem( nId, bValue );
3683 }
3684}
3685
3686void SvxColorToolBoxControl::execute(sal_Int16 /*nSelectModifier*/)
3687{
3688 if ( !m_bSplitButton )
3689 {
3690 if (m_pToolbar)
3691 {
3692 // Toggle the popup also when toolbutton is activated
3693 m_pToolbar->set_menu_item_active(m_aCommandURL, !m_pToolbar->get_menu_item_active(m_aCommandURL));
3694 }
3695 else
3696 {
3697 // Open the popup also when Enter key is pressed.
3698 createPopupWindow();
3699 }
3700 return;
3701 }
3702
3703 OUString aCommand = m_aCommandURL;
3704 Color aColor = m_xBtnUpdater->GetCurrentColor();
3705
3706 switch( m_nSlotId )
3707 {
3708 case SID_ATTR_CHAR_COLOR2 :
3709 aCommand = ".uno:CharColorExt";
3710 break;
3711 }
3712
3714 { m_aCommandURL.copy(5), css::uno::Any(aColor) }
3715 } ) );
3716 dispatchCommand( aCommand, aArgs );
3717
3719 OUString sColorName = m_xBtnUpdater->GetCurrentColorName();
3720 m_xPaletteManager->AddRecentColor(aColor, sColorName);
3721}
3722
3724{
3725 // We mark this controller as a sub-toolbar controller, so we get notified
3726 // (through updateImage method) on button image changes, and could redraw
3727 // the last used color on top of it.
3728 return true;
3729}
3730
3732{
3733 m_xBtnUpdater->Update(m_xBtnUpdater->GetCurrentColor(), true);
3734}
3735
3737{
3738 return OUString();
3739}
3740
3741void SvxColorToolBoxControl::functionSelected( const OUString& /*rCommand*/ )
3742{
3743}
3744
3746{
3747 return "com.sun.star.comp.svx.ColorToolBoxControl";
3748}
3749
3751{
3752 return { "com.sun.star.frame.ToolbarController" };
3753}
3754
3755extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3757 css::uno::XComponentContext* rContext,
3758 css::uno::Sequence<css::uno::Any> const & )
3759{
3760 return cppu::acquire( new SvxColorToolBoxControl( rContext ) );
3761}
3762
3763SvxFrameToolBoxControl::SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext )
3764 : svt::PopupWindowController( rContext, nullptr, OUString() )
3765{
3766}
3767
3768void SAL_CALL SvxFrameToolBoxControl::execute(sal_Int16 /*KeyModifier*/)
3769{
3770 if (m_pToolbar)
3771 {
3772 // Toggle the popup also when toolbutton is activated
3773 m_pToolbar->set_menu_item_active(m_aCommandURL, !m_pToolbar->get_menu_item_active(m_aCommandURL));
3774 }
3775 else
3776 {
3777 // Open the popup also when Enter key is pressed.
3778 createPopupWindow();
3779 }
3780}
3781
3782void SvxFrameToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3783{
3784 svt::PopupWindowController::initialize( rArguments );
3785
3786 if (m_pToolbar)
3787 {
3788 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3789 m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
3790 }
3791
3792 ToolBox* pToolBox = nullptr;
3794 if (getToolboxId(nId, &pToolBox))
3795 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
3796}
3797
3798std::unique_ptr<WeldToolbarPopup> SvxFrameToolBoxControl::weldPopupWindow()
3799{
3800 if ( m_aCommandURL == ".uno:LineStyle" )
3801 return std::make_unique<SvxLineWindow_Impl>(this, m_pToolbar);
3802 return std::make_unique<SvxFrameWindow_Impl>(this, m_pToolbar);
3803}
3804
3805VclPtr<vcl::Window> SvxFrameToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
3806{
3807 if ( m_aCommandURL == ".uno:LineStyle" )
3808 {
3809 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3810 std::make_unique<SvxLineWindow_Impl>(this, pParent->GetFrameWeld()), true);
3811
3812 mxInterimPopover->Show();
3813
3814 mxInterimPopover->SetText(SvxResId(RID_SVXSTR_FRAME_STYLE));
3815
3816 return mxInterimPopover;
3817 }
3818
3819 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
3820 std::make_unique<SvxFrameWindow_Impl>(this, pParent->GetFrameWeld()), true);
3821
3822 mxInterimPopover->Show();
3823
3824 mxInterimPopover->SetText(SvxResId(RID_SVXSTR_FRAME));
3825
3826 return mxInterimPopover;
3827}
3828
3829OUString SvxFrameToolBoxControl::getImplementationName()
3830{
3831 return "com.sun.star.comp.svx.FrameToolBoxControl";
3832}
3833
3834css::uno::Sequence< OUString > SvxFrameToolBoxControl::getSupportedServiceNames()
3835{
3836 return { "com.sun.star.frame.ToolbarController" };
3837}
3838
3839extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3841 css::uno::XComponentContext* rContext,
3842 css::uno::Sequence<css::uno::Any> const & )
3843{
3844 return cppu::acquire( new SvxFrameToolBoxControl( rContext ) );
3845}
3846
3847SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
3848 PopupWindowController( rContext, nullptr, OUString() ),
3849 m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
3850 m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND )
3851{
3852}
3853
3854SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}
3855
3856namespace
3857{
3859 class SvxCurrencyList_Impl : public WeldToolbarPopup
3860 {
3861 private:
3863 std::unique_ptr<weld::Label> m_xLabel;
3864 std::unique_ptr<weld::TreeView> m_xCurrencyLb;
3865 std::unique_ptr<weld::Button> m_xOkBtn;
3866 OUString& m_rSelectedFormat;
3867 LanguageType& m_eSelectedLanguage;
3868
3869 std::vector<OUString> m_aFormatEntries;
3870 LanguageType m_eFormatLanguage;
3871 DECL_LINK(RowActivatedHdl, weld::TreeView&, bool);
3872 DECL_LINK(OKHdl, weld::Button&, void);
3873
3874 virtual void GrabFocus() override;
3875
3876 public:
3877 SvxCurrencyList_Impl(SvxCurrencyToolBoxControl* pControl, weld::Widget* pParent, OUString& rSelectedFormat, LanguageType& eSelectedLanguage)
3878 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/currencywindow.ui", "CurrencyWindow")
3879 , m_xControl(pControl)
3880 , m_xLabel(m_xBuilder->weld_label("label"))
3881 , m_xCurrencyLb(m_xBuilder->weld_tree_view("currency"))
3882 , m_xOkBtn(m_xBuilder->weld_button("ok"))
3883 , m_rSelectedFormat(rSelectedFormat)
3884 , m_eSelectedLanguage(eSelectedLanguage)
3885 {
3887 sal_uInt16 nLen = rCurrencyTable.size();
3888
3889 SvNumberFormatter aFormatter( m_xControl->getContext(), LANGUAGE_SYSTEM );
3890 m_eFormatLanguage = aFormatter.GetLanguage();
3891
3892 const SvxCurrencyToolBoxControl::SvxCurrencyVect_t &rCurrencies = pControl->GetCurrencySymbols( );
3893
3894 sal_uInt16 nPos = 0, nCount = 0;
3895 sal_Int32 nSelectedPos = -1;
3896 bool bIsSymbol;
3897 NfWSStringsDtor aStringsDtor;
3898
3899 OUString sLongestString;
3900
3901 m_xCurrencyLb->freeze();
3902 for( const SvxCurrencyToolBoxControl::SvxCurrencyData& curr : rCurrencies )
3903 {
3904 const OUString& rItem = curr.m_label;
3905 sal_uInt16 rCurrencyIndex = rCurrencies[ nCount ].m_currencyIdx;
3906
3907 if ( rCurrencyIndex < nLen )
3908 {
3909 m_xCurrencyLb->append_text(rItem);
3910
3911 if (rItem.getLength() > sLongestString.getLength())
3912 sLongestString = rItem;
3913
3914 bIsSymbol = nPos >= nLen;
3915
3916 sal_uInt16 nDefaultFormat;
3917 const NfCurrencyEntry& rCurrencyEntry = rCurrencyTable[ rCurrencyIndex ];
3918 if (rCurrencyIndex == 0)
3919 {
3920 // Stored with system locale, but we want the resolved
3921 // full LCID format string. For example
3922 // "[$$-409]#,##0.00" instead of "[$$]#,##0.00".
3923 NfCurrencyEntry aCurrencyEntry( rCurrencyEntry);
3924 aCurrencyEntry.SetLanguage( LanguageTag( aCurrencyEntry.GetLanguage()).getLanguageType());
3925 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, aCurrencyEntry, bIsSymbol);
3926 }
3927 else
3928 {
3929 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, rCurrencyEntry, bIsSymbol);
3930 }
3931 const OUString& rFormatStr = aStringsDtor[ nDefaultFormat ];
3932 m_aFormatEntries.push_back( rFormatStr );
3933 if( rFormatStr == m_rSelectedFormat )
3934 nSelectedPos = nPos;
3935 ++nPos;
3936 }
3937 ++nCount;
3938 }
3939 m_xCurrencyLb->thaw();
3940 // enable multiple selection enabled so we can start with nothing selected
3941 m_xCurrencyLb->set_selection_mode(SelectionMode::Multiple);
3942 m_xCurrencyLb->connect_row_activated( LINK( this, SvxCurrencyList_Impl, RowActivatedHdl ) );
3943 m_xLabel->set_label(SvxResId(RID_SVXSTR_TBLAFMT_CURRENCY));
3944 m_xCurrencyLb->select( nSelectedPos );
3945 m_xOkBtn->connect_clicked(LINK(this, SvxCurrencyList_Impl, OKHdl));
3946
3947 // gtk will initially make a best guess depending on the first few entries, so copy the probable
3948 // longest entry to the start temporarily and force in the width at this point
3949 m_xCurrencyLb->insert_text(0, sLongestString);
3950 m_xCurrencyLb->set_size_request(m_xCurrencyLb->get_preferred_size().Width(), m_xCurrencyLb->get_height_rows(12));
3951 m_xCurrencyLb->remove(0);
3952 }
3953 };
3954
3955 void SvxCurrencyList_Impl::GrabFocus()
3956 {
3957 m_xCurrencyLb->grab_focus();
3958 }
3959
3960 IMPL_LINK_NOARG(SvxCurrencyList_Impl, OKHdl, weld::Button&, void)
3961 {
3962 RowActivatedHdl(*m_xCurrencyLb);
3963 }
3964
3965 IMPL_LINK_NOARG(SvxCurrencyList_Impl, RowActivatedHdl, weld::TreeView&, bool)
3966 {
3967 if (!m_xControl.is())
3968 return true;
3969
3970 // multiple selection enabled so we can start with nothing selected,
3971 // so force single selection after something is picked
3972 int nSelected = m_xCurrencyLb->get_selected_index();
3973 if (nSelected == -1)
3974 return true;
3975
3976 m_xCurrencyLb->set_selection_mode(SelectionMode::Single);
3977
3978 m_rSelectedFormat = m_aFormatEntries[nSelected];
3979 m_eSelectedLanguage = m_eFormatLanguage;
3980
3981 m_xControl->execute(nSelected + 1);
3982
3983 m_xCurrencyLb->scroll_to_row(0);
3984
3985 m_xControl->EndPopupMode();
3986
3987 return true;
3988 }
3989}
3990
3991void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
3992{
3993 PopupWindowController::initialize(rArguments);
3994
3995 if (m_pToolbar)
3996 {
3997 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
3998 m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
3999 return;
4000 }
4001
4002 ToolBox* pToolBox = nullptr;
4004 if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL)
4005 pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId));
4006}
4007
4008const SvxCurrencyToolBoxControl::SvxCurrencyVect_t &SvxCurrencyToolBoxControl::GetCurrencySymbols( ) {
4009 inner_GetCurrencySymbols( true, m_currencies, m_mru_currencies );
4010 return m_currencies;
4011}
4012
4013void SvxCurrencyToolBoxControl::addMruCurrency(sal_Int16 currencyPosition) {
4014 if (currencyPosition == 1)
4015 return;
4016
4017 const SvxCurrencyData& curr = m_currencies[currencyPosition];
4018 auto currencyIter = std::find( m_mru_currencies.begin(), m_mru_currencies.end(), curr );
4019
4020 if ( currencyIter != m_mru_currencies.end() )
4021 m_mru_currencies.erase( currencyIter );
4022
4023 m_mru_currencies.insert( m_mru_currencies.begin(), curr );
4024 if (m_mru_currencies.size() > MAX_MRU_CURRENCIES)
4025 m_mru_currencies.resize( MAX_MRU_CURRENCIES );
4026}
4027
4028std::unique_ptr<WeldToolbarPopup> SvxCurrencyToolBoxControl::weldPopupWindow()
4029{
4030 return std::make_unique<SvxCurrencyList_Impl>(this, m_pToolbar, m_aFormatString, m_eLanguage);
4031}
4032
4033VclPtr<vcl::Window> SvxCurrencyToolBoxControl::createVclPopupWindow( vcl::Window* pParent )
4034{
4035 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
4036 std::make_unique<SvxCurrencyList_Impl>(this, pParent->GetFrameWeld(), m_aFormatString, m_eLanguage));
4037
4038 mxInterimPopover->Show();
4039
4040 return mxInterimPopover;
4041}
4042
4043void SvxCurrencyToolBoxControl::execute( sal_Int16 nSelectModifier )
4044{
4045 sal_uInt32 nFormatKey;
4046 if (m_aFormatString.isEmpty())
4047 nFormatKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
4048 else
4049 {
4050 if ( nSelectModifier > 0 )
4051 {
4052 try
4053 {
4054 uno::Reference< util::XNumberFormatsSupplier > xRef( m_xFrame->getController()->getModel(), uno::UNO_QUERY );
4055 uno::Reference< util::XNumberFormats > rxNumberFormats( xRef->getNumberFormats(), uno::UNO_SET_THROW );
4056 css::lang::Locale aLocale = LanguageTag::convertToLocale( m_eLanguage );
4057 nFormatKey = rxNumberFormats->queryKey( m_aFormatString, aLocale, false );
4058 if ( nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND )
4059 nFormatKey = rxNumberFormats->addNew( m_aFormatString, aLocale );
4060 addMruCurrency(nSelectModifier);
4061 }
4062 catch( const uno::Exception& )
4063 {
4064 nFormatKey = m_nFormatKey;
4065 }
4066 }
4067 else
4068 nFormatKey = m_nFormatKey;
4069 }
4070
4071 if( nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
4072 {
4073 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue("NumberFormatCurrency",
4074 nFormatKey) };
4075 dispatchCommand( m_aCommandURL, aArgs );
4076 m_nFormatKey = nFormatKey;
4077 }
4078 else
4079 PopupWindowController::execute( nSelectModifier );
4080}
4081
4082OUString SvxCurrencyToolBoxControl::getImplementationName()
4083{
4084 return "com.sun.star.comp.svx.CurrencyToolBoxControl";
4085}
4086
4087css::uno::Sequence<OUString> SvxCurrencyToolBoxControl::getSupportedServiceNames()
4088{
4089 return { "com.sun.star.frame.ToolbarController" };
4090}
4091
4092extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
4094 css::uno::XComponentContext* rContext,
4095 css::uno::Sequence<css::uno::Any> const & )
4096{
4097 return cppu::acquire( new SvxCurrencyToolBoxControl( rContext ) );
4098}
4099
4100Reference< css::accessibility::XAccessible > SvxFontNameBox_Impl::CreateAccessible()
4101{
4102 FillList();
4104}
4105
4106//static
4107sal_uInt16 const SvxCurrencyToolBoxControl::SvxCurrencyData::InvalidCurrency = INVALID_CURRENCY;
4108
4109SvxCurrencyToolBoxControl::SvxCurrencyData::SvxCurrencyData(
4110 sal_uInt16 currencyIdx,
4111 bool onlyIsoCode
4112) :
4113 m_currencyIdx(currencyIdx),
4114 m_onlyIsoCode(onlyIsoCode)
4115{}
4116
4117bool SvxCurrencyToolBoxControl::SvxCurrencyData::operator == (const SvxCurrencyData& other) const
4118{
4119 return
4120 (m_currencyIdx == other.m_currencyIdx) &&
4121 (m_onlyIsoCode == other.m_onlyIsoCode);
4122}
4123
4124//static
4125void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
4126 std::vector<sal_uInt16>& rCurrencyList )
4127{
4128 SvxCurrencyVect_t currencies, mru_currencies;
4129
4130 inner_GetCurrencySymbols(bFlag, currencies, mru_currencies);
4131
4132 rList.resize(currencies.size());
4133 rCurrencyList.resize(currencies.size());
4134
4135 for (size_t j = 0; j < currencies.size(); j++) {
4136 rList[j] = std::move(currencies[j].m_label);
4137 rCurrencyList[j] = currencies[j].m_currencyIdx;
4138 }
4139}
4140
4141//static
4142void SvxCurrencyToolBoxControl::inner_GetCurrencySymbols(
4143 bool bFlag,
4144 SvxCurrencyVect_t &pCurrencies,
4145 SvxCurrencyVect_t &p_mru_currencies)
4146{
4148 sal_uInt16 nCount = rCurrencyTable.size();
4149
4150 // reserving space for mru currencies on top of vector after -1 element
4151 pCurrencies.resize( p_mru_currencies.size() + 1);
4152 std::fill( pCurrencies.begin() + 1, pCurrencies.end(), SvxCurrencyData() );
4153
4154 // lambda for vector insertion: mru currencies are on top
4155 auto addCurrency = [&pCurrencies, &p_mru_currencies]
4156 (SvxCurrencyData& curr, size_t position = SIZE_MAX)
4157 {
4158 auto mruIter = std::find(p_mru_currencies.begin(), p_mru_currencies.end(), curr);
4159
4160 if (mruIter == p_mru_currencies.end()) {
4161 if (position == SIZE_MAX)
4162 pCurrencies.push_back( std::move(curr) );
4163 else
4164 pCurrencies.insert( pCurrencies.begin() + position, std::move(curr) );
4165 }
4166 else {
4167 size_t index = mruIter - p_mru_currencies.begin();
4168 pCurrencies[index] = std::move(curr);
4169 }
4170 };
4171
4172 SvxCurrencyData aCurr( sal_uInt16(-1) );
4173 aCurr.m_label = ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) + " ";
4175 rCurrencyTable[0].GetLanguage() ) );
4176
4177 pCurrencies[0] = aCurr;
4178 if( bFlag ) {
4179 aCurr.m_currencyIdx = 0;
4180 addCurrency( aCurr );
4181 }
4182
4183 sal_uInt16 nStart = pCurrencies.size();
4184
4185 CollatorWrapper aCollator( ::comphelper::getProcessComponentContext() );
4186 aCollator.loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
4187
4188 static constexpr OUStringLiteral aTwoSpace(u" ");
4189
4190 // appending "long symbol" list
4191 for( sal_uInt16 i = 1; i < nCount; ++i )
4192 {
4193 SvxCurrencyData curr( i );
4194 curr.m_label = ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol() );
4195 curr.m_label += aTwoSpace;
4196 curr.m_label += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
4197 curr.m_label += aTwoSpace;
4199 rCurrencyTable[i].GetLanguage() ) );
4200
4201 SvxCurrencyVect_t::size_type j = nStart;
4202 for( ; j < pCurrencies.size(); ++j )
4203 if ( aCollator.compareString( curr.m_label, pCurrencies[j].m_label ) < 0 )
4204 break; // insert before first greater than
4205
4206 addCurrency( curr, j );
4207 }
4208
4209 // Append ISO codes to symbol list.
4210 // XXX If this is to be changed, various other places would had to be
4211 // adapted that assume this order!
4212 size_t nCont = pCurrencies.size();
4213
4214 for ( sal_uInt16 i = 1; i < nCount; ++i )
4215 {
4216 bool bInsert = true;
4217 SvxCurrencyData curr( i, true );
4218 curr.m_label = ApplyLreOrRleEmbedding(rCurrencyTable[i].GetBankSymbol());
4219
4220 size_t j = nCont;
4221 for ( ; j < pCurrencies.size() && bInsert; ++j )
4222 {
4223 if( pCurrencies[j].m_label == curr.m_label )
4224 bInsert = false;
4225 else if ( aCollator.compareString( curr.m_label, pCurrencies[j].m_label ) < 0 )
4226 break; // insert before first greater than
4227 }
4228 if ( bInsert )
4229 addCurrency( curr, j );
4230 }
4231
4232 for ( int j = p_mru_currencies.size() - 1; j > 0; j-- )
4233 if ( pCurrencies[j].m_currencyIdx == SvxCurrencyData::InvalidCurrency )
4234 pCurrencies.erase( pCurrencies.begin() + j );
4235}
4236
4238 : mpControl(pControl)
4239{
4240}
4241
4243 [[maybe_unused]] const OUString& /*rCommand*/, const NamedColor& rColor)
4244{
4245 mpControl->Selected(rColor);
4246}
4247
4249{
4250 if (!m_xPaletteManager)
4251 {
4252 m_xPaletteManager = std::make_shared<PaletteManager>();
4253 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
4254 }
4255}
4256
4257void ColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
4258{
4259 m_nSlotId = nSlotId;
4260 m_bShowNoneButton = bShowNoneButton;
4261 m_xButton->set_popover(nullptr);
4262 m_xColorWindow.reset();
4263 m_aSelectedColor = bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId);
4266}
4267
4268ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl,
4269 TopLevelParentFunction aTopLevelParentFunction,
4270 const ColorListBox* pCache)
4271 : m_xButton(std::move(pControl))
4272 , m_aColorWrapper(this)
4273 , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
4274 , m_nSlotId(0)
4275 , m_bShowNoneButton(false)
4276 , m_aTopLevelParentFunction(std::move(aTopLevelParentFunction))
4277{
4278 m_xButton->connect_toggled(LINK(this, ColorListBox, ToggleHdl));
4279 m_aSelectedColor = GetAutoColor(m_nSlotId);
4280 if (!pCache)
4282 else
4283 {
4284 LockWidthRequest(pCache->m_xButton->get_size_request().Width());
4285 m_xPaletteManager.reset(pCache->m_xPaletteManager->Clone());
4286 m_xPaletteManager->SetColorSelectFunction(std::ref(m_aColorWrapper));
4287 }
4289}
4290
4291IMPL_LINK(ColorListBox, ToggleHdl, weld::Toggleable&, rButton, void)
4292{
4293 if (rButton.get_active())
4294 {
4295 ColorWindow* pColorWindow = getColorWindow();
4296 if (pColorWindow && !comphelper::LibreOfficeKit::isActive())
4297 pColorWindow->GrabFocus();
4298 }
4299}
4300
4302{
4303}
4304
4306{
4307 if (!m_xColorWindow)
4308 const_cast<ColorListBox*>(this)->createColorWindow();
4309 return m_xColorWindow.get();
4310}
4311
4313{
4314 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
4315 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
4316 css::uno::Reference<css::frame::XFrame> xFrame(pFrame ? pFrame->GetFrameInterface() : uno::Reference<css::frame::XFrame>());
4317
4319
4320 m_xColorWindow.reset(new ColorWindow(
4321 OUString() /*m_aCommandURL*/,
4324 m_nSlotId,
4325 xFrame,
4326 m_xButton.get(),
4329
4331 m_xButton->set_popover(m_xColorWindow->getTopLevel());
4333 m_xColorWindow->ShowNoneButton();
4334 m_xColorWindow->SelectEntry(m_aSelectedColor);
4335}
4336
4338{
4339 if (o3tl::trim(rColor.m_aName).empty())
4340 {
4341 SelectEntry(rColor.m_aColor);
4342 return;
4343 }
4344 ColorWindow* pColorWindow = getColorWindow();
4345 pColorWindow->SelectEntry(rColor);
4346 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
4348}
4349
4351{
4352 ColorWindow* pColorWindow = getColorWindow();
4353 pColorWindow->SelectEntry(rColor);
4354 m_aSelectedColor = pColorWindow->GetSelectEntryColor();
4356}
4357
4359{
4360 ShowPreview(rColor);
4361 m_aSelectedColor = rColor;
4362 if (m_aSelectedLink.IsSet())
4363 m_aSelectedLink.Call(*this);
4364}
4365
4366//to avoid the box resizing every time the color is changed to
4367//the optimal size of the individual color, get the longest
4368//standard color and stick with that as the size for all
4370{
4371 NamedColor aLongestColor;
4372 tools::Long nMaxStandardColorTextWidth = 0;
4373 XColorListRef const xColorTable = XColorList::CreateStdColorList();
4374 for (tools::Long i = 0; i != xColorTable->Count(); ++i)
4375 {
4376 XColorEntry& rEntry = *xColorTable->GetColor(i);
4377 auto nColorTextWidth = m_xButton->get_pixel_size(rEntry.GetName()).Width();
4378 if (nColorTextWidth > nMaxStandardColorTextWidth)
4379 {
4380 nMaxStandardColorTextWidth = nColorTextWidth;
4381 aLongestColor.m_aName = rEntry.GetName();
4382 }
4383 }
4384 ShowPreview(aLongestColor);
4385 return m_xButton->get_preferred_size().Width();
4386}
4387
4389{
4390 m_xButton->set_size_request(nWidth, -1);
4391}
4392
4394{
4395 // ScGridWindow::UpdateAutoFilterFromMenu is similar
4396 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
4397 Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
4398
4400 xDevice->SetOutputSize(aImageSize);
4401 const tools::Rectangle aRect(Point(0, 0), aImageSize);
4402 if (m_bShowNoneButton && rColor.m_aColor == COL_NONE_COLOR)
4403 {
4404 const Color aW(COL_WHITE);
4405 const Color aG(0xef, 0xef, 0xef);
4406 int nMinDim = std::min(aImageSize.Width(), aImageSize.Height()) + 1;
4407 int nCheckSize = nMinDim / 3;
4408 xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), std::min(nCheckSize, 8), aW, aG);
4409 xDevice->SetFillColor();
4410 }
4411 else
4412 {
4413 if (rColor.m_aColor == COL_AUTO)
4414 xDevice->SetFillColor(m_aAutoDisplayColor);
4415 else
4416 xDevice->SetFillColor(rColor.m_aColor);
4417 }
4418
4419 xDevice->SetLineColor(rStyleSettings.GetDisableColor());
4420 xDevice->DrawRect(aRect);
4421
4422 m_xButton->set_image(xDevice.get());
4423 m_xButton->set_label(rColor.m_aName);
4424}
4425
4427 : m_pMenuButton(pMenuButton)
4428 , m_pToolbar(nullptr)
4429 , m_pControl(nullptr)
4430 , m_nId(0)
4431{
4432}
4433
4435 : m_pMenuButton(nullptr)
4436 , m_pToolbar(pToolbar)
4437 , m_aIdent(std::move(aIdent))
4438 , m_pControl(nullptr)
4439 , m_nId(0)
4440{
4441}
4442
4444 : m_pMenuButton(nullptr)
4445 , m_pToolbar(nullptr)
4446 , m_pControl(pControl)
4447 , m_xToolBox(pToolbar)
4448 , m_nId(nId)
4449{
4450}
4451
4453{
4454}
4455
4457{
4458 if (m_pMenuButton)
4459 return m_pMenuButton->get_active();
4460 if (m_pToolbar)
4462 return m_xToolBox->GetDownItemId() == m_nId;
4463}
4464
4466{
4467 if (m_pMenuButton)
4468 {
4470 m_pMenuButton->set_active(false);
4471 return;
4472 }
4473 if (m_pToolbar)
4474 {
4477 return;
4478 }
4479 m_pControl->EndPopupMode();
4480}
4481
4483{
4484 if (m_pMenuButton)
4485 return m_pMenuButton;
4486 if (m_pToolbar)
4487 return m_pToolbar;
4488 return m_xToolBox->GetFrameWeld();
4489}
4490
4491/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
basegfx::BColor maColor
std::function< void(const OUString &, const NamedColor &)> ColorSelectFunction
Definition: Palette.hxx:27
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:4312
void ShowPreview(const NamedColor &rColor)
Definition: tbcontrl.cxx:4393
std::unique_ptr< weld::MenuButton > m_xButton
Definition: colorbox.hxx:34
ColorListBox(std::unique_ptr< weld::MenuButton > pControl, TopLevelParentFunction aTopLevelParentFunction, const ColorListBox *pCache=nullptr)
Definition: tbcontrl.cxx:4268
void EnsurePaletteManager()
Definition: tbcontrl.cxx:4248
sal_uInt16 m_nSlotId
Definition: colorbox.hxx:40
void Selected(const NamedColor &rNamedColor)
Definition: tbcontrl.cxx:4358
Link< ColorListBox &, void > m_aSelectedLink
Definition: colorbox.hxx:35
int CalcBestWidthRequest()
Definition: tbcontrl.cxx:4369
NamedColor m_aSelectedColor
Definition: colorbox.hxx:39
void LockWidthRequest(int nWidthRequest)
Definition: tbcontrl.cxx:4388
ColorStatus m_aColorStatus
Definition: colorbox.hxx:44
bool m_bShowNoneButton
Definition: colorbox.hxx:41
void SelectEntry(const NamedColor &rColor)
Definition: tbcontrl.cxx:4337
ListBoxColorWrapper m_aColorWrapper
Definition: colorbox.hxx:36
void SetNoSelection()
Definition: colorbox.hxx:72
TopLevelParentFunction m_aTopLevelParentFunction
Definition: colorbox.hxx:43
ColorWindow * getColorWindow() const
Definition: tbcontrl.cxx:4305
Color m_aAutoDisplayColor
Definition: colorbox.hxx:37
void SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton=false)
Definition: tbcontrl.cxx:4257
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:2137
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:2141
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:2015
OUString maCommand
Definition: colorwindow.hxx:84
const sal_uInt16 theSlotId
Definition: colorwindow.hxx:83
virtual void GrabFocus() override
Definition: tbcontrl.cxx:2124
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:2132
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:2196
sal_uInt8 GetLuminance() const
void DecreaseContrast(sal_uInt8 cContDec)
void DecreaseLuminance(sal_uInt8 cLumDec)
bool IsBright() const
bool IsFullyTransparent() 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:4237
void operator()(const OUString &rCommand, const NamedColor &rColor)
Definition: tbcontrl.cxx:4242
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:4456
weld::Widget * get_widget() const
Definition: tbcontrl.cxx:4482
void set_inactive() const
Definition: tbcontrl.cxx:4465
VclPtr< ToolBox > m_xToolBox
Definition: colorwindow.hxx:62
MenuOrToolMenuButton(weld::MenuButton *pMenuButton)
Definition: tbcontrl.cxx:4426
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)
void DrawRect(const tools::Rectangle &rRect)
const Wallpaper & GetBackground() const
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) 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 bool GetThemeAndEffectIndex(sal_uInt16 nItemId, sal_uInt16 &rThemeIndex, sal_uInt16 &rEffectIndex)
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 SAL_WARN_UNUSED_RESULT 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:856
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 SAL_WARN_UNUSED_RESULT 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:3602
virtual std::unique_ptr< WeldToolbarPopup > weldPopupWindow() override
Definition: tbcontrl.cxx:3608
virtual sal_Bool SAL_CALL opensSubToolbar() override
Definition: tbcontrl.cxx:3723
virtual void SAL_CALL execute(sal_Int16 nSelectModifier) override
Definition: tbcontrl.cxx:3686
ColorStatus m_aColorStatus
Definition: tbcontrl.hxx:209
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &rArguments) override
Definition: tbcontrl.cxx:3525
virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent &rEvent) override
Definition: tbcontrl.cxx:3656
void setColorSelectFunction(const ColorSelectFunction &aColorSelectFunction)
Definition: tbcontrl.cxx:3595
std::shared_ptr< PaletteManager > m_xPaletteManager
Definition: tbcontrl.hxx:208
virtual VclPtr< vcl::Window > createVclPopupWindow(vcl::Window *pParent) override
Definition: tbcontrl.cxx:3625
std::unique_ptr< svx::ToolboxButtonColorUpdaterBase > m_xBtnUpdater
Definition: tbcontrl.hxx:207
virtual OUString SAL_CALL getImplementationName() override
Definition: tbcontrl.cxx:3745
virtual ~SvxColorToolBoxControl() override
Definition: tbcontrl.cxx:3589
virtual void SAL_CALL updateImage() override
Definition: tbcontrl.cxx:3731
ColorSelectFunction m_aColorSelectFunction
Definition: tbcontrl.hxx:212
virtual OUString SAL_CALL getSubToolbarName() override
Definition: tbcontrl.cxx:3736
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: tbcontrl.cxx:3750
virtual void SAL_CALL functionSelected(const OUString &rCommand) override
Definition: tbcontrl.cxx:3741
SvxColorToolBoxControl(const css::uno::Reference< css::uno::XComponentContext > &rContext)
Definition: tbcontrl.cxx:3486
virtual void SAL_CALL update() override
Definition: tbcontrl.cxx:3558
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:188
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:3332
void SetFamilyState(sal_uInt16 nIdx, const SfxTemplateItem *pItem)
Definition: tbcontrl.cxx:3306
void SelectStyle(const OUString &rStyleName)
Definition: tbcontrl.cxx:3233
friend class SfxStyleControllerItem_Impl
Definition: tbcontrl.hxx:196
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:189
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:3313
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:157
SfxStyleSheetBasePool * pStyleSheetPool
Definition: tbcontrl.hxx:187
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 OUString &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 OUString &rIdent) const=0
virtual void set_menu_item_active(const OUString &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 OUStringLiteral HID_STYLE_LISTBOX
Definition: helpids.h:41
constexpr OUStringLiteral HID_POPUP_LINE
Definition: helpids.h:38
constexpr OUStringLiteral HID_POPUP_COLOR_CTRL
Definition: helpids.h:36
constexpr OUStringLiteral HID_POPUP_COLOR
Definition: helpids.h:35
constexpr OUStringLiteral 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)
SvtScriptType
sal_uInt16 nPos
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
int n2
int n1
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()
class SvxPropertySetInfoPool
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)
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
index
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)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
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
OUString m_aName
Color m_aColor
sal_Int16 m_nLumOff
sal_Int16 m_nLumMod
sal_Int16 m_nThemeIndex
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
SfxStyleFamily
Reference< XFrame > xFrame
Reference< XModel > xModel
IMPL_LINK(SvxStyleBox_Base, CustomGetSizeHdl, OutputDevice &, rArg, Size)
Definition: tbcontrl.cxx:899
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:3479
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:3840
#define MAX_MRU_CURRENCIES
Definition: tbcontrl.cxx:114
static bool GetWhich(const SfxItemSet &rSet, sal_uInt16 nSlot, sal_uInt16 &rWhich)
Definition: tbcontrl.cxx:1296
IMPL_STATIC_LINK_NOARG(SvxStyleBox_Base, ShowMoreHdl, void *, void)
Definition: tbcontrl.cxx:956
#define MAX_MRU_FONTNAME_ENTRIES
Definition: tbcontrl.cxx:110
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:3756
#define ITEM_HEIGHT
Definition: tbcontrl.cxx:860
#define BUTTON_PADDING
Definition: tbcontrl.cxx:859
static void SetFontStyle(const SfxItemSet &rSet, sal_uInt16 nPosture, sal_uInt16 nWeight, SvxFont &rFont)
Definition: tbcontrl.cxx:1332
#define INVALID_CURRENCY
Definition: tbcontrl.cxx:116
static bool lcl_GetDocFontList(const FontList **ppFontList, SvxFontNameBox_Base *pBox)
Definition: tbcontrl.cxx:1643
static bool SetFont(const SfxItemSet &rSet, sal_uInt16 nSlot, SvxFont &rFont)
Definition: tbcontrl.cxx:1302
static Color lcl_mediumColor(Color aMain, Color)
Definition: tbcontrl.cxx:2782
#define COMBO_WIDTH_IN_CHARS
Definition: tbcontrl.cxx:112
static bool SetFontSize(vcl::RenderContext &rRenderContext, const SfxItemSet &rSet, sal_uInt16 nSlot, SvxFont &rFont)
Definition: tbcontrl.cxx:1315
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:4093
IMPL_LINK_NOARG(SvxStyleBox_Base, ActivateHdl, weld::ComboBox &, bool)
Definition: tbcontrl.cxx:971
#define MAX_FAMILIES
Definition: tbcontrl.hxx:185
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