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 <o3tl/string_view.hxx>
31 #include <cppuhelper/supportsservice.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 std::optional
<SdrObjKind
> nType
= UHashMap::getId( rServiceSpecifier
);
174 SdrInventor nI
= IsInventorE3D(*nType
) ? SdrInventor::E3d
: SdrInventor::Default
;
176 return uno::Reference
< uno::XInterface
>( static_cast<drawing::XShape
*>(SvxDrawPage::CreateShapeByTypeAndInventor( *nType
, nI
, nullptr, nullptr, referer
).get()) );
179 else if (rServiceSpecifier
== "com.sun.star.document.ImportGraphicStorageHandler")
181 rtl::Reference
<SvXMLGraphicHelper
> pGraphicHelper
= SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode::Read
);
182 uno::Reference
< uno::XInterface
> xRet( static_cast< ::cppu::OWeakObject
* >( pGraphicHelper
.get() ) );
185 else if (rServiceSpecifier
== "com.sun.star.text.TextColumns")
187 return SvxXTextColumns_createInstance();
190 uno::Reference
< uno::XInterface
> xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier
) );
192 throw lang::ServiceNotRegisteredException("unknown service: " + rServiceSpecifier
);
199 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstance( const OUString
& rServiceSpecifier
)
201 return create(rServiceSpecifier
, "");
204 uno::Reference
< uno::XInterface
> SvxUnoDrawMSFactory::createTextField( std::u16string_view ServiceSpecifier
)
206 return SvxUnoTextCreateTextField( ServiceSpecifier
);
209 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstanceWithArguments( const OUString
& ServiceSpecifier
, const uno::Sequence
< css::uno::Any
>& Arguments
)
212 if ((ServiceSpecifier
== "com.sun.star.drawing.GraphicObjectShape"
213 || ServiceSpecifier
== "com.sun.star.drawing.AppletShape"
214 || ServiceSpecifier
== "com.sun.star.drawing.FrameShape"
215 || ServiceSpecifier
== "com.sun.star.drawing.OLE2Shape"
216 || ServiceSpecifier
== "com.sun.star.drawing.MediaShape"
217 || ServiceSpecifier
== "com.sun.star.drawing.PluginShape")
218 && Arguments
.getLength() == 1 && (Arguments
[0] >>= arg
))
220 return create(ServiceSpecifier
, arg
);
222 throw lang::NoSupportException();
225 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawMSFactory::getAvailableServiceNames()
227 return UHashMap::getServiceNames();
230 SdrModel
& SvxUnoDrawingModel::getSdrModelFromUnoModel() const
232 OSL_ENSURE(mpDoc
, "No SdrModel in UnoDrawingModel, should not happen");
236 SvxUnoDrawingModel::SvxUnoDrawingModel(SdrModel
* pDoc
) noexcept
237 : SfxBaseModel(nullptr),
242 SvxUnoDrawingModel::~SvxUnoDrawingModel() noexcept
246 uno::Any SAL_CALL
SvxUnoDrawingModel::queryInterface( const uno::Type
& rType
)
250 QUERYINT(lang::XServiceInfo
);
251 else QUERYINT(lang::XMultiServiceFactory
);
252 else QUERYINT(drawing::XDrawPagesSupplier
);
253 else QUERYINT(css::ucb::XAnyCompareFactory
);
255 return SfxBaseModel::queryInterface( rType
);
261 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoDrawingModel::getTypes( )
263 if( !maTypeSequence
.hasElements() )
265 maTypeSequence
= comphelper::concatSequences( SfxBaseModel::getTypes(),
267 cppu::UnoType
<lang::XServiceInfo
>::get(),
268 cppu::UnoType
<lang::XMultiServiceFactory
>::get(),
269 cppu::UnoType
<drawing::XDrawPagesSupplier
>::get(),
270 cppu::UnoType
<css::ucb::XAnyCompareFactory
>::get() });
272 return maTypeSequence
;
275 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoDrawingModel::getImplementationId( )
277 return css::uno::Sequence
<sal_Int8
>();
280 void SAL_CALL
SvxUnoDrawingModel::lockControllers( )
283 mpDoc
->setLock(true);
286 void SAL_CALL
SvxUnoDrawingModel::unlockControllers( )
288 if( mpDoc
&& mpDoc
->isLocked() )
290 mpDoc
->setLock(false);
294 sal_Bool SAL_CALL
SvxUnoDrawingModel::hasControllersLocked( )
296 return mpDoc
&& mpDoc
->isLocked();
299 // XDrawPagesSupplier
300 uno::Reference
< drawing::XDrawPages
> SAL_CALL
SvxUnoDrawingModel::getDrawPages()
302 ::SolarMutexGuard aGuard
;
304 uno::Reference
< drawing::XDrawPages
> xDrawPages( mxDrawPagesAccess
);
306 if( !xDrawPages
.is() )
307 mxDrawPagesAccess
= xDrawPages
= new SvxUnoDrawPagesAccess(*this);
312 // XMultiServiceFactory ( SvxFmMSFactory )
313 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawingModel::createInstance( const OUString
& aServiceSpecifier
)
315 ::SolarMutexGuard aGuard
;
317 if( aServiceSpecifier
== "com.sun.star.drawing.DashTable" )
319 if( !mxDashTable
.is() )
320 mxDashTable
= SvxUnoDashTable_createInstance( mpDoc
);
323 if( aServiceSpecifier
== "com.sun.star.drawing.GradientTable" )
325 if( !mxGradientTable
.is() )
326 mxGradientTable
= SvxUnoGradientTable_createInstance( mpDoc
);
327 return mxGradientTable
;
329 if( aServiceSpecifier
== "com.sun.star.drawing.HatchTable" )
331 if( !mxHatchTable
.is() )
332 mxHatchTable
= SvxUnoHatchTable_createInstance( mpDoc
);
335 if( aServiceSpecifier
== "com.sun.star.drawing.BitmapTable" )
337 if( !mxBitmapTable
.is() )
338 mxBitmapTable
= SvxUnoBitmapTable_createInstance( mpDoc
);
339 return mxBitmapTable
;
341 if( aServiceSpecifier
== "com.sun.star.drawing.TransparencyGradientTable" )
343 if( !mxTransGradientTable
.is() )
344 mxTransGradientTable
= SvxUnoTransGradientTable_createInstance( mpDoc
);
345 return mxTransGradientTable
;
347 if( aServiceSpecifier
== "com.sun.star.drawing.MarkerTable" )
349 if( !mxMarkerTable
.is() )
350 mxMarkerTable
= SvxUnoMarkerTable_createInstance( mpDoc
);
351 return mxMarkerTable
;
353 if( aServiceSpecifier
== "com.sun.star.text.NumberingRules" )
355 return uno::Reference
< uno::XInterface
>( SvxCreateNumRule( mpDoc
), uno::UNO_QUERY
);
358 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapRectangleObject" )
360 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
363 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapCircleObject" )
365 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
368 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapPolygonObject" )
370 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
373 if( aServiceSpecifier
== "com.sun.star.text.TextField.DateTime" )
375 return static_cast<cppu::OWeakObject
*>(new SvxUnoTextField(text::textfield::Type::DATE
));
378 uno::Reference
< uno::XInterface
> xRet
;
380 static const OUStringLiteral
aPackagePrefix( u
"com.sun.star.presentation." );
381 if( aServiceSpecifier
.startsWith( aPackagePrefix
) )
383 SvxShape
* pShape
= nullptr;
385 SdrObjKind nType
= SdrObjKind::Text
;
386 std::u16string_view aTypeName
= aServiceSpecifier
.subView( aPackagePrefix
.getLength() );
387 // create a shape wrapper
388 if( o3tl::starts_with(aTypeName
, u
"TitleTextShape") )
390 nType
= SdrObjKind::Text
;
392 else if( o3tl::starts_with(aTypeName
, u
"OutlinerShape" ) )
394 nType
= SdrObjKind::Text
;
396 else if( o3tl::starts_with(aTypeName
, u
"SubtitleShape" ) )
398 nType
= SdrObjKind::Text
;
400 else if( o3tl::starts_with(aTypeName
, u
"GraphicObjectShape" ) )
402 nType
= SdrObjKind::Graphic
;
404 else if( o3tl::starts_with(aTypeName
, u
"PageShape" ) )
406 nType
= SdrObjKind::Page
;
408 else if( o3tl::starts_with(aTypeName
, u
"OLE2Shape" ) )
410 nType
= SdrObjKind::OLE2
;
412 else if( o3tl::starts_with(aTypeName
, u
"ChartShape" ) )
414 nType
= SdrObjKind::OLE2
;
416 else if( o3tl::starts_with(aTypeName
, u
"OrgChartShape" ) )
418 nType
= SdrObjKind::OLE2
;
420 else if( o3tl::starts_with(aTypeName
, u
"NotesShape" ) )
422 nType
= SdrObjKind::Text
;
424 else if( o3tl::starts_with(aTypeName
, u
"HandoutShape" ) )
426 nType
= SdrObjKind::Page
;
428 else if( o3tl::starts_with(aTypeName
, u
"FooterShape" ) )
430 nType
= SdrObjKind::Text
;
432 else if( o3tl::starts_with(aTypeName
, u
"HeaderShape" ) )
434 nType
= SdrObjKind::Text
;
436 else if( o3tl::starts_with(aTypeName
, u
"SlideNumberShape" ) )
438 nType
= SdrObjKind::Text
;
440 else if( o3tl::starts_with(aTypeName
, u
"DateTimeShape" ) )
442 nType
= SdrObjKind::Text
;
444 else if( o3tl::starts_with(aTypeName
, u
"TableShape" ) )
446 nType
= SdrObjKind::Table
;
450 throw lang::ServiceNotRegisteredException();
453 // create the API wrapper
454 rtl::Reference
<SvxShape
> xNewShape
= CreateSvxShapeByTypeAndInventor( nType
, SdrInventor::Default
, "" );
455 pShape
= xNewShape
.get();
459 pShape
->SetShapeType(aServiceSpecifier
);
461 xRet
= static_cast<uno::XWeak
*>(pShape
);
465 xRet
= SvxFmMSFactory::createInstance( aServiceSpecifier
);
471 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getAvailableServiceNames()
473 const uno::Sequence
< OUString
> aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
475 uno::Sequence
< OUString
> aSNS
{
476 "com.sun.star.drawing.DashTable",
477 "com.sun.star.drawing.GradientTable",
478 "com.sun.star.drawing.HatchTable",
479 "com.sun.star.drawing.BitmapTable",
480 "com.sun.star.drawing.TransparencyGradientTable",
481 "com.sun.star.drawing.MarkerTable",
482 "com.sun.star.text.NumberingRules",
483 "com.sun.star.image.ImageMapRectangleObject",
484 "com.sun.star.image.ImageMapCircleObject",
485 "com.sun.star.image.ImageMapPolygonObject",
487 "com.sun.star.presentation.TitleTextShape",
488 "com.sun.star.presentation.OutlinerShape",
489 "com.sun.star.presentation.SubtitleShape",
490 "com.sun.star.presentation.GraphicObjectShape",
491 "com.sun.star.presentation.ChartShape",
492 "com.sun.star.presentation.PageShape",
493 "com.sun.star.presentation.OLE2Shape",
494 "com.sun.star.presentation.TableShape",
495 "com.sun.star.presentation.OrgChartShape",
496 "com.sun.star.presentation.NotesShape",
497 "com.sun.star.presentation.HandoutShape"
500 return comphelper::concatSequences( aSNS_ORG
, aSNS
);
503 // lang::XServiceInfo
504 OUString SAL_CALL
SvxUnoDrawingModel::getImplementationName()
506 return "SvxUnoDrawingModel";
509 sal_Bool SAL_CALL
SvxUnoDrawingModel::supportsService( const OUString
& ServiceName
)
511 return cppu::supportsService( this, ServiceName
);
514 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getSupportedServiceNames()
516 return { "com.sun.star.drawing.DrawingDocument" };
519 // XAnyCompareFactory
520 uno::Reference
< css::ucb::XAnyCompare
> SAL_CALL
SvxUnoDrawingModel::createAnyCompareByName( const OUString
& )
522 return SvxCreateNumRuleCompare();
525 SvxUnoDrawPagesAccess::SvxUnoDrawPagesAccess( SvxUnoDrawingModel
& rMyModel
) noexcept
531 sal_Int32 SAL_CALL
SvxUnoDrawPagesAccess::getCount()
533 ::SolarMutexGuard aGuard
;
535 sal_Int32 nCount
= 0;
538 nCount
= mrModel
.mpDoc
->GetPageCount();
543 uno::Any SAL_CALL
SvxUnoDrawPagesAccess::getByIndex( sal_Int32 Index
)
545 ::SolarMutexGuard aGuard
;
551 if( (Index
< 0) || (Index
>= mrModel
.mpDoc
->GetPageCount() ) )
552 throw lang::IndexOutOfBoundsException();
554 SdrPage
* pPage
= mrModel
.mpDoc
->GetPage( static_cast<sal_uInt16
>(Index
) );
557 uno::Reference
< uno::XInterface
> xPage( pPage
->mxUnoPage
);
561 if( dynamic_cast<FmFormModel
*>( mrModel
.mpDoc
) )
562 xPage
= static_cast<drawing::XDrawPage
*>(new SvxFmDrawPage( pPage
));
564 xPage
= static_cast<drawing::XDrawPage
*>(new SvxDrawPage( pPage
));
566 pPage
->mxUnoPage
= xPage
;
576 uno::Type SAL_CALL
SvxUnoDrawPagesAccess::getElementType()
578 return cppu::UnoType
<drawing::XDrawPage
>::get();
581 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::hasElements()
583 return getCount() > 0;
588 // create a new page with model at given position
589 // and return corresponding SdDrawPage
590 uno::Reference
< drawing::XDrawPage
> SAL_CALL
SvxUnoDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex
)
592 ::SolarMutexGuard aGuard
;
594 uno::Reference
< drawing::XDrawPage
> xDrawPage
;
598 rtl::Reference
<SdrPage
> pPage
;
600 if( auto pFormModel
= dynamic_cast<FmFormModel
*>( mrModel
.mpDoc
) )
601 pPage
= new FmFormPage(*pFormModel
);
603 pPage
= new SdrPage(*mrModel
.mpDoc
);
605 mrModel
.mpDoc
->InsertPage( pPage
.get(), static_cast<sal_uInt16
>(nIndex
) );
606 xDrawPage
.set( pPage
->getUnoPage(), uno::UNO_QUERY
);
612 void SAL_CALL
SvxUnoDrawPagesAccess::remove( const uno::Reference
< drawing::XDrawPage
>& xPage
)
614 ::SolarMutexGuard aGuard
;
616 sal_uInt16 nPageCount
= mrModel
.mpDoc
->GetPageCount();
617 if( nPageCount
<= 1 )
620 // get pPage from xPage and get Id (nPos)
621 SvxDrawPage
* pSvxPage
= comphelper::getFromUnoTunnel
<SvxDrawPage
>( xPage
);
624 SdrPage
* pPage
= pSvxPage
->GetSdrPage();
627 sal_uInt16 nPage
= pPage
->GetPageNum();
628 mrModel
.mpDoc
->DeletePage( nPage
);
635 OUString SAL_CALL
SvxUnoDrawPagesAccess::getImplementationName( )
637 return "SvxUnoDrawPagesAccess";
640 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::supportsService( const OUString
& ServiceName
)
642 return cppu::supportsService(this, ServiceName
);
645 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawPagesAccess::getSupportedServiceNames( )
647 return { "com.sun.star.drawing.DrawPages" };
650 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule(SdrModel
* pModel
)
652 const SvxNumRule
* pDefaultRule
= nullptr;
655 const SvxNumBulletItem
* pItem
= pModel
->GetItemPool().GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET
);
658 pDefaultRule
= &pItem
->GetNumRule();
664 return SvxCreateNumRule( *pDefaultRule
);
668 SvxNumRule
aTempRule( SvxNumRuleFlags::NONE
, 10, false );
669 return SvxCreateNumRule( aTempRule
);
674 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */