1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <com/sun/star/lang/XServiceInfo.hpp>
21 #include <com/sun/star/beans/PropertyState.hpp>
22 
23 #include <comphelper/propertysetinfo.hxx>
24 #include <cppuhelper/supportsservice.hxx>
25 #include <vcl/svapp.hxx>
26 #include <svx/unopool.hxx>
27 #include <svx/svdmodel.hxx>
28 #include <svx/svdpool.hxx>
29 #include <svx/unoprov.hxx>
30 #include <svx/unoshprp.hxx>
31 #include <svx/xflbstit.hxx>
32 #include <svx/xflbmtit.hxx>
33 #include <svx/svdetc.hxx>
34 #include <editeng/editeng.hxx>
35 #include <tools/debug.hxx>
36 
37 #include <memory>
38 
39 using namespace ::com::sun::star;
40 using namespace ::cppu;
41 
SvxUnoDrawPool(SdrModel * pModel,sal_Int32 nServiceId)42 SvxUnoDrawPool::SvxUnoDrawPool(SdrModel* pModel, sal_Int32 nServiceId)
43 : PropertySetHelper( SvxPropertySetInfoPool::getOrCreate( nServiceId ) ), mpModel( pModel )
44 {
45     init();
46 }
47 
48 /* deprecated */
SvxUnoDrawPool(SdrModel * pModel)49 SvxUnoDrawPool::SvxUnoDrawPool(SdrModel* pModel)
50 : PropertySetHelper( SvxPropertySetInfoPool::getOrCreate( SVXUNO_SERVICEID_COM_SUN_STAR_DRAWING_DEFAULTS ) ), mpModel( pModel )
51 {
52     init();
53 }
54 
~SvxUnoDrawPool()55 SvxUnoDrawPool::~SvxUnoDrawPool() noexcept
56 {
57 }
58 
init()59 void SvxUnoDrawPool::init()
60 {
61     mpDefaultsPool = new SdrItemPool();
62     rtl::Reference<SfxItemPool> pOutlPool = EditEngine::CreatePool();
63     mpDefaultsPool->SetSecondaryPool(pOutlPool.get());
64 
65     SdrModel::SetTextDefaults( mpDefaultsPool.get(), SdrEngineDefaults::GetFontHeight() );
66     mpDefaultsPool->SetDefaultMetric(SdrEngineDefaults::GetMapUnit());
67     mpDefaultsPool->FreezeIdRanges();
68 }
69 
getModelPool(bool bReadOnly)70 SfxItemPool* SvxUnoDrawPool::getModelPool( bool bReadOnly ) noexcept
71 {
72     if( mpModel )
73     {
74         return &mpModel->GetItemPool();
75     }
76     else
77     {
78         if( bReadOnly )
79             return mpDefaultsPool.get();
80         else
81             return nullptr;
82     }
83 }
84 
getAny(SfxItemPool const * pPool,const comphelper::PropertyMapEntry * pEntry,uno::Any & rValue)85 void SvxUnoDrawPool::getAny( SfxItemPool const * pPool, const comphelper::PropertyMapEntry* pEntry, uno::Any& rValue )
86 {
87     switch( pEntry->mnHandle )
88     {
89     case OWN_ATTR_FILLBMP_MODE:
90         {
91             if (pPool->GetDefaultItem(XATTR_FILLBMP_TILE).GetValue())
92             {
93                 rValue <<= drawing::BitmapMode_REPEAT;
94             }
95             else if (pPool->GetDefaultItem(XATTR_FILLBMP_STRETCH).GetValue())
96             {
97                 rValue <<= drawing::BitmapMode_STRETCH;
98             }
99             else
100             {
101                 rValue <<= drawing::BitmapMode_NO_REPEAT;
102             }
103             break;
104         }
105     default:
106         {
107             const MapUnit eMapUnit = pPool->GetMetric(static_cast<sal_uInt16>(pEntry->mnHandle));
108 
109             sal_uInt8 nMemberId = pEntry->mnMemberId;
110             if( eMapUnit == MapUnit::Map100thMM )
111                 nMemberId &= (~CONVERT_TWIPS);
112 
113             // Assure, that ID is a Which-ID (it could be a Slot-ID.)
114             // Thus, convert handle to Which-ID.
115             pPool->GetDefaultItem( pPool->GetWhich( static_cast<sal_uInt16>(pEntry->mnHandle) ) ).QueryValue( rValue, nMemberId );
116         }
117     }
118 
119 
120     // check for needed metric translation
121     const MapUnit eMapUnit = pPool->GetMetric(static_cast<sal_uInt16>(pEntry->mnHandle));
122     if(pEntry->mnMoreFlags & PropertyMoreFlags::METRIC_ITEM && eMapUnit != MapUnit::Map100thMM)
123     {
124         SvxUnoConvertToMM( eMapUnit, rValue );
125     }
126     // convert int32 to correct enum type if needed
127     else if ( pEntry->maType.getTypeClass() == uno::TypeClass_ENUM && rValue.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
128     {
129         sal_Int32 nEnum;
130         rValue >>= nEnum;
131 
132         rValue.setValue( &nEnum, pEntry->maType );
133     }
134 }
135 
putAny(SfxItemPool * pPool,const comphelper::PropertyMapEntry * pEntry,const uno::Any & rValue)136 void SvxUnoDrawPool::putAny( SfxItemPool* pPool, const comphelper::PropertyMapEntry* pEntry, const uno::Any& rValue )
137 {
138     uno::Any aValue( rValue );
139 
140     const MapUnit eMapUnit = pPool->GetMetric(static_cast<sal_uInt16>(pEntry->mnHandle));
141     if(pEntry->mnMoreFlags & PropertyMoreFlags::METRIC_ITEM && eMapUnit != MapUnit::Map100thMM)
142     {
143         SvxUnoConvertFromMM( eMapUnit, aValue );
144     }
145 
146     // Assure, that ID is a Which-ID (it could be a Slot-ID.)
147     // Thus, convert handle to Which-ID.
148     const sal_uInt16 nWhich = pPool->GetWhich( static_cast<sal_uInt16>(pEntry->mnHandle) );
149     switch( nWhich )
150     {
151         case OWN_ATTR_FILLBMP_MODE:
152             do
153             {
154                 drawing::BitmapMode eMode;
155                 if(!(aValue >>= eMode) )
156                 {
157                     sal_Int32 nMode = 0;
158                     if(!(aValue >>= nMode))
159                         throw lang::IllegalArgumentException();
160 
161                     eMode = static_cast<drawing::BitmapMode>(nMode);
162                 }
163 
164                 pPool->SetPoolDefaultItem( XFillBmpStretchItem( eMode == drawing::BitmapMode_STRETCH ) );
165                 pPool->SetPoolDefaultItem( XFillBmpTileItem( eMode == drawing::BitmapMode_REPEAT ) );
166                 return;
167             }
168             while(false);
169 
170     default:
171         {
172             std::unique_ptr<SfxPoolItem> pNewItem( pPool->GetDefaultItem( nWhich ).Clone() );
173             sal_uInt8 nMemberId = pEntry->mnMemberId;
174             if( pPool->GetMetric(nWhich) == MapUnit::Map100thMM )
175                 nMemberId &= (~CONVERT_TWIPS);
176 
177             if( !pNewItem->PutValue( aValue, nMemberId ) )
178                 throw lang::IllegalArgumentException();
179 
180             pPool->SetPoolDefaultItem( *pNewItem );
181         }
182     }
183 }
184 
_setPropertyValues(const comphelper::PropertyMapEntry ** ppEntries,const uno::Any * pValues)185 void SvxUnoDrawPool::_setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const uno::Any* pValues )
186 {
187     SolarMutexGuard aGuard;
188 
189     SfxItemPool* pPool = getModelPool( false );
190 
191     DBG_ASSERT( pPool, "I need a SfxItemPool!" );
192     if( nullptr == pPool )
193         throw beans::UnknownPropertyException( "no pool, no properties..", static_cast<cppu::OWeakObject*>(this));
194 
195     while( *ppEntries )
196         putAny( pPool, *ppEntries++, *pValues++ );
197 }
198 
_getPropertyValues(const comphelper::PropertyMapEntry ** ppEntries,uno::Any * pValue)199 void SvxUnoDrawPool::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, uno::Any* pValue )
200 {
201     SolarMutexGuard aGuard;
202 
203     SfxItemPool* pPool = getModelPool( true );
204 
205     DBG_ASSERT( pPool, "I need a SfxItemPool!" );
206     if( nullptr == pPool )
207         throw beans::UnknownPropertyException( "no pool, no properties..", static_cast<cppu::OWeakObject*>(this));
208 
209     while( *ppEntries )
210         getAny( pPool, *ppEntries++, *pValue++ );
211 }
212 
_getPropertyStates(const comphelper::PropertyMapEntry ** ppEntries,beans::PropertyState * pStates)213 void SvxUnoDrawPool::_getPropertyStates( const comphelper::PropertyMapEntry** ppEntries, beans::PropertyState* pStates )
214 {
215     SolarMutexGuard aGuard;
216 
217     SfxItemPool* pPool = getModelPool( true );
218 
219     if( pPool && pPool != mpDefaultsPool.get() )
220     {
221         while( *ppEntries )
222         {
223             //Assure, that ID is a Which-ID (it could be a Slot-ID.)
224             // Thus, convert handle to Which-ID.
225             const sal_uInt16 nWhich = pPool->GetWhich( static_cast<sal_uInt16>((*ppEntries)->mnHandle) );
226 
227             switch( nWhich )
228             {
229             case OWN_ATTR_FILLBMP_MODE:
230                 {
231                     // use method <IsStaticDefaultItem(..)> instead of using
232                     // probably incompatible item pool <mpDefaultPool>.
233                     if ( IsStaticDefaultItem( &(pPool->GetDefaultItem( XATTR_FILLBMP_STRETCH )) ) ||
234                          IsStaticDefaultItem( &(pPool->GetDefaultItem( XATTR_FILLBMP_TILE )) ) )
235                     {
236                         *pStates = beans::PropertyState_DEFAULT_VALUE;
237                     }
238                     else
239                     {
240                         *pStates = beans::PropertyState_DIRECT_VALUE;
241                     }
242                 }
243                 break;
244             case OWN_ATTR_TEXTCOLUMNS:
245                 if (IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_NUMBER)))
246                     && IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_SPACING))))
247                     *pStates = beans::PropertyState_DEFAULT_VALUE;
248                 else
249                     *pStates = beans::PropertyState_DIRECT_VALUE;
250                 break;
251             default:
252                 //#i18732# - correction:
253                 // use method <IsStaticDefaultItem(..)> instead of using probably
254                 // incompatible item pool <mpDefaultPool>.
255                 const SfxPoolItem& r1 = pPool->GetDefaultItem( nWhich );
256                 //const SfxPoolItem& r2 = mpDefaultPool->GetDefaultItem( nWhich );
257 
258                 if ( IsStaticDefaultItem( &r1 ) )
259                 {
260                     *pStates = beans::PropertyState_DEFAULT_VALUE;
261                 }
262                 else
263                 {
264                     *pStates = beans::PropertyState_DIRECT_VALUE;
265                 }
266             }
267 
268             pStates++;
269             ppEntries++;
270         }
271     }
272     else
273     {
274         // as long as we have no model, all properties are default
275         while( *ppEntries++ )
276             *pStates++ = beans::PropertyState_DEFAULT_VALUE;
277         return;
278     }
279 }
280 
_setPropertyToDefault(const comphelper::PropertyMapEntry * pEntry)281 void SvxUnoDrawPool::_setPropertyToDefault( const comphelper::PropertyMapEntry* pEntry )
282 {
283     SolarMutexGuard aGuard;
284 
285     SfxItemPool* pPool = getModelPool( true );
286 
287     // Assure, that ID is a Which-ID (it could be a Slot-ID.)
288     // Thus, convert handle to Which-ID.
289     const sal_uInt16 nWhich = pPool->GetWhich( static_cast<sal_uInt16>(pEntry->mnHandle) );
290     if ( pPool && pPool != mpDefaultsPool.get() )
291     {
292         // use method <ResetPoolDefaultItem(..)> instead of using probably incompatible item pool <mpDefaultsPool>.
293         pPool->ResetPoolDefaultItem( nWhich );
294     }
295 }
296 
_getPropertyDefault(const comphelper::PropertyMapEntry * pEntry)297 uno::Any SvxUnoDrawPool::_getPropertyDefault( const comphelper::PropertyMapEntry* pEntry )
298 {
299     SolarMutexGuard aGuard;
300     //#i18732# - use method <GetPoolDefaultItem(..)> instead of
301     // using probably incompatible item pool <mpDefaultsPool>
302     uno::Any aAny;
303     SfxItemPool* pPool = getModelPool( true );
304     const sal_uInt16 nWhich = pPool->GetWhich( static_cast<sal_uInt16>(pEntry->mnHandle) );
305     const SfxPoolItem *pItem = pPool->GetPoolDefaultItem ( nWhich );
306     if (pItem)
307     {
308         pItem->QueryValue( aAny, pEntry->mnMemberId );
309     }
310 
311     return aAny;
312 }
313 
314 // XInterface
315 
queryInterface(const uno::Type & rType)316 uno::Any SAL_CALL SvxUnoDrawPool::queryInterface( const uno::Type & rType )
317 {
318     return OWeakAggObject::queryInterface( rType );
319 }
320 
queryAggregation(const uno::Type & rType)321 uno::Any SAL_CALL SvxUnoDrawPool::queryAggregation( const uno::Type & rType )
322 {
323     uno::Any aAny;
324 
325     if( rType == cppu::UnoType<lang::XServiceInfo>::get())
326         aAny <<= uno::Reference< lang::XServiceInfo >(this);
327     else if( rType == cppu::UnoType<lang::XTypeProvider>::get())
328         aAny <<= uno::Reference< lang::XTypeProvider >(this);
329     else if( rType == cppu::UnoType<beans::XPropertySet>::get())
330         aAny <<= uno::Reference< beans::XPropertySet >(this);
331     else if( rType == cppu::UnoType<beans::XPropertyState>::get())
332         aAny <<= uno::Reference< beans::XPropertyState >(this);
333     else if( rType == cppu::UnoType<beans::XMultiPropertySet>::get())
334         aAny <<= uno::Reference< beans::XMultiPropertySet >(this);
335     else
336         aAny = OWeakAggObject::queryAggregation( rType );
337 
338     return aAny;
339 }
340 
getTypes()341 uno::Sequence< uno::Type > SAL_CALL SvxUnoDrawPool::getTypes()
342 {
343     static const uno::Sequence aTypes {
344         cppu::UnoType<uno::XAggregation>::get(),
345         cppu::UnoType<lang::XServiceInfo>::get(),
346         cppu::UnoType<lang::XTypeProvider>::get(),
347         cppu::UnoType<beans::XPropertySet>::get(),
348         cppu::UnoType<beans::XPropertyState>::get(),
349         cppu::UnoType<beans::XMultiPropertySet>::get() };
350     return aTypes;
351 }
352 
getImplementationId()353 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoDrawPool::getImplementationId()
354 {
355     return css::uno::Sequence<sal_Int8>();
356 }
357 
358 // XServiceInfo
supportsService(const OUString & ServiceName)359 sal_Bool SAL_CALL SvxUnoDrawPool::supportsService( const  OUString& ServiceName )
360 {
361     return cppu::supportsService(this, ServiceName);
362 }
363 
getImplementationName()364 OUString SAL_CALL SvxUnoDrawPool::getImplementationName()
365 {
366     return "SvxUnoDrawPool";
367 }
368 
getSupportedServiceNames()369 uno::Sequence< OUString > SAL_CALL SvxUnoDrawPool::getSupportedServiceNames(  )
370 {
371     uno::Sequence<OUString> aSNS { "com.sun.star.drawing.Defaults" };
372     return aSNS;
373 }
374 
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
376