Bump version to 24.04.3.4
[LibreOffice.git] / svx / source / unodraw / unomod.cxx
blobe5927030d13338e12a0f4a560f68da017e59ba74
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 <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/fmmodel.hxx>
39 #include <svx/fmpage.hxx>
40 #include <svx/unoapi.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/unoprov.hxx>
44 #include <svx/unopage.hxx>
45 #include <editeng/unofield.hxx>
46 #include <svx/unomod.hxx>
47 #include <svx/unomodel.hxx>
48 #include <svx/svdobj.hxx>
49 #include <svx/svdpage.hxx>
50 #include <svx/SvxXTextColumns.hxx>
51 #include <svx/unoshape.hxx>
52 #include <svx/xmlgrhlp.hxx>
54 #include <com/sun/star/text/textfield/Type.hpp>
56 //-
58 using namespace ::com::sun::star;
60 //-
62 #define QUERYINT( xint ) \
63 if( rType == cppu::UnoType<xint>::get() ) \
64 aAny <<= uno::Reference< xint >(this)
66 //-
68 class SvxUnoDrawPagesAccess : public ::cppu::WeakImplHelper< css::drawing::XDrawPages, css::lang::XServiceInfo >
70 private:
71 SvxUnoDrawingModel& mrModel;
73 public:
74 explicit SvxUnoDrawPagesAccess( SvxUnoDrawingModel& rMyModel ) noexcept;
76 // XDrawPages
77 virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL insertNewByIndex( sal_Int32 nIndex ) override;
78 virtual void SAL_CALL remove( const css::uno::Reference< css::drawing::XDrawPage >& xPage ) override;
80 // XIndexAccess
81 virtual sal_Int32 SAL_CALL getCount() override ;
82 virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
84 // XElementAccess
85 virtual css::uno::Type SAL_CALL getElementType() override;
86 virtual sal_Bool SAL_CALL hasElements() override;
88 // XServiceInfo
89 virtual OUString SAL_CALL getImplementationName( ) override;
90 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
91 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
93 //-
95 static const SvEventDescription* ImplGetSupportedMacroItems()
97 static const SvEventDescription aMacroDescriptionsImpl[] =
99 { SvMacroItemId::OnMouseOver, "OnMouseOver" },
100 { SvMacroItemId::OnMouseOut, "OnMouseOut" },
101 { SvMacroItemId::NONE, nullptr }
104 return aMacroDescriptionsImpl;
109 /** fills the given EventObject from the given SdrHint.
110 @returns
111 true if the SdrHint could be translated to an EventObject<br>
112 false if not
114 bool SvxUnoDrawMSFactory::createEvent( const SdrModel* pDoc, const SdrHint* pSdrHint, css::document::EventObject& aEvent )
116 const SdrObject* pObj = nullptr;
117 const SdrPage* pPage = nullptr;
119 switch( pSdrHint->GetKind() )
121 // case SdrHintKind::LayerChange: // layer definition changed
122 // case SdrHintKind::LayerOrderChange: // layer order changed (Insert/Remove/ChangePos)
123 // case HINT_LAYERSETCHG: // layer set changed
124 // case HINT_LAYERSETORDERCHG: // layer set order changed (Insert/Remove/ChangePos)
126 // case HINT_PAGECHG: // page changed
127 // aEvent.EventName = "PageModified";
128 // pPage = pSdrHint->GetPage();
129 // break;
130 case SdrHintKind::PageOrderChange: // draw or master page order changed (Insert/Remove/ChangePos)
131 aEvent.EventName = "PageOrderModified";
132 pPage = pSdrHint->GetPage();
133 break;
134 case SdrHintKind::ObjectChange: // object changed
135 aEvent.EventName = "ShapeModified";
136 pObj = pSdrHint->GetObject();
137 break;
138 case SdrHintKind::ObjectInserted: // add new draw object
139 aEvent.EventName = "ShapeInserted";
140 pObj = pSdrHint->GetObject();
141 break;
142 case SdrHintKind::ObjectRemoved: // removed draw object from list
143 aEvent.EventName = "ShapeRemoved";
144 pObj = pSdrHint->GetObject();
145 break;
146 // SdrHintKind::DefaultTabChange, // default tab width changed
147 // SdrHintKind::SwitchToPage, // #94278# UNDO/REDO at an object evtl. on another page
148 // HINT_OBJLISTCLEAR // Is called before an SdrObjList will be cleared
149 default:
150 return false;
153 if( pObj )
154 aEvent.Source = const_cast<SdrObject*>(pObj)->getUnoShape();
155 else if( pPage )
156 aEvent.Source = const_cast<SdrPage*>(pPage)->getUnoPage();
157 else
158 aEvent.Source = const_cast<SdrModel*>(pDoc)->getUnoModel();
160 return true;
163 namespace {
165 css::uno::Reference<css::uno::XInterface> create(
166 OUString const & rServiceSpecifier, OUString const & referer)
168 if( rServiceSpecifier.startsWith("com.sun.star.drawing.") )
170 std::optional<SdrObjKind> nType = UHashMap::getId( rServiceSpecifier );
171 if( nType )
173 SdrInventor nI = IsInventorE3D(*nType) ? SdrInventor::E3d : SdrInventor::Default;
175 return cppu::getXWeak(SvxDrawPage::CreateShapeByTypeAndInventor( *nType, nI, nullptr, nullptr, referer ).get());
178 else if (rServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler")
180 return cppu::getXWeak( SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode::Read ).get() );
182 else if (rServiceSpecifier == "com.sun.star.text.TextColumns")
184 return SvxXTextColumns_createInstance();
187 uno::Reference< uno::XInterface > xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier ) );
188 if( !xRet.is() )
189 throw lang::ServiceNotRegisteredException("unknown service: " + rServiceSpecifier);
191 return xRet;
196 uno::Reference< uno::XInterface > SAL_CALL SvxUnoDrawMSFactory::createInstance( const OUString& rServiceSpecifier )
198 return create(rServiceSpecifier, "");
201 uno::Reference< uno::XInterface > SvxUnoDrawMSFactory::createTextField( std::u16string_view ServiceSpecifier )
203 return SvxUnoTextCreateTextField( ServiceSpecifier );
206 uno::Reference< uno::XInterface > SAL_CALL SvxUnoDrawMSFactory::createInstanceWithArguments( const OUString& ServiceSpecifier, const uno::Sequence< css::uno::Any >& Arguments )
208 OUString arg;
209 if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape"
210 || ServiceSpecifier == "com.sun.star.drawing.AppletShape"
211 || ServiceSpecifier == "com.sun.star.drawing.FrameShape"
212 || ServiceSpecifier == "com.sun.star.drawing.OLE2Shape"
213 || ServiceSpecifier == "com.sun.star.drawing.MediaShape"
214 || ServiceSpecifier == "com.sun.star.drawing.PluginShape")
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");
230 return *mpDoc;
233 SvxUnoDrawingModel::SvxUnoDrawingModel(SdrModel* pDoc) noexcept
234 : SfxBaseModel(nullptr),
235 mpDoc(pDoc)
239 SvxUnoDrawingModel::~SvxUnoDrawingModel() noexcept
243 uno::Any SAL_CALL SvxUnoDrawingModel::queryInterface( const uno::Type & rType )
245 uno::Any aAny;
247 QUERYINT(lang::XServiceInfo);
248 else QUERYINT(lang::XMultiServiceFactory);
249 else QUERYINT(drawing::XDrawPagesSupplier);
250 else QUERYINT(css::ucb::XAnyCompareFactory);
251 else
252 return SfxBaseModel::queryInterface( rType );
254 return aAny;
257 // XTypeProvider
258 uno::Sequence< uno::Type > SAL_CALL SvxUnoDrawingModel::getTypes( )
260 if( !maTypeSequence.hasElements() )
262 maTypeSequence = comphelper::concatSequences( SfxBaseModel::getTypes(),
263 uno::Sequence {
264 cppu::UnoType<lang::XServiceInfo>::get(),
265 cppu::UnoType<lang::XMultiServiceFactory>::get(),
266 cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
267 cppu::UnoType<css::ucb::XAnyCompareFactory>::get() });
269 return maTypeSequence;
272 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoDrawingModel::getImplementationId( )
274 return css::uno::Sequence<sal_Int8>();
277 void SAL_CALL SvxUnoDrawingModel::lockControllers( )
279 if( mpDoc )
280 mpDoc->setLock(true);
283 void SAL_CALL SvxUnoDrawingModel::unlockControllers( )
285 if( mpDoc && mpDoc->isLocked() )
287 mpDoc->setLock(false);
291 sal_Bool SAL_CALL SvxUnoDrawingModel::hasControllersLocked( )
293 return mpDoc && mpDoc->isLocked();
296 // XDrawPagesSupplier
297 uno::Reference< drawing::XDrawPages > SAL_CALL SvxUnoDrawingModel::getDrawPages()
299 ::SolarMutexGuard aGuard;
301 uno::Reference< drawing::XDrawPages > xDrawPages( mxDrawPagesAccess );
303 if( !xDrawPages.is() )
304 mxDrawPagesAccess = xDrawPages = new SvxUnoDrawPagesAccess(*this);
306 return xDrawPages;
309 // XMultiServiceFactory ( SvxFmMSFactory )
310 uno::Reference< uno::XInterface > SAL_CALL SvxUnoDrawingModel::createInstance( const OUString& aServiceSpecifier )
312 ::SolarMutexGuard aGuard;
314 if( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
316 if( !mxDashTable.is() )
317 mxDashTable = SvxUnoDashTable_createInstance( mpDoc );
318 return mxDashTable;
320 if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
322 if( !mxGradientTable.is() )
323 mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc );
324 return mxGradientTable;
326 if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
328 if( !mxHatchTable.is() )
329 mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc );
330 return mxHatchTable;
332 if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
334 if( !mxBitmapTable.is() )
335 mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc );
336 return mxBitmapTable;
338 if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
340 if( !mxTransGradientTable.is() )
341 mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc );
342 return mxTransGradientTable;
344 if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
346 if( !mxMarkerTable.is() )
347 mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc );
348 return mxMarkerTable;
350 if( aServiceSpecifier == "com.sun.star.text.NumberingRules" )
352 return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY );
355 if ( aServiceSpecifier == "com.sun.star.image.ImageMapRectangleObject" )
357 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
360 if ( aServiceSpecifier == "com.sun.star.image.ImageMapCircleObject" )
362 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
365 if ( aServiceSpecifier == "com.sun.star.image.ImageMapPolygonObject" )
367 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
370 if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" )
372 return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::DATE));
375 uno::Reference< uno::XInterface > xRet;
377 static constexpr OUString aPackagePrefix( u"com.sun.star.presentation."_ustr );
378 if( aServiceSpecifier.startsWith( aPackagePrefix ) )
380 SvxShape* pShape = nullptr;
382 SdrObjKind nType = SdrObjKind::Text;
383 std::u16string_view aTypeName = aServiceSpecifier.subView( aPackagePrefix.getLength() );
384 // create a shape wrapper
385 if( o3tl::starts_with(aTypeName, u"TitleTextShape") )
387 nType = SdrObjKind::Text;
389 else if( o3tl::starts_with(aTypeName, u"OutlinerShape" ) )
391 nType = SdrObjKind::Text;
393 else if( o3tl::starts_with(aTypeName, u"SubtitleShape" ) )
395 nType = SdrObjKind::Text;
397 else if( o3tl::starts_with(aTypeName, u"GraphicObjectShape" ) )
399 nType = SdrObjKind::Graphic;
401 else if( o3tl::starts_with(aTypeName, u"PageShape" ) )
403 nType = SdrObjKind::Page;
405 else if( o3tl::starts_with(aTypeName, u"OLE2Shape" ) )
407 nType = SdrObjKind::OLE2;
409 else if( o3tl::starts_with(aTypeName, u"ChartShape" ) )
411 nType = SdrObjKind::OLE2;
413 else if( o3tl::starts_with(aTypeName, u"OrgChartShape" ) )
415 nType = SdrObjKind::OLE2;
417 else if( o3tl::starts_with(aTypeName, u"NotesShape" ) )
419 nType = SdrObjKind::Text;
421 else if( o3tl::starts_with(aTypeName, u"HandoutShape" ) )
423 nType = SdrObjKind::Page;
425 else if( o3tl::starts_with(aTypeName, u"FooterShape" ) )
427 nType = SdrObjKind::Text;
429 else if( o3tl::starts_with(aTypeName, u"HeaderShape" ) )
431 nType = SdrObjKind::Text;
433 else if( o3tl::starts_with(aTypeName, u"SlideNumberShape" ) )
435 nType = SdrObjKind::Text;
437 else if( o3tl::starts_with(aTypeName, u"DateTimeShape" ) )
439 nType = SdrObjKind::Text;
441 else if( o3tl::starts_with(aTypeName, u"TableShape" ) )
443 nType = SdrObjKind::Table;
445 else
447 throw lang::ServiceNotRegisteredException();
450 // create the API wrapper
451 rtl::Reference<SvxShape> xNewShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, "" );
452 pShape = xNewShape.get();
454 // set shape type
455 if( pShape )
456 pShape->SetShapeType(aServiceSpecifier);
458 xRet = cppu::getXWeak(pShape);
460 else
462 xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
465 return xRet;
468 uno::Sequence< OUString > SAL_CALL SvxUnoDrawingModel::getAvailableServiceNames()
470 const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
472 uno::Sequence< OUString > aSNS{
473 "com.sun.star.drawing.DashTable",
474 "com.sun.star.drawing.GradientTable",
475 "com.sun.star.drawing.HatchTable",
476 "com.sun.star.drawing.BitmapTable",
477 "com.sun.star.drawing.TransparencyGradientTable",
478 "com.sun.star.drawing.MarkerTable",
479 "com.sun.star.text.NumberingRules",
480 "com.sun.star.image.ImageMapRectangleObject",
481 "com.sun.star.image.ImageMapCircleObject",
482 "com.sun.star.image.ImageMapPolygonObject",
484 "com.sun.star.presentation.TitleTextShape",
485 "com.sun.star.presentation.OutlinerShape",
486 "com.sun.star.presentation.SubtitleShape",
487 "com.sun.star.presentation.GraphicObjectShape",
488 "com.sun.star.presentation.ChartShape",
489 "com.sun.star.presentation.PageShape",
490 "com.sun.star.presentation.OLE2Shape",
491 "com.sun.star.presentation.TableShape",
492 "com.sun.star.presentation.OrgChartShape",
493 "com.sun.star.presentation.NotesShape",
494 "com.sun.star.presentation.HandoutShape"
497 return comphelper::concatSequences( aSNS_ORG, aSNS );
500 // lang::XServiceInfo
501 OUString SAL_CALL SvxUnoDrawingModel::getImplementationName()
503 return "SvxUnoDrawingModel";
506 sal_Bool SAL_CALL SvxUnoDrawingModel::supportsService( const OUString& ServiceName )
508 return cppu::supportsService( this, ServiceName );
511 uno::Sequence< OUString > SAL_CALL SvxUnoDrawingModel::getSupportedServiceNames()
513 return { "com.sun.star.drawing.DrawingDocument" };
516 // XAnyCompareFactory
517 uno::Reference< css::ucb::XAnyCompare > SAL_CALL SvxUnoDrawingModel::createAnyCompareByName( const OUString& )
519 return SvxCreateNumRuleCompare();
522 SvxUnoDrawPagesAccess::SvxUnoDrawPagesAccess( SvxUnoDrawingModel& rMyModel ) noexcept
523 : mrModel(rMyModel)
527 // XIndexAccess
528 sal_Int32 SAL_CALL SvxUnoDrawPagesAccess::getCount()
530 ::SolarMutexGuard aGuard;
532 sal_Int32 nCount = 0;
534 if( mrModel.mpDoc )
535 nCount = mrModel.mpDoc->GetPageCount();
537 return nCount;
540 uno::Any SAL_CALL SvxUnoDrawPagesAccess::getByIndex( sal_Int32 Index )
542 ::SolarMutexGuard aGuard;
544 uno::Any aAny;
546 if( mrModel.mpDoc )
548 if( (Index < 0) || (Index >= mrModel.mpDoc->GetPageCount() ) )
549 throw lang::IndexOutOfBoundsException();
551 SdrPage* pPage = mrModel.mpDoc->GetPage( static_cast<sal_uInt16>(Index) );
552 if( pPage )
554 uno::Reference< uno::XInterface > xPage( pPage->mxUnoPage );
556 if( !xPage.is() )
558 xPage = static_cast<drawing::XDrawPage*>(new SvxDrawPage( pPage ));
559 pPage->mxUnoPage = xPage;
562 aAny <<= xPage;
565 return aAny;
568 // XElementAccess
569 uno::Type SAL_CALL SvxUnoDrawPagesAccess::getElementType()
571 return cppu::UnoType<drawing::XDrawPage>::get();
574 sal_Bool SAL_CALL SvxUnoDrawPagesAccess::hasElements()
576 return getCount() > 0;
579 // XDrawPages
581 // create a new page with model at given position
582 // and return corresponding SdDrawPage
583 uno::Reference< drawing::XDrawPage > SAL_CALL SvxUnoDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex )
585 ::SolarMutexGuard aGuard;
587 uno::Reference< drawing::XDrawPage > xDrawPage;
589 if( mrModel.mpDoc )
591 rtl::Reference<SdrPage> pPage;
593 if( auto pFormModel = dynamic_cast<FmFormModel*>( mrModel.mpDoc ) )
594 pPage = new FmFormPage(*pFormModel);
595 else
596 pPage = new SdrPage(*mrModel.mpDoc);
598 mrModel.mpDoc->InsertPage( pPage.get(), static_cast<sal_uInt16>(nIndex) );
599 xDrawPage.set( pPage->getUnoPage(), uno::UNO_QUERY );
602 return xDrawPage;
605 void SAL_CALL SvxUnoDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
607 ::SolarMutexGuard aGuard;
609 sal_uInt16 nPageCount = mrModel.mpDoc->GetPageCount();
610 if( nPageCount <= 1 )
611 return;
613 // get pPage from xPage and get Id (nPos)
614 SvxDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
615 if( pSvxPage )
617 SdrPage* pPage = pSvxPage->GetSdrPage();
618 if(pPage)
620 sal_uInt16 nPage = pPage->GetPageNum();
621 mrModel.mpDoc->DeletePage( nPage );
626 // XServiceInfo
628 OUString SAL_CALL SvxUnoDrawPagesAccess::getImplementationName( )
630 return "SvxUnoDrawPagesAccess";
633 sal_Bool SAL_CALL SvxUnoDrawPagesAccess::supportsService( const OUString& ServiceName )
635 return cppu::supportsService(this, ServiceName);
638 uno::Sequence< OUString > SAL_CALL SvxUnoDrawPagesAccess::getSupportedServiceNames( )
640 return { "com.sun.star.drawing.DrawPages" };
643 css::uno::Reference< css::container::XIndexReplace > SvxCreateNumRule(SdrModel* pModel)
645 const SvxNumRule* pDefaultRule = nullptr;
646 if( pModel )
648 const SvxNumBulletItem* pItem = pModel->GetItemPool().GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);
649 if( pItem )
651 pDefaultRule = &pItem->GetNumRule();
655 if( pDefaultRule )
657 return SvxCreateNumRule( *pDefaultRule );
659 else
661 SvxNumRule aTempRule( SvxNumRuleFlags::NONE, 10, false );
662 return SvxCreateNumRule( aTempRule );
667 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */