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