1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "DrawCommandDispatch.h"
22 #include <ChartController.hxx>
23 #include <DrawViewWrapper.hxx>
24 #include <chartview/DrawModelWrapper.hxx>
26 #include <com/sun/star/frame/CommandGroup.hpp>
27 #include <o3tl/unsafe_downcast.hxx>
28 #include <vcl/svapp.hxx>
29 #include <svl/itempool.hxx>
30 #include <editeng/adjustitem.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <svx/strings.hrc>
33 #include <svx/dialmgr.hxx>
34 #include <svx/fmmodel.hxx>
35 #include <svx/gallery.hxx>
36 #include <svx/svdoashp.hxx>
37 #include <svx/svdocapt.hxx>
38 #include <svx/svdopath.hxx>
39 #include <svx/svdpage.hxx>
40 #include <svx/unoapi.hxx>
41 #include <svx/xlnedit.hxx>
42 #include <svx/xlnedwit.hxx>
43 #include <svx/xlnwtit.hxx>
44 #include <svx/xtable.hxx>
45 #include <svx/sdtagitm.hxx>
46 #include <basegfx/polygon/b2dpolygon.hxx>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::frame
;
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::Sequence
;
58 DrawCommandDispatch::DrawCommandDispatch( const Reference
< uno::XComponentContext
>& rxContext
,
59 ChartController
* pController
)
60 :FeatureCommandDispatchBase( rxContext
)
61 ,m_pChartController( pController
)
65 DrawCommandDispatch::~DrawCommandDispatch()
69 bool DrawCommandDispatch::isFeatureSupported( const OUString
& rCommandURL
)
71 sal_uInt16 nFeatureId
= 0;
72 OUString aBaseCommand
;
73 OUString aCustomShapeType
;
74 return parseCommandURL( rCommandURL
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
);
77 static ::basegfx::B2DPolyPolygon
getPolygon(const char* pResId
, const SdrModel
& rModel
)
79 ::basegfx::B2DPolyPolygon aReturn
;
80 XLineEndListRef pLineEndList
= rModel
.GetLineEndList();
81 if ( pLineEndList
.is() )
83 OUString
aName(SvxResId(pResId
));
84 long nCount
= pLineEndList
->Count();
85 for ( long nIndex
= 0; nIndex
< nCount
; ++nIndex
)
87 const XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd(nIndex
);
88 if ( pEntry
->GetName() == aName
)
90 aReturn
= pEntry
->GetLineEnd();
98 void DrawCommandDispatch::setAttributes( SdrObject
* pObj
)
100 if ( m_pChartController
)
102 DrawModelWrapper
* pDrawModelWrapper
= m_pChartController
->GetDrawModelWrapper();
103 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
104 if ( pDrawModelWrapper
&& pDrawViewWrapper
&& pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_CUSTOMSHAPE
)
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
) )
117 SfxItemPool
& rPool(aModel
.GetItemPool());
118 rPool
.FreezeIdRanges();
120 if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT
, i
, &aModel
) )
122 const SdrObject
* pSourceObj
= aModel
.GetPage( 0 )->GetObj( 0 );
125 const SfxItemSet
& rSource
= pSourceObj
->GetMergedItemSet();
127 pObj
->getSdrModelFromSdrObject().GetItemPool(),
129 // Ranges from SdrAttrObj:
130 SDRATTR_START
, SDRATTR_SHADOW_LAST
,
133 SDRATTR_TEXTDIRECTION
,
134 SDRATTR_TEXTDIRECTION
,
135 // Graphic attributes, 3D
136 // properties, CustomShape
139 SDRATTR_CUSTOMSHAPE_LAST
,
140 // Range from SdrTextObj:
141 EE_ITEMS_START
, EE_ITEMS_END
>{});
142 aDest
.Set( rSource
);
143 pObj
->SetMergedItemSet( aDest
);
144 sal_Int32 nAngle
= pSourceObj
->GetRotateAngle();
147 double a
= nAngle
* F_PI18000
;
148 pObj
->NbcRotate( pObj
->GetSnapRect().Center(), nAngle
, sin( a
), cos( a
) );
150 bAttributesAppliedFromGallery
= true;
158 if ( !bAttributesAppliedFromGallery
)
160 pObj
->SetMergedItem( SvxAdjustItem( SvxAdjust::Center
, 0 ) );
161 pObj
->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER
) );
162 pObj
->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK
) );
163 pObj
->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
165 o3tl::unsafe_downcast
< SdrObjCustomShape
* >( pObj
)->MergeDefaultAttributes( &m_aCustomShapeType
);
171 void DrawCommandDispatch::setLineEnds( SfxItemSet
& rAttr
)
173 if ( m_nFeatureId
== COMMAND_ID_LINE_ARROW_END
&& m_pChartController
)
175 DrawModelWrapper
* pDrawModelWrapper
= m_pChartController
->GetDrawModelWrapper();
176 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
177 if ( pDrawModelWrapper
&& pDrawViewWrapper
)
179 ::basegfx::B2DPolyPolygon
aArrow( getPolygon( RID_SVXSTR_ARROW
, pDrawModelWrapper
->getSdrModel() ) );
180 if ( !aArrow
.count() )
182 ::basegfx::B2DPolygon aNewArrow
;
183 aNewArrow
.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
184 aNewArrow
.append( ::basegfx::B2DPoint( 0.0, 30.0) );
185 aNewArrow
.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
186 aNewArrow
.setClosed( true );
187 aArrow
.append( aNewArrow
);
190 SfxItemSet
aSet( pDrawViewWrapper
->GetModel()->GetItemPool() );
191 pDrawViewWrapper
->GetAttributes( aSet
);
193 long nWidth
= 300; // (1/100th mm)
194 if ( aSet
.GetItemState( XATTR_LINEWIDTH
) != SfxItemState::DONTCARE
)
196 long nValue
= aSet
.Get( XATTR_LINEWIDTH
).GetValue();
203 rAttr
.Put( XLineEndItem( SvxResId( RID_SVXSTR_ARROW
), aArrow
) );
204 rAttr
.Put( XLineEndWidthItem( nWidth
) );
209 // WeakComponentImplHelperBase
210 void DrawCommandDispatch::disposing()
215 void DrawCommandDispatch::disposing( const lang::EventObject
& /* Source */ )
219 FeatureState
DrawCommandDispatch::getState( const OUString
& rCommand
)
221 FeatureState aReturn
;
222 aReturn
.bEnabled
= false;
223 aReturn
.aState
<<= false;
225 sal_uInt16 nFeatureId
= 0;
226 OUString aBaseCommand
;
227 OUString aCustomShapeType
;
228 if ( parseCommandURL( rCommand
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
) )
230 switch ( nFeatureId
)
232 case COMMAND_ID_OBJECT_SELECT
:
233 case COMMAND_ID_DRAW_LINE
:
234 case COMMAND_ID_LINE_ARROW_END
:
235 case COMMAND_ID_DRAW_RECT
:
236 case COMMAND_ID_DRAW_ELLIPSE
:
237 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
238 case COMMAND_ID_DRAW_TEXT
:
239 case COMMAND_ID_DRAW_CAPTION
:
240 case COMMAND_ID_DRAWTBX_CS_BASIC
:
241 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
242 case COMMAND_ID_DRAWTBX_CS_ARROW
:
243 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
244 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
245 case COMMAND_ID_DRAWTBX_CS_STAR
:
247 aReturn
.bEnabled
= true;
248 aReturn
.aState
<<= false;
253 aReturn
.bEnabled
= false;
254 aReturn
.aState
<<= false;
263 void DrawCommandDispatch::execute( const OUString
& rCommand
, const Sequence
< beans::PropertyValue
>& rArgs
)
265 ChartDrawMode eDrawMode
= CHARTDRAW_SELECT
;
266 SdrObjKind eKind
= OBJ_NONE
;
268 sal_uInt16 nFeatureId
= 0;
269 OUString aBaseCommand
;
270 OUString aCustomShapeType
;
271 if ( parseCommandURL( rCommand
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
) )
273 bool bCreate
= false;
274 m_nFeatureId
= nFeatureId
;
275 m_aCustomShapeType
= aCustomShapeType
;
277 switch ( nFeatureId
)
279 case COMMAND_ID_OBJECT_SELECT
:
281 eDrawMode
= CHARTDRAW_SELECT
;
285 case COMMAND_ID_DRAW_LINE
:
286 case COMMAND_ID_LINE_ARROW_END
:
288 eDrawMode
= CHARTDRAW_INSERT
;
292 case COMMAND_ID_DRAW_RECT
:
294 eDrawMode
= CHARTDRAW_INSERT
;
298 case COMMAND_ID_DRAW_ELLIPSE
:
300 eDrawMode
= CHARTDRAW_INSERT
;
304 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
306 eDrawMode
= CHARTDRAW_INSERT
;
307 eKind
= OBJ_FREELINE
;
310 case COMMAND_ID_DRAW_TEXT
:
312 eDrawMode
= CHARTDRAW_INSERT
;
317 case COMMAND_ID_DRAW_CAPTION
:
319 eDrawMode
= CHARTDRAW_INSERT
;
323 case COMMAND_ID_DRAWTBX_CS_BASIC
:
324 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
325 case COMMAND_ID_DRAWTBX_CS_ARROW
:
326 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
327 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
328 case COMMAND_ID_DRAWTBX_CS_STAR
:
330 eDrawMode
= CHARTDRAW_INSERT
;
331 eKind
= OBJ_CUSTOMSHAPE
;
336 eDrawMode
= CHARTDRAW_SELECT
;
342 if ( m_pChartController
)
344 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
345 if ( pDrawViewWrapper
)
347 SolarMutexGuard aGuard
;
348 m_pChartController
->setDrawMode( eDrawMode
);
349 setInsertObj( sal::static_int_cast
< sal_uInt16
>( eKind
) );
352 pDrawViewWrapper
->SetCreateMode();
355 const OUString
sKeyModifier( "KeyModifier" );
356 const beans::PropertyValue
* pIter
= rArgs
.getConstArray();
357 const beans::PropertyValue
* pEnd
= pIter
+ rArgs
.getLength();
358 const beans::PropertyValue
* pKeyModifier
= std::find_if(pIter
, pEnd
,
359 [&sKeyModifier
](const beans::PropertyValue
& lhs
)
360 {return lhs
.Name
== sKeyModifier
;} );
361 sal_Int16 nKeyModifier
= 0;
362 if ( pKeyModifier
!= pEnd
&& ( pKeyModifier
->Value
>>= nKeyModifier
) && nKeyModifier
== KEY_MOD1
)
364 if ( eDrawMode
== CHARTDRAW_INSERT
)
366 SdrObject
* pObj
= createDefaultObject( nFeatureId
);
369 SdrPageView
* pPageView
= pDrawViewWrapper
->GetSdrPageView();
370 if (pDrawViewWrapper
->InsertObjectAtView(pObj
, *pPageView
))
371 m_pChartController
->SetAndApplySelection(Reference
<drawing::XShape
>(pObj
->getUnoShape(), uno::UNO_QUERY
));
372 if ( nFeatureId
== COMMAND_ID_DRAW_TEXT
)
374 m_pChartController
->StartTextEdit();
384 void DrawCommandDispatch::describeSupportedFeatures()
386 implDescribeSupportedFeature( ".uno:SelectObject", COMMAND_ID_OBJECT_SELECT
, CommandGroup::INSERT
);
387 implDescribeSupportedFeature( ".uno:Line", COMMAND_ID_DRAW_LINE
, CommandGroup::INSERT
);
388 implDescribeSupportedFeature( ".uno:LineArrowEnd", COMMAND_ID_LINE_ARROW_END
, CommandGroup::INSERT
);
389 implDescribeSupportedFeature( ".uno:Rect", COMMAND_ID_DRAW_RECT
, CommandGroup::INSERT
);
390 implDescribeSupportedFeature( ".uno:Ellipse", COMMAND_ID_DRAW_ELLIPSE
, CommandGroup::INSERT
);
391 implDescribeSupportedFeature( ".uno:Freeline_Unfilled", COMMAND_ID_DRAW_FREELINE_NOFILL
, CommandGroup::INSERT
);
392 implDescribeSupportedFeature( ".uno:DrawText", COMMAND_ID_DRAW_TEXT
, CommandGroup::INSERT
);
393 implDescribeSupportedFeature( ".uno:DrawCaption", COMMAND_ID_DRAW_CAPTION
, CommandGroup::INSERT
);
394 implDescribeSupportedFeature( ".uno:BasicShapes", COMMAND_ID_DRAWTBX_CS_BASIC
, CommandGroup::INSERT
);
395 implDescribeSupportedFeature( ".uno:SymbolShapes", COMMAND_ID_DRAWTBX_CS_SYMBOL
, CommandGroup::INSERT
);
396 implDescribeSupportedFeature( ".uno:ArrowShapes", COMMAND_ID_DRAWTBX_CS_ARROW
, CommandGroup::INSERT
);
397 implDescribeSupportedFeature( ".uno:FlowChartShapes", COMMAND_ID_DRAWTBX_CS_FLOWCHART
, CommandGroup::INSERT
);
398 implDescribeSupportedFeature( ".uno:CalloutShapes", COMMAND_ID_DRAWTBX_CS_CALLOUT
, CommandGroup::INSERT
);
399 implDescribeSupportedFeature( ".uno:StarShapes", COMMAND_ID_DRAWTBX_CS_STAR
, CommandGroup::INSERT
);
402 void DrawCommandDispatch::setInsertObj( sal_uInt16 eObj
)
404 DrawViewWrapper
* pDrawViewWrapper
= ( m_pChartController
? m_pChartController
->GetDrawViewWrapper() : nullptr );
405 if ( pDrawViewWrapper
)
407 pDrawViewWrapper
->SetCurrentObj( eObj
/*, Inventor */);
411 SdrObject
* DrawCommandDispatch::createDefaultObject( const sal_uInt16 nID
)
413 SdrObject
* pObj
= nullptr;
414 DrawViewWrapper
* pDrawViewWrapper
= ( m_pChartController
? m_pChartController
->GetDrawViewWrapper() : nullptr );
415 DrawModelWrapper
* pDrawModelWrapper
= ( m_pChartController
? m_pChartController
->GetDrawModelWrapper() : nullptr );
417 if ( pDrawViewWrapper
&& pDrawModelWrapper
)
419 Reference
< drawing::XDrawPage
> xDrawPage( pDrawModelWrapper
->getMainDrawPage() );
420 SdrPage
* pPage
= GetSdrPageFromXDrawPage( xDrawPage
);
423 SolarMutexGuard aGuard
;
425 pObj
= SdrObjFactory::MakeNewObject(
426 pDrawModelWrapper
->getSdrModel(),
427 pDrawViewWrapper
->GetCurrentObjInventor(),
428 pDrawViewWrapper
->GetCurrentObjIdentifier());
432 Size
aObjectSize( 4000, 2500 );
433 tools::Rectangle
aPageRect( tools::Rectangle( Point( 0, 0 ), pPage
->GetSize() ) );
434 Point aObjectPos
= aPageRect
.Center();
435 aObjectPos
.AdjustX( -(aObjectSize
.Width() / 2) );
436 aObjectPos
.AdjustY( -(aObjectSize
.Height() / 2) );
437 tools::Rectangle
aRect( aObjectPos
, aObjectSize
);
441 case COMMAND_ID_DRAW_LINE
:
442 case COMMAND_ID_LINE_ARROW_END
:
444 if ( auto const pathObj
= dynamic_cast<SdrPathObj
*>( pObj
) )
446 Point aStart
= aRect
.TopLeft();
447 Point aEnd
= aRect
.BottomRight();
448 sal_Int32
nYMiddle( ( aRect
.Top() + aRect
.Bottom() ) / 2 );
449 basegfx::B2DPolygon aPoly
;
450 aPoly
.append( basegfx::B2DPoint( aStart
.X(), nYMiddle
) );
451 aPoly
.append( basegfx::B2DPoint( aEnd
.X(), nYMiddle
) );
452 pathObj
->SetPathPoly(basegfx::B2DPolyPolygon(aPoly
));
453 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
455 pObj
->SetMergedItemSet( aSet
);
459 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
461 if ( auto const pathObj
= dynamic_cast<SdrPathObj
*>( pObj
) )
463 basegfx::B2DPolygon aInnerPoly
;
464 aInnerPoly
.append( basegfx::B2DPoint( aRect
.Left(), aRect
.Bottom() ) );
465 aInnerPoly
.appendBezierSegment(
466 basegfx::B2DPoint( aRect
.Left(), aRect
.Top() ),
467 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Top() ),
468 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Center().Y() ) );
469 aInnerPoly
.appendBezierSegment(
470 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Bottom() ),
471 basegfx::B2DPoint( aRect
.Right(), aRect
.Bottom() ),
472 basegfx::B2DPoint( aRect
.Right(), aRect
.Top() ) );
473 basegfx::B2DPolyPolygon aPoly
;
474 aPoly
.append( aInnerPoly
);
475 pathObj
->SetPathPoly(aPoly
);
479 case COMMAND_ID_DRAW_TEXT
:
480 case COMMAND_ID_DRAW_TEXT_VERTICAL
:
482 if ( SdrTextObj
* pTextObj
= dynamic_cast<SdrTextObj
*>( pObj
) )
484 pTextObj
->SetLogicRect( aRect
);
485 bool bVertical
= ( nID
== COMMAND_ID_DRAW_TEXT_VERTICAL
);
486 pTextObj
->SetVerticalWriting( bVertical
);
489 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
490 aSet
.Put( makeSdrTextAutoGrowWidthItem( true ) );
491 aSet
.Put( makeSdrTextAutoGrowHeightItem( false ) );
492 aSet
.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_TOP
) );
493 aSet
.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT
) );
494 pTextObj
->SetMergedItemSet( aSet
);
499 case COMMAND_ID_DRAW_CAPTION
:
500 case COMMAND_ID_DRAW_CAPTION_VERTICAL
:
502 if ( SdrCaptionObj
* pCaptionObj
= dynamic_cast<SdrCaptionObj
*>( pObj
) )
504 bool bIsVertical( nID
== COMMAND_ID_DRAW_CAPTION_VERTICAL
);
505 pCaptionObj
->SetVerticalWriting( bIsVertical
);
508 SfxItemSet
aSet( pObj
->GetMergedItemSet() );
509 aSet
.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER
) );
510 aSet
.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT
) );
511 pObj
->SetMergedItemSet( aSet
);
513 pCaptionObj
->SetLogicRect( aRect
);
514 pCaptionObj
->SetTailPos(
515 aRect
.TopLeft() - Point( aRect
.GetWidth() / 2, aRect
.GetHeight() / 2 ) );
521 pObj
->SetLogicRect( aRect
);
522 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
523 setAttributes( pObj
);
524 pObj
->SetMergedItemSet( aSet
);
535 bool DrawCommandDispatch::parseCommandURL( const OUString
& rCommandURL
, sal_uInt16
* pnFeatureId
,
536 OUString
* pBaseCommand
, OUString
* pCustomShapeType
)
539 sal_uInt16 nFeatureId
= 0;
540 OUString aBaseCommand
;
543 sal_Int32 nIndex
= 1;
544 OUString aToken
= rCommandURL
.getToken( 0, '.', nIndex
);
545 if ( nIndex
== -1 || aToken
.isEmpty() )
547 aBaseCommand
= rCommandURL
;
548 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( aBaseCommand
);
549 if ( aIter
!= m_aSupportedFeatures
.end() )
551 nFeatureId
= aIter
->second
.nFeatureId
;
553 switch ( nFeatureId
)
555 case COMMAND_ID_DRAWTBX_CS_BASIC
:
560 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
565 case COMMAND_ID_DRAWTBX_CS_ARROW
:
567 aType
= "left-right-arrow";
570 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
572 aType
= "flowchart-internal-storage";
575 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
577 aType
= "round-rectangular-callout";
580 case COMMAND_ID_DRAWTBX_CS_STAR
:
598 aBaseCommand
= rCommandURL
.copy( 0, nIndex
- 1 );
599 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( aBaseCommand
);
600 if ( aIter
!= m_aSupportedFeatures
.end() )
602 nFeatureId
= aIter
->second
.nFeatureId
;
603 aType
= rCommandURL
.getToken( 0, '.', nIndex
);
611 *pnFeatureId
= nFeatureId
;
612 *pBaseCommand
= aBaseCommand
;
613 *pCustomShapeType
= aType
;
620 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */