tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / controller / main / DrawCommandDispatch.cxx
blob39e5956ec0e120669e1ba26b15276112bbd07afd
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 "DrawCommandDispatch.hxx"
21 #include <ChartController.hxx>
22 #include <DrawViewWrapper.hxx>
23 #include <chartview/DrawModelWrapper.hxx>
25 #include <com/sun/star/frame/CommandGroup.hpp>
26 #include <o3tl/unsafe_downcast.hxx>
27 #include <o3tl/string_view.hxx>
28 #include <vcl/svapp.hxx>
29 #include <editeng/eeitem.hxx>
30 #include <svx/strings.hrc>
31 #include <svx/dialmgr.hxx>
32 #include <svx/fmmodel.hxx>
33 #include <svx/gallery.hxx>
34 #include <svx/svdoashp.hxx>
35 #include <svx/svdocapt.hxx>
36 #include <svx/svdopath.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/unoapi.hxx>
39 #include <svx/xlnedit.hxx>
40 #include <svx/xlnedwit.hxx>
41 #include <svx/xlnwtit.hxx>
42 #include <svx/xtable.hxx>
43 #include <svx/sdtagitm.hxx>
44 #include <basegfx/polygon/b2dpolygon.hxx>
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::frame;
49 using ::com::sun::star::uno::Reference;
50 using ::com::sun::star::uno::Sequence;
53 namespace chart
56 DrawCommandDispatch::DrawCommandDispatch( const Reference< uno::XComponentContext >& rxContext,
57 ChartController* pController )
58 :FeatureCommandDispatchBase( rxContext )
59 ,m_pChartController( pController )
63 DrawCommandDispatch::~DrawCommandDispatch()
67 bool DrawCommandDispatch::isFeatureSupported( const OUString& rCommandURL )
69 ChartCommandID nFeatureId = ChartCommandID::NONE;
70 OUString aBaseCommand;
71 OUString aCustomShapeType;
72 return parseCommandURL( rCommandURL, &nFeatureId, &aBaseCommand, &aCustomShapeType );
75 static ::basegfx::B2DPolyPolygon getPolygon(TranslateId pResId, const SdrModel& rModel)
77 ::basegfx::B2DPolyPolygon aReturn;
78 XLineEndListRef pLineEndList = rModel.GetLineEndList();
79 if ( pLineEndList.is() )
81 OUString aName(SvxResId(pResId));
82 tools::Long nCount = pLineEndList->Count();
83 for ( tools::Long nIndex = 0; nIndex < nCount; ++nIndex )
85 const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nIndex);
86 if ( pEntry->GetName() == aName )
88 aReturn = pEntry->GetLineEnd();
89 break;
93 return aReturn;
96 void DrawCommandDispatch::setAttributes( SdrObject* pObj )
98 if ( !m_pChartController )
99 return;
101 DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper();
102 DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
103 if ( !(pDrawModelWrapper && pDrawViewWrapper && pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::CustomShape) )
104 return;
106 bool bAttributesAppliedFromGallery = false;
107 if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) )
109 std::vector< OUString > aObjList;
110 if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) )
112 for ( size_t i = 0; i < aObjList.size(); ++i )
114 if ( aObjList[ i ].equalsIgnoreAsciiCase( m_aCustomShapeType ) )
116 FmFormModel aModel;
118 if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aModel ) )
120 const SdrObject* pSourceObj = aModel.GetPage( 0 )->GetObj( 0 );
121 if ( pSourceObj )
123 const SfxItemSet& rSource = pSourceObj->GetMergedItemSet();
124 SfxItemSetFixed<
125 // Ranges from SdrAttrObj:
126 SDRATTR_START, SDRATTR_SHADOW_LAST,
127 SDRATTR_MISC_FIRST,
128 SDRATTR_MISC_LAST,
129 SDRATTR_TEXTDIRECTION,
130 SDRATTR_TEXTDIRECTION,
131 // Graphic attributes, 3D
132 // properties, CustomShape
133 // properties:
134 SDRATTR_GRAF_FIRST,
135 SDRATTR_CUSTOMSHAPE_LAST,
136 // Range from SdrTextObj:
137 EE_ITEMS_START, EE_ITEMS_END>
138 aDest(pObj->getSdrModelFromSdrObject().GetItemPool());
139 aDest.Set( rSource );
140 pObj->SetMergedItemSet( aDest );
141 Degree100 nAngle = pSourceObj->GetRotateAngle();
142 if ( nAngle )
143 pObj->NbcRotate( pObj->GetSnapRect().Center(), nAngle );
144 bAttributesAppliedFromGallery = true;
147 break;
152 if ( !bAttributesAppliedFromGallery )
154 pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) );
155 pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
156 pObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
158 o3tl::unsafe_downcast< SdrObjCustomShape* >( pObj )->MergeDefaultAttributes( &m_aCustomShapeType );
162 void DrawCommandDispatch::setLineEnds( SfxItemSet& rAttr )
164 if ( !(m_nFeatureId == ChartCommandID::DrawLineArrowEnd && m_pChartController) )
165 return;
167 DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper();
168 DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
169 if ( !(pDrawModelWrapper && pDrawViewWrapper) )
170 return;
172 ::basegfx::B2DPolyPolygon aArrow( getPolygon( RID_SVXSTR_ARROW, pDrawModelWrapper->getSdrModel() ) );
173 if ( !aArrow.count() )
175 ::basegfx::B2DPolygon aNewArrow;
176 aNewArrow.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
177 aNewArrow.append( ::basegfx::B2DPoint( 0.0, 30.0) );
178 aNewArrow.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
179 aNewArrow.setClosed( true );
180 aArrow.append( aNewArrow );
183 SfxItemSet aSet(pDrawViewWrapper->GetModel().GetItemPool());
184 pDrawViewWrapper->GetAttributes( aSet );
186 tools::Long nWidth = 300; // (1/100th mm)
187 if ( aSet.GetItemState( XATTR_LINEWIDTH ) != SfxItemState::INVALID )
189 tools::Long nValue = aSet.Get( XATTR_LINEWIDTH ).GetValue();
190 if ( nValue > 0 )
192 nWidth = nValue * 3;
196 rAttr.Put( XLineEndItem( SvxResId( RID_SVXSTR_ARROW ), std::move(aArrow) ) );
197 rAttr.Put( XLineEndWidthItem( nWidth ) );
200 // WeakComponentImplHelperBase
201 void DrawCommandDispatch::disposing(std::unique_lock<std::mutex>& /*rGuard*/)
205 // XEventListener
206 void DrawCommandDispatch::disposing( const lang::EventObject& /* Source */ )
210 FeatureState DrawCommandDispatch::getState( const OUString& rCommand )
212 FeatureState aReturn;
213 aReturn.bEnabled = false;
214 aReturn.aState <<= false;
216 ChartCommandID nFeatureId = ChartCommandID::NONE;
217 OUString aBaseCommand;
218 OUString aCustomShapeType;
219 if ( parseCommandURL( rCommand, &nFeatureId, &aBaseCommand, &aCustomShapeType ) )
221 switch ( nFeatureId )
223 case ChartCommandID::DrawObjectSelect:
224 case ChartCommandID::DrawLine:
225 case ChartCommandID::DrawLineArrowEnd:
226 case ChartCommandID::DrawRect:
227 case ChartCommandID::DrawEllipse:
228 case ChartCommandID::DrawFreelineNoFill:
229 case ChartCommandID::DrawText:
230 case ChartCommandID::DrawCaption:
231 case ChartCommandID::DrawToolboxCsBasic:
232 case ChartCommandID::DrawToolboxCsSymbol:
233 case ChartCommandID::DrawToolboxCsArrow:
234 case ChartCommandID::DrawToolboxCsFlowchart:
235 case ChartCommandID::DrawToolboxCsCallout:
236 case ChartCommandID::DrawToolboxCsStar:
238 aReturn.bEnabled = true;
239 aReturn.aState <<= false;
241 break;
242 default:
244 aReturn.bEnabled = false;
245 aReturn.aState <<= false;
247 break;
251 return aReturn;
254 void DrawCommandDispatch::execute( const OUString& rCommand, const Sequence< beans::PropertyValue>& rArgs )
256 ChartDrawMode eDrawMode = CHARTDRAW_SELECT;
257 SdrObjKind eKind = SdrObjKind::NONE;
259 ChartCommandID nFeatureId = ChartCommandID::NONE;
260 OUString aBaseCommand;
261 OUString aCustomShapeType;
262 if ( !parseCommandURL( rCommand, &nFeatureId, &aBaseCommand, &aCustomShapeType ) )
263 return;
265 bool bCreate = false;
266 m_nFeatureId = nFeatureId;
267 m_aCustomShapeType = aCustomShapeType;
269 switch ( nFeatureId )
271 case ChartCommandID::DrawObjectSelect:
273 eDrawMode = CHARTDRAW_SELECT;
274 eKind = SdrObjKind::NONE;
276 break;
277 case ChartCommandID::DrawLine:
278 case ChartCommandID::DrawLineArrowEnd:
280 eDrawMode = CHARTDRAW_INSERT;
281 eKind = SdrObjKind::Line;
283 break;
284 case ChartCommandID::DrawRect:
286 eDrawMode = CHARTDRAW_INSERT;
287 eKind = SdrObjKind::Rectangle;
289 break;
290 case ChartCommandID::DrawEllipse:
292 eDrawMode = CHARTDRAW_INSERT;
293 eKind = SdrObjKind::CircleOrEllipse;
295 break;
296 case ChartCommandID::DrawFreelineNoFill:
298 eDrawMode = CHARTDRAW_INSERT;
299 eKind = SdrObjKind::FreehandLine;
301 break;
302 case ChartCommandID::DrawText:
304 eDrawMode = CHARTDRAW_INSERT;
305 eKind = SdrObjKind::Text;
306 bCreate = true;
308 break;
309 case ChartCommandID::DrawCaption:
311 eDrawMode = CHARTDRAW_INSERT;
312 eKind = SdrObjKind::Caption;
314 break;
315 case ChartCommandID::DrawToolboxCsBasic:
316 case ChartCommandID::DrawToolboxCsSymbol:
317 case ChartCommandID::DrawToolboxCsArrow:
318 case ChartCommandID::DrawToolboxCsFlowchart:
319 case ChartCommandID::DrawToolboxCsCallout:
320 case ChartCommandID::DrawToolboxCsStar:
322 eDrawMode = CHARTDRAW_INSERT;
323 eKind = SdrObjKind::CustomShape;
325 break;
326 default:
328 eDrawMode = CHARTDRAW_SELECT;
329 eKind = SdrObjKind::NONE;
331 break;
334 if ( !m_pChartController )
335 return;
337 DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
338 if ( !pDrawViewWrapper )
339 return;
341 SolarMutexGuard aGuard;
342 m_pChartController->setDrawMode( eDrawMode );
343 setInsertObj(eKind);
344 if ( bCreate )
346 pDrawViewWrapper->SetCreateMode();
349 const beans::PropertyValue* pKeyModifier = std::find_if(rArgs.begin(), rArgs.end(),
350 [](const beans::PropertyValue& lhs)
351 {return lhs.Name == "KeyModifier";} );
352 sal_Int16 nKeyModifier = 0;
353 if ( !(pKeyModifier != rArgs.end() && ( pKeyModifier->Value >>= nKeyModifier ) && nKeyModifier == KEY_MOD1) )
354 return;
356 if ( eDrawMode != CHARTDRAW_INSERT )
357 return;
359 rtl::Reference<SdrObject> pObj = createDefaultObject( nFeatureId );
360 if ( pObj )
362 SdrPageView* pPageView = pDrawViewWrapper->GetSdrPageView();
363 if (pDrawViewWrapper->InsertObjectAtView(pObj.get(), *pPageView))
364 m_pChartController->SetAndApplySelection(Reference<drawing::XShape>(pObj->getUnoShape(), uno::UNO_QUERY));
365 if ( nFeatureId == ChartCommandID::DrawText )
367 m_pChartController->StartTextEdit();
372 void DrawCommandDispatch::describeSupportedFeatures()
374 implDescribeSupportedFeature( ".uno:SelectObject", ChartCommandID::DrawObjectSelect, CommandGroup::INSERT );
375 implDescribeSupportedFeature( ".uno:Line", ChartCommandID::DrawLine, CommandGroup::INSERT );
376 implDescribeSupportedFeature( ".uno:LineArrowEnd", ChartCommandID::DrawLineArrowEnd, CommandGroup::INSERT );
377 implDescribeSupportedFeature( ".uno:Rect", ChartCommandID::DrawRect, CommandGroup::INSERT );
378 implDescribeSupportedFeature( ".uno:Ellipse", ChartCommandID::DrawEllipse, CommandGroup::INSERT );
379 implDescribeSupportedFeature( ".uno:Freeline_Unfilled", ChartCommandID::DrawFreelineNoFill, CommandGroup::INSERT );
380 implDescribeSupportedFeature( ".uno:DrawText", ChartCommandID::DrawText, CommandGroup::INSERT );
381 implDescribeSupportedFeature( ".uno:DrawCaption", ChartCommandID::DrawCaption, CommandGroup::INSERT );
382 implDescribeSupportedFeature( ".uno:BasicShapes", ChartCommandID::DrawToolboxCsBasic, CommandGroup::INSERT );
383 implDescribeSupportedFeature( ".uno:SymbolShapes", ChartCommandID::DrawToolboxCsSymbol, CommandGroup::INSERT );
384 implDescribeSupportedFeature( ".uno:ArrowShapes", ChartCommandID::DrawToolboxCsArrow, CommandGroup::INSERT );
385 implDescribeSupportedFeature( ".uno:FlowChartShapes", ChartCommandID::DrawToolboxCsFlowchart, CommandGroup::INSERT );
386 implDescribeSupportedFeature( ".uno:CalloutShapes", ChartCommandID::DrawToolboxCsCallout, CommandGroup::INSERT );
387 implDescribeSupportedFeature( ".uno:StarShapes", ChartCommandID::DrawToolboxCsStar, CommandGroup::INSERT );
390 void DrawCommandDispatch::setInsertObj(SdrObjKind eObj)
392 DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : nullptr );
393 if ( pDrawViewWrapper )
395 pDrawViewWrapper->SetCurrentObj( eObj /*, Inventor */);
399 rtl::Reference<SdrObject> DrawCommandDispatch::createDefaultObject( const ChartCommandID nID )
401 rtl::Reference<SdrObject> pObj;
402 DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : nullptr );
403 DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : nullptr );
405 if ( pDrawViewWrapper && pDrawModelWrapper )
407 Reference< drawing::XDrawPage > xDrawPage( pDrawModelWrapper->getMainDrawPage() );
408 SdrPage* pPage = GetSdrPageFromXDrawPage( xDrawPage );
409 if ( pPage )
411 SolarMutexGuard aGuard;
413 pObj = SdrObjFactory::MakeNewObject(
414 pDrawModelWrapper->getSdrModel(),
415 pDrawViewWrapper->GetCurrentObjInventor(),
416 pDrawViewWrapper->GetCurrentObjIdentifier());
418 if ( pObj )
420 Size aObjectSize( 4000, 2500 );
421 tools::Rectangle aPageRect( tools::Rectangle( Point( 0, 0 ), pPage->GetSize() ) );
422 Point aObjectPos = aPageRect.Center();
423 aObjectPos.AdjustX( -(aObjectSize.Width() / 2) );
424 aObjectPos.AdjustY( -(aObjectSize.Height() / 2) );
425 tools::Rectangle aRect( aObjectPos, aObjectSize );
427 switch ( nID )
429 case ChartCommandID::DrawLine:
430 case ChartCommandID::DrawLineArrowEnd:
432 if ( auto const pathObj = dynamic_cast<SdrPathObj*>( pObj.get()) )
434 Point aStart = aRect.TopLeft();
435 Point aEnd = aRect.BottomRight();
436 sal_Int32 nYMiddle( ( aRect.Top() + aRect.Bottom() ) / 2 );
437 basegfx::B2DPolygon aPoly;
438 aPoly.append( basegfx::B2DPoint( aStart.X(), nYMiddle ) );
439 aPoly.append( basegfx::B2DPoint( aEnd.X(), nYMiddle ) );
440 pathObj->SetPathPoly(basegfx::B2DPolyPolygon(aPoly));
441 SfxItemSet aSet( pDrawModelWrapper->GetItemPool() );
442 setLineEnds( aSet );
443 pObj->SetMergedItemSet( aSet );
446 break;
447 case ChartCommandID::DrawFreelineNoFill:
449 if ( auto const pathObj = dynamic_cast<SdrPathObj*>( pObj.get()) )
451 basegfx::B2DPolygon aInnerPoly;
452 aInnerPoly.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom() ) );
453 aInnerPoly.appendBezierSegment(
454 basegfx::B2DPoint( aRect.Left(), aRect.Top() ),
455 basegfx::B2DPoint( aRect.Center().X(), aRect.Top() ),
456 basegfx::B2DPoint( aRect.Center().X(), aRect.Center().Y() ) );
457 aInnerPoly.appendBezierSegment(
458 basegfx::B2DPoint( aRect.Center().X(), aRect.Bottom() ),
459 basegfx::B2DPoint( aRect.Right(), aRect.Bottom() ),
460 basegfx::B2DPoint( aRect.Right(), aRect.Top() ) );
461 basegfx::B2DPolyPolygon aPoly;
462 aPoly.append( aInnerPoly );
463 pathObj->SetPathPoly(aPoly);
466 break;
467 case ChartCommandID::DrawText:
468 case ChartCommandID::DrawTextVertical:
470 if ( SdrTextObj* pTextObj = DynCastSdrTextObj( pObj.get()) )
472 pTextObj->SetLogicRect( aRect );
473 bool bVertical = ( nID == ChartCommandID::DrawTextVertical );
474 pTextObj->SetVerticalWriting( bVertical );
475 if ( bVertical )
477 SfxItemSet aSet( pDrawModelWrapper->GetItemPool() );
478 aSet.Put( makeSdrTextAutoGrowWidthItem( true ) );
479 aSet.Put( makeSdrTextAutoGrowHeightItem( false ) );
480 aSet.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_TOP ) );
481 aSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT ) );
482 pTextObj->SetMergedItemSet( aSet );
486 break;
487 case ChartCommandID::DrawCaption:
488 case ChartCommandID::DrawCaptionVertical:
490 if ( SdrCaptionObj* pCaptionObj = dynamic_cast<SdrCaptionObj*>( pObj.get()) )
492 bool bIsVertical( nID == ChartCommandID::DrawCaptionVertical );
493 pCaptionObj->SetVerticalWriting( bIsVertical );
494 if ( bIsVertical )
496 SfxItemSet aSet( pObj->GetMergedItemSet() );
497 aSet.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) );
498 aSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT ) );
499 pObj->SetMergedItemSet( aSet );
501 pCaptionObj->SetLogicRect( aRect );
502 pCaptionObj->SetTailPos(
503 aRect.TopLeft() - Point( aRect.GetWidth() / 2, aRect.GetHeight() / 2 ) );
506 break;
507 default:
509 pObj->SetLogicRect( aRect );
510 SfxItemSet aSet( pDrawModelWrapper->GetItemPool() );
511 setAttributes( pObj.get() );
512 pObj->SetMergedItemSet( aSet );
514 break;
520 return pObj;
523 bool DrawCommandDispatch::parseCommandURL( const OUString& rCommandURL, ChartCommandID* pnFeatureId,
524 OUString* pBaseCommand, OUString* pCustomShapeType )
526 bool bFound = true;
527 ChartCommandID nFeatureId = ChartCommandID::NONE;
528 OUString aBaseCommand;
529 OUString aType;
531 sal_Int32 nIndex = std::min(sal_Int32(1), rCommandURL.getLength());
532 std::u16string_view aToken = o3tl::getToken(rCommandURL, 0, '.', nIndex );
533 if ( nIndex == -1 || aToken.empty() )
535 aBaseCommand = rCommandURL;
536 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( aBaseCommand );
537 if ( aIter != m_aSupportedFeatures.end() )
539 nFeatureId = aIter->second.nFeatureId;
541 switch ( nFeatureId )
543 case ChartCommandID::DrawToolboxCsBasic:
545 aType = "diamond";
547 break;
548 case ChartCommandID::DrawToolboxCsSymbol:
550 aType = "smiley";
552 break;
553 case ChartCommandID::DrawToolboxCsArrow:
555 aType = "left-right-arrow";
557 break;
558 case ChartCommandID::DrawToolboxCsFlowchart:
560 aType = "flowchart-internal-storage";
562 break;
563 case ChartCommandID::DrawToolboxCsCallout:
565 aType = "round-rectangular-callout";
567 break;
568 case ChartCommandID::DrawToolboxCsStar:
570 aType = "star5";
572 break;
573 default:
576 break;
579 else
581 bFound = false;
584 else
586 aBaseCommand = rCommandURL.copy( 0, nIndex - 1 );
587 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( aBaseCommand );
588 if ( aIter != m_aSupportedFeatures.end() )
590 nFeatureId = aIter->second.nFeatureId;
591 aType = rCommandURL.getToken( 0, '.', nIndex );
593 else
595 bFound = false;
599 *pnFeatureId = nFeatureId;
600 *pBaseCommand = aBaseCommand;
601 *pCustomShapeType = aType;
603 return bFound;
606 } // namespace chart
608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */