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