tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / svx / source / toolbars / fontworkbar.cxx
blobf30b43d6625008978f60af48c9053b0ad8dd3883
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svdundo.hxx>
21 #include <sfx2/request.hxx>
22 #include <sfx2/objface.hxx>
23 #include <sfx2/viewsh.hxx>
24 #include <svx/unoapi.hxx>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
27 #include <sal/log.hxx>
28 #include <svx/dialmgr.hxx>
29 #include <svx/svdoashp.hxx>
30 #include <svx/strings.hrc>
31 #include <svx/svdpage.hxx>
32 #include <svx/svdview.hxx>
33 #include <svx/sdasitm.hxx>
34 #include <svx/gallery.hxx>
35 #include <svx/fmmodel.hxx>
36 #include <svx/sdtfsitm.hxx>
37 #include <svl/itempool.hxx>
38 #include <svl/stritem.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/charscaleitem.hxx>
42 #include <editeng/kernitem.hxx>
44 #include <svx/svxids.hrc>
45 #include <svx/fontworkbar.hxx>
46 #include <svx/fontworkgallery.hxx>
49 using namespace ::svx;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::uno;
54 static void SetAlignmentState( SdrView const * pSdrView, SfxItemSet& rSet )
56 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
57 const size_t nCount = rMarkList.GetMarkCount();
59 sal_Int32 nAlignment = -1;
60 for( size_t i = 0; i < nCount; ++i )
62 SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
63 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
65 sal_Int32 nOldAlignment = nAlignment;
66 const SdrTextHorzAdjustItem& rTextHorzAdjustItem = pObj->GetMergedItem( SDRATTR_TEXT_HORZADJUST );
67 const SdrTextFitToSizeTypeItem& rTextFitToSizeTypeItem = pObj->GetMergedItem( SDRATTR_TEXT_FITTOSIZE );
68 switch ( rTextHorzAdjustItem.GetValue() )
70 case SDRTEXTHORZADJUST_LEFT : nAlignment = 0; break;
71 case SDRTEXTHORZADJUST_CENTER : nAlignment = 1; break;
72 case SDRTEXTHORZADJUST_RIGHT : nAlignment = 2; break;
73 case SDRTEXTHORZADJUST_BLOCK :
75 auto const fit(rTextFitToSizeTypeItem.GetValue());
76 if (fit == drawing::TextFitToSizeType_NONE)
78 nAlignment = 3;
80 else if (fit == drawing::TextFitToSizeType_ALLLINES ||
81 fit == drawing::TextFitToSizeType_PROPORTIONAL)
83 nAlignment = 4;
87 if ( ( nOldAlignment != -1 ) && ( nOldAlignment != nAlignment ) )
89 nAlignment = -1;
90 break;
94 rSet.Put( SfxInt32Item( SID_FONTWORK_ALIGNMENT, nAlignment ) );
97 static void SetCharacterSpacingState( SdrView const * pSdrView, SfxItemSet& rSet )
99 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
100 const size_t nCount = rMarkList.GetMarkCount();
102 sal_Int32 nCharacterSpacing = -1;
103 for( size_t i = 0; i < nCount; ++i )
105 SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
106 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
108 sal_Int32 nOldCharacterSpacing = nCharacterSpacing;
109 const SvxCharScaleWidthItem& rCharScaleWidthItem = pObj->GetMergedItem( EE_CHAR_FONTWIDTH );
110 nCharacterSpacing = rCharScaleWidthItem.GetValue();
111 if ( ( nOldCharacterSpacing != -1 ) && ( nOldCharacterSpacing != nCharacterSpacing ) )
113 nCharacterSpacing = -1;
114 break;
118 rSet.Put( SfxInt32Item( SID_FONTWORK_CHARACTER_SPACING, nCharacterSpacing ) );
122 static void SetKernCharacterPairsState( SdrView const * pSdrView, SfxItemSet& rSet )
124 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
125 const size_t nCount = rMarkList.GetMarkCount();
127 bool bChecked = false;
128 for( size_t i = 0; i < nCount; ++i )
130 SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
131 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
133 const SvxKerningItem& rKerningItem = pObj->GetMergedItem( EE_CHAR_KERNING );
134 if ( rKerningItem.GetValue() )
135 bChecked = true;
138 rSet.Put( SfxBoolItem( SID_FONTWORK_KERN_CHARACTER_PAIRS, bChecked ) );
141 static void SetFontWorkShapeTypeState( SdrView const * pSdrView, SfxItemSet& rSet )
143 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
144 const size_t nCount = rMarkList.GetMarkCount();
146 OUString aFontWorkShapeType;
148 for( size_t i = 0; i < nCount; ++i )
150 SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
151 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
153 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
154 const Any* pAny = rGeometryItem.GetPropertyValueByName( u"Type"_ustr );
155 if( pAny )
157 OUString aType;
158 if ( *pAny >>= aType )
160 if ( !aFontWorkShapeType.isEmpty() )
162 if ( aFontWorkShapeType != aType ) // different FontWorkShapeTypes selected ?
164 aFontWorkShapeType.clear();
165 break;
168 aFontWorkShapeType = aType;
173 rSet.Put( SfxStringItem( SID_FONTWORK_SHAPE_TYPE, aFontWorkShapeType ) );
176 // Declare the default interface. (The slotmap must not be empty, so
177 // we enter something which never occurs here (hopefully).)
178 static SfxSlot aFontworkBarSlots_Impl[] =
180 { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, u""_ustr }
183 SFX_IMPL_INTERFACE(FontworkBar, SfxShell)
185 void FontworkBar::InitInterface_Impl()
187 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Svx_Fontwork_Bar);
191 FontworkBar::FontworkBar(SfxViewShell* pViewShell )
192 : SfxShell(pViewShell)
194 DBG_ASSERT( pViewShell, "svx::FontworkBar::FontworkBar(), I need a viewshell!" );
195 if( pViewShell )
196 SetPool(&pViewShell->GetPool());
198 SetName( SvxResId( RID_SVX_FONTWORK_BAR ));
201 FontworkBar::~FontworkBar()
203 SetRepeatTarget(nullptr);
206 namespace svx {
207 bool checkForFontWork( const SdrObject* pObj )
209 static constexpr OUString sTextPath = u"TextPath"_ustr;
210 bool bFound = false;
212 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
214 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
215 const Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
216 if( pAny )
217 *pAny >>= bFound;
220 return bFound;
223 bool checkForSelectedFontWork( SdrView const * pSdrView )
225 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
226 const size_t nCount = rMarkList.GetMarkCount();
227 bool bFound = false;
228 for(size_t i=0; (i<nCount) && !bFound ; ++i)
230 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
231 bFound = checkForFontWork(pObj);
233 return bFound;
236 static void impl_execute( SfxRequest const & rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
238 sal_uInt16 nSID = rReq.GetSlot();
239 switch( nSID )
241 case SID_FONTWORK_SAME_LETTER_HEIGHTS:
243 css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( u"TextPath"_ustr, u"SameLetterHeights"_ustr );
245 bool bOn = false;
246 if( pAny )
247 (*pAny) >>= bOn;
248 bOn = !bOn;
249 css::beans::PropertyValue aPropValue;
250 aPropValue.Name = "SameLetterHeights";
251 aPropValue.Value <<= bOn;
252 rGeometryItem.SetPropertyValue(u"TextPath"_ustr, aPropValue);
254 break;
256 case SID_FONTWORK_ALIGNMENT:
258 const SfxInt32Item* pAlignItem = nullptr;
259 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_FONTWORK_ALIGNMENT, true, &pAlignItem ) == SfxItemState::SET )
261 sal_Int32 nValue = pAlignItem->GetValue();
262 if ( ( nValue >= 0 ) && ( nValue < 5 ) )
264 drawing::TextFitToSizeType eFTS = drawing::TextFitToSizeType_NONE;
265 SdrTextHorzAdjust eHorzAdjust;
266 switch ( nValue )
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;
274 pObj->SetMergedItem( SdrTextHorzAdjustItem( eHorzAdjust ) );
275 pObj->SetMergedItem( SdrTextFitToSizeTypeItem( eFTS ) );
276 pObj->BroadcastObjectChange();
280 break;
282 case SID_FONTWORK_CHARACTER_SPACING:
284 const SfxInt32Item* pSpacingItem = nullptr;
285 if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_CHARACTER_SPACING, true, &pSpacingItem ) == SfxItemState::SET ) )
287 sal_Int32 nCharSpacing = pSpacingItem->GetValue();
288 pObj->SetMergedItem( SvxCharScaleWidthItem( static_cast<sal_uInt16>(nCharSpacing), EE_CHAR_FONTWIDTH ) );
289 pObj->BroadcastObjectChange();
292 break;
294 case SID_FONTWORK_KERN_CHARACTER_PAIRS:
296 if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_KERN_CHARACTER_PAIRS ) == SfxItemState::SET ) )
298 // sal_Bool bKernCharacterPairs = ((const SfxBoolItem*)rReq.GetArgs()->GetItem(SID_FONTWORK_KERN_CHARACTER_PAIRS))->GetValue();
299 //TODO: pObj->SetMergedItem( SvxCharScaleWidthItem( (sal_uInt16)nCharSpacing, EE_CHAR_FONTWIDTH ) );
300 pObj->BroadcastObjectChange();
303 break;
307 static void GetGeometryForCustomShape( SdrCustomShapeGeometryItem& rGeometryItem, const OUString& rCustomShape )
309 static constexpr OUString sType( u"Type"_ustr );
311 css::beans::PropertyValue aPropVal;
312 aPropVal.Name = sType;
313 aPropVal.Value <<= rCustomShape;
314 rGeometryItem.SetPropertyValue( aPropVal );
316 static constexpr OUString sAdjustmentValues( u"AdjustmentValues"_ustr );
317 static constexpr OUString sCoordinateOrigin( u"CoordinateOrigin"_ustr );
318 static constexpr OUString sCoordinateSize( u"CoordinateSize"_ustr );
319 static constexpr OUString sEquations( u"Equations"_ustr );
320 static constexpr OUString sHandles( u"Handles"_ustr );
321 static constexpr OUString sPath( u"Path"_ustr );
322 rGeometryItem.ClearPropertyValue( sAdjustmentValues );
323 rGeometryItem.ClearPropertyValue( sCoordinateOrigin );
324 rGeometryItem.ClearPropertyValue( sCoordinateSize );
325 rGeometryItem.ClearPropertyValue( sEquations );
326 rGeometryItem.ClearPropertyValue( sHandles );
327 rGeometryItem.ClearPropertyValue( sPath );
329 /* SJ: CustomShapes that are available in the gallery are having the highest
330 priority, so we will take a look there before taking the internal default */
332 if ( !GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) )
333 return;
335 std::vector< OUString > aObjList;
336 if ( !GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) )
337 return;
339 for ( std::vector<OUString>::size_type i = 0; i < aObjList.size(); i++ )
341 if ( aObjList[ i ].equalsIgnoreAsciiCase( rCustomShape ) )
343 FmFormModel aFormModel;
345 if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aFormModel ) )
347 const SdrObject* pSourceObj = nullptr;
348 if (aFormModel.GetPageCount() > 0)
349 pSourceObj = aFormModel.GetPage( 0 )->GetObj( 0 );
350 SAL_WARN_IF(!pSourceObj, "svx.form", "No content in gallery custom shape '" << rCustomShape << "'" );
351 if( pSourceObj )
353 PropertyValue aPropVal_;
354 const SdrCustomShapeGeometryItem& rSourceGeometry = pSourceObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
355 const css::uno::Any* pAny = rSourceGeometry.GetPropertyValueByName( sType );
356 if ( pAny )
358 aPropVal_.Name = sType;
359 aPropVal_.Value = *pAny;
360 rGeometryItem.SetPropertyValue( aPropVal_ );
362 pAny = rSourceGeometry.GetPropertyValueByName( sAdjustmentValues );
363 if ( pAny )
365 aPropVal_.Name = sAdjustmentValues;
366 aPropVal_.Value = *pAny;
367 rGeometryItem.SetPropertyValue( aPropVal_ );
369 pAny = rSourceGeometry.GetPropertyValueByName( sCoordinateOrigin );
370 if ( pAny )
372 aPropVal_.Name = sCoordinateOrigin;
373 aPropVal_.Value = *pAny;
374 rGeometryItem.SetPropertyValue( aPropVal_ );
376 pAny = rSourceGeometry.GetPropertyValueByName( sCoordinateSize );
377 if ( pAny )
379 aPropVal_.Name = sCoordinateSize;
380 aPropVal_.Value = *pAny;
381 rGeometryItem.SetPropertyValue( aPropVal_ );
383 pAny = rSourceGeometry.GetPropertyValueByName( sEquations );
384 if ( pAny )
386 aPropVal_.Name = sEquations;
387 aPropVal_.Value = *pAny;
388 rGeometryItem.SetPropertyValue( aPropVal_ );
390 pAny = rSourceGeometry.GetPropertyValueByName( sHandles );
391 if ( pAny )
393 aPropVal_.Name = sHandles;
394 aPropVal_.Value = *pAny;
395 rGeometryItem.SetPropertyValue( aPropVal_ );
397 pAny = rSourceGeometry.GetPropertyValueByName( sPath );
398 if ( pAny )
400 aPropVal_.Name = sPath;
401 aPropVal_.Value = *pAny;
402 rGeometryItem.SetPropertyValue( aPropVal_ );
411 void FontworkBar::execute( SdrView& rSdrView, SfxRequest const & rReq, SfxBindings& rBindings )
413 TranslateId pStrResId;
415 sal_uInt16 nSID = rReq.GetSlot();
416 switch( nSID )
418 case SID_FONTWORK_GALLERY_FLOATER:
420 std::shared_ptr<FontWorkGalleryDialog> pDlg = std::make_shared<FontWorkGalleryDialog>(rReq.GetFrameWeld(), rSdrView, rBindings.GetActiveFrame());
421 weld::DialogController::runAsync(pDlg, [](int){});
423 break;
425 case SID_FONTWORK_SHAPE_TYPE:
427 OUString aCustomShape;
428 const SfxItemSet* pArgs = rReq.GetArgs();
429 if ( pArgs )
431 const SfxStringItem& rItm = static_cast<const SfxStringItem&>(pArgs->Get( rReq.GetSlot() ));
432 aCustomShape = rItm.GetValue();
434 if ( !aCustomShape.isEmpty() )
436 const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
437 const size_t nCount = rMarkList.GetMarkCount();
438 for( size_t i = 0; i < nCount; ++i )
440 SdrObject* pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
441 if( auto pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) )
443 const bool bUndo = rSdrView.IsUndoEnabled();
445 if( bUndo )
447 OUString aStr( SvxResId( RID_SVXSTR_UNDO_APPLY_FONTWORK_SHAPE ) );
448 rSdrView.BegUndo(aStr);
449 rSdrView.AddUndo(rSdrView.GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
451 SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
452 GetGeometryForCustomShape( aGeometryItem, aCustomShape );
453 pObj->SetMergedItem( aGeometryItem );
455 Reference< drawing::XShape > aXShape = GetXShapeForSdrObject( pCustomShape );
456 if ( aXShape.is() )
458 Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( aXShape, UNO_QUERY );
459 if( xDefaulter.is() )
460 xDefaulter->createCustomShapeDefaults( aCustomShape );
463 pObj->BroadcastObjectChange();
464 if (bUndo)
465 rSdrView.EndUndo();
466 rSdrView.AdjustMarkHdl(); //HMH sal_True );
467 rBindings.Invalidate( SID_FONTWORK_SHAPE_TYPE );
472 break;
474 case SID_FONTWORK_CHARACTER_SPACING_DIALOG :
476 const SfxInt32Item* pSpacingItem = nullptr;
477 if( rReq.GetArgs() && ( rReq.GetArgs()->GetItemState( SID_FONTWORK_CHARACTER_SPACING, true, &pSpacingItem ) == SfxItemState::SET ) )
479 sal_Int32 nCharSpacing = pSpacingItem->GetValue();
480 FontworkCharacterSpacingDialog aDlg(rReq.GetFrameWeld(), nCharSpacing);
481 sal_uInt16 nRet = aDlg.run();
482 if (nRet != RET_CANCEL)
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) );
490 break;
492 case SID_FONTWORK_SHAPE:
493 case SID_FONTWORK_ALIGNMENT:
495 if ( !pStrResId )
496 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_ALIGNMENT;
497 [[fallthrough]];
499 case SID_FONTWORK_CHARACTER_SPACING:
501 if ( !pStrResId )
502 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_CHARACTER_SPACING;
503 [[fallthrough]];
505 case SID_FONTWORK_KERN_CHARACTER_PAIRS:
507 if ( !pStrResId )
508 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_CHARACTER_SPACING;
509 [[fallthrough]];
511 case SID_FONTWORK_SAME_LETTER_HEIGHTS:
513 if ( !pStrResId )
514 pStrResId = RID_SVXSTR_UNDO_APPLY_FONTWORK_SAME_LETTER_HEIGHT;
516 const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
517 const size_t nCount = rMarkList.GetMarkCount();
518 for( size_t i = 0; i < nCount; ++i )
520 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
521 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
523 const bool bUndo = rSdrView.IsUndoEnabled();
524 if( bUndo )
526 OUString aStr( SvxResId( pStrResId ) );
527 rSdrView.BegUndo(aStr);
528 rSdrView.AddUndo(rSdrView.GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
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();
539 break;
543 void FontworkBar::getState( SdrView const * pSdrView, SfxItemSet& rSet )
545 if ( checkForSelectedFontWork( pSdrView ) )
547 SetAlignmentState( pSdrView, rSet );
548 SetCharacterSpacingState( pSdrView, rSet );
549 SetKernCharacterPairsState( pSdrView, rSet );
550 SetFontWorkShapeTypeState( pSdrView, rSet );
552 else
554 rSet.DisableItem( SID_FONTWORK_ALIGNMENT_FLOATER );
555 rSet.DisableItem( SID_FONTWORK_ALIGNMENT );
556 rSet.DisableItem( SID_FONTWORK_CHARACTER_SPACING_FLOATER );
557 rSet.DisableItem( SID_FONTWORK_CHARACTER_SPACING );
558 rSet.DisableItem( SID_FONTWORK_KERN_CHARACTER_PAIRS );
559 rSet.DisableItem( SID_FONTWORK_SAME_LETTER_HEIGHTS );
560 rSet.DisableItem( SID_FONTWORK_SHAPE_TYPE );
565 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */