Line data Source code
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/util/XModifiable.hpp>
21 : #include <com/sun/star/embed/XLinkageSupport.hpp>
22 : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
23 : #include <com/sun/star/embed/Aspects.hpp>
24 : #include <com/sun/star/task/XInteractionHandler.hpp>
25 : #include <com/sun/star/ucb/CommandFailedException.hpp>
26 :
27 : #include <vcl/virdev.hxx>
28 : #include <svx/svdoole2.hxx>
29 : #include <svx/svdomedia.hxx>
30 : #include <svx/svdpool.hxx>
31 : #include <comphelper/classids.hxx>
32 : #include <sfx2/frmdescr.hxx>
33 : #include <vcl/svapp.hxx>
34 : #include <osl/mutex.hxx>
35 :
36 : #include <toolkit/helper/vclunohelper.hxx>
37 : #include <sfx2/objsh.hxx>
38 : #include <sfx2/docfile.hxx>
39 :
40 : #include <sot/storage.hxx>
41 : #include <sot/exchange.hxx>
42 : #include <vcl/FilterConfigItem.hxx>
43 :
44 : #include <svx/svdmodel.hxx>
45 : #include "shapeimpl.hxx"
46 :
47 : #include <svx/unoshprp.hxx>
48 :
49 : #include "svx/unoapi.hxx"
50 : #include "svx/svdpagv.hxx"
51 : #include "svx/svdview.hxx"
52 : #include "svdglob.hxx"
53 : #include "svx/svdstr.hrc"
54 : #include <svdoopengl.hxx>
55 : #include <vcl/wmf.hxx>
56 : #include <svtools/embedhlp.hxx>
57 :
58 :
59 : using namespace ::osl;
60 : using namespace ::cppu;
61 : using namespace ::com::sun::star;
62 : using namespace ::com::sun::star::uno;
63 : using namespace ::com::sun::star::lang;
64 : using namespace ::com::sun::star::container;
65 : using namespace ::com::sun::star::beans;
66 :
67 :
68 0 : SvxOle2Shape::SvxOle2Shape( SdrObject* pObject ) throw()
69 0 : : SvxShapeText( pObject, getSvxMapProvider().GetMap(SVXMAP_OLE2),
70 0 : getSvxMapProvider().GetPropertySet(SVXMAP_OLE2,SdrObject::GetGlobalDrawObjectItemPool()) )
71 : {
72 0 : }
73 :
74 272 : SvxOle2Shape::SvxOle2Shape( SdrObject* pObject, const SfxItemPropertyMapEntry* pPropertyMap, const SvxItemPropertySet* pPropertySet ) throw ()
75 272 : : SvxShapeText( pObject, pPropertyMap, pPropertySet )
76 : {
77 272 : }
78 :
79 541 : SvxOle2Shape::~SvxOle2Shape() throw()
80 : {
81 541 : }
82 :
83 8844 : ::com::sun::star::uno::Any SAL_CALL SvxOle2Shape::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception)
84 : {
85 8844 : return SvxShapeText::queryAggregation( rType );
86 : }
87 :
88 : //XPropertySet
89 3235 : bool SvxOle2Shape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
90 : {
91 3235 : switch( pProperty->nWID )
92 : {
93 : case OWN_ATTR_OLE_VISAREA:
94 : {
95 : // TODO/LATER: seems to make no sense for iconified object
96 :
97 0 : awt::Rectangle aVisArea;
98 0 : if( (rValue >>= aVisArea) && mpObj->ISA(SdrOle2Obj))
99 : {
100 0 : Size aTmp( aVisArea.X + aVisArea.Width, aVisArea.Y + aVisArea.Height );
101 0 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef();
102 0 : if( xObj.is() )
103 : {
104 : try
105 : {
106 0 : MapUnit aMapUnit( MAP_100TH_MM ); // the API handles with MAP_100TH_MM map mode
107 0 : MapUnit aObjUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT ) );
108 0 : aTmp = OutputDevice::LogicToLogic( aTmp, aMapUnit, aObjUnit );
109 0 : xObj->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, awt::Size( aTmp.Width(), aTmp.Height() ) );
110 : }
111 0 : catch( uno::Exception& )
112 : {
113 : OSL_FAIL( "Couldn't set the visual area for the object!\n" );
114 : }
115 : }
116 :
117 0 : return true;
118 : }
119 0 : break;
120 : }
121 : case OWN_ATTR_OLE_ASPECT:
122 : {
123 48 : sal_Int64 nAspect = 0;
124 48 : if( rValue >>= nAspect )
125 : {
126 48 : static_cast<SdrOle2Obj*>(mpObj.get())->SetAspect( nAspect );
127 48 : return true;
128 : }
129 0 : break;
130 : }
131 : case OWN_ATTR_CLSID:
132 : {
133 167 : OUString aCLSID;
134 167 : if( rValue >>= aCLSID )
135 : {
136 : // init a ole object with a global name
137 167 : SvGlobalName aClassName;
138 167 : if( aClassName.MakeId( aCLSID ) )
139 : {
140 167 : if( createObject( aClassName ) )
141 167 : return true;
142 0 : }
143 : }
144 0 : break;
145 : }
146 : case OWN_ATTR_THUMBNAIL:
147 : {
148 0 : OUString aURL;
149 0 : if( rValue >>= aURL )
150 : {
151 0 : GraphicObject aGrafObj( GraphicObject::CreateGraphicObjectFromURL( aURL ) );
152 0 : static_cast<SdrOle2Obj*>(mpObj.get())->SetGraphic( &aGrafObj.GetGraphic() );
153 0 : return true;
154 : }
155 0 : break;
156 : }
157 : case OWN_ATTR_VALUE_GRAPHIC:
158 : {
159 2 : uno::Reference< graphic::XGraphic > xGraphic( rValue, uno::UNO_QUERY );
160 2 : if( xGraphic.is() )
161 : {
162 2 : SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
163 2 : if( pOle )
164 : {
165 2 : GraphicObject aGrafObj( xGraphic );
166 4 : const Graphic aGraphic( aGrafObj.GetGraphic() );
167 4 : pOle->SetGraphicToObj( aGraphic, OUString() );
168 : }
169 2 : return true;
170 : }
171 0 : break;
172 : }
173 : case OWN_ATTR_PERSISTNAME:
174 : {
175 214 : OUString aPersistName;
176 214 : if( rValue >>= aPersistName )
177 : {
178 : SdrOle2Obj *pOle;
179 : #if OSL_DEBUG_LEVEL > 0
180 : pOle = dynamic_cast<SdrOle2Obj*>(mpObj.get());
181 : assert(pOle);
182 : #else
183 214 : pOle = static_cast<SdrOle2Obj*>(mpObj.get());
184 : #endif
185 214 : pOle->SetPersistName( aPersistName );
186 214 : return true;
187 : }
188 0 : break;
189 : }
190 : case OWN_ATTR_OLE_LINKURL:
191 : {
192 0 : OUString aLinkURL;
193 0 : if( rValue >>= aLinkURL )
194 : {
195 0 : createLink( aLinkURL );
196 0 : return true;
197 : }
198 0 : break;
199 : }
200 : default:
201 2804 : return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
202 : }
203 :
204 0 : throw IllegalArgumentException();
205 : }
206 :
207 808 : bool SvxOle2Shape::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
208 : {
209 808 : switch( pProperty->nWID )
210 : {
211 : case OWN_ATTR_CLSID:
212 : {
213 8 : OUString aCLSID;
214 16 : SvGlobalName aClassName = GetClassName_Impl(aCLSID);
215 8 : rValue <<= aCLSID;
216 16 : break;
217 : }
218 :
219 : case OWN_ATTR_INTERNAL_OLE:
220 : {
221 8 : OUString sCLSID;
222 8 : rValue <<= SotExchange::IsInternal( GetClassName_Impl(sCLSID) );
223 8 : break;
224 : }
225 :
226 : case OWN_ATTR_METAFILE:
227 : {
228 0 : SdrOle2Obj* pObj = dynamic_cast<SdrOle2Obj*>(mpObj.get());
229 0 : if( pObj )
230 : {
231 0 : const Graphic* pGraphic = pObj->GetGraphic();
232 0 : if( pGraphic )
233 : {
234 0 : bool bIsWMF = false;
235 0 : if ( pGraphic->IsLink() )
236 : {
237 0 : GfxLink aLnk = pGraphic->GetLink();
238 0 : if ( aLnk.GetType() == GFX_LINK_TYPE_NATIVE_WMF )
239 : {
240 0 : bIsWMF = true;
241 0 : uno::Sequence<sal_Int8> aSeq(reinterpret_cast<sal_Int8 const *>(aLnk.GetData()), (sal_Int32) aLnk.GetDataSize());
242 0 : rValue <<= aSeq;
243 0 : }
244 : }
245 0 : if ( !bIsWMF )
246 : {
247 : // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
248 0 : GDIMetaFile aMtf(pObj->GetGraphic()->GetGDIMetaFile());
249 0 : SvMemoryStream aDestStrm( 65535, 65535 );
250 0 : ConvertGDIMetaFileToWMF( aMtf, aDestStrm, NULL, false );
251 : const uno::Sequence<sal_Int8> aSeq(
252 0 : static_cast< const sal_Int8* >(aDestStrm.GetData()),
253 0 : aDestStrm.GetEndOfData());
254 0 : rValue <<= aSeq;
255 : }
256 : }
257 : }
258 : else
259 : {
260 0 : rValue = GetBitmap( true );
261 : }
262 0 : break;
263 : }
264 :
265 : case OWN_ATTR_OLE_VISAREA:
266 : {
267 0 : awt::Rectangle aVisArea;
268 0 : if( mpObj->ISA(SdrOle2Obj))
269 : {
270 0 : MapMode aMapMode( MAP_100TH_MM ); // the API uses this map mode
271 0 : Size aTmp = static_cast<SdrOle2Obj*>(mpObj.get())->GetOrigObjSize( &aMapMode ); // get the size in the requested map mode
272 0 : aVisArea = awt::Rectangle( 0, 0, aTmp.Width(), aTmp.Height() );
273 : }
274 :
275 0 : rValue <<= aVisArea;
276 0 : break;
277 : }
278 :
279 : case OWN_ATTR_OLESIZE:
280 : {
281 0 : Size aTmp( static_cast<SdrOle2Obj*>(mpObj.get())->GetOrigObjSize() );
282 0 : rValue <<= awt::Size( aTmp.Width(), aTmp.Height() );
283 0 : break;
284 : }
285 :
286 : case OWN_ATTR_OLE_ASPECT:
287 : {
288 4 : rValue <<= static_cast<SdrOle2Obj*>(mpObj.get())->GetAspect();
289 4 : break;
290 : }
291 :
292 : case OWN_ATTR_OLEMODEL:
293 : case OWN_ATTR_OLE_EMBEDDED_OBJECT:
294 : case OWN_ATTR_OLE_EMBEDDED_OBJECT_NONEWCLIENT:
295 : {
296 292 : SdrOle2Obj* pObj = dynamic_cast<SdrOle2Obj*>( mpObj.get() );
297 292 : if( pObj )
298 : {
299 292 : uno::Reference < embed::XEmbeddedObject > xObj( pObj->GetObjRef() );
300 584 : if ( xObj.is()
301 292 : && ( pProperty->nWID == OWN_ATTR_OLE_EMBEDDED_OBJECT || pProperty->nWID == OWN_ATTR_OLE_EMBEDDED_OBJECT_NONEWCLIENT || svt::EmbeddedObjectRef::TryRunningState( xObj ) ) )
302 : {
303 : // Discussed with CL fue to the before GetPaintingPageView
304 : // usage. Removed it, former fallback is used now
305 292 : if ( pProperty->nWID == OWN_ATTR_OLEMODEL || pProperty->nWID == OWN_ATTR_OLE_EMBEDDED_OBJECT )
306 : {
307 : #if OSL_DEBUG_LEVEL > 0
308 : const bool bSuccess(pObj->AddOwnLightClient());
309 : OSL_ENSURE( bSuccess, "An object without client is provided!" );
310 : #else
311 292 : pObj->AddOwnLightClient();
312 : #endif
313 : }
314 :
315 292 : if ( pProperty->nWID == OWN_ATTR_OLEMODEL )
316 206 : rValue <<= pObj->GetObjRef()->getComponent();
317 : else
318 86 : rValue <<= xObj;
319 292 : }
320 : }
321 292 : break;
322 : }
323 :
324 : case OWN_ATTR_VALUE_GRAPHIC:
325 : {
326 0 : uno::Reference< graphic::XGraphic > xGraphic;
327 0 : const Graphic* pGraphic = static_cast<SdrOle2Obj*>( mpObj.get() )->GetGraphic();
328 0 : if( pGraphic )
329 0 : xGraphic = pGraphic->GetXGraphic();
330 0 : rValue <<= xGraphic;
331 0 : break;
332 : }
333 :
334 : case OWN_ATTR_THUMBNAIL:
335 : {
336 0 : OUString aURL;
337 0 : SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
338 0 : if( pOle )
339 : {
340 0 : const Graphic* pGraphic = pOle->GetGraphic();
341 :
342 : // if there isn't already a preview graphic set, check if we need to generate
343 : // one if model says so
344 0 : if( pGraphic == NULL && !pOle->IsEmptyPresObj() && mpModel->IsSaveOLEPreview() )
345 0 : pGraphic = pOle->GetGraphic();
346 :
347 0 : if( pGraphic )
348 : {
349 0 : GraphicObject aObj( *pGraphic );
350 0 : aURL = UNO_NAME_GRAPHOBJ_URLPREFIX;
351 0 : aURL += OStringToOUString(aObj.GetUniqueID(),
352 0 : RTL_TEXTENCODING_ASCII_US);
353 : }
354 : }
355 0 : rValue <<= aURL;
356 0 : break;
357 : }
358 : case OWN_ATTR_PERSISTNAME:
359 : {
360 205 : OUString aPersistName;
361 205 : SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
362 :
363 205 : if( pOle )
364 : {
365 205 : aPersistName = pOle->GetPersistName();
366 205 : if( !aPersistName.isEmpty() )
367 : {
368 38 : ::comphelper::IEmbeddedHelper *pPersist = mpObj->GetModel()->GetPersist();
369 38 : if( (NULL == pPersist) || !pPersist->getEmbeddedObjectContainer().HasEmbeddedObject( pOle->GetPersistName() ) )
370 0 : aPersistName.clear();
371 : }
372 : }
373 :
374 205 : rValue <<= aPersistName;
375 205 : break;
376 : }
377 : case OWN_ATTR_OLE_LINKURL:
378 : {
379 4 : OUString aLinkURL;
380 4 : SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
381 :
382 4 : if( pOle )
383 : {
384 4 : uno::Reference< embed::XLinkageSupport > xLink( pOle->GetObjRef(), uno::UNO_QUERY );
385 4 : if ( xLink.is() && xLink->isLink() )
386 0 : aLinkURL = xLink->getLinkURL();
387 : }
388 :
389 4 : rValue <<= aLinkURL;
390 4 : break;
391 : }
392 : default:
393 287 : return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
394 : }
395 :
396 521 : return true;
397 : }
398 :
399 167 : bool SvxOle2Shape::createObject( const SvGlobalName &aClassName )
400 : {
401 : DBG_TESTSOLARMUTEX();
402 :
403 167 : SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
404 167 : if ( !pOle2Obj || !pOle2Obj->IsEmpty() )
405 0 : return false;
406 :
407 : // create storage and inplace object
408 167 : ::comphelper::IEmbeddedHelper* pPersist = mpModel->GetPersist();
409 167 : OUString aPersistName;
410 334 : OUString aTmpStr;
411 167 : if( SvxShape::getPropertyValue( UNO_NAME_OLE2_PERSISTNAME ) >>= aTmpStr )
412 167 : aPersistName = aTmpStr;
413 :
414 : //TODO/LATER: how to cope with creation failure?!
415 334 : uno::Reference < embed::XEmbeddedObject > xObj( pPersist->getEmbeddedObjectContainer().CreateEmbeddedObject( aClassName.GetByteSequence(), aPersistName ) );
416 167 : if( xObj.is() )
417 : {
418 167 : Rectangle aRect = pOle2Obj->GetLogicRect();
419 167 : if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 )
420 : {
421 : // TODO/LATER: is it possible that this method is used to create an iconified object?
422 : // default size
423 : try
424 : {
425 0 : awt::Size aSz = xObj->getVisualAreaSize( pOle2Obj->GetAspect() );
426 0 : aRect.SetSize( Size( aSz.Width, aSz.Height ) );
427 : }
428 0 : catch( embed::NoVisualAreaSizeException& )
429 : {}
430 0 : pOle2Obj->SetLogicRect( aRect );
431 : }
432 167 : else if (!aRect.IsEmpty()) //HACK: can aRect legally be empty?
433 : {
434 81 : awt::Size aSz;
435 81 : Size aSize = aRect.GetSize();
436 81 : aSz.Width = aSize.Width();
437 81 : aSz.Height = aSize.Height();
438 81 : xObj->setVisualAreaSize( pOle2Obj->GetAspect(), aSz );
439 : }
440 :
441 : // connect the object after the visual area is set
442 167 : SvxShape::setPropertyValue( UNO_NAME_OLE2_PERSISTNAME, Any( aTmpStr = aPersistName ) );
443 :
444 : // the object is inserted during setting of PersistName property usually
445 167 : if( pOle2Obj->IsEmpty() )
446 0 : pOle2Obj->SetObjRef( xObj );
447 : }
448 :
449 334 : return xObj.is();
450 : }
451 :
452 0 : bool SvxOle2Shape::createLink( const OUString& aLinkURL )
453 : {
454 : DBG_TESTSOLARMUTEX();
455 :
456 0 : SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
457 0 : if ( !pOle2Obj || !pOle2Obj->IsEmpty() )
458 0 : return false;
459 :
460 0 : OUString aPersistName;
461 :
462 0 : ::comphelper::IEmbeddedHelper* pPersist = mpModel->GetPersist();
463 :
464 0 : uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
465 0 : aMediaDescr[0].Name = "URL";
466 0 : aMediaDescr[0].Value <<= aLinkURL;
467 :
468 0 : uno::Reference< task::XInteractionHandler > xInteraction = pPersist->getInteractionHandler();
469 0 : if ( xInteraction.is() )
470 : {
471 0 : aMediaDescr.realloc( 2 );
472 0 : aMediaDescr[1].Name = "InteractionHandler";
473 0 : aMediaDescr[1].Value <<= xInteraction;
474 : }
475 :
476 : //TODO/LATER: how to cope with creation failure?!
477 : uno::Reference< embed::XEmbeddedObject > xObj =
478 0 : pPersist->getEmbeddedObjectContainer().InsertEmbeddedLink( aMediaDescr , aPersistName );
479 :
480 0 : if( xObj.is() )
481 : {
482 0 : Rectangle aRect = pOle2Obj->GetLogicRect();
483 0 : if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 )
484 : {
485 : // default size
486 : try
487 : {
488 0 : awt::Size aSz = xObj->getVisualAreaSize( pOle2Obj->GetAspect() );
489 0 : aRect.SetSize( Size( aSz.Width, aSz.Height ) );
490 : }
491 0 : catch( embed::NoVisualAreaSizeException& )
492 : {}
493 0 : pOle2Obj->SetLogicRect( aRect );
494 : }
495 : else
496 : {
497 0 : awt::Size aSz;
498 0 : Size aSize = pOle2Obj->GetLogicRect().GetSize();
499 0 : aSz.Width = aSize.Width();
500 0 : aSz.Height = aSize.Height();
501 0 : xObj->setVisualAreaSize( pOle2Obj->GetAspect(), aSz );
502 : }
503 :
504 : // connect the object after the visual area is set
505 0 : SvxShape::setPropertyValue( UNO_NAME_OLE2_PERSISTNAME, uno::makeAny( aPersistName ) );
506 :
507 : // the object is inserted during setting of PersistName property usually
508 0 : if ( pOle2Obj->IsEmpty() )
509 0 : pOle2Obj->SetObjRef( xObj );
510 : }
511 :
512 0 : return xObj.is();
513 : }
514 :
515 0 : void SvxOle2Shape::resetModifiedState()
516 : {
517 0 : ::comphelper::IEmbeddedHelper* pPersist = mpModel ? mpModel->GetPersist() : 0;
518 0 : if( pPersist && !pPersist->isEnableSetModified() )
519 : {
520 0 : SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
521 0 : if( pOle && !pOle->IsEmpty() )
522 : {
523 0 : uno::Reference < util::XModifiable > xMod( pOle->GetObjRef(), uno::UNO_QUERY );
524 0 : if( xMod.is() )
525 : // TODO/MBA: what's this?!
526 0 : xMod->setModified( sal_False );
527 : }
528 : }
529 0 : }
530 :
531 16 : const SvGlobalName SvxOle2Shape::GetClassName_Impl(OUString& rHexCLSID)
532 : {
533 : DBG_TESTSOLARMUTEX();
534 16 : SvGlobalName aClassName;
535 16 : SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( mpObj.get() );
536 :
537 16 : if( pOle2Obj )
538 : {
539 16 : rHexCLSID.clear();
540 :
541 16 : if( pOle2Obj->IsEmpty() )
542 : {
543 0 : ::comphelper::IEmbeddedHelper* pPersist = mpModel->GetPersist();
544 0 : if( pPersist )
545 : {
546 : uno::Reference < embed::XEmbeddedObject > xObj =
547 0 : pPersist->getEmbeddedObjectContainer().GetEmbeddedObject( pOle2Obj->GetPersistName() );
548 0 : if ( xObj.is() )
549 : {
550 0 : aClassName = SvGlobalName( xObj->getClassID() );
551 0 : rHexCLSID = aClassName.GetHexName();
552 0 : }
553 : }
554 : }
555 :
556 16 : if (rHexCLSID.isEmpty())
557 : {
558 16 : uno::Reference < embed::XEmbeddedObject > xObj( pOle2Obj->GetObjRef() );
559 16 : if ( xObj.is() )
560 : {
561 16 : aClassName = SvGlobalName( xObj->getClassID() );
562 16 : rHexCLSID = aClassName.GetHexName();
563 16 : }
564 : }
565 : }
566 :
567 16 : return aClassName;
568 : }
569 :
570 :
571 :
572 1 : SvxAppletShape::SvxAppletShape( SdrObject* pObject ) throw()
573 1 : : SvxOle2Shape( pObject, getSvxMapProvider().GetMap(SVXMAP_APPLET), getSvxMapProvider().GetPropertySet(SVXMAP_APPLET, SdrObject::GetGlobalDrawObjectItemPool()) )
574 : {
575 1 : SetShapeType( OUString( "com.sun.star.drawing.AppletShape" ) );
576 1 : }
577 :
578 2 : SvxAppletShape::~SvxAppletShape() throw()
579 : {
580 2 : }
581 :
582 0 : void SvxAppletShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
583 : {
584 0 : SvxShape::Create( pNewObj, pNewPage );
585 0 : const SvGlobalName aAppletClassId( SO3_APPLET_CLASSID );
586 0 : createObject(aAppletClassId);
587 0 : SetShapeType( OUString( "com.sun.star.drawing.AppletShape" ) );
588 0 : }
589 :
590 0 : void SAL_CALL SvxAppletShape::setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
591 : {
592 0 : SvxShape::setPropertyValue( aPropertyName, rValue );
593 0 : resetModifiedState();
594 0 : }
595 :
596 0 : void SAL_CALL SvxAppletShape::setPropertyValues( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rValues ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
597 : {
598 0 : SvxShape::setPropertyValues( aPropertyNames, rValues );
599 0 : resetModifiedState();
600 0 : }
601 :
602 0 : bool SvxAppletShape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
603 : {
604 0 : if( (pProperty->nWID >= OWN_ATTR_APPLET_DOCBASE) && (pProperty->nWID <= OWN_ATTR_APPLET_ISSCRIPT) )
605 : {
606 0 : if ( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
607 : {
608 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
609 0 : if( xSet.is() )
610 : {
611 : // allow exceptions to pass through
612 0 : xSet->setPropertyValue( rName, rValue );
613 0 : }
614 : }
615 0 : return true;
616 : }
617 : else
618 : {
619 0 : return SvxOle2Shape::setPropertyValueImpl( rName, pProperty, rValue );
620 : }
621 : }
622 :
623 0 : bool SvxAppletShape::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
624 : {
625 0 : if( (pProperty->nWID >= OWN_ATTR_APPLET_DOCBASE) && (pProperty->nWID <= OWN_ATTR_APPLET_ISSCRIPT) )
626 : {
627 0 : if ( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
628 : {
629 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
630 0 : if( xSet.is() )
631 : {
632 0 : rValue = xSet->getPropertyValue( rName );
633 0 : }
634 : }
635 0 : return true;
636 : }
637 : else
638 : {
639 0 : return SvxOle2Shape::getPropertyValueImpl( rName, pProperty, rValue );
640 : }
641 : }
642 :
643 :
644 :
645 1 : SvxPluginShape::SvxPluginShape( SdrObject* pObject ) throw()
646 1 : : SvxOle2Shape( pObject, getSvxMapProvider().GetMap(SVXMAP_PLUGIN), getSvxMapProvider().GetPropertySet(SVXMAP_PLUGIN, SdrObject::GetGlobalDrawObjectItemPool()) )
647 : {
648 1 : SetShapeType( OUString( "com.sun.star.drawing.PluginShape" ) );
649 1 : }
650 :
651 2 : SvxPluginShape::~SvxPluginShape() throw()
652 : {
653 2 : }
654 :
655 0 : void SvxPluginShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
656 : {
657 0 : SvxShape::Create( pNewObj, pNewPage );
658 0 : const SvGlobalName aPluginClassId( SO3_PLUGIN_CLASSID );
659 0 : createObject(aPluginClassId);
660 0 : SetShapeType( OUString( "com.sun.star.drawing.PluginShape" ) );
661 0 : }
662 :
663 0 : void SAL_CALL SvxPluginShape::setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
664 : {
665 0 : SvxShape::setPropertyValue( aPropertyName, rValue );
666 0 : resetModifiedState();
667 0 : }
668 :
669 0 : void SAL_CALL SvxPluginShape::setPropertyValues( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rValues ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
670 : {
671 0 : SvxShape::setPropertyValues( aPropertyNames, rValues );
672 0 : resetModifiedState();
673 0 : }
674 :
675 0 : bool SvxPluginShape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
676 : {
677 0 : if( (pProperty->nWID >= OWN_ATTR_PLUGIN_MIMETYPE) && (pProperty->nWID <= OWN_ATTR_PLUGIN_COMMANDS) )
678 : {
679 0 : if( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
680 : {
681 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
682 0 : if( xSet.is() )
683 : {
684 : // allow exceptions to pass through
685 0 : xSet->setPropertyValue( rName, rValue );
686 0 : }
687 : }
688 0 : return true;
689 : }
690 : else
691 : {
692 0 : return SvxOle2Shape::setPropertyValueImpl( rName, pProperty, rValue );
693 : }
694 : }
695 :
696 0 : bool SvxPluginShape::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
697 : {
698 0 : if( (pProperty->nWID >= OWN_ATTR_PLUGIN_MIMETYPE) && (pProperty->nWID <= OWN_ATTR_PLUGIN_COMMANDS) )
699 : {
700 0 : if( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
701 : {
702 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
703 0 : if( xSet.is() )
704 : {
705 0 : rValue <<= xSet->getPropertyValue( rName );
706 0 : }
707 : }
708 0 : return true;
709 : }
710 : else
711 : {
712 0 : return SvxOle2Shape::getPropertyValueImpl( rName, pProperty, rValue );
713 : }
714 : }
715 :
716 :
717 :
718 1 : SvxFrameShape::SvxFrameShape( SdrObject* pObject ) throw()
719 1 : : SvxOle2Shape( pObject, getSvxMapProvider().GetMap(SVXMAP_FRAME), getSvxMapProvider().GetPropertySet(SVXMAP_FRAME, SdrObject::GetGlobalDrawObjectItemPool()) )
720 : {
721 1 : SetShapeType( OUString( "com.sun.star.drawing.FrameShape" ) );
722 1 : }
723 :
724 2 : SvxFrameShape::~SvxFrameShape() throw()
725 : {
726 2 : }
727 :
728 0 : void SvxFrameShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage ) throw (uno::RuntimeException)
729 : {
730 0 : SvxShape::Create( pNewObj, pNewPage );
731 0 : const SvGlobalName aIFrameClassId( SO3_IFRAME_CLASSID );
732 0 : createObject(aIFrameClassId);
733 0 : SetShapeType( OUString( "com.sun.star.drawing.FrameShape" ) );
734 0 : }
735 :
736 0 : void SAL_CALL SvxFrameShape::setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
737 : {
738 0 : SvxShape::setPropertyValue( aPropertyName, rValue );
739 0 : resetModifiedState();
740 0 : }
741 :
742 0 : void SAL_CALL SvxFrameShape::setPropertyValues( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rValues ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
743 : {
744 0 : SvxShape::setPropertyValues( aPropertyNames, rValues );
745 0 : resetModifiedState();
746 0 : }
747 :
748 0 : bool SvxFrameShape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
749 : {
750 0 : if( (pProperty->nWID >= OWN_ATTR_FRAME_URL) && (pProperty->nWID <= OWN_ATTR_FRAME_MARGIN_HEIGHT) )
751 : {
752 0 : if( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
753 : {
754 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
755 0 : if( xSet.is() )
756 : {
757 : // allow exceptions to pass through
758 0 : xSet->setPropertyValue( rName, rValue );
759 0 : }
760 : }
761 0 : return true;
762 : }
763 : else
764 : {
765 0 : return SvxOle2Shape::setPropertyValueImpl( rName, pProperty, rValue );
766 : }
767 : }
768 :
769 0 : bool SvxFrameShape::getPropertyValueImpl(const OUString& rName, const SfxItemPropertySimpleEntry* pProperty,
770 : css::uno::Any& rValue)
771 : throw (css::beans::UnknownPropertyException,
772 : css::lang::WrappedTargetException,
773 : css::uno::RuntimeException,
774 : std::exception)
775 : {
776 0 : if( (pProperty->nWID >= OWN_ATTR_FRAME_URL) && (pProperty->nWID <= OWN_ATTR_FRAME_MARGIN_HEIGHT) )
777 : {
778 0 : if( svt::EmbeddedObjectRef::TryRunningState( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef() ) )
779 : {
780 0 : uno::Reference < beans::XPropertySet > xSet( static_cast<SdrOle2Obj*>(mpObj.get())->GetObjRef()->getComponent(), uno::UNO_QUERY );
781 0 : if( xSet.is() )
782 : {
783 0 : rValue <<= xSet->getPropertyValue( rName );
784 0 : }
785 : }
786 0 : return true;
787 : }
788 : else
789 : {
790 0 : return SvxOle2Shape::getPropertyValueImpl( rName, pProperty, rValue );
791 : }
792 : }
793 19 : SvxMediaShape::SvxMediaShape( SdrObject* pObj, OUString const & referer ) throw()
794 57 : : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_MEDIA), getSvxMapProvider().GetPropertySet(SVXMAP_MEDIA, SdrObject::GetGlobalDrawObjectItemPool()) ),
795 57 : referer_(referer)
796 : {
797 19 : SetShapeType( OUString( "com.sun.star.drawing.MediaShape" ) );
798 19 : }
799 :
800 :
801 38 : SvxMediaShape::~SvxMediaShape() throw()
802 : {
803 38 : }
804 :
805 :
806 :
807 60 : bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
808 : {
809 60 : if( ((pProperty->nWID >= OWN_ATTR_MEDIA_URL) && (pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM))
810 19 : || (pProperty->nWID == OWN_ATTR_MEDIA_STREAM)
811 17 : || (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE) )
812 : {
813 48 : SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( mpObj.get() );
814 48 : ::avmedia::MediaItem aItem;
815 48 : bool bOk = false;
816 :
817 48 : switch( pProperty->nWID )
818 : {
819 : case OWN_ATTR_MEDIA_URL:
820 : {
821 7 : OUString aURL;
822 7 : if( rValue >>= aURL )
823 : {
824 7 : bOk = true;
825 7 : aItem.setURL( aURL, "", referer_ );
826 7 : }
827 : }
828 7 : break;
829 :
830 : case( OWN_ATTR_MEDIA_LOOP ):
831 : {
832 : bool bLoop;
833 :
834 10 : if( rValue >>= bLoop )
835 : {
836 10 : bOk = true;
837 10 : aItem.setLoop( bLoop );
838 : }
839 : }
840 10 : break;
841 :
842 : case( OWN_ATTR_MEDIA_MUTE ):
843 : {
844 : bool bMute;
845 :
846 10 : if( rValue >>= bMute )
847 : {
848 10 : bOk = true;
849 10 : aItem.setMute( bMute );
850 : }
851 : }
852 10 : break;
853 :
854 : case( OWN_ATTR_MEDIA_VOLUMEDB ):
855 : {
856 10 : sal_Int16 nVolumeDB = sal_Int16();
857 :
858 10 : if( rValue >>= nVolumeDB )
859 : {
860 10 : bOk = true;
861 10 : aItem.setVolumeDB( nVolumeDB );
862 : }
863 : }
864 10 : break;
865 :
866 : case( OWN_ATTR_MEDIA_ZOOM ):
867 : {
868 : ::com::sun::star::media::ZoomLevel eLevel;
869 :
870 4 : if( rValue >>= eLevel )
871 : {
872 4 : bOk = true;
873 4 : aItem.setZoom( eLevel );
874 : }
875 : }
876 4 : break;
877 :
878 : case OWN_ATTR_MEDIA_MIMETYPE:
879 : {
880 5 : OUString sMimeType;
881 5 : if( rValue >>= sMimeType )
882 : {
883 5 : bOk = true;
884 5 : aItem.setMimeType( sMimeType );
885 5 : }
886 : }
887 5 : break;
888 :
889 : case OWN_ATTR_MEDIA_STREAM:
890 : try
891 : {
892 2 : uno::Reference<io::XInputStream> xStream;
893 2 : if (rValue >>= xStream)
894 : {
895 2 : pMedia->SetInputStream(xStream);
896 2 : }
897 : }
898 0 : catch (const css::ucb::ContentCreationException& e)
899 : {
900 : throw css::lang::WrappedTargetException(
901 : "ContentCreationException Setting InputStream!",
902 : static_cast<OWeakObject *>(this),
903 0 : makeAny(e));
904 : }
905 0 : catch (const css::ucb::CommandFailedException& e)
906 : {
907 : throw css::lang::WrappedTargetException(
908 : "CommandFailedException Setting InputStream!",
909 : static_cast<OWeakObject *>(this),
910 0 : makeAny(e));
911 : }
912 2 : break;
913 :
914 : default:
915 : OSL_FAIL("SvxMediaShape::setPropertyValueImpl(), unknown argument!");
916 : }
917 :
918 48 : if( bOk )
919 : {
920 46 : pMedia->setMediaProperties( aItem );
921 46 : return true;
922 2 : }
923 : }
924 : else
925 : {
926 12 : return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
927 : }
928 :
929 2 : throw IllegalArgumentException();
930 : }
931 :
932 :
933 :
934 29 : bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
935 : {
936 46 : if ( ((pProperty->nWID >= OWN_ATTR_MEDIA_URL) &&
937 17 : (pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM))
938 17 : || (pProperty->nWID == OWN_ATTR_MEDIA_STREAM)
939 15 : || (pProperty->nWID == OWN_ATTR_MEDIA_TEMPFILEURL)
940 15 : || (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE)
941 13 : || (pProperty->nWID == OWN_ATTR_FALLBACK_GRAPHIC))
942 : {
943 17 : SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( mpObj.get() );
944 17 : const ::avmedia::MediaItem aItem( pMedia->getMediaProperties() );
945 :
946 17 : switch( pProperty->nWID )
947 : {
948 : case OWN_ATTR_MEDIA_URL:
949 4 : rValue <<= aItem.getURL();
950 4 : break;
951 :
952 : case( OWN_ATTR_MEDIA_LOOP ):
953 2 : rValue <<= aItem.isLoop();
954 2 : break;
955 :
956 : case( OWN_ATTR_MEDIA_MUTE ):
957 2 : rValue <<= aItem.isMute();
958 2 : break;
959 :
960 : case( OWN_ATTR_MEDIA_VOLUMEDB ):
961 2 : rValue <<= (sal_Int16) aItem.getVolumeDB();
962 2 : break;
963 :
964 : case( OWN_ATTR_MEDIA_ZOOM ):
965 2 : rValue <<= aItem.getZoom();
966 2 : break;
967 :
968 : case OWN_ATTR_MEDIA_STREAM:
969 : try
970 : {
971 2 : rValue <<= pMedia->GetInputStream();
972 : }
973 0 : catch (const css::ucb::ContentCreationException& e)
974 : {
975 : throw css::lang::WrappedTargetException(
976 : "ContentCreationException Getting InputStream!",
977 : static_cast < OWeakObject * > ( this ),
978 0 : makeAny( e ) );
979 : }
980 0 : catch (const css::ucb::CommandFailedException& e)
981 : {
982 : throw css::lang::WrappedTargetException(
983 : "CommandFailedException Getting InputStream!",
984 : static_cast < OWeakObject * > ( this ),
985 0 : makeAny( e ) );
986 : }
987 :
988 2 : break;
989 :
990 : case OWN_ATTR_MEDIA_TEMPFILEURL:
991 0 : rValue <<= aItem.getTempURL();
992 0 : break;
993 :
994 : case OWN_ATTR_MEDIA_MIMETYPE:
995 2 : rValue <<= aItem.getMimeType();
996 2 : break;
997 :
998 : case OWN_ATTR_FALLBACK_GRAPHIC:
999 1 : rValue <<= pMedia->getSnapshot();
1000 1 : break;
1001 :
1002 : default:
1003 : OSL_FAIL("SvxMediaShape::getPropertyValueImpl(), unknown property!");
1004 : }
1005 17 : return true;
1006 : }
1007 : else
1008 : {
1009 12 : return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
1010 : }
1011 : }
1012 :
1013 0 : SvxDummyShapeContainer::SvxDummyShapeContainer(uno::Reference< drawing::XShapes > xObject):
1014 0 : m_xDummyObject(xObject)
1015 : {
1016 0 : }
1017 :
1018 0 : SvxDummyShapeContainer::~SvxDummyShapeContainer() throw()
1019 : {
1020 0 : }
1021 :
1022 0 : void SvxOpenGLObject::setRenderer(IOpenGLRenderer* pRenderer)
1023 : {
1024 0 : static_cast<SdrOpenGLObj*>(GetSdrObject())->setRenderer(pRenderer);
1025 0 : }
1026 :
1027 0 : IOpenGLRenderer* SvxOpenGLObject::getRenderer()
1028 : {
1029 0 : return static_cast<SdrOpenGLObj*>(GetSdrObject())->getRenderer();
1030 435 : }
1031 :
1032 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|