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 <svx/svdundo.hxx>
21 #include <sfx2/app.hxx>
22 #include <sfx2/request.hxx>
23 #include <sfx2/objface.hxx>
24 #include <sfx2/viewsh.hxx>
25 #include <svx/unoapi.hxx>
26 #include <com/sun/star/drawing/XShape.hpp>
27 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
28 #include <sal/log.hxx>
29 #include <svx/dialmgr.hxx>
30 #include <svx/svdoashp.hxx>
31 #include <svx/strings.hrc>
32 #include <svx/svdview.hxx>
33 #include <svx/sdasitm.hxx>
34 #include <svx/gallery.hxx>
35 #include <svx/fmmodel.hxx>
36 #include <svx/fmpage.hxx>
37 #include <svx/sdtfsitm.hxx>
38 #include <svl/itempool.hxx>
39 #include <svl/stritem.hxx>
40 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
41 #include <sfx2/bindings.hxx>
42 #include <editeng/eeitem.hxx>
43 #include <editeng/charscaleitem.hxx>
44 #include <editeng/kernitem.hxx>
45 #include <svx/sdrpaintwindow.hxx>
46 
47 #include <svx/svxids.hrc>
48 #include <svx/fontworkbar.hxx>
49 #include <svx/fontworkgallery.hxx>
50 
51 
52 using namespace ::svx;
53 using namespace ::cppu;
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::uno;
57 
SetAlignmentState(SdrView const * pSdrView,SfxItemSet & rSet)58 static void SetAlignmentState( SdrView const * pSdrView, SfxItemSet& rSet )
59 {
60     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
61     const size_t nCount = rMarkList.GetMarkCount();
62 
63     sal_Int32   nAlignment = -1;
64     for( size_t i = 0; i < nCount; ++i )
65     {
66         SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
67         if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
68         {
69             sal_Int32 nOldAlignment = nAlignment;
70             const SdrTextHorzAdjustItem&      rTextHorzAdjustItem    = pObj->GetMergedItem( SDRATTR_TEXT_HORZADJUST );
71             const SdrTextFitToSizeTypeItem&   rTextFitToSizeTypeItem = pObj->GetMergedItem( SDRATTR_TEXT_FITTOSIZE );
72             switch ( rTextHorzAdjustItem.GetValue() )
73             {
74                 case SDRTEXTHORZADJUST_LEFT   : nAlignment = 0; break;
75                 case SDRTEXTHORZADJUST_CENTER : nAlignment = 1; break;
76                 case SDRTEXTHORZADJUST_RIGHT  : nAlignment = 2; break;
77                 case SDRTEXTHORZADJUST_BLOCK  :
78                 {
79                     auto const fit(rTextFitToSizeTypeItem.GetValue());
80                     if (fit == drawing::TextFitToSizeType_NONE)
81                     {
82                         nAlignment = 3;
83                     }
84                     else if (fit == drawing::TextFitToSizeType_ALLLINES ||
85                              fit == drawing::TextFitToSizeType_PROPORTIONAL)
86                     {
87                         nAlignment = 4;
88                     }
89                 }
90             }
91             if ( ( nOldAlignment != -1 ) && ( nOldAlignment != nAlignment ) )
92             {
93                 nAlignment = -1;
94                 break;
95             }
96         }
97     }
98     rSet.Put( SfxInt32Item( SID_FONTWORK_ALIGNMENT, nAlignment ) );
99 }
100 
SetCharacterSpacingState(SdrView const * pSdrView,SfxItemSet & rSet)101 static void SetCharacterSpacingState( SdrView const * pSdrView, SfxItemSet& rSet )
102 {
103     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
104     const size_t nCount = rMarkList.GetMarkCount();
105 
106     sal_Int32   nCharacterSpacing = -1;
107     for( size_t i = 0; i < nCount; ++i )
108     {
109         SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
110         if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
111         {
112             sal_Int32 nOldCharacterSpacing = nCharacterSpacing;
113             const SvxCharScaleWidthItem& rCharScaleWidthItem = pObj->GetMergedItem( EE_CHAR_FONTWIDTH );
114             nCharacterSpacing = rCharScaleWidthItem.GetValue();
115             if ( ( nOldCharacterSpacing != -1 ) && ( nOldCharacterSpacing != nCharacterSpacing ) )
116             {
117                 nCharacterSpacing = -1;
118                 break;
119             }
120         }
121     }
122     rSet.Put( SfxInt32Item( SID_FONTWORK_CHARACTER_SPACING, nCharacterSpacing ) );
123 }
124 
125 
SetKernCharacterPairsState(SdrView const * pSdrView,SfxItemSet & rSet)126 static void SetKernCharacterPairsState( SdrView const * pSdrView, SfxItemSet& rSet )
127 {
128     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
129     const size_t nCount = rMarkList.GetMarkCount();
130 
131     bool    bChecked = false;
132     for( size_t i = 0; i < nCount; ++i )
133     {
134         SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
135         if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
136         {
137             const SvxKerningItem& rKerningItem = pObj->GetMergedItem( EE_CHAR_KERNING );
138             if ( rKerningItem.GetValue() )
139                 bChecked = true;
140         }
141     }
142     rSet.Put( SfxBoolItem( SID_FONTWORK_KERN_CHARACTER_PAIRS, bChecked ) );
143 }
144 
SetFontWorkShapeTypeState(SdrView const * pSdrView,SfxItemSet & rSet)145 static void SetFontWorkShapeTypeState( SdrView const * pSdrView, SfxItemSet& rSet )
146 {
147     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
148     const size_t nCount = rMarkList.GetMarkCount();
149 
150     OUString aFontWorkShapeType;
151 
152     for( size_t i = 0; i < nCount; ++i )
153     {
154         SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
155         if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
156         {
157             const SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
158             const Any* pAny = aGeometryItem.GetPropertyValueByName( "Type" );
159             if( pAny )
160             {
161                 OUString aType;
162                 if ( *pAny >>= aType )
163                 {
164                     if ( !aFontWorkShapeType.isEmpty() )
165                     {
166                         if ( aFontWorkShapeType != aType )  // different FontWorkShapeTypes selected ?
167                         {
168                             aFontWorkShapeType.clear();
169                             break;
170                         }
171                     }
172                     aFontWorkShapeType = aType;
173                 }
174             }
175         }
176     }
177     rSet.Put( SfxStringItem( SID_FONTWORK_SHAPE_TYPE, aFontWorkShapeType ) );
178 }
179 
180 // Declare the default interface. (The slotmap must not be empty, so
181 // we enter something which never occurs here (hopefully).)
182 static SfxSlot aFontworkBarSlots_Impl[] =
183 {
184     { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, nullptr }
185 };
186 
SFX_IMPL_INTERFACE(FontworkBar,SfxShell)187 SFX_IMPL_INTERFACE(FontworkBar, SfxShell)
188 
189 void FontworkBar::InitInterface_Impl()
190 {
191     GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Svx_Fontwork_Bar);
192 }
193 
194 
FontworkBar(SfxViewShell * pViewShell)195 FontworkBar::FontworkBar(SfxViewShell* pViewShell )
196 : SfxShell(pViewShell)
197 {
198     DBG_ASSERT( pViewShell, "svx::FontworkBar::FontworkBar(), I need a viewshell!" );
199     if( pViewShell )
200         SetPool(&pViewShell->GetPool());
201 
202     SetName( SvxResId( RID_SVX_FONTWORK_BAR ));
203 }
204 
~FontworkBar()205 FontworkBar::~FontworkBar()
206 {
207     SetRepeatTarget(nullptr);
208 }
209 
210 namespace svx {
checkForSelectedFontWork(SdrView const * pSdrView,sal_uInt32 & nCheckStatus)211 bool checkForSelectedFontWork( SdrView const * pSdrView, sal_uInt32& nCheckStatus )
212 {
213     if ( nCheckStatus & 2 )
214         return ( nCheckStatus & 1 ) != 0;
215 
216     static const char sTextPath[] = "TextPath";
217 
218     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
219     const size_t nCount = rMarkList.GetMarkCount();
220     bool bFound = false;
221     for(size_t i=0; (i<nCount) && !bFound ; ++i)
222     {
223         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
224         if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
225         {
226             const SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
227             const Any* pAny = aGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
228             if( pAny )
229                 *pAny >>= bFound;
230         }
231     }
232     if ( bFound )
233         nCheckStatus |= 1;
234     nCheckStatus |= 2;
235     return bFound;
236 }
237 }
238 
impl_execute(SfxRequest const & rReq,SdrCustomShapeGeometryItem & rGeometryItem,SdrObject * pObj)239 static void impl_execute( SfxRequest const & rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
240 {
241     sal_uInt16 nSID = rReq.GetSlot();
242     switch( nSID )
243     {
244         case SID_FONTWORK_SAME_LETTER_HEIGHTS:
245         {
246             css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "SameLetterHeights" );
247             if( pAny )
248             {
249                 bool bOn = false;
250                 (*pAny) >>= bOn;
251                 bOn = !bOn;
252                 (*pAny) <<= bOn;
253             }
254         }
255         break;
256 
257         case SID_FONTWORK_ALIGNMENT:
258         {
259             if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_FONTWORK_ALIGNMENT ) == SfxItemState::SET )
260             {
261                 sal_Int32 nValue = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_FONTWORK_ALIGNMENT)->GetValue();
262                 if ( ( nValue >= 0 ) && ( nValue < 5 ) )
263                 {
264                     drawing::TextFitToSizeType eFTS = drawing::TextFitToSizeType_NONE;
265                     SdrTextHorzAdjust eHorzAdjust;
266                     switch ( nValue )
267                     {
268                         case 4 : eFTS = drawing::TextFitToSizeType_ALLLINES; [[fallthrough]];
269                         case 3 : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
270                         default: eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
271                         case 1 : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
272                         case 2 : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
273                     }
274                     pObj->SetMergedItem( SdrTextHorzAdjustItem( eHorzAdjust ) );
275                     pObj->SetMergedItem( SdrTextFitToSizeTypeItem( eFTS ) );
276                     pObj->BroadcastObjectChange();
277                 }
278             }
279         }
280         break;
281 
282         case SID_FONTWORK_CHARACTER_SPACING:
283         {
284             if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_CHARACTER_SPACING ) == SfxItemState::SET ) )
285             {
286                 sal_Int32 nCharSpacing = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_FONTWORK_CHARACTER_SPACING)->GetValue();
287                 pObj->SetMergedItem( SvxCharScaleWidthItem( static_cast<sal_uInt16>(nCharSpacing), EE_CHAR_FONTWIDTH ) );
288                 pObj->BroadcastObjectChange();
289             }
290         }
291         break;
292 
293         case SID_FONTWORK_KERN_CHARACTER_PAIRS:
294         {
295             if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_KERN_CHARACTER_PAIRS ) == SfxItemState::SET ) )
296             {
297                 // sal_Bool bKernCharacterPairs = ((const SfxBoolItem*)rReq.GetArgs()->GetItem(SID_FONTWORK_KERN_CHARACTER_PAIRS))->GetValue();
298 //TODO:             pObj->SetMergedItem( SvxCharScaleWidthItem( (sal_uInt16)nCharSpacing, EE_CHAR_FONTWIDTH ) );
299                 pObj->BroadcastObjectChange();
300             }
301         }
302         break;
303     }
304 }
305 
GetGeometryForCustomShape(SdrCustomShapeGeometryItem & rGeometryItem,const OUString & rCustomShape)306 static void GetGeometryForCustomShape( SdrCustomShapeGeometryItem& rGeometryItem, const OUString& rCustomShape )
307 {
308     const OUString sType( "Type" );
309 
310     css::beans::PropertyValue aPropVal;
311     aPropVal.Name = sType;
312     aPropVal.Value <<= rCustomShape;
313     rGeometryItem.SetPropertyValue( aPropVal );
314 
315     const OUString sAdjustmentValues( "AdjustmentValues" );
316     const OUString sCoordinateOrigin( "CoordinateOrigin" );
317     const OUString sCoordinateSize( "CoordinateSize" );
318     const OUString sEquations( "Equations" );
319     const OUString sHandles( "Handles" );
320     const OUString sPath( "Path" );
321     rGeometryItem.ClearPropertyValue( sAdjustmentValues );
322     rGeometryItem.ClearPropertyValue( sCoordinateOrigin );
323     rGeometryItem.ClearPropertyValue( sCoordinateSize );
324     rGeometryItem.ClearPropertyValue( sEquations );
325     rGeometryItem.ClearPropertyValue( sHandles );
326     rGeometryItem.ClearPropertyValue( sPath );
327 
328     /* SJ: CustomShapes that are available in the gallery are having the highest
329        priority, so we will take a look there before taking the internal default */
330 
331     if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) )
332     {
333         std::vector< OUString > aObjList;
334         if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) )
335         {
336             for ( std::vector<OUString>::size_type i = 0; i < aObjList.size(); i++ )
337             {
338                 if ( aObjList[ i ].equalsIgnoreAsciiCase( rCustomShape ) )
339                 {
340                     FmFormModel aFormModel;
341                     SfxItemPool& rPool(aFormModel.GetItemPool());
342                     rPool.FreezeIdRanges();
343 
344                     if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aFormModel ) )
345                     {
346                         const SdrObject* pSourceObj = nullptr;
347                         if (aFormModel.GetPageCount() > 0)
348                             pSourceObj = aFormModel.GetPage( 0 )->GetObj( 0 );
349                         SAL_WARN_IF(!pSourceObj, "svx.form", "No content in gallery custom shape '" << rCustomShape << "'" );
350                         if( pSourceObj )
351                         {
352                             PropertyValue aPropVal_;
353                             const SdrCustomShapeGeometryItem& rSourceGeometry = pSourceObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
354                             const css::uno::Any* pAny = rSourceGeometry.GetPropertyValueByName( sType );
355                             if ( pAny )
356                             {
357                                 aPropVal_.Name = sType;
358                                 aPropVal_.Value = *pAny;
359                                 rGeometryItem.SetPropertyValue( aPropVal_ );
360                             }
361                             pAny = rSourceGeometry.GetPropertyValueByName( sAdjustmentValues );
362                             if ( pAny )
363                             {
364                                 aPropVal_.Name = sAdjustmentValues;
365                                 aPropVal_.Value = *pAny;
366                                 rGeometryItem.SetPropertyValue( aPropVal_ );
367                             }
368                             pAny = rSourceGeometry.GetPropertyValueByName( sCoordinateOrigin );
369                             if ( pAny )
370                             {
371                                 aPropVal_.Name = sCoordinateOrigin;
372                                 aPropVal_.Value = *pAny;
373                                 rGeometryItem.SetPropertyValue( aPropVal_ );
374                             }
375                             pAny = rSourceGeometry.GetPropertyValueByName( sCoordinateSize );
376                             if ( pAny )
377                             {
378                                 aPropVal_.Name = sCoordinateSize;
379                                 aPropVal_.Value = *pAny;
380                                 rGeometryItem.SetPropertyValue( aPropVal_ );
381                             }
382                             pAny = rSourceGeometry.GetPropertyValueByName( sEquations );
383                             if ( pAny )
384                             {
385                                 aPropVal_.Name = sEquations;
386                                 aPropVal_.Value = *pAny;
387                                 rGeometryItem.SetPropertyValue( aPropVal_ );
388                             }
389                             pAny = rSourceGeometry.GetPropertyValueByName( sHandles );
390                             if ( pAny )
391                             {
392                                 aPropVal_.Name = sHandles;
393                                 aPropVal_.Value = *pAny;
394                                 rGeometryItem.SetPropertyValue( aPropVal_ );
395                             }
396                             pAny = rSourceGeometry.GetPropertyValueByName( sPath );
397                             if ( pAny )
398                             {
399                                 aPropVal_.Name = sPath;
400                                 aPropVal_.Value = *pAny;
401                                 rGeometryItem.SetPropertyValue( aPropVal_ );
402                             }
403                         }
404                     }
405                 }
406             }
407         }
408     }
409 }
410 
411 
execute(SdrView & rSdrView,SfxRequest const & rReq,SfxBindings & rBindings)412 void FontworkBar::execute( SdrView& rSdrView, SfxRequest const & rReq, SfxBindings& rBindings )
413 {
414     const char* pStrResId = nullptr;
415 
416     sal_uInt16 nSID = rReq.GetSlot();
417     switch( nSID )
418     {
419         case SID_FONTWORK_GALLERY_FLOATER:
420         {
421             FontWorkGalleryDialog aDlg(rReq.GetFrameWeld(), rSdrView);
422             aDlg.run();
423         }
424         break;
425 
426         case SID_FONTWORK_SHAPE_TYPE:
427         {
428             OUString aCustomShape;
429             const SfxItemSet* pArgs = rReq.GetArgs();
430             if ( pArgs )
431             {
432                 const SfxStringItem& rItm = static_cast<const SfxStringItem&>(pArgs->Get( rReq.GetSlot() ));
433                 aCustomShape = rItm.GetValue();
434             }
435             if ( !aCustomShape.isEmpty() )
436             {
437                 const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
438                 const size_t nCount = rMarkList.GetMarkCount();
439                 for( size_t i = 0; i < nCount; ++i )
440                 {
441                     SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
442                     if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
443                     {
444                         const bool bUndo = rSdrView.IsUndoEnabled();
445 
446                         if( bUndo )
447                         {
448                             OUString aStr( SvxResId( RID_SVXSTR_UNDO_APPLY_FONTWORK_SHAPE ) );
449                             rSdrView.BegUndo(aStr);
450                             rSdrView.AddUndo(rSdrView.GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
451                         }
452                         SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
453                         GetGeometryForCustomShape( aGeometryItem, aCustomShape );
454                         pObj->SetMergedItem( aGeometryItem );
455 
456                         Reference< drawing::XShape > aXShape = GetXShapeForSdrObject( static_cast<SdrObjCustomShape*>(pObj) );
457                         if ( aXShape.is() )
458                         {
459                             Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( aXShape, UNO_QUERY );
460                             if( xDefaulter.is() )
461                                 xDefaulter->createCustomShapeDefaults( aCustomShape );
462                         }
463 
464                         pObj->BroadcastObjectChange();
465                         if (bUndo)
466                             rSdrView.EndUndo();
467                         rSdrView.AdjustMarkHdl(); //HMH sal_True );
468                         rBindings.Invalidate( SID_FONTWORK_SHAPE_TYPE );
469                     }
470                 }
471             }
472         }
473         break;
474 
475         case SID_FONTWORK_CHARACTER_SPACING_DIALOG :
476         {
477             if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_CHARACTER_SPACING ) == SfxItemState::SET ) )
478             {
479                 sal_Int32 nCharSpacing = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_FONTWORK_CHARACTER_SPACING)->GetValue();
480                 FontworkCharacterSpacingDialog aDlg(rReq.GetFrameWeld(), nCharSpacing);
481                 sal_uInt16 nRet = aDlg.run();
482                 if (nRet != RET_CANCEL)
483                 {
484                     SfxInt32Item aItem(SID_FONTWORK_CHARACTER_SPACING, aDlg.getScale());
485                     SfxPoolItem* aItems[] = { &aItem, nullptr };
486                     rBindings.Execute( SID_FONTWORK_CHARACTER_SPACING, const_cast<const SfxPoolItem**>(aItems) );
487                 }
488             }
489         }
490         break;
491 
492         case SID_FONTWORK_SHAPE:
493         case SID_FONTWORK_ALIGNMENT:
494         {
495             if ( !pStrResId )
496                 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_ALIGNMENT;
497             [[fallthrough]];
498         }
499         case SID_FONTWORK_CHARACTER_SPACING:
500         {
501             if ( !pStrResId )
502                 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_CHARACTER_SPACING;
503             [[fallthrough]];
504         }
505         case SID_FONTWORK_KERN_CHARACTER_PAIRS:
506         {
507             if ( !pStrResId )
508                 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_CHARACTER_SPACING;
509             [[fallthrough]];
510         }
511         case SID_FONTWORK_SAME_LETTER_HEIGHTS:
512         {
513             if ( !pStrResId )
514                 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_SAME_LETTER_HEIGHT;
515 
516             const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
517             const size_t nCount = rMarkList.GetMarkCount();
518             for( size_t i = 0; i < nCount; ++i )
519             {
520                 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
521                 if( dynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
522                 {
523                     const bool bUndo = rSdrView.IsUndoEnabled();
524                     if( bUndo )
525                     {
526                         OUString aStr( SvxResId( pStrResId ) );
527                         rSdrView.BegUndo(aStr);
528                         rSdrView.AddUndo(rSdrView.GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
529                     }
530                     SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
531                     impl_execute( rReq, aGeometryItem, pObj );
532                     pObj->SetMergedItem( aGeometryItem );
533                     pObj->BroadcastObjectChange();
534                     if (bUndo)
535                         rSdrView.EndUndo();
536                 }
537             }
538         }
539         break;
540     };
541 }
542 
getState(SdrView const * pSdrView,SfxItemSet & rSet)543 void FontworkBar::getState( SdrView const * pSdrView, SfxItemSet& rSet )
544 {
545     sal_uInt32 nCheckStatus = 0;
546 
547     if ( rSet.GetItemState( SID_FONTWORK_ALIGNMENT_FLOATER ) != SfxItemState::UNKNOWN )
548     {
549         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
550             rSet.DisableItem( SID_FONTWORK_ALIGNMENT_FLOATER );
551     }
552     if ( rSet.GetItemState( SID_FONTWORK_ALIGNMENT ) != SfxItemState::UNKNOWN )
553     {
554         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
555             rSet.DisableItem( SID_FONTWORK_ALIGNMENT );
556         else
557             SetAlignmentState( pSdrView, rSet );
558     }
559     if ( rSet.GetItemState( SID_FONTWORK_CHARACTER_SPACING_FLOATER ) != SfxItemState::UNKNOWN )
560     {
561         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
562             rSet.DisableItem( SID_FONTWORK_CHARACTER_SPACING_FLOATER );
563     }
564     if ( rSet.GetItemState( SID_FONTWORK_CHARACTER_SPACING ) != SfxItemState::UNKNOWN )
565     {
566         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
567             rSet.DisableItem( SID_FONTWORK_CHARACTER_SPACING );
568         else
569             SetCharacterSpacingState( pSdrView, rSet );
570     }
571     if ( rSet.GetItemState( SID_FONTWORK_KERN_CHARACTER_PAIRS ) != SfxItemState::UNKNOWN )
572     {
573         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
574             rSet.DisableItem( SID_FONTWORK_KERN_CHARACTER_PAIRS );
575         else
576             SetKernCharacterPairsState( pSdrView, rSet );
577     }
578     if ( rSet.GetItemState( SID_FONTWORK_SAME_LETTER_HEIGHTS ) != SfxItemState::UNKNOWN )
579     {
580         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus ) )
581             rSet.DisableItem( SID_FONTWORK_SAME_LETTER_HEIGHTS );
582     }
583     if ( rSet.GetItemState( SID_FONTWORK_SHAPE_TYPE ) != SfxItemState::UNKNOWN )
584     {
585         if ( !checkForSelectedFontWork( pSdrView, nCheckStatus  ) )
586             rSet.DisableItem( SID_FONTWORK_SHAPE_TYPE );
587         else
588             SetFontWorkShapeTypeState( pSdrView, rSet );
589     }
590 }
591 
592 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
593