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 <vcl/svapp.hxx>
26 #include <svl/itempool.hxx>
27 #include <svtools/unoevent.hxx>
28 #include <comphelper/sequence.hxx>
29 #include <o3tl/string_view.hxx>
30 #include <cppuhelper/supportsservice.hxx>
32 #include <cppuhelper/implbase.hxx>
33 #include <svx/unofill.hxx>
34 #include <editeng/unonrule.hxx>
35 #include <svtools/unoimap.hxx>
36 #include <sfx2/event.hxx>
37 #include <svx/fmmodel.hxx>
38 #include <svx/fmpage.hxx>
39 #include <svx/unoapi.hxx>
41 #include <svx/svdmodel.hxx>
42 #include <svx/unoprov.hxx>
43 #include <svx/unopage.hxx>
44 #include <editeng/unofield.hxx>
45 #include <svx/unomod.hxx>
46 #include <svx/unomodel.hxx>
47 #include <svx/svdobj.hxx>
48 #include <svx/svdpage.hxx>
49 #include <svx/SvxXTextColumns.hxx>
50 #include <svx/unoshape.hxx>
51 #include <svx/xmlgrhlp.hxx>
53 #include <com/sun/star/text/textfield/Type.hpp>
57 using namespace ::com::sun::star
;
61 #define QUERYINT( xint ) \
62 if( rType == cppu::UnoType<xint>::get() ) \
63 aAny <<= uno::Reference< xint >(this)
67 class SvxUnoDrawPagesAccess
: public ::cppu::WeakImplHelper
< css::drawing::XDrawPages
, css::lang::XServiceInfo
>
70 SvxUnoDrawingModel
& mrModel
;
73 explicit SvxUnoDrawPagesAccess( SvxUnoDrawingModel
& rMyModel
) noexcept
;
76 virtual css::uno::Reference
< css::drawing::XDrawPage
> SAL_CALL
insertNewByIndex( sal_Int32 nIndex
) override
;
77 virtual void SAL_CALL
remove( const css::uno::Reference
< css::drawing::XDrawPage
>& xPage
) override
;
80 virtual sal_Int32 SAL_CALL
getCount() override
;
81 virtual css::uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) override
;
84 virtual css::uno::Type SAL_CALL
getElementType() override
;
85 virtual sal_Bool SAL_CALL
hasElements() override
;
88 virtual OUString SAL_CALL
getImplementationName( ) override
;
89 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
90 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
94 static const SvEventDescription
* ImplGetSupportedMacroItems()
96 static const SvEventDescription aMacroDescriptionsImpl
[] =
98 { SvMacroItemId::OnMouseOver
, "OnMouseOver" },
99 { SvMacroItemId::OnMouseOut
, "OnMouseOut" },
100 { SvMacroItemId::NONE
, nullptr }
103 return aMacroDescriptionsImpl
;
108 /** fills the given EventObject from the given SdrHint.
110 true if the SdrHint could be translated to an EventObject<br>
113 bool SvxUnoDrawMSFactory::createEvent( const SdrModel
* pDoc
, const SdrHint
* pSdrHint
, css::document::EventObject
& aEvent
)
115 const SdrObject
* pObj
= nullptr;
116 const SdrPage
* pPage
= nullptr;
118 switch( pSdrHint
->GetKind() )
120 // case SdrHintKind::LayerChange: // layer definition changed
121 // case SdrHintKind::LayerOrderChange: // layer order changed (Insert/Remove/ChangePos)
122 // case HINT_LAYERSETCHG: // layer set changed
123 // case HINT_LAYERSETORDERCHG: // layer set order changed (Insert/Remove/ChangePos)
125 // case HINT_PAGECHG: // page changed
126 // aEvent.EventName = "PageModified";
127 // pPage = pSdrHint->GetPage();
129 case SdrHintKind::PageOrderChange
: // draw or master page order changed (Insert/Remove/ChangePos)
130 aEvent
.EventName
= "PageOrderModified";
131 pPage
= pSdrHint
->GetPage();
133 case SdrHintKind::ObjectChange
: // object changed
134 aEvent
.EventName
= "ShapeModified";
135 pObj
= pSdrHint
->GetObject();
137 case SdrHintKind::ObjectInserted
: // add new draw object
138 aEvent
.EventName
= "ShapeInserted";
139 pObj
= pSdrHint
->GetObject();
141 case SdrHintKind::ObjectRemoved
: // removed draw object from list
142 aEvent
.EventName
= "ShapeRemoved";
143 pObj
= pSdrHint
->GetObject();
145 // SdrHintKind::DefaultTabChange, // default tab width changed
146 // SdrHintKind::SwitchToPage, // #94278# UNDO/REDO at an object evtl. on another page
147 // HINT_OBJLISTCLEAR // Is called before an SdrObjList will be cleared
153 aEvent
.Source
= const_cast<SdrObject
*>(pObj
)->getUnoShape();
155 aEvent
.Source
= const_cast<SdrPage
*>(pPage
)->getUnoPage();
157 aEvent
.Source
= const_cast<SdrModel
*>(pDoc
)->getUnoModel();
164 css::uno::Reference
<css::uno::XInterface
> create(
165 OUString
const & rServiceSpecifier
, OUString
const & referer
)
167 if( rServiceSpecifier
.startsWith("com.sun.star.drawing.") )
169 std::optional
<SdrObjKind
> nType
= UHashMap::getId( rServiceSpecifier
);
172 SdrInventor nI
= IsInventorE3D(*nType
) ? SdrInventor::E3d
: SdrInventor::Default
;
174 return cppu::getXWeak(SvxDrawPage::CreateShapeByTypeAndInventor( *nType
, nI
, nullptr, nullptr, referer
).get());
177 else if (rServiceSpecifier
== "com.sun.star.document.ImportGraphicStorageHandler")
179 return cppu::getXWeak( SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode::Read
).get() );
181 else if (rServiceSpecifier
== "com.sun.star.text.TextColumns")
183 return SvxXTextColumns_createInstance();
186 uno::Reference
< uno::XInterface
> xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier
) );
188 throw lang::ServiceNotRegisteredException("unknown service: " + rServiceSpecifier
);
195 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstance( const OUString
& rServiceSpecifier
)
197 return create(rServiceSpecifier
, u
""_ustr
);
200 uno::Reference
< uno::XInterface
> SvxUnoDrawMSFactory::createTextField( std::u16string_view ServiceSpecifier
)
202 return SvxUnoTextCreateTextField( ServiceSpecifier
);
205 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawMSFactory::createInstanceWithArguments( const OUString
& ServiceSpecifier
, const uno::Sequence
< css::uno::Any
>& Arguments
)
208 if ((ServiceSpecifier
== "com.sun.star.drawing.GraphicObjectShape"
209 || ServiceSpecifier
== "com.sun.star.drawing.AppletShape"
210 || ServiceSpecifier
== "com.sun.star.drawing.FrameShape"
211 || ServiceSpecifier
== "com.sun.star.drawing.OLE2Shape"
212 || ServiceSpecifier
== "com.sun.star.drawing.MediaShape"
213 || ServiceSpecifier
== "com.sun.star.drawing.PluginShape")
214 && Arguments
.getLength() == 1 && (Arguments
[0] >>= arg
))
216 return create(ServiceSpecifier
, arg
);
218 throw lang::NoSupportException();
221 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawMSFactory::getAvailableServiceNames()
223 return UHashMap::getServiceNames();
226 SdrModel
& SvxUnoDrawingModel::getSdrModelFromUnoModel() const
228 OSL_ENSURE(mpDoc
, "No SdrModel in UnoDrawingModel, should not happen");
232 SvxUnoDrawingModel::SvxUnoDrawingModel(SdrModel
* pDoc
) noexcept
233 : SfxBaseModel(nullptr),
238 SvxUnoDrawingModel::~SvxUnoDrawingModel() noexcept
242 uno::Any SAL_CALL
SvxUnoDrawingModel::queryInterface( const uno::Type
& rType
)
246 QUERYINT(lang::XServiceInfo
);
247 else QUERYINT(lang::XMultiServiceFactory
);
248 else QUERYINT(drawing::XDrawPagesSupplier
);
249 else QUERYINT(css::ucb::XAnyCompareFactory
);
251 return SfxBaseModel::queryInterface( rType
);
257 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoDrawingModel::getTypes( )
259 if( !maTypeSequence
.hasElements() )
261 maTypeSequence
= comphelper::concatSequences( SfxBaseModel::getTypes(),
263 cppu::UnoType
<lang::XServiceInfo
>::get(),
264 cppu::UnoType
<lang::XMultiServiceFactory
>::get(),
265 cppu::UnoType
<drawing::XDrawPagesSupplier
>::get(),
266 cppu::UnoType
<css::ucb::XAnyCompareFactory
>::get() });
268 return maTypeSequence
;
271 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoDrawingModel::getImplementationId( )
273 return css::uno::Sequence
<sal_Int8
>();
276 void SAL_CALL
SvxUnoDrawingModel::lockControllers( )
279 mpDoc
->setLock(true);
282 void SAL_CALL
SvxUnoDrawingModel::unlockControllers( )
284 if( mpDoc
&& mpDoc
->isLocked() )
286 mpDoc
->setLock(false);
290 sal_Bool SAL_CALL
SvxUnoDrawingModel::hasControllersLocked( )
292 return mpDoc
&& mpDoc
->isLocked();
295 // XDrawPagesSupplier
296 uno::Reference
< drawing::XDrawPages
> SAL_CALL
SvxUnoDrawingModel::getDrawPages()
298 ::SolarMutexGuard aGuard
;
300 uno::Reference
< drawing::XDrawPages
> xDrawPages( mxDrawPagesAccess
);
302 if( !xDrawPages
.is() )
303 mxDrawPagesAccess
= xDrawPages
= new SvxUnoDrawPagesAccess(*this);
308 // XMultiServiceFactory ( SvxFmMSFactory )
309 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoDrawingModel::createInstance( const OUString
& aServiceSpecifier
)
311 ::SolarMutexGuard aGuard
;
313 if( aServiceSpecifier
== "com.sun.star.drawing.DashTable" )
315 if( !mxDashTable
.is() )
316 mxDashTable
= SvxUnoDashTable_createInstance( mpDoc
);
319 if( aServiceSpecifier
== "com.sun.star.drawing.GradientTable" )
321 if( !mxGradientTable
.is() )
322 mxGradientTable
= SvxUnoGradientTable_createInstance( mpDoc
);
323 return mxGradientTable
;
325 if( aServiceSpecifier
== "com.sun.star.drawing.HatchTable" )
327 if( !mxHatchTable
.is() )
328 mxHatchTable
= SvxUnoHatchTable_createInstance( mpDoc
);
331 if( aServiceSpecifier
== "com.sun.star.drawing.BitmapTable" )
333 if( !mxBitmapTable
.is() )
334 mxBitmapTable
= SvxUnoBitmapTable_createInstance( mpDoc
);
335 return mxBitmapTable
;
337 if( aServiceSpecifier
== "com.sun.star.drawing.TransparencyGradientTable" )
339 if( !mxTransGradientTable
.is() )
340 mxTransGradientTable
= SvxUnoTransGradientTable_createInstance( mpDoc
);
341 return mxTransGradientTable
;
343 if( aServiceSpecifier
== "com.sun.star.drawing.MarkerTable" )
345 if( !mxMarkerTable
.is() )
346 mxMarkerTable
= SvxUnoMarkerTable_createInstance( mpDoc
);
347 return mxMarkerTable
;
349 if( aServiceSpecifier
== "com.sun.star.text.NumberingRules" )
351 return uno::Reference
< uno::XInterface
>( SvxCreateNumRule( mpDoc
), uno::UNO_QUERY
);
354 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapRectangleObject" )
356 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
359 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapCircleObject" )
361 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
364 if ( aServiceSpecifier
== "com.sun.star.image.ImageMapPolygonObject" )
366 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
369 if( aServiceSpecifier
== "com.sun.star.text.TextField.DateTime" )
371 return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::DATE
));
374 uno::Reference
< uno::XInterface
> xRet
;
376 static constexpr OUString
aPackagePrefix( u
"com.sun.star.presentation."_ustr
);
377 if( aServiceSpecifier
.startsWith( aPackagePrefix
) )
379 SvxShape
* pShape
= nullptr;
381 SdrObjKind nType
= SdrObjKind::Text
;
382 std::u16string_view aTypeName
= aServiceSpecifier
.subView( aPackagePrefix
.getLength() );
383 // create a shape wrapper
384 if( o3tl::starts_with(aTypeName
, u
"TitleTextShape") )
386 nType
= SdrObjKind::Text
;
388 else if( o3tl::starts_with(aTypeName
, u
"OutlinerShape" ) )
390 nType
= SdrObjKind::Text
;
392 else if( o3tl::starts_with(aTypeName
, u
"SubtitleShape" ) )
394 nType
= SdrObjKind::Text
;
396 else if( o3tl::starts_with(aTypeName
, u
"GraphicObjectShape" ) )
398 nType
= SdrObjKind::Graphic
;
400 else if( o3tl::starts_with(aTypeName
, u
"PageShape" ) )
402 nType
= SdrObjKind::Page
;
404 else if( o3tl::starts_with(aTypeName
, u
"OLE2Shape" ) )
406 nType
= SdrObjKind::OLE2
;
408 else if( o3tl::starts_with(aTypeName
, u
"ChartShape" ) )
410 nType
= SdrObjKind::OLE2
;
412 else if( o3tl::starts_with(aTypeName
, u
"OrgChartShape" ) )
414 nType
= SdrObjKind::OLE2
;
416 else if( o3tl::starts_with(aTypeName
, u
"NotesShape" ) )
418 nType
= SdrObjKind::Text
;
420 else if( o3tl::starts_with(aTypeName
, u
"HandoutShape" ) )
422 nType
= SdrObjKind::Page
;
424 else if( o3tl::starts_with(aTypeName
, u
"FooterShape" ) )
426 nType
= SdrObjKind::Text
;
428 else if( o3tl::starts_with(aTypeName
, u
"HeaderShape" ) )
430 nType
= SdrObjKind::Text
;
432 else if( o3tl::starts_with(aTypeName
, u
"SlideNumberShape" ) )
434 nType
= SdrObjKind::Text
;
436 else if( o3tl::starts_with(aTypeName
, u
"DateTimeShape" ) )
438 nType
= SdrObjKind::Text
;
440 else if( o3tl::starts_with(aTypeName
, u
"TableShape" ) )
442 nType
= SdrObjKind::Table
;
446 throw lang::ServiceNotRegisteredException();
449 // create the API wrapper
450 rtl::Reference
<SvxShape
> xNewShape
= CreateSvxShapeByTypeAndInventor( nType
, SdrInventor::Default
, u
""_ustr
);
451 pShape
= xNewShape
.get();
455 pShape
->SetShapeType(aServiceSpecifier
);
457 xRet
= cppu::getXWeak(pShape
);
461 xRet
= SvxFmMSFactory::createInstance( aServiceSpecifier
);
467 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getAvailableServiceNames()
469 const uno::Sequence
< OUString
> aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
471 static constexpr OUString aSNS
[] {
472 u
"com.sun.star.drawing.DashTable"_ustr
,
473 u
"com.sun.star.drawing.GradientTable"_ustr
,
474 u
"com.sun.star.drawing.HatchTable"_ustr
,
475 u
"com.sun.star.drawing.BitmapTable"_ustr
,
476 u
"com.sun.star.drawing.TransparencyGradientTable"_ustr
,
477 u
"com.sun.star.drawing.MarkerTable"_ustr
,
478 u
"com.sun.star.text.NumberingRules"_ustr
,
479 u
"com.sun.star.image.ImageMapRectangleObject"_ustr
,
480 u
"com.sun.star.image.ImageMapCircleObject"_ustr
,
481 u
"com.sun.star.image.ImageMapPolygonObject"_ustr
,
483 u
"com.sun.star.presentation.TitleTextShape"_ustr
,
484 u
"com.sun.star.presentation.OutlinerShape"_ustr
,
485 u
"com.sun.star.presentation.SubtitleShape"_ustr
,
486 u
"com.sun.star.presentation.GraphicObjectShape"_ustr
,
487 u
"com.sun.star.presentation.ChartShape"_ustr
,
488 u
"com.sun.star.presentation.PageShape"_ustr
,
489 u
"com.sun.star.presentation.OLE2Shape"_ustr
,
490 u
"com.sun.star.presentation.TableShape"_ustr
,
491 u
"com.sun.star.presentation.OrgChartShape"_ustr
,
492 u
"com.sun.star.presentation.NotesShape"_ustr
,
493 u
"com.sun.star.presentation.HandoutShape"_ustr
496 return comphelper::concatSequences( aSNS_ORG
, aSNS
);
499 // lang::XServiceInfo
500 OUString SAL_CALL
SvxUnoDrawingModel::getImplementationName()
502 return u
"SvxUnoDrawingModel"_ustr
;
505 sal_Bool SAL_CALL
SvxUnoDrawingModel::supportsService( const OUString
& ServiceName
)
507 return cppu::supportsService( this, ServiceName
);
510 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawingModel::getSupportedServiceNames()
512 return { u
"com.sun.star.drawing.DrawingDocument"_ustr
};
515 // XAnyCompareFactory
516 uno::Reference
< css::ucb::XAnyCompare
> SAL_CALL
SvxUnoDrawingModel::createAnyCompareByName( const OUString
& )
518 return SvxCreateNumRuleCompare();
521 SvxUnoDrawPagesAccess::SvxUnoDrawPagesAccess( SvxUnoDrawingModel
& rMyModel
) noexcept
527 sal_Int32 SAL_CALL
SvxUnoDrawPagesAccess::getCount()
529 ::SolarMutexGuard aGuard
;
531 sal_Int32 nCount
= 0;
534 nCount
= mrModel
.mpDoc
->GetPageCount();
539 uno::Any SAL_CALL
SvxUnoDrawPagesAccess::getByIndex( sal_Int32 Index
)
541 ::SolarMutexGuard aGuard
;
547 if( (Index
< 0) || (Index
>= mrModel
.mpDoc
->GetPageCount() ) )
548 throw lang::IndexOutOfBoundsException();
550 SdrPage
* pPage
= mrModel
.mpDoc
->GetPage( static_cast<sal_uInt16
>(Index
) );
553 uno::Reference
< uno::XInterface
> xPage( pPage
->mxUnoPage
);
557 xPage
= static_cast<drawing::XDrawPage
*>(new SvxDrawPage( pPage
));
558 pPage
->mxUnoPage
= xPage
;
568 uno::Type SAL_CALL
SvxUnoDrawPagesAccess::getElementType()
570 return cppu::UnoType
<drawing::XDrawPage
>::get();
573 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::hasElements()
575 return getCount() > 0;
580 // create a new page with model at given position
581 // and return corresponding SdDrawPage
582 uno::Reference
< drawing::XDrawPage
> SAL_CALL
SvxUnoDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex
)
584 ::SolarMutexGuard aGuard
;
586 uno::Reference
< drawing::XDrawPage
> xDrawPage
;
590 rtl::Reference
<SdrPage
> pPage
;
592 if( auto pFormModel
= dynamic_cast<FmFormModel
*>( mrModel
.mpDoc
) )
593 pPage
= new FmFormPage(*pFormModel
);
595 pPage
= new SdrPage(*mrModel
.mpDoc
);
597 mrModel
.mpDoc
->InsertPage( pPage
.get(), static_cast<sal_uInt16
>(nIndex
) );
598 xDrawPage
.set( pPage
->getUnoPage(), uno::UNO_QUERY
);
604 void SAL_CALL
SvxUnoDrawPagesAccess::remove( const uno::Reference
< drawing::XDrawPage
>& xPage
)
606 ::SolarMutexGuard aGuard
;
608 sal_uInt16 nPageCount
= mrModel
.mpDoc
->GetPageCount();
609 if( nPageCount
<= 1 )
612 // get pPage from xPage and get Id (nPos)
613 SvxDrawPage
* pSvxPage
= comphelper::getFromUnoTunnel
<SvxDrawPage
>( xPage
);
616 SdrPage
* pPage
= pSvxPage
->GetSdrPage();
619 sal_uInt16 nPage
= pPage
->GetPageNum();
620 mrModel
.mpDoc
->DeletePage( nPage
);
627 OUString SAL_CALL
SvxUnoDrawPagesAccess::getImplementationName( )
629 return u
"SvxUnoDrawPagesAccess"_ustr
;
632 sal_Bool SAL_CALL
SvxUnoDrawPagesAccess::supportsService( const OUString
& ServiceName
)
634 return cppu::supportsService(this, ServiceName
);
637 uno::Sequence
< OUString
> SAL_CALL
SvxUnoDrawPagesAccess::getSupportedServiceNames( )
639 return { u
"com.sun.star.drawing.DrawPages"_ustr
};
642 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule(SdrModel
* pModel
)
644 const SvxNumRule
* pDefaultRule
= nullptr;
647 const SvxNumBulletItem
* pItem
= pModel
->GetItemPool().GetSecondaryPool()->GetUserDefaultItem(EE_PARA_NUMBULLET
);
650 pDefaultRule
= &pItem
->GetNumRule();
656 return SvxCreateNumRule( *pDefaultRule
);
660 SvxNumRule
aTempRule( SvxNumRuleFlags::NONE
, 10, false );
661 return SvxCreateNumRule( aTempRule
);
666 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */