Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / unodraw / unomod.cxx
blob4a562caeadad2961a713c22b096d9760e9a4945c
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/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>
57 //-
59 using namespace ::com::sun::star;
61 //-
63 #define QUERYINT( xint ) \
64 if( rType == cppu::UnoType<xint>::get() ) \
65 aAny <<= uno::Reference< xint >(this)
67 //-
69 class SvxUnoDrawPagesAccess : public ::cppu::WeakImplHelper< css::drawing::XDrawPages, css::lang::XServiceInfo >
71 private:
72 SvxUnoDrawingModel& mrModel;
74 public:
75 explicit SvxUnoDrawPagesAccess( SvxUnoDrawingModel& rMyModel ) noexcept;
77 // XDrawPages
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;
81 // XIndexAccess
82 virtual sal_Int32 SAL_CALL getCount() override ;
83 virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
85 // XElementAccess
86 virtual css::uno::Type SAL_CALL getElementType() override;
87 virtual sal_Bool SAL_CALL hasElements() override;
89 // XServiceInfo
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;
94 //-
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.
111 @returns
112 true if the SdrHint could be translated to an EventObject<br>
113 false if not
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();
130 // break;
131 case SdrHintKind::PageOrderChange: // draw or master page order changed (Insert/Remove/ChangePos)
132 aEvent.EventName = "PageOrderModified";
133 pPage = pSdrHint->GetPage();
134 break;
135 case SdrHintKind::ObjectChange: // object changed
136 aEvent.EventName = "ShapeModified";
137 pObj = pSdrHint->GetObject();
138 break;
139 case SdrHintKind::ObjectInserted: // add new draw object
140 aEvent.EventName = "ShapeInserted";
141 pObj = pSdrHint->GetObject();
142 break;
143 case SdrHintKind::ObjectRemoved: // removed draw object from list
144 aEvent.EventName = "ShapeRemoved";
145 pObj = pSdrHint->GetObject();
146 break;
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
150 default:
151 return false;
154 if( pObj )
155 aEvent.Source = const_cast<SdrObject*>(pObj)->getUnoShape();
156 else if( pPage )
157 aEvent.Source = const_cast<SdrPage*>(pPage)->getUnoPage();
158 else
159 aEvent.Source = const_cast<SdrModel*>(pDoc)->getUnoModel();
161 return true;
164 namespace {
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 );
172 if( nType )
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() ) );
183 return xRet;
185 else if (rServiceSpecifier == "com.sun.star.text.TextColumns")
187 return SvxXTextColumns_createInstance();
190 uno::Reference< uno::XInterface > xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier ) );
191 if( !xRet.is() )
192 throw lang::ServiceNotRegisteredException("unknown service: " + rServiceSpecifier);
194 return xRet;
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 )
211 OUString arg;
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");
233 return *mpDoc;
236 SvxUnoDrawingModel::SvxUnoDrawingModel(SdrModel* pDoc) noexcept
237 : SfxBaseModel(nullptr),
238 mpDoc(pDoc)
242 SvxUnoDrawingModel::~SvxUnoDrawingModel() noexcept
246 uno::Any SAL_CALL SvxUnoDrawingModel::queryInterface( const uno::Type & rType )
248 uno::Any aAny;
250 QUERYINT(lang::XServiceInfo);
251 else QUERYINT(lang::XMultiServiceFactory);
252 else QUERYINT(drawing::XDrawPagesSupplier);
253 else QUERYINT(css::ucb::XAnyCompareFactory);
254 else
255 return SfxBaseModel::queryInterface( rType );
257 return aAny;
260 // XTypeProvider
261 uno::Sequence< uno::Type > SAL_CALL SvxUnoDrawingModel::getTypes( )
263 if( !maTypeSequence.hasElements() )
265 maTypeSequence = comphelper::concatSequences( SfxBaseModel::getTypes(),
266 uno::Sequence {
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( )
282 if( mpDoc )
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);
309 return xDrawPages;
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 );
321 return mxDashTable;
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 );
333 return mxHatchTable;
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;
448 else
450 throw lang::ServiceNotRegisteredException();
453 // create the API wrapper
454 rtl::Reference<SvxShape> xNewShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, "" );
455 pShape = xNewShape.get();
457 // set shape type
458 if( pShape )
459 pShape->SetShapeType(aServiceSpecifier);
461 xRet = static_cast<uno::XWeak*>(pShape);
463 else
465 xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
468 return xRet;
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
526 : mrModel(rMyModel)
530 // XIndexAccess
531 sal_Int32 SAL_CALL SvxUnoDrawPagesAccess::getCount()
533 ::SolarMutexGuard aGuard;
535 sal_Int32 nCount = 0;
537 if( mrModel.mpDoc )
538 nCount = mrModel.mpDoc->GetPageCount();
540 return nCount;
543 uno::Any SAL_CALL SvxUnoDrawPagesAccess::getByIndex( sal_Int32 Index )
545 ::SolarMutexGuard aGuard;
547 uno::Any aAny;
549 if( mrModel.mpDoc )
551 if( (Index < 0) || (Index >= mrModel.mpDoc->GetPageCount() ) )
552 throw lang::IndexOutOfBoundsException();
554 SdrPage* pPage = mrModel.mpDoc->GetPage( static_cast<sal_uInt16>(Index) );
555 if( pPage )
557 uno::Reference< uno::XInterface > xPage( pPage->mxUnoPage );
559 if( !xPage.is() )
561 if( dynamic_cast<FmFormModel*>( mrModel.mpDoc ) )
562 xPage = static_cast<drawing::XDrawPage*>(new SvxFmDrawPage( pPage ));
563 else
564 xPage = static_cast<drawing::XDrawPage*>(new SvxDrawPage( pPage ));
566 pPage->mxUnoPage = xPage;
569 aAny <<= xPage;
572 return aAny;
575 // XElementAccess
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;
586 // XDrawPages
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;
596 if( mrModel.mpDoc )
598 rtl::Reference<SdrPage> pPage;
600 if( auto pFormModel = dynamic_cast<FmFormModel*>( mrModel.mpDoc ) )
601 pPage = new FmFormPage(*pFormModel);
602 else
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 );
609 return xDrawPage;
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 )
618 return;
620 // get pPage from xPage and get Id (nPos)
621 SvxDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
622 if( pSvxPage )
624 SdrPage* pPage = pSvxPage->GetSdrPage();
625 if(pPage)
627 sal_uInt16 nPage = pPage->GetPageNum();
628 mrModel.mpDoc->DeletePage( nPage );
633 // XServiceInfo
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;
653 if( pModel )
655 const SvxNumBulletItem* pItem = pModel->GetItemPool().GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);
656 if( pItem )
658 pDefaultRule = &pItem->GetNumRule();
662 if( pDefaultRule )
664 return SvxCreateNumRule( *pDefaultRule );
666 else
668 SvxNumRule aTempRule( SvxNumRuleFlags::NONE, 10, false );
669 return SvxCreateNumRule( aTempRule );
674 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */