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 :
21 : #include "frm_resource.hrc"
22 : #include "frm_resource.hxx"
23 : #include "InterfaceContainer.hxx"
24 : #include "componenttools.hxx"
25 : #include "property.hrc"
26 : #include "services.hxx"
27 :
28 : #include <com/sun/star/beans/XPropertySet.hpp>
29 : #include <com/sun/star/container/XNamed.hpp>
30 : #include <com/sun/star/io/WrongFormatException.hpp>
31 : #include <com/sun/star/io/XMarkableStream.hpp>
32 : #include <com/sun/star/lang/XComponent.hpp>
33 : #include <com/sun/star/util/XCloneable.hpp>
34 : #include <com/sun/star/form/XForm.hpp>
35 :
36 : #include <comphelper/container.hxx>
37 : #include <comphelper/enumhelper.hxx>
38 : #include <comphelper/eventattachermgr.hxx>
39 : #include <comphelper/property.hxx>
40 : #include <comphelper/sequence.hxx>
41 : #include <comphelper/types.hxx>
42 : #include <cppuhelper/exc_hlp.hxx>
43 : #include <cppuhelper/queryinterface.hxx>
44 : #include <rtl/logfile.hxx>
45 : #include <tools/debug.hxx>
46 : #include <tools/diagnose_ex.h>
47 :
48 : #include <algorithm>
49 : #include <memory>
50 :
51 : //.........................................................................
52 : #include <com/sun/star/frame/XModel.hpp>
53 : #include <com/sun/star/document/XCodeNameQuery.hpp>
54 : #include <ooo/vba/XVBAToOOEventDescGen.hpp>
55 : #include <comphelper/processfactory.hxx>
56 :
57 : namespace frm
58 : {
59 : //.........................................................................
60 :
61 : using namespace ::com::sun::star::frame;
62 : using namespace ::com::sun::star::lang;
63 : using namespace ::com::sun::star::uno;
64 : using namespace ::com::sun::star::beans;
65 : using namespace ::com::sun::star::document;
66 : using namespace ::com::sun::star::container;
67 : using namespace ::com::sun::star::script;
68 : using namespace ::com::sun::star::io;
69 : using namespace ::com::sun::star::form;
70 : using namespace ::com::sun::star::util;
71 :
72 : namespace
73 : {
74 : //---------------------------------------------------------------------
75 0 : static void lcl_throwIllegalArgumentException()
76 : {
77 0 : throw IllegalArgumentException();
78 : }
79 : }
80 :
81 : bool
82 0 : lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
83 : {
84 0 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
85 0 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
86 0 : for ( ; pDesc != pEnd; ++pDesc )
87 : {
88 0 : if ( pDesc->ScriptType == "VBAInterop" )
89 0 : return true;
90 : }
91 0 : return false;
92 : }
93 :
94 : Sequence< ScriptEventDescriptor >
95 0 : lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
96 : {
97 0 : Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );
98 :
99 0 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
100 0 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
101 0 : sal_Int32 nCopied = 0;
102 0 : for ( ; pDesc != pEnd; ++pDesc )
103 : {
104 0 : if ( pDesc->ScriptType != "VBAInterop" )
105 : {
106 0 : sStripped[ nCopied++ ] = *pDesc;
107 : }
108 : }
109 0 : if ( nCopied )
110 0 : sStripped.realloc( nCopied );
111 0 : return sStripped;
112 : }
113 :
114 4 : void OInterfaceContainer::impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex )
115 : {
116 : // we are dealing with form controls
117 : try
118 : {
119 : do
120 : {
121 4 : Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
122 4 : if ( !xDoc.is() )
123 : break;
124 :
125 3 : Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
126 3 : Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooo.vba.VBACodeNameProvider") ) ), UNO_QUERY );
127 3 : if ( !xNameQuery.is() )
128 : break;
129 :
130 0 : ::osl::MutexGuard aGuard( m_rMutex );
131 0 : bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
132 0 : if ( hasVBABindings )
133 : break;
134 :
135 0 : Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
136 0 : Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
137 0 : if ( xElementAsForm.is() )
138 : break;
139 :
140 : // Try getting the code name from the container first (faster),
141 : // then from the element if that fails (slower).
142 0 : Reference<XInterface> xThis = static_cast<XContainer*>(this);
143 0 : rtl::OUString sCodeName = xNameQuery->getCodeNameForContainer(xThis);
144 0 : if (sCodeName.isEmpty())
145 0 : sCodeName = xNameQuery->getCodeNameForObject(xElement);
146 :
147 0 : Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
148 0 : ::rtl::OUString sServiceName;
149 0 : xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultControl") ) ) >>= sServiceName;
150 :
151 0 : Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooo.vba.VBAToOOEventDesc") ) ), UNO_QUERY_THROW );
152 0 : Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( m_xServiceFactory->createInstance( sServiceName ), sCodeName );
153 : // register the vba script events
154 0 : m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
155 : }
156 : while ( false );
157 : }
158 0 : catch ( const ServiceNotRegisteredException& )
159 : {
160 : // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
161 : }
162 0 : catch( const Exception& )
163 : {
164 : DBG_UNHANDLED_EXCEPTION();
165 : }
166 :
167 4 : }
168 : //==================================================================
169 : //= ElementDescription
170 : //==================================================================
171 : //------------------------------------------------------------------
172 15 : ElementDescription::ElementDescription( )
173 : {
174 15 : }
175 :
176 : //------------------------------------------------------------------
177 30 : ElementDescription::~ElementDescription()
178 : {
179 30 : }
180 :
181 : //==================================================================
182 : //= OInterfaceContainer
183 : //==================================================================
184 : //------------------------------------------------------------------
185 22 : OInterfaceContainer::OInterfaceContainer(
186 : const Reference<XMultiServiceFactory>& _rxFactory,
187 : ::osl::Mutex& _rMutex,
188 : const Type& _rElementType)
189 : :OInterfaceContainer_BASE()
190 : ,m_rMutex(_rMutex)
191 : ,m_aContainerListeners(_rMutex)
192 : ,m_aElementType(_rElementType)
193 22 : ,m_xServiceFactory(_rxFactory)
194 : {
195 22 : impl_createEventAttacher_nothrow();
196 22 : }
197 :
198 : //------------------------------------------------------------------------------
199 0 : OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
200 : :OInterfaceContainer_BASE()
201 : ,m_rMutex( _rMutex )
202 : ,m_aContainerListeners( _rMutex )
203 : ,m_aElementType( _cloneSource.m_aElementType )
204 0 : ,m_xServiceFactory( _cloneSource.m_xServiceFactory )
205 : {
206 0 : impl_createEventAttacher_nothrow();
207 0 : }
208 :
209 : //------------------------------------------------------------------------------
210 0 : void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource )
211 : {
212 : try
213 : {
214 0 : const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
215 0 : const sal_Int32 nCount = xSourceHierarchy->getCount();
216 0 : for ( sal_Int32 i=0; i<nCount; ++i )
217 : {
218 0 : Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
219 0 : Reference< XInterface > xClone( xCloneable->createClone() );
220 0 : insertByIndex( i, makeAny( xClone ) );
221 0 : }
222 : }
223 0 : catch( const Exception& )
224 : {
225 : throw WrappedTargetException(
226 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ),
227 : static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
228 : ::cppu::getCaughtException()
229 0 : );
230 : }
231 0 : }
232 :
233 : //------------------------------------------------------------------------------
234 22 : void OInterfaceContainer::impl_createEventAttacher_nothrow()
235 : {
236 : try
237 : {
238 22 : m_xEventAttacher.set( ::comphelper::createEventAttacherManager( comphelper::getComponentContext(m_xServiceFactory) ), UNO_SET_THROW );
239 : }
240 0 : catch( const Exception& )
241 : {
242 : DBG_UNHANDLED_EXCEPTION();
243 : }
244 22 : }
245 :
246 : //------------------------------------------------------------------------------
247 11 : OInterfaceContainer::~OInterfaceContainer()
248 : {
249 11 : }
250 :
251 : //------------------------------------------------------------------------------
252 12 : void OInterfaceContainer::disposing()
253 : {
254 : // dispose all elements
255 24 : for (sal_Int32 i = m_aItems.size(); i > 0; --i)
256 : {
257 12 : Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
258 12 : if (xSet.is())
259 12 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
260 :
261 : // revoke event knittings
262 12 : if ( m_xEventAttacher.is() )
263 : {
264 12 : Reference< XInterface > xIfc( xSet, UNO_QUERY );
265 12 : m_xEventAttacher->detach( i - 1, xIfc );
266 12 : m_xEventAttacher->removeEntry( i - 1 );
267 : }
268 :
269 12 : Reference<XComponent> xComponent(xSet, UNO_QUERY);
270 12 : if (xComponent.is())
271 12 : xComponent->dispose();
272 12 : }
273 12 : m_aMap.clear();
274 12 : m_aItems.clear();
275 :
276 12 : EventObject aEvt(static_cast<XContainer*>(this));
277 12 : m_aContainerListeners.disposeAndClear(aEvt);
278 12 : }
279 :
280 : // XPersistObject
281 : //------------------------------------------------------------------------------
282 : namespace
283 : {
284 : //..........................................................................
285 0 : void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
286 : const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
287 : {
288 : OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
289 0 : if ( !_rxManager.is() )
290 0 : return;
291 :
292 : // reserve the space needed
293 0 : _rSave.reserve( _nItemCount );
294 :
295 : // copy the events
296 0 : for (sal_Int32 i=0; i<_nItemCount; ++i)
297 0 : _rSave.push_back(_rxManager->getScriptEvents( i ));
298 : }
299 :
300 : //..........................................................................
301 0 : void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
302 : const Reference< XEventAttacherManager >& _rxManager )
303 : {
304 : OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
305 0 : if ( !_rxManager.is() )
306 0 : return;
307 :
308 0 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
309 0 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
310 0 : for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
311 : {
312 0 : _rxManager->revokeScriptEvents( i );
313 0 : _rxManager->registerScriptEvents( i, *aLoop );
314 : }
315 : }
316 : }
317 :
318 : //------------------------------------------------------------------------------
319 0 : void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
320 : {
321 : // We're writing a document in SO 5.2 format (or even from earlier versions)
322 : // -> convert the events from the new runtime format to the format of the 5.2 files
323 : // but before, remember the current script events set for our children
324 0 : ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
325 0 : if ( m_xEventAttacher.is() )
326 0 : lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
327 :
328 0 : transformEvents( efVersionSO5x );
329 :
330 : try
331 : {
332 0 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
333 0 : sal_Int32 nMark = xMark->createMark();
334 :
335 0 : sal_Int32 nObjLen = 0;
336 0 : _rxOutStream->writeLong(nObjLen);
337 :
338 0 : Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
339 0 : if (xScripts.is())
340 0 : xScripts->write(_rxOutStream);
341 :
342 : // feststellen der Laenge
343 0 : nObjLen = xMark->offsetToMark(nMark) - 4;
344 0 : xMark->jumpToMark(nMark);
345 0 : _rxOutStream->writeLong(nObjLen);
346 0 : xMark->jumpToFurthest();
347 0 : xMark->deleteMark(nMark);
348 : }
349 0 : catch( const Exception& )
350 : {
351 : // restore the events
352 0 : if ( m_xEventAttacher.is() )
353 0 : lcl_restoreEvents( aSave, m_xEventAttacher );
354 0 : throw;
355 : }
356 :
357 : // restore the events
358 0 : if ( m_xEventAttacher.is() )
359 0 : lcl_restoreEvents( aSave, m_xEventAttacher );
360 0 : }
361 :
362 : //------------------------------------------------------------------------------
363 : struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
364 : {
365 0 : void operator()( ScriptEventDescriptor& _rDescriptor )
366 : {
367 0 : if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
368 : { // it's a starbasic macro
369 0 : sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
370 0 : if ( 0 <= nPrefixLength )
371 : { // the macro name does not already contain a :
372 : #ifdef DBG_UTIL
373 : const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
374 : DBG_ASSERT( 0 == sPrefix.compareToAscii( "document" )
375 : || 0 == sPrefix.compareToAscii( "application" ),
376 : "TransformEventTo52Format: invalid (unknown) prefix!" );
377 : #endif
378 : // cut the prefix
379 0 : _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
380 : }
381 : }
382 0 : }
383 : };
384 :
385 : //------------------------------------------------------------------------------
386 : struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
387 : {
388 0 : void operator()( ScriptEventDescriptor& _rDescriptor )
389 : {
390 0 : if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
391 : { // it's a starbasic macro
392 0 : if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
393 : { // the macro name does not already contain a :
394 : // -> default the type to "document"
395 0 : ::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) );
396 0 : sNewScriptCode += _rDescriptor.ScriptCode;
397 0 : _rDescriptor.ScriptCode = sNewScriptCode;
398 : }
399 : }
400 0 : }
401 : };
402 :
403 : //------------------------------------------------------------------------------
404 0 : void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
405 : {
406 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
407 0 : if ( !m_xEventAttacher.is() )
408 0 : return;
409 :
410 : try
411 : {
412 : // loop through all our children
413 0 : sal_Int32 nItems = m_aItems.size();
414 0 : Sequence< ScriptEventDescriptor > aChildEvents;
415 :
416 0 : for (sal_Int32 i=0; i<nItems; ++i)
417 : {
418 : // get the script events for this object
419 0 : aChildEvents = m_xEventAttacher->getScriptEvents( i );
420 :
421 0 : if ( aChildEvents.getLength() )
422 : {
423 : // the "iterators" for the events for this child
424 0 : ScriptEventDescriptor* pChildEvents = aChildEvents.getArray();
425 0 : ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength();
426 :
427 : // do the transformation
428 0 : if ( efVersionSO6x == _eTargetFormat )
429 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
430 : else
431 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
432 :
433 : // revoke the script events
434 0 : m_xEventAttacher->revokeScriptEvents( i );
435 : // and re-register them
436 0 : m_xEventAttacher->registerScriptEvents( i, aChildEvents );
437 : }
438 0 : }
439 : }
440 0 : catch( const Exception& )
441 : {
442 : DBG_UNHANDLED_EXCEPTION();
443 : }
444 : }
445 :
446 : //------------------------------------------------------------------------------
447 0 : void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
448 : {
449 0 : ::osl::MutexGuard aGuard( m_rMutex );
450 :
451 : // Scripting Info lesen
452 0 : Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
453 0 : sal_Int32 nObjLen = _rxInStream->readLong();
454 0 : if (nObjLen)
455 : {
456 0 : sal_Int32 nMark = xMark->createMark();
457 0 : Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
458 0 : if (xObj.is())
459 0 : xObj->read(_rxInStream);
460 0 : xMark->jumpToMark(nMark);
461 0 : _rxInStream->skipBytes(nObjLen);
462 0 : xMark->deleteMark(nMark);
463 : }
464 :
465 : // Attachement lesen
466 0 : if ( m_xEventAttacher.is() )
467 : {
468 0 : OInterfaceArray::const_iterator aAttach = m_aItems.begin();
469 0 : OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
470 0 : for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
471 : {
472 0 : Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this ....
473 0 : Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
474 0 : m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
475 0 : }
476 0 : }
477 0 : }
478 :
479 : //------------------------------------------------------------------------------
480 0 : void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
481 : {
482 0 : ::osl::MutexGuard aGuard( m_rMutex );
483 0 : sal_Int32 nLen = m_aItems.size();
484 :
485 : // schreiben der laenge
486 0 : _rxOutStream->writeLong(nLen);
487 :
488 0 : if (nLen)
489 : {
490 : // 1. Version
491 0 : _rxOutStream->writeShort(0x0001);
492 :
493 : // 2. Objekte
494 0 : for (sal_Int32 i = 0; i < nLen; i++)
495 : {
496 0 : Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY);
497 0 : if (xObj.is())
498 0 : _rxOutStream->writeObject(xObj);
499 : else
500 : {
501 : // ::com::sun::star::chaos::Error
502 : }
503 0 : }
504 :
505 : // 3. Scripts
506 0 : writeEvents(_rxOutStream);
507 0 : }
508 0 : }
509 :
510 : //------------------------------------------------------------------------------
511 : namespace
512 : {
513 0 : Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB )
514 : {
515 0 : Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY );
516 : DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
517 0 : if ( xObject.is() )
518 : {
519 : // set some properties describing what we did
520 0 : Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
521 0 : if ( xObject.is() )
522 : {
523 : try
524 : {
525 0 : xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
526 0 : xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
527 : }
528 0 : catch(const Exception&)
529 : {
530 : }
531 0 : }
532 : }
533 0 : return xObject;
534 : }
535 : }
536 :
537 : //------------------------------------------------------------------------------
538 0 : void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
539 : {
540 0 : ::osl::MutexGuard aGuard( m_rMutex );
541 :
542 : // after ::read the object is expected to be in the state it was when ::write was called, so we have
543 : // to empty ourself here
544 0 : while (getCount())
545 0 : removeByIndex(0);
546 :
547 : // Schreibt nur in Abhaengigkeit der Laenge
548 0 : sal_Int32 nLen = _rxInStream->readLong();
549 :
550 0 : if (nLen)
551 : {
552 : // 1. Version
553 0 : sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
554 :
555 : // 2. Objekte
556 0 : for (sal_Int32 i = 0; i < nLen; i++)
557 : {
558 0 : Reference<XPersistObject> xObj;
559 : try
560 : {
561 0 : xObj = _rxInStream->readObject();
562 : }
563 0 : catch(const WrongFormatException&)
564 : {
565 : // the object could not be read
566 : // create a object (so the readEvents below will assign the events to the right controls)
567 0 : xObj = lcl_createPlaceHolder( m_xServiceFactory );
568 0 : if ( !xObj.is() )
569 : // couldn't handle it
570 0 : throw;
571 : }
572 0 : catch(const Exception&)
573 : {
574 : // unsere Map leeren
575 0 : while (!m_aItems.empty())
576 0 : removeElementsNoEvents(0);
577 :
578 : // und die Exception nach aussen
579 0 : throw;
580 : }
581 :
582 0 : if ( xObj.is() )
583 : {
584 0 : Reference< XPropertySet > xElement( xObj, UNO_QUERY );
585 : try
586 : {
587 : implInsert(
588 0 : m_aItems.size(), // position
589 : xElement, // element to insert
590 : sal_False, // no event attacher manager handling
591 : NULL, // not yet approved - let implInsert do it
592 : sal_True // fire the event
593 0 : );
594 : }
595 0 : catch( const Exception& )
596 : {
597 : OSL_FAIL( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
598 : // create a placeholder
599 0 : xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) );
600 0 : if ( !xElement.is() )
601 : // couldn't handle it
602 0 : throw;
603 : // insert the placeholder
604 0 : implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
605 0 : }
606 : }
607 0 : }
608 :
609 0 : readEvents(_rxInStream);
610 : }
611 : else
612 : {
613 : try
614 : {
615 0 : m_xEventAttacher = ::comphelper::createEventAttacherManager( comphelper::getComponentContext(m_xServiceFactory) );
616 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
617 : }
618 0 : catch( const Exception& )
619 : {
620 : DBG_UNHANDLED_EXCEPTION();
621 : }
622 0 : }
623 0 : }
624 :
625 : // XContainer
626 : //------------------------------------------------------------------------------
627 26 : void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
628 : {
629 26 : m_aContainerListeners.addInterface(_rxListener);
630 26 : }
631 :
632 : //------------------------------------------------------------------------------
633 12 : void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
634 : {
635 12 : m_aContainerListeners.removeInterface(_rxListener);
636 12 : }
637 :
638 : // XEventListener
639 : //------------------------------------------------------------------------------
640 0 : void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
641 : {
642 0 : ::osl::MutexGuard aGuard( m_rMutex );
643 :
644 0 : Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
645 : // normalized source
646 :
647 0 : OInterfaceArray::iterator j;
648 0 : for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
649 : {
650 : DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
651 : "OInterfaceContainer::disposing: vector element not normalized!" );
652 :
653 0 : if ( xSource.get() == j->get() )
654 : // found the element
655 0 : break;
656 : }
657 :
658 0 : if ( m_aItems.end() != j )
659 : {
660 0 : m_aItems.erase(j);
661 :
662 : // look up in, and erase from, m_aMap, too
663 0 : OInterfaceMap::iterator i = m_aMap.begin();
664 0 : while ( i != m_aMap.end() )
665 : {
666 : DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
667 : "OInterfaceContainer::disposing: map element not normalized!" );
668 :
669 0 : if ( i->second.get() == xSource.get() )
670 : {
671 : // found it
672 0 : m_aMap.erase(i);
673 0 : break;
674 : }
675 :
676 0 : ++i;
677 :
678 : DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
679 : }
680 0 : }
681 0 : }
682 :
683 : // XPropertyChangeListener
684 : //------------------------------------------------------------------------------
685 1 : void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
686 : throw (::com::sun::star::uno::RuntimeException) {
687 1 : if (evt.PropertyName == PROPERTY_NAME)
688 : {
689 1 : ::osl::MutexGuard aGuard( m_rMutex );
690 : OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
691 1 : ::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
692 1 : if (i != m_aMap.end())
693 : {
694 1 : InterfaceRef xCorrectType((*i).second);
695 1 : m_aMap.erase(i);
696 1 : m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
697 1 : }
698 : }
699 1 : }
700 :
701 : // XElementAccess
702 : //------------------------------------------------------------------------------
703 16 : sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
704 : {
705 16 : return !m_aMap.empty();
706 : }
707 :
708 : //------------------------------------------------------------------------------
709 0 : Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
710 : {
711 0 : return m_aElementType;
712 : }
713 :
714 : // XEnumerationAccess
715 : //------------------------------------------------------------------------------
716 0 : Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
717 : {
718 0 : ::osl::MutexGuard aGuard( m_rMutex );
719 0 : return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
720 : }
721 :
722 : // XNameAccess
723 : //------------------------------------------------------------------------------
724 0 : Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
725 : {
726 : ::std::pair <OInterfaceMap::iterator,
727 0 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
728 :
729 0 : if (aPair.first == aPair.second)
730 0 : throw NoSuchElementException();
731 :
732 0 : return (*aPair.first).second->queryInterface( m_aElementType );
733 : }
734 :
735 : //------------------------------------------------------------------------------
736 0 : StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
737 : {
738 0 : StringSequence aNameList(m_aItems.size());
739 0 : ::rtl::OUString* pStringArray = aNameList.getArray();
740 :
741 0 : for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
742 : {
743 0 : *pStringArray = (*i).first;
744 : }
745 0 : return aNameList;
746 : }
747 :
748 : //------------------------------------------------------------------------------
749 3 : sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
750 : {
751 : ::std::pair <OInterfaceMap::iterator,
752 3 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
753 3 : return aPair.first != aPair.second;
754 : }
755 :
756 : // XIndexAccess
757 : //------------------------------------------------------------------------------
758 114 : sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
759 : {
760 114 : return m_aItems.size();
761 : }
762 :
763 : //------------------------------------------------------------------------------
764 66 : Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
765 : {
766 66 : if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
767 0 : throw IndexOutOfBoundsException();
768 :
769 66 : return m_aItems[_nIndex]->queryInterface( m_aElementType );
770 : }
771 :
772 : //------------------------------------------------------------------------------
773 15 : void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
774 : {
775 : // it has to be non-NULL
776 15 : if ( !_rxObject.is() )
777 0 : throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
778 :
779 : // it has to support our element type interface
780 15 : Any aCorrectType = _rxObject->queryInterface( m_aElementType );
781 15 : if ( !aCorrectType.hasValue() )
782 0 : lcl_throwIllegalArgumentException();
783 :
784 : // it has to have a "Name" property
785 15 : if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
786 0 : lcl_throwIllegalArgumentException();
787 :
788 : // it has to be a child, and it must not have a parent already
789 15 : Reference< XChild > xChild( _rxObject, UNO_QUERY );
790 15 : if ( !xChild.is() || xChild->getParent().is() )
791 : {
792 0 : lcl_throwIllegalArgumentException();
793 : }
794 :
795 : // passed all tests. cache the information we have so far
796 : DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
797 15 : if ( _pElement )
798 : {
799 15 : _pElement->xPropertySet = _rxObject;
800 15 : _pElement->xChild = xChild;
801 15 : _pElement->aElementTypeInterface = aCorrectType;
802 15 : _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
803 15 : }
804 15 : }
805 :
806 : //------------------------------------------------------------------------------
807 15 : void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
808 : sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
809 : {
810 15 : const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
811 :
812 : // SYNCHRONIZED ----->
813 15 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
814 :
815 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
816 15 : ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
817 : SAL_WNODEPRECATED_DECLARATIONS_POP
818 15 : ElementDescription* pElementMetaData = _pApprovalResult;
819 15 : if ( !pElementMetaData )
820 : { // not yet approved by the caller -> do ourself
821 11 : pElementMetaData = createElementMetaData();
822 : DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
823 :
824 : // ensure that the meta data structure will be deleted later on
825 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
826 11 : aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );
827 : SAL_WNODEPRECATED_DECLARATIONS_POP
828 :
829 : // will throw an exception if necessary
830 11 : approveNewElement( _rxElement, pElementMetaData );
831 : }
832 :
833 :
834 : // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
835 : // exist
836 :
837 : // set the name, and add as change listener for the name
838 15 : ::rtl::OUString sName;
839 15 : _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
840 15 : _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
841 :
842 : // insert the object into our internal structures
843 15 : if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
844 : {
845 0 : _nIndex = m_aItems.size();
846 0 : m_aItems.push_back( pElementMetaData->xInterface );
847 : }
848 : else
849 15 : m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
850 :
851 15 : m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
852 :
853 : // announce ourself as parent to the new element
854 15 : pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
855 :
856 : // handle the events
857 15 : if ( bHandleEvents )
858 : {
859 15 : m_xEventAttacher->insertEntry(_nIndex);
860 15 : m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
861 : }
862 :
863 : // notify derived classes
864 15 : implInserted( pElementMetaData );
865 :
866 15 : aGuard.clear();
867 : // <----- SYNCHRONIZED
868 :
869 : // insert faked VBA events?
870 15 : bool bHandleVbaEvents = false;
871 : try
872 : {
873 19 : _rxElement->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("GenerateVbaEvents") ) ) >>= bHandleVbaEvents;
874 : }
875 4 : catch( const Exception& )
876 : {
877 : }
878 15 : if ( bHandleVbaEvents )
879 : {
880 4 : Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
881 4 : if ( xMgr.is() )
882 : {
883 0 : OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
884 0 : sal_Int32 nLen = pIfcMgr->getCount();
885 0 : for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
886 : {
887 : // add fake events to the control at index i
888 0 : pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
889 : }
890 : }
891 : else
892 : {
893 : // add fake events to the control at index i
894 4 : impl_addVbEvents_nolck_nothrow( _nIndex );
895 4 : }
896 : }
897 :
898 : // fire the notification about the change
899 15 : if ( _bFire )
900 : {
901 : // notify listeners
902 15 : ContainerEvent aEvt;
903 15 : aEvt.Source = static_cast<XContainer*>(this);
904 15 : aEvt.Accessor <<= _nIndex;
905 15 : aEvt.Element = pElementMetaData->aElementTypeInterface;
906 :
907 15 : aGuard.clear();
908 15 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
909 15 : }
910 15 : }
911 :
912 : //------------------------------------------------------------------------------
913 0 : void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
914 : {
915 0 : OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
916 0 : InterfaceRef xElement(*i);
917 :
918 0 : OInterfaceMap::iterator j = m_aMap.begin();
919 0 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
920 :
921 0 : m_aItems.erase(i);
922 0 : m_aMap.erase(j);
923 :
924 0 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
925 0 : if (xSet.is())
926 0 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
927 :
928 0 : Reference<XChild> xChild(xElement, UNO_QUERY);
929 0 : if (xChild.is())
930 0 : xChild->setParent(InterfaceRef ());
931 0 : }
932 :
933 : //------------------------------------------------------------------------------
934 15 : void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
935 : {
936 : // not inrerested in
937 15 : }
938 :
939 : //------------------------------------------------------------------------------
940 1 : void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
941 : {
942 : // not inrerested in
943 1 : }
944 :
945 : //------------------------------------------------------------------------------
946 0 : void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
947 : {
948 0 : _rInstanceLock.clear();
949 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
950 0 : }
951 :
952 : // XIndexContainer
953 : //------------------------------------------------------------------------------
954 11 : void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
955 : {
956 11 : Reference< XPropertySet > xElement;
957 11 : _rElement >>= xElement;
958 11 : implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
959 11 : }
960 :
961 : //------------------------------------------------------------------------------
962 0 : void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
963 : {
964 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
965 :
966 : // approve the new object
967 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
968 0 : ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
969 : SAL_WNODEPRECATED_DECLARATIONS_POP
970 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
971 : {
972 0 : Reference< XPropertySet > xElementProps;
973 0 : _rNewElement >>= xElementProps;
974 0 : approveNewElement( xElementProps, aElementMetaData.get() );
975 : }
976 :
977 : // get the old element
978 0 : InterfaceRef xOldElement( m_aItems[ _nIndex ] );
979 : DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
980 : "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
981 :
982 : // locate the old element in the map
983 0 : OInterfaceMap::iterator j = m_aMap.begin();
984 0 : while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
985 0 : ++j;
986 :
987 : // remove event knittings
988 0 : if ( m_xEventAttacher.is() )
989 : {
990 0 : InterfaceRef xNormalized( xOldElement, UNO_QUERY );
991 0 : m_xEventAttacher->detach( _nIndex, xNormalized );
992 0 : m_xEventAttacher->removeEntry( _nIndex );
993 : }
994 :
995 : // don't listen for property changes anymore
996 0 : Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
997 0 : if (xSet.is())
998 0 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
999 :
1000 : // give the old element a new (void) parent
1001 0 : Reference<XChild> xChild(xOldElement, UNO_QUERY);
1002 0 : if (xChild.is())
1003 0 : xChild->setParent(InterfaceRef ());
1004 :
1005 : // remove the old one
1006 0 : m_aMap.erase(j);
1007 :
1008 : // examine the new element
1009 0 : ::rtl::OUString sName;
1010 : DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1011 :
1012 0 : aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1013 0 : aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1014 :
1015 : // insert the new one
1016 0 : m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1017 0 : m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1018 :
1019 0 : aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1020 :
1021 0 : if ( m_xEventAttacher.is() )
1022 : {
1023 0 : m_xEventAttacher->insertEntry( _nIndex );
1024 0 : m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1025 : }
1026 :
1027 0 : ContainerEvent aReplaceEvent;
1028 0 : aReplaceEvent.Source = static_cast< XContainer* >( this );
1029 0 : aReplaceEvent.Accessor <<= _nIndex;
1030 0 : aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1031 0 : aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1032 :
1033 0 : impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1034 0 : }
1035 :
1036 : //------------------------------------------------------------------------------
1037 1 : void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1038 : {
1039 1 : if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1040 0 : throw IndexOutOfBoundsException();
1041 1 : }
1042 :
1043 : //------------------------------------------------------------------------------
1044 0 : void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1045 : {
1046 0 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1047 : // check the index
1048 0 : implCheckIndex( _nIndex );
1049 : // do the replace
1050 0 : implReplaceByIndex( _nIndex, Element, aGuard );
1051 0 : }
1052 :
1053 : //------------------------------------------------------------------------------
1054 1 : void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1055 : {
1056 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1057 :
1058 1 : OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1059 1 : InterfaceRef xElement(*i);
1060 :
1061 1 : OInterfaceMap::iterator j = m_aMap.begin();
1062 1 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
1063 :
1064 1 : m_aItems.erase(i);
1065 1 : m_aMap.erase(j);
1066 :
1067 : // remove event knittings
1068 1 : if ( m_xEventAttacher.is() )
1069 : {
1070 1 : InterfaceRef xNormalized( xElement, UNO_QUERY );
1071 1 : m_xEventAttacher->detach( _nIndex, xNormalized );
1072 1 : m_xEventAttacher->removeEntry( _nIndex );
1073 : }
1074 :
1075 1 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1076 1 : if (xSet.is())
1077 1 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1078 :
1079 1 : Reference<XChild> xChild(xElement, UNO_QUERY);
1080 1 : if (xChild.is())
1081 1 : xChild->setParent(InterfaceRef ());
1082 :
1083 : // notify derived classes
1084 1 : implRemoved(xElement);
1085 :
1086 : // notify listeners
1087 1 : ContainerEvent aEvt;
1088 1 : aEvt.Source = static_cast<XContainer*>(this);
1089 1 : aEvt.Element = xElement->queryInterface( m_aElementType );
1090 1 : aEvt.Accessor <<= _nIndex;
1091 :
1092 1 : _rClearBeforeNotify.clear();
1093 1 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1094 1 : }
1095 :
1096 : //------------------------------------------------------------------------------
1097 1 : void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1098 : {
1099 1 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1100 : // check the index
1101 1 : implCheckIndex( _nIndex );
1102 : // do the removal
1103 1 : implRemoveByIndex( _nIndex, aGuard );
1104 1 : }
1105 :
1106 : //------------------------------------------------------------------------
1107 15 : ElementDescription* OInterfaceContainer::createElementMetaData( )
1108 : {
1109 15 : return new ElementDescription;
1110 : }
1111 :
1112 : //------------------------------------------------------------------------
1113 4 : void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1114 : {
1115 4 : Reference< XPropertySet > xElementProps;
1116 :
1117 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1118 4 : ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1119 : SAL_WNODEPRECATED_DECLARATIONS_POP
1120 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1121 :
1122 : // ensure the correct name of the element
1123 : try
1124 : {
1125 4 : _rElement >>= xElementProps;
1126 4 : approveNewElement( xElementProps, aElementMetaData.get() );
1127 :
1128 4 : xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1129 : }
1130 0 : catch( const IllegalArgumentException& )
1131 : {
1132 0 : throw; // allowed to leave
1133 : }
1134 0 : catch( const ElementExistException& )
1135 : {
1136 0 : throw; // allowed to leave
1137 : }
1138 0 : catch( const Exception& )
1139 : {
1140 : OSL_FAIL( "OInterfaceContainer::insertByName: caught an exception!" );
1141 : }
1142 4 : implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1143 4 : }
1144 :
1145 : //------------------------------------------------------------------------
1146 0 : void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1147 : {
1148 0 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1149 : ::std::pair <OInterfaceMap::iterator,
1150 0 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1151 0 : if (aPair.first == aPair.second)
1152 0 : throw NoSuchElementException();
1153 :
1154 0 : if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1155 0 : lcl_throwIllegalArgumentException();
1156 :
1157 0 : Reference<XPropertySet> xSet;
1158 0 : Element >>= xSet;
1159 0 : if (xSet.is())
1160 : {
1161 0 : if (!hasProperty(PROPERTY_NAME, xSet))
1162 0 : lcl_throwIllegalArgumentException();
1163 :
1164 0 : xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1165 : }
1166 :
1167 : // determine the element pos
1168 0 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1169 :
1170 0 : implReplaceByIndex( nPos, Element, aGuard );
1171 0 : }
1172 :
1173 : //------------------------------------------------------------------------
1174 0 : void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1175 : {
1176 0 : ::osl::MutexGuard aGuard( m_rMutex );
1177 : ::std::pair <OInterfaceMap::iterator,
1178 0 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1179 0 : if (aPair.first == aPair.second)
1180 0 : throw NoSuchElementException();
1181 :
1182 0 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1183 0 : removeByIndex(nPos);
1184 0 : }
1185 :
1186 :
1187 : // XEventAttacherManager
1188 : //------------------------------------------------------------------------
1189 0 : void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
1190 : {
1191 0 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1192 0 : if ( m_xEventAttacher.is() )
1193 : {
1194 0 : m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1195 0 : aGuard.clear();
1196 0 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1197 0 : }
1198 0 : }
1199 :
1200 : //------------------------------------------------------------------------
1201 0 : void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
1202 : {
1203 0 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1204 0 : if ( m_xEventAttacher.is() )
1205 : {
1206 0 : m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1207 0 : aGuard.clear();
1208 0 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1209 0 : }
1210 0 : }
1211 :
1212 : //------------------------------------------------------------------------
1213 0 : void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
1214 : {
1215 0 : if ( m_xEventAttacher.is() )
1216 0 : m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1217 0 : }
1218 :
1219 : //------------------------------------------------------------------------
1220 0 : void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1221 : {
1222 0 : if ( m_xEventAttacher.is() )
1223 0 : m_xEventAttacher->revokeScriptEvents( nIndex );
1224 0 : }
1225 :
1226 : //------------------------------------------------------------------------
1227 0 : void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1228 : {
1229 0 : if ( m_xEventAttacher.is() )
1230 0 : m_xEventAttacher->insertEntry( nIndex );
1231 0 : }
1232 :
1233 : //------------------------------------------------------------------------
1234 0 : void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1235 : {
1236 0 : if ( m_xEventAttacher.is() )
1237 0 : m_xEventAttacher->removeEntry( nIndex );
1238 0 : }
1239 :
1240 : //------------------------------------------------------------------------
1241 0 : Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1242 : {
1243 0 : Sequence< ScriptEventDescriptor > aReturn;
1244 0 : if ( m_xEventAttacher.is() )
1245 : {
1246 0 : aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1247 0 : if ( lcl_hasVbaEvents( aReturn ) )
1248 : {
1249 0 : aReturn = lcl_stripVbaEvents( aReturn );
1250 : }
1251 : }
1252 0 : return aReturn;
1253 : }
1254 :
1255 : //------------------------------------------------------------------------
1256 4 : void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
1257 : {
1258 4 : if ( m_xEventAttacher.is() )
1259 4 : m_xEventAttacher->attach( nIndex, xObject, aHelper );
1260 4 : }
1261 :
1262 : //------------------------------------------------------------------------
1263 2 : void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
1264 : {
1265 2 : if ( m_xEventAttacher.is() )
1266 2 : m_xEventAttacher->detach( nIndex, xObject );
1267 2 : }
1268 :
1269 : //------------------------------------------------------------------------
1270 44 : void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1271 : {
1272 44 : if ( m_xEventAttacher.is() )
1273 44 : m_xEventAttacher->addScriptListener( xListener );
1274 44 : }
1275 :
1276 : //------------------------------------------------------------------------
1277 24 : void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1278 : {
1279 24 : if ( m_xEventAttacher.is() )
1280 24 : m_xEventAttacher->removeScriptListener( xListener );
1281 24 : }
1282 :
1283 : //==================================================================
1284 : //= OFormComponents
1285 : //==================================================================
1286 : //------------------------------------------------------------------------------
1287 101 : Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
1288 : {
1289 101 : Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1290 101 : if (!aReturn.hasValue())
1291 : {
1292 101 : aReturn = OInterfaceContainer::queryInterface(_rType);
1293 :
1294 101 : if (!aReturn.hasValue())
1295 45 : aReturn = FormComponentsBase::queryAggregation(_rType);
1296 : }
1297 :
1298 101 : return aReturn;
1299 : }
1300 :
1301 : //------------------------------------------------------------------
1302 0 : Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
1303 : {
1304 0 : return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1305 : }
1306 :
1307 : //------------------------------------------------------------------------------
1308 4 : OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory)
1309 : :FormComponentsBase( m_aMutex )
1310 4 : ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
1311 8 : ,OFormComponents_BASE()
1312 : {
1313 4 : }
1314 :
1315 : //------------------------------------------------------------------------------
1316 0 : OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1317 : :FormComponentsBase( m_aMutex )
1318 : ,OInterfaceContainer( m_aMutex, _cloneSource )
1319 0 : ,OFormComponents_BASE()
1320 : {
1321 0 : }
1322 :
1323 : //------------------------------------------------------------------------------
1324 4 : OFormComponents::~OFormComponents()
1325 : {
1326 2 : if (!FormComponentsBase::rBHelper.bDisposed)
1327 : {
1328 0 : acquire();
1329 0 : dispose();
1330 : }
1331 2 : }
1332 :
1333 : // OComponentHelper
1334 : //------------------------------------------------------------------------------
1335 3 : void OFormComponents::disposing()
1336 : {
1337 3 : OInterfaceContainer::disposing();
1338 3 : FormComponentsBase::disposing();
1339 3 : m_xParent = NULL;
1340 3 : }
1341 :
1342 : //XChild
1343 : //------------------------------------------------------------------------------
1344 4 : void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
1345 : {
1346 4 : ::osl::MutexGuard aGuard( m_aMutex );
1347 4 : m_xParent = Parent;
1348 4 : }
1349 :
1350 : //------------------------------------------------------------------------------
1351 24 : InterfaceRef OFormComponents::getParent() throw( RuntimeException )
1352 : {
1353 24 : return m_xParent;
1354 : }
1355 :
1356 : //.........................................................................
1357 : } // namespace frm
1358 : //.........................................................................
1359 :
1360 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|