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 <sal/config.h>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
24 #include <com/sun/star/lang/NoSupportException.hpp>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <vcl/svapp.hxx>
27 #include <svl/itempool.hxx>
28 #include <svtools/unoevent.hxx>
29 #include <comphelper/sequence.hxx>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <tools/debug.hxx>
33 #include <cppuhelper/implbase.hxx>
34 #include <svx/unofill.hxx>
35 #include <editeng/unonrule.hxx>
36 #include <svtools/unoimap.hxx>
37 #include <sfx2/event.hxx>
38 #include <svx/fmdpage.hxx>
39 #include <svx/fmmodel.hxx>
40 #include <svx/fmpage.hxx>
41 #include <svx/unoapi.hxx>
43 #include <svx/svdmodel.hxx>
44 #include <svx/unoprov.hxx>
45 #include <svx/unopage.hxx>
46 #include <editeng/unofield.hxx>
47 #include <svx/unomod.hxx>
48 #include <svx/unomodel.hxx>
49 #include <svx/svdobj.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/SvxXTextColumns.hxx>
52 #include <svx/unoshape.hxx>
53 #include <svx/xmlgrhlp.hxx>
55 #include <com/sun/star/text/textfield/Type.hpp>
59 using namespace ::com::sun::star
;
63 #define QUERYINT( xint ) \
64 if( rType == cppu::UnoType<xint>::get() ) \
65 aAny <<= uno::Reference< xint >(this)
69 class SvxUnoDrawPagesAccess
: public ::cppu::WeakImplHelper
< css::drawing::XDrawPages
, css::lang::XServiceInfo
>
72 SvxUnoDrawingModel
& mrModel
;
75 explicit SvxUnoDrawPagesAccess( SvxUnoDrawingModel
& rMyModel
) noexcept
;
78 virtual css::uno::Reference
< css::drawing::XDrawPage
> SAL_CALL
insertNewByIndex( sal_Int32 nIndex
) override
;
79 virtual void SAL_CALL
remove( const css::uno::Reference
< css::drawing::XDrawPage
>& xPage
) override
;
82 virtual sal_Int32 SAL_CALL
getCount() override
;
83 virtual css::uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) override
;
86 virtual css::uno::Type SAL_CALL
getElementType() override
;
87 virtual sal_Bool SAL_CALL
hasElements() override
;
90 virtual OUString SAL_CALL
getImplementationName( ) override
;
91 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
92 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
96 static const SvEventDescription
* ImplGetSupportedMacroItems()
98 static const SvEventDescription aMacroDescriptionsImpl
[] =
100 { SvMacroItemId::OnMouseOver
, "OnMouseOver" },
101 { SvMacroItemId::OnMouseOut
, "OnMouseOut" },
102 { SvMacroItemId::NONE
, nullptr }
105 return aMacroDescriptionsImpl
;
110 /** fills the given EventObject from the given SdrHint.
112 true if the SdrHint could be translated to an EventObject<br>
115 bool SvxUnoDrawMSFactory::createEvent( const SdrModel
* pDoc
, const SdrHint
* pSdrHint
, css::document::EventObject
& aEvent
)
117 const SdrObject
* pObj
= nullptr;
118 const SdrPage
* pPage
= nullptr;
120 switch( pSdrHint
->GetKind() )
122 // case SdrHintKind::LayerChange: // layer definition changed
123 // case SdrHintKind::LayerOrderChange: // layer order changed (Insert/Remove/ChangePos)
124 // case HINT_LAYERSETCHG: // layer set changed
125 // case HINT_LAYERSETORDERCHG: // layer set order changed (Insert/Remove/ChangePos)
127 // case HINT_PAGECHG: // page changed
128 // aEvent.EventName = "PageModified";
129 // pPage = pSdrHint->GetPage();
131 case SdrHintKind::PageOrderChange
: // draw or master page order changed (Insert/Remove/ChangePos)
132 aEvent
.EventName
= "PageOrderModified";
133 pPage
= pSdrHint
->GetPage();
135 case SdrHintKind::ObjectChange
: // object changed
136 aEvent
.EventName
= "ShapeModified";
137 pObj
= pSdrHint
->GetObject();
139 case SdrHintKind::ObjectInserted
: // add new draw object
140 aEvent
.EventName
= "ShapeInserted";
141 pObj
= pSdrHint
->GetObject();
143 case SdrHintKind::ObjectRemoved
: // removed draw object from list
144 aEvent
.EventName
= "ShapeRemoved";
145 pObj
= pSdrHint
->GetObject();
147 // SdrHintKind::DefaultTabChange, // default tab width changed
148 // SdrHintKind::SwitchToPage, // #94278# UNDO/REDO at an object evtl. on another page
149 // HINT_OBJLISTCLEAR // Is called before an SdrObjList will be cleared
155 aEvent
.Source
= const_cast<SdrObject
*>(pObj
)->getUnoShape();
157 aEvent
.Source
= const_cast<SdrPage
*>(pPage
)->getUnoPage();
159 aEvent
.Source
= const_cast<SdrModel
*>(pDoc
)->getUnoModel();
166 css::uno::Reference
<css::uno::XInterface
> create(
167 OUString
const & rServiceSpecifier
, OUString
const & referer
)
169 if( rServiceSpecifier
.startsWith("com.sun.star.drawing.") )
171 sal_uInt32 nType
= UHashMap::getId( rServiceSpecifier
);
172 if( nType
!= UHASHMAP_NOTFOUND
)
174 sal_uInt16 nT
= static_cast<sal_uInt16
>(nType
& ~E3D_INVENTOR_FLAG
);
175 SdrInventor nI
= (nType
& E3D_INVENTOR_FLAG
) ? SdrInventor::E3d
: SdrInventor::Default
;
177 return uno::Reference
< uno::XInterface
>( static_cast<drawing::XShape
*>(SvxDrawPage::CreateShapeByTypeAndInventor( nT
, nI
, nullptr, nullptr, referer
).get()) );
180 else if (rServiceSpecifier
== "com.sun.star.document.ImportGraphicStorageHandler")
182 rtl::Reference
<SvXMLGraphicHelper
> pGraphicHelper
= SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode::Read
);
183 uno::Reference
< uno::XInterface
> xRet( static_cast< ::cppu::OWeakObject
* >( pGraphicHelper
.get() ) );
186 else if (rServiceSpecifier
== "com.sun.star.text.TextColumns")
188 return SvxXTextColumns_createInstance();
191 uno::Reference
< uno::XInterface
> xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier
) );
193 throw lang::ServiceNotRegisteredException("unknown service: " + rServiceSpecifier
);
200 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstance( const OUString
& rServiceSpecifier
)
202 return create(rServiceSpecifier
, "");
205 uno::Reference
< uno::XInterface
> SvxUnoDrawMSFactory::createTextField( const OUString
& ServiceSpecifier
)
207 return SvxUnoTextCreateTextField( ServiceSpecifier
);
210 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstanceWithArguments( const OUString
& ServiceSpecifier
, const uno::Sequence
< css::uno::Any
>& Arguments
)
213 if ((ServiceSpecifier
== "com.sun.star.drawing.GraphicObjectShape"
214 || ServiceSpecifier
== "com.sun.star.drawing.MediaShape")
215 && Arguments
.getLength() == 1 && (Arguments
[0] >>= arg
))
217 return create(ServiceSpecifier
, arg
);
219 throw lang::NoSupportException();
222 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawMSFactory::getAvailableServiceNames()
224 return UHashMap::getServiceNames();
227 SdrModel
& SvxUnoDrawingModel::getSdrModelFromUnoModel() const
229 OSL_ENSURE(mpDoc
, "No SdrModel in UnoDrawingModel, should not happen");
233 SvxUnoDrawingModel::SvxUnoDrawingModel(SdrModel
* pDoc
) noexcept
234 : SfxBaseModel(nullptr),
236 css::drawing::XDrawPagesSupplier(),
237 css::lang::XServiceInfo(),
238 css::ucb::XAnyCompareFactory(),
245 mxTransGradientTable(),
251 SvxUnoDrawingModel::~SvxUnoDrawingModel() noexcept
255 uno::Any SAL_CALL
SvxUnoDrawingModel::queryInterface( const uno::Type
& rType
)
259 QUERYINT(lang::XServiceInfo
);
260 else QUERYINT(lang::XMultiServiceFactory
);
261 else QUERYINT(drawing::XDrawPagesSupplier
);
262 else QUERYINT(css::ucb::XAnyCompareFactory
);
264 return SfxBaseModel::queryInterface( rType
);
270 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoDrawingModel::getTypes( )
272 if( !maTypeSequence
.hasElements() )
274 maTypeSequence
= comphelper::concatSequences( SfxBaseModel::getTypes(),
276 cppu::UnoType
<lang::XServiceInfo
>::get(),
277 cppu::UnoType
<lang::XMultiServiceFactory
>::get(),
278 cppu::UnoType
<drawing::XDrawPagesSupplier
>::get(),
279 cppu::UnoType
<css::ucb::XAnyCompareFactory
>::get() });
281 return maTypeSequence
;
284 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoDrawingModel::getImplementationId( )
286 return css::uno::Sequence
<sal_Int8
>();
289 void SAL_CALL
SvxUnoDrawingModel::lockControllers( )
292 mpDoc
->setLock(true);
295 void SAL_CALL
SvxUnoDrawingModel::unlockControllers( )
297 if( mpDoc
&& mpDoc
->isLocked() )
299 mpDoc
->setLock(false);
303 sal_Bool SAL_CALL
SvxUnoDrawingModel::hasControllersLocked( )
305 return mpDoc
&& mpDoc
->isLocked();
308 // XDrawPagesSupplier
309 uno::Reference
< drawing::XDrawPages
> SAL_CALL
SvxUnoDrawingModel::getDrawPages()
311 ::SolarMutexGuard aGuard
;
313 uno::Reference
< drawing::XDrawPages
> xDrawPages( mxDrawPagesAccess
);
315 if( !xDrawPages
.is() )
316 mxDrawPagesAccess
= xDrawPages
= new SvxUnoDrawPagesAccess(*this);
321 // XMultiServiceFactory ( SvxFmMSFactory )
322 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawingModel::createInstance( const OUString
& aServiceSpecifier
)
324 ::SolarMutexGuard aGuard
;
326 if( aServiceSpecifier
== "com.sun.star.drawing.DashTable" )
328 if( !mxDashTable
.is() )
329 mxDashTable
= SvxUnoDashTable_createInstance( mpDoc
);
332 if( aServiceSpecifier
== "com.sun.star.drawing.GradientTable" )
334 if( !mxGradientTable
.is() )
335 mxGradientTable
= SvxUnoGradientTable_createInstance( mpDoc
);
336 return mxGradientTable
;
338 if( aServiceSpecifier
== "com.sun.star.drawing.HatchTable" )
340 if( !mxHatchTable
.is() )
341 mxHatchTable
= SvxUnoHatchTable_createInstance( mpDoc
);
344 if( aServiceSpecifier
== "com.sun.star.drawing.BitmapTable" )
346 if( !mxBitmapTable
.is() )
347 mxBitmapTable
= SvxUnoBitmapTable_createInstance( mpDoc
);
348 return mxBitmapTable
;
350 if( aServiceSpecifier
== "com.sun.star.drawing.TransparencyGradientTable" )
352 if( !mxTransGradientTable
.is() )
353 mxTransGradientTable
= SvxUnoTransGradientTable_createInstance( mpDoc
);
354 return mxTransGradientTable
;
356 if( aServiceSpecifier
== "com.sun.star.drawing.MarkerTable" )
358 if( !mxMarkerTable
.is() )
359 mxMarkerTable
= SvxUnoMarkerTable_createInstance( mpDoc
);
360 return mxMarkerTable
;
362 if( aServiceSpecifier
== "com.sun.star.text.NumberingRules" )
364 return uno::Reference
< uno::XInterface
>( SvxCreateNumRule( mpDoc
), uno::UNO_QUERY
);
367 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapRectangleObject" )
369 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
372 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapCircleObject" )
374 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
377 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapPolygonObject" )
379 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
382 if( aServiceSpecifier
== "com.sun.star.text.TextField.DateTime" )
384 return static_cast<cppu::OWeakObject
*>(new SvxUnoTextField(text::textfield::Type::DATE
));
387 uno::Reference
< uno::XInterface
> xRet
;
389 static const OUStringLiteral
aPackagePrefix( u
"com.sun.star.presentation." );
390 if( aServiceSpecifier
.startsWith( aPackagePrefix
) )
392 SvxShape
* pShape
= nullptr;
394 sal_uInt16 nType
= OBJ_TEXT
;
395 OUString aTypeName
= aServiceSpecifier
.copy( aPackagePrefix
.getLength() );
396 // create a shape wrapper
397 if( aTypeName
.startsWith("TitleTextShape") )
401 else if( aTypeName
.startsWith( "OutlinerShape" ) )
405 else if( aTypeName
.startsWith( "SubtitleShape" ) )
409 else if( aTypeName
.startsWith( "GraphicObjectShape" ) )
413 else if( aTypeName
.startsWith( "PageShape" ) )
417 else if( aTypeName
.startsWith( "OLE2Shape" ) )
421 else if( aTypeName
.startsWith( "ChartShape" ) )
425 else if( aTypeName
.startsWith( "OrgChartShape" ) )
429 else if( aTypeName
.startsWith( "NotesShape" ) )
433 else if( aTypeName
.startsWith( "HandoutShape" ) )
437 else if( aTypeName
.startsWith( "FooterShape" ) )
441 else if( aTypeName
.startsWith( "HeaderShape" ) )
445 else if( aTypeName
.startsWith( "SlideNumberShape" ) )
449 else if( aTypeName
.startsWith( "DateTimeShape" ) )
453 else if( aTypeName
.startsWith( "TableShape" ) )
459 throw lang::ServiceNotRegisteredException();
462 // create the API wrapper
463 rtl::Reference
<SvxShape
> xNewShape
= CreateSvxShapeByTypeAndInventor( nType
, SdrInventor::Default
, "" );
464 pShape
= xNewShape
.get();
468 pShape
->SetShapeType(aServiceSpecifier
);
470 xRet
= static_cast<uno::XWeak
*>(pShape
);
474 xRet
= SvxFmMSFactory::createInstance( aServiceSpecifier
);
480 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getAvailableServiceNames()
482 const uno::Sequence
< OUString
> aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
484 uno::Sequence
< OUString
> aSNS( 21 );
488 aSNS
[i
++] = "com.sun.star.drawing.DashTable";
489 aSNS
[i
++] = "com.sun.star.drawing.GradientTable";
490 aSNS
[i
++] = "com.sun.star.drawing.HatchTable";
491 aSNS
[i
++] = "com.sun.star.drawing.BitmapTable";
492 aSNS
[i
++] = "com.sun.star.drawing.TransparencyGradientTable";
493 aSNS
[i
++] = "com.sun.star.drawing.MarkerTable";
494 aSNS
[i
++] = "com.sun.star.text.NumberingRules";
495 aSNS
[i
++] = "com.sun.star.image.ImageMapRectangleObject";
496 aSNS
[i
++] = "com.sun.star.image.ImageMapCircleObject";
497 aSNS
[i
++] = "com.sun.star.image.ImageMapPolygonObject";
499 aSNS
[i
++] = "com.sun.star.presentation.TitleTextShape";
500 aSNS
[i
++] = "com.sun.star.presentation.OutlinerShape";
501 aSNS
[i
++] = "com.sun.star.presentation.SubtitleShape";
502 aSNS
[i
++] = "com.sun.star.presentation.GraphicObjectShape";
503 aSNS
[i
++] = "com.sun.star.presentation.ChartShape";
504 aSNS
[i
++] = "com.sun.star.presentation.PageShape";
505 aSNS
[i
++] = "com.sun.star.presentation.OLE2Shape";
506 aSNS
[i
++] = "com.sun.star.presentation.TableShape";
507 aSNS
[i
++] = "com.sun.star.presentation.OrgChartShape";
508 aSNS
[i
++] = "com.sun.star.presentation.NotesShape";
509 aSNS
[i
++] = "com.sun.star.presentation.HandoutShape";
511 DBG_ASSERT( i
== aSNS
.getLength(), "Sequence overrun!" );
513 return comphelper::concatSequences( aSNS_ORG
, aSNS
);
516 // lang::XServiceInfo
517 OUString SAL_CALL
SvxUnoDrawingModel::getImplementationName()
519 return "SvxUnoDrawingModel";
522 sal_Bool SAL_CALL
SvxUnoDrawingModel::supportsService( const OUString
& ServiceName
)
524 return cppu::supportsService( this, ServiceName
);
527 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getSupportedServiceNames()
529 return { "com.sun.star.drawing.DrawingDocument" };
532 // XAnyCompareFactory
533 uno::Reference
< css::ucb::XAnyCompare
> SAL_CALL
SvxUnoDrawingModel::createAnyCompareByName( const OUString
& )
535 return SvxCreateNumRuleCompare();
538 SvxUnoDrawPagesAccess::SvxUnoDrawPagesAccess( SvxUnoDrawingModel
& rMyModel
) noexcept
544 sal_Int32 SAL_CALL
SvxUnoDrawPagesAccess::getCount()
546 ::SolarMutexGuard aGuard
;
548 sal_Int32 nCount
= 0;
551 nCount
= mrModel
.mpDoc
->GetPageCount();
556 uno::Any SAL_CALL
SvxUnoDrawPagesAccess::getByIndex( sal_Int32 Index
)
558 ::SolarMutexGuard aGuard
;
564 if( (Index
< 0) || (Index
>= mrModel
.mpDoc
->GetPageCount() ) )
565 throw lang::IndexOutOfBoundsException();
567 SdrPage
* pPage
= mrModel
.mpDoc
->GetPage( static_cast<sal_uInt16
>(Index
) );
570 uno::Reference
< uno::XInterface
> xPage( pPage
->mxUnoPage
);
574 if( dynamic_cast<FmFormModel
*>( mrModel
.mpDoc
) )
575 xPage
= static_cast<drawing::XDrawPage
*>(new SvxFmDrawPage( pPage
));
577 xPage
= static_cast<drawing::XDrawPage
*>(new SvxDrawPage( pPage
));
579 pPage
->mxUnoPage
= xPage
;
589 uno::Type SAL_CALL
SvxUnoDrawPagesAccess::getElementType()
591 return cppu::UnoType
<drawing::XDrawPage
>::get();
594 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::hasElements()
596 return getCount() > 0;
601 // create a new page with model at given position
602 // and return corresponding SdDrawPage
603 uno::Reference
< drawing::XDrawPage
> SAL_CALL
SvxUnoDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex
)
605 ::SolarMutexGuard aGuard
;
607 uno::Reference
< drawing::XDrawPage
> xDrawPage
;
611 rtl::Reference
<SdrPage
> pPage
;
613 if( auto pFormModel
= dynamic_cast<FmFormModel
*>( mrModel
.mpDoc
) )
614 pPage
= new FmFormPage(*pFormModel
);
616 pPage
= new SdrPage(*mrModel
.mpDoc
);
618 mrModel
.mpDoc
->InsertPage( pPage
.get(), static_cast<sal_uInt16
>(nIndex
) );
619 xDrawPage
.set( pPage
->getUnoPage(), uno::UNO_QUERY
);
625 void SAL_CALL
SvxUnoDrawPagesAccess::remove( const uno::Reference
< drawing::XDrawPage
>& xPage
)
627 ::SolarMutexGuard aGuard
;
629 sal_uInt16 nPageCount
= mrModel
.mpDoc
->GetPageCount();
630 if( nPageCount
<= 1 )
633 // get pPage from xPage and get Id (nPos)
634 SvxDrawPage
* pSvxPage
= comphelper::getUnoTunnelImplementation
<SvxDrawPage
>( xPage
);
637 SdrPage
* pPage
= pSvxPage
->GetSdrPage();
640 sal_uInt16 nPage
= pPage
->GetPageNum();
641 mrModel
.mpDoc
->DeletePage( nPage
);
648 OUString SAL_CALL
SvxUnoDrawPagesAccess::getImplementationName( )
650 return "SvxUnoDrawPagesAccess";
653 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::supportsService( const OUString
& ServiceName
)
655 return cppu::supportsService(this, ServiceName
);
658 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawPagesAccess::getSupportedServiceNames( )
660 return { "com.sun.star.drawing.DrawPages" };
663 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule(SdrModel
* pModel
)
665 const SvxNumRule
* pDefaultRule
= nullptr;
668 const SvxNumBulletItem
* pItem
= pModel
->GetItemPool().GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET
);
671 pDefaultRule
= &pItem
->GetNumRule();
677 return SvxCreateNumRule( *pDefaultRule
);
681 SvxNumRule
aTempRule( SvxNumRuleFlags::NONE
, 10, false );
682 return SvxCreateNumRule( aTempRule
);
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */