1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_file.hxx"
24 #include <rtl/uri.hxx>
25 #include <rtl/ustrbuf.hxx>
26 #include <osl/file.hxx>
27
28 #include "osl/diagnose.h"
29 #include <com/sun/star/ucb/OpenMode.hpp>
30 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #endif
33 #include <com/sun/star/ucb/XProgressHandler.hpp>
34 #include <com/sun/star/task/XInteractionHandler.hpp>
35 #include <com/sun/star/io/XActiveDataStreamer.hpp>
36 #include <com/sun/star/io/XOutputStream.hpp>
37 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
40 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
41 #include <com/sun/star/ucb/ContentAction.hpp>
42 #include <com/sun/star/ucb/NameClash.hpp>
43 #include "filglob.hxx"
44 #include "filid.hxx"
45 #include "filrow.hxx"
46 #include "bc.hxx"
47 #include "prov.hxx"
48 #ifndef _FILERROR_HXX_
49 #include "filerror.hxx"
50 #endif
51 #include "filinsreq.hxx"
52
53
54 using namespace fileaccess;
55 using namespace com::sun::star;
56 using namespace com::sun::star::uno;
57 using namespace com::sun::star::ucb;
58
59 // PropertyListeners
60
61
62 typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
63 PropertyListeners_impl;
64
65 class fileaccess::PropertyListeners
66 : public PropertyListeners_impl
67 {
68 public:
PropertyListeners(::osl::Mutex & aMutex)69 PropertyListeners( ::osl::Mutex& aMutex )
70 : PropertyListeners_impl( aMutex )
71 {
72 }
73 };
74
75
76 /****************************************************************************************/
77 /* BaseContent */
78 /****************************************************************************************/
79
80 ////////////////////////////////////////////////////////////////////////////////
81 // Private Constructor for just inserted Contents
82
BaseContent(shell * pMyShell,const rtl::OUString & parentName,sal_Bool bFolder)83 BaseContent::BaseContent( shell* pMyShell,
84 const rtl::OUString& parentName,
85 sal_Bool bFolder )
86 : m_pMyShell( pMyShell ),
87 m_xContentIdentifier( 0 ),
88 m_aUncPath( parentName ),
89 m_bFolder( bFolder ),
90 m_nState( JustInserted ),
91 m_pDisposeEventListeners( 0 ),
92 m_pContentEventListeners( 0 ),
93 m_pPropertySetInfoChangeListeners( 0 ),
94 m_pPropertyListener( 0 )
95 {
96 m_pMyShell->m_pProvider->acquire();
97 // No registering, since we have no name
98 }
99
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // Constructor for full featured Contents
103
BaseContent(shell * pMyShell,const Reference<XContentIdentifier> & xContentIdentifier,const rtl::OUString & aUncPath)104 BaseContent::BaseContent( shell* pMyShell,
105 const Reference< XContentIdentifier >& xContentIdentifier,
106 const rtl::OUString& aUncPath )
107 : m_pMyShell( pMyShell ),
108 m_xContentIdentifier( xContentIdentifier ),
109 m_aUncPath( aUncPath ),
110 m_bFolder( false ),
111 m_nState( FullFeatured ),
112 m_pDisposeEventListeners( 0 ),
113 m_pContentEventListeners( 0 ),
114 m_pPropertySetInfoChangeListeners( 0 ),
115 m_pPropertyListener( 0 )
116 {
117 m_pMyShell->m_pProvider->acquire();
118 m_pMyShell->registerNotifier( m_aUncPath,this );
119 m_pMyShell->insertDefaultProperties( m_aUncPath );
120 }
121
122
~BaseContent()123 BaseContent::~BaseContent( )
124 {
125 if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
126 {
127 m_pMyShell->deregisterNotifier( m_aUncPath,this );
128 }
129 m_pMyShell->m_pProvider->release();
130
131 delete m_pDisposeEventListeners;
132 delete m_pContentEventListeners;
133 delete m_pPropertyListener;
134 delete m_pPropertySetInfoChangeListeners;
135 }
136
137
138 //////////////////////////////////////////////////////////////////////////
139 // XInterface
140 //////////////////////////////////////////////////////////////////////////
141
142 void SAL_CALL
acquire(void)143 BaseContent::acquire( void )
144 throw()
145 {
146 OWeakObject::acquire();
147 }
148
149
150 void SAL_CALL
release(void)151 BaseContent::release( void )
152 throw()
153 {
154 OWeakObject::release();
155 }
156
157
158 Any SAL_CALL
queryInterface(const Type & rType)159 BaseContent::queryInterface( const Type& rType )
160 {
161 Any aRet = cppu::queryInterface( rType,
162 SAL_STATIC_CAST( lang::XComponent*, this ),
163 SAL_STATIC_CAST( lang::XTypeProvider*, this ),
164 SAL_STATIC_CAST( lang::XServiceInfo*, this ),
165 SAL_STATIC_CAST( XCommandProcessor*, this ),
166 SAL_STATIC_CAST( container::XChild*, this ),
167 SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ),
168 SAL_STATIC_CAST( beans::XPropertyContainer*, this ),
169 SAL_STATIC_CAST( XContentCreator*,this ),
170 SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ),
171 SAL_STATIC_CAST( XContent*,this) );
172 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
173 }
174
175
176
177
178 //////////////////////////////////////////////////////////////////////////////////////////
179 // XComponent
180 ////////////////////////////////////////////////////////////////////////////////////////
181
182 void SAL_CALL
addEventListener(const Reference<lang::XEventListener> & Listener)183 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
184 {
185 osl::MutexGuard aGuard( m_aMutex );
186
187 if ( ! m_pDisposeEventListeners )
188 m_pDisposeEventListeners =
189 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
190
191 m_pDisposeEventListeners->addInterface( Listener );
192 }
193
194
195 void SAL_CALL
removeEventListener(const Reference<lang::XEventListener> & Listener)196 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
197 {
198 osl::MutexGuard aGuard( m_aMutex );
199
200 if ( m_pDisposeEventListeners )
201 m_pDisposeEventListeners->removeInterface( Listener );
202 }
203
204
205 void SAL_CALL
dispose()206 BaseContent::dispose()
207 {
208 lang::EventObject aEvt;
209 cppu::OInterfaceContainerHelper* pDisposeEventListeners;
210 cppu::OInterfaceContainerHelper* pContentEventListeners;
211 cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
212 PropertyListeners* pPropertyListener;
213
214 {
215 osl::MutexGuard aGuard( m_aMutex );
216 aEvt.Source = static_cast< XContent* >( this );
217
218
219 pDisposeEventListeners =
220 m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
221
222 pContentEventListeners =
223 m_pContentEventListeners, m_pContentEventListeners = 0;
224
225 pPropertySetInfoChangeListeners =
226 m_pPropertySetInfoChangeListeners,
227 m_pPropertySetInfoChangeListeners = 0;
228
229 pPropertyListener =
230 m_pPropertyListener, m_pPropertyListener = 0;
231 }
232
233 if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
234 pDisposeEventListeners->disposeAndClear( aEvt );
235
236 if ( pContentEventListeners && pContentEventListeners->getLength() )
237 pContentEventListeners->disposeAndClear( aEvt );
238
239 if( pPropertyListener )
240 pPropertyListener->disposeAndClear( aEvt );
241
242 if( pPropertySetInfoChangeListeners )
243 pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
244
245 delete pDisposeEventListeners;
246 delete pContentEventListeners;
247 delete pPropertyListener;
248 delete pPropertySetInfoChangeListeners;
249 }
250
251
252
253 //////////////////////////////////////////////////////////////////////////////////////////
254 // XServiceInfo
255 //////////////////////////////////////////////////////////////////////////////////////////
256
257 rtl::OUString SAL_CALL
getImplementationName()258 BaseContent::getImplementationName()
259 {
260 return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" );
261 }
262
263
264
265 sal_Bool SAL_CALL
supportsService(const rtl::OUString & ServiceName)266 BaseContent::supportsService( const rtl::OUString& ServiceName )
267 {
268 if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 )
269 return true;
270 else
271 return false;
272 }
273
274
275
276 Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()277 BaseContent::getSupportedServiceNames()
278 {
279 Sequence< rtl::OUString > ret( 1 );
280 ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" );
281 return ret;
282 }
283
284
285
286 //////////////////////////////////////////////////////////////////////////////////////////
287 // XTypeProvider
288 //////////////////////////////////////////////////////////////////////////////////////////
289
XTYPEPROVIDER_IMPL_10(BaseContent,lang::XComponent,lang::XTypeProvider,lang::XServiceInfo,XCommandProcessor,XContentCreator,XContent,container::XChild,beans::XPropertiesChangeNotifier,beans::XPropertyContainer,beans::XPropertySetInfoChangeNotifier)290 XTYPEPROVIDER_IMPL_10( BaseContent,
291 lang::XComponent,
292 lang::XTypeProvider,
293 lang::XServiceInfo,
294 XCommandProcessor,
295 XContentCreator,
296 XContent,
297 container::XChild,
298 beans::XPropertiesChangeNotifier,
299 beans::XPropertyContainer,
300 beans::XPropertySetInfoChangeNotifier )
301
302
303 //////////////////////////////////////////////////////////////////////////////////////////
304 // XCommandProcessor
305 //////////////////////////////////////////////////////////////////////////////////////////
306
307 sal_Int32 SAL_CALL
308 BaseContent::createCommandIdentifier( void )
309 {
310 return m_pMyShell->getCommandId();
311 }
312
313
314 void SAL_CALL
abort(sal_Int32 CommandId)315 BaseContent::abort( sal_Int32 CommandId )
316 {
317 m_pMyShell->abort( CommandId );
318 }
319
320
321 Any SAL_CALL
execute(const Command & aCommand,sal_Int32 CommandId,const Reference<XCommandEnvironment> & Environment)322 BaseContent::execute( const Command& aCommand,
323 sal_Int32 CommandId,
324 const Reference< XCommandEnvironment >& Environment )
325 {
326 if( ! CommandId )
327 // A Command with commandid zero cannot be aborted
328 CommandId = createCommandIdentifier();
329
330 m_pMyShell->startTask( CommandId,
331 Environment );
332
333 Any aAny;
334
335 if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) ) // No exceptions
336 {
337 aAny <<= getPropertySetInfo( CommandId );
338 }
339 else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) ) // no exceptions
340 {
341 aAny <<= getCommandInfo();
342 }
343 else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) )
344 {
345 Sequence< beans::PropertyValue > sPropertyValues;
346
347 if( ! ( aCommand.Argument >>= sPropertyValues ) )
348 m_pMyShell->installError( CommandId,
349 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
350 else
351 aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
352 }
353 else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) )
354 {
355 Sequence< beans::Property > ListOfRequestedProperties;
356
357 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
358 m_pMyShell->installError( CommandId,
359 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
360 else
361 aAny <<= getPropertyValues( CommandId,
362 ListOfRequestedProperties );
363 }
364 else if( ! aCommand.Name.compareToAscii( "open" ) )
365 {
366 OpenCommandArgument2 aOpenArgument;
367 if( ! ( aCommand.Argument >>= aOpenArgument ) )
368 m_pMyShell->installError( CommandId,
369 TASKHANDLING_WRONG_OPEN_ARGUMENT );
370 else
371 {
372 Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
373 if( result.is() )
374 aAny <<= result;
375 }
376 }
377 else if( ! aCommand.Name.compareToAscii( "delete" ) )
378 {
379 if( ! aCommand.Argument.has< sal_Bool >() )
380 m_pMyShell->installError( CommandId,
381 TASKHANDLING_WRONG_DELETE_ARGUMENT );
382 else
383 deleteContent( CommandId );
384 }
385 else if( ! aCommand.Name.compareToAscii( "transfer" ) )
386 {
387 TransferInfo aTransferInfo;
388 if( ! ( aCommand.Argument >>= aTransferInfo ) )
389 m_pMyShell->installError( CommandId,
390 TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
391 else
392 transfer( CommandId, aTransferInfo );
393 }
394 else if( ! aCommand.Name.compareToAscii( "insert" ) )
395 {
396 InsertCommandArgument aInsertArgument;
397 if( ! ( aCommand.Argument >>= aInsertArgument ) )
398 m_pMyShell->installError( CommandId,
399 TASKHANDLING_WRONG_INSERT_ARGUMENT );
400 else
401 insert( CommandId,aInsertArgument );
402 }
403 else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) )
404 {
405 Sequence< beans::Property > seq(1);
406 seq[0] = beans::Property(
407 rtl::OUString::createFromAscii("CasePreservingURL"),
408 -1,
409 getCppuType( static_cast< sal_Bool* >(0) ),
410 0 );
411 Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
412 rtl::OUString CasePreservingURL = xRow->getString(1);
413 if(!xRow->wasNull())
414 aAny <<= CasePreservingURL;
415 }
416 else if( ! aCommand.Name.compareToAscii( "createNewContent" ) )
417 {
418 ucb::ContentInfo aArg;
419 if ( !( aCommand.Argument >>= aArg ) )
420 m_pMyShell->installError( CommandId,
421 TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
422 else
423 aAny <<= createNewContent( aArg );
424 }
425 else
426 m_pMyShell->installError( CommandId,
427 TASKHANDLER_UNSUPPORTED_COMMAND );
428
429
430 // This is the only function allowed to throw an exception
431 endTask( CommandId );
432
433 return aAny;
434 }
435
436
437
438 void SAL_CALL
addPropertiesChangeListener(const Sequence<rtl::OUString> & PropertyNames,const Reference<beans::XPropertiesChangeListener> & Listener)439 BaseContent::addPropertiesChangeListener(
440 const Sequence< rtl::OUString >& PropertyNames,
441 const Reference< beans::XPropertiesChangeListener >& Listener )
442 {
443 if( ! Listener.is() )
444 return;
445
446 osl::MutexGuard aGuard( m_aMutex );
447
448 if( ! m_pPropertyListener )
449 m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex );
450
451
452 if( PropertyNames.getLength() == 0 )
453 m_pPropertyListener->addInterface( rtl::OUString(),Listener );
454 else
455 {
456 Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
457 for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
458 if( xProp->hasPropertyByName( PropertyNames[i] ) )
459 m_pPropertyListener->addInterface( PropertyNames[i],Listener );
460 }
461 }
462
463
464 void SAL_CALL
removePropertiesChangeListener(const Sequence<rtl::OUString> & PropertyNames,const Reference<beans::XPropertiesChangeListener> & Listener)465 BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames,
466 const Reference< beans::XPropertiesChangeListener >& Listener )
467 {
468 if( ! Listener.is() )
469 return;
470
471 osl::MutexGuard aGuard( m_aMutex );
472
473 if( ! m_pPropertyListener )
474 return;
475
476 for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
477 m_pPropertyListener->removeInterface( PropertyNames[i],Listener );
478
479 m_pPropertyListener->removeInterface( rtl::OUString(), Listener );
480 }
481
482
483 /////////////////////////////////////////////////////////////////////////////////////////
484 // XContent
485 /////////////////////////////////////////////////////////////////////////////////////////
486
487 Reference< ucb::XContentIdentifier > SAL_CALL
getIdentifier()488 BaseContent::getIdentifier()
489 {
490 return m_xContentIdentifier;
491 }
492
493
494 rtl::OUString SAL_CALL
getContentType()495 BaseContent::getContentType()
496 {
497 if( !( m_nState & Deleted ) )
498 {
499 if( m_nState & JustInserted )
500 {
501 if ( m_bFolder )
502 return m_pMyShell->FolderContentType;
503 else
504 return m_pMyShell->FileContentType;
505 }
506 else
507 {
508 try
509 {
510 // Who am I ?
511 Sequence< beans::Property > seq(1);
512 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
513 -1,
514 getCppuType( static_cast< sal_Bool* >(0) ),
515 0 );
516 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
517 sal_Bool IsDocument = xRow->getBoolean( 1 );
518
519 if ( !xRow->wasNull() )
520 {
521 if ( IsDocument )
522 return m_pMyShell->FileContentType;
523 else
524 return m_pMyShell->FolderContentType;
525 }
526 else
527 {
528 OSL_ENSURE( false,
529 "BaseContent::getContentType - Property value was null!" );
530 }
531 }
532 catch ( sdbc::SQLException const & )
533 {
534 OSL_ENSURE( false,
535 "BaseContent::getContentType - Caught SQLException!" );
536 }
537 }
538 }
539
540 return rtl::OUString();
541 }
542
543
544
545 void SAL_CALL
addContentEventListener(const Reference<XContentEventListener> & Listener)546 BaseContent::addContentEventListener(
547 const Reference< XContentEventListener >& Listener )
548 {
549 osl::MutexGuard aGuard( m_aMutex );
550
551 if ( ! m_pContentEventListeners )
552 m_pContentEventListeners =
553 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
554
555
556 m_pContentEventListeners->addInterface( Listener );
557 }
558
559
560 void SAL_CALL
removeContentEventListener(const Reference<XContentEventListener> & Listener)561 BaseContent::removeContentEventListener(
562 const Reference< XContentEventListener >& Listener )
563 {
564 osl::MutexGuard aGuard( m_aMutex );
565
566 if ( m_pContentEventListeners )
567 m_pContentEventListeners->removeInterface( Listener );
568 }
569
570
571
572 ////////////////////////////////////////////////////////////////////////////////
573 // XPropertyContainer
574 ////////////////////////////////////////////////////////////////////////////////
575
576
577 void SAL_CALL
addProperty(const rtl::OUString & Name,sal_Int16 Attributes,const Any & DefaultValue)578 BaseContent::addProperty(
579 const rtl::OUString& Name,
580 sal_Int16 Attributes,
581 const Any& DefaultValue )
582 {
583 if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() )
584 {
585 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
586 }
587
588 m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
589 }
590
591
592 void SAL_CALL
removeProperty(const rtl::OUString & Name)593 BaseContent::removeProperty(
594 const rtl::OUString& Name )
595 {
596
597 if( m_nState & Deleted )
598 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
599
600 m_pMyShell->deassociate( m_aUncPath, Name );
601 }
602
603 ////////////////////////////////////////////////////////////////////////////////
604 // XContentCreator
605 ////////////////////////////////////////////////////////////////////////////////
606
607 Sequence< ContentInfo > SAL_CALL
queryCreatableContentsInfo(void)608 BaseContent::queryCreatableContentsInfo(
609 void )
610 {
611 return m_pMyShell->queryCreatableContentsInfo();
612 }
613
614
615 Reference< XContent > SAL_CALL
createNewContent(const ContentInfo & Info)616 BaseContent::createNewContent(
617 const ContentInfo& Info )
618 {
619 // Check type.
620 if ( !Info.Type.getLength() )
621 return Reference< XContent >();
622
623 sal_Bool bFolder
624 = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
625 if ( !bFolder )
626 {
627 if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
628 {
629 // Neither folder nor file to create!
630 return Reference< XContent >();
631 }
632 }
633
634 // Who am I ?
635 sal_Bool IsDocument = false;
636
637 try
638 {
639 Sequence< beans::Property > seq(1);
640 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
641 -1,
642 getCppuType( static_cast< sal_Bool* >(0) ),
643 0 );
644 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
645 IsDocument = xRow->getBoolean( 1 );
646
647 if ( xRow->wasNull() )
648 {
649 IsDocument = false;
650 // OSL_ENSURE( false,
651 // "BaseContent::createNewContent - Property value was null!" );
652 // return Reference< XContent >();
653 }
654 }
655 catch ( sdbc::SQLException const & )
656 {
657 OSL_ENSURE( false,
658 "BaseContent::createNewContent - Caught SQLException!" );
659 return Reference< XContent >();
660 }
661
662 rtl::OUString dstUncPath;
663
664 if( IsDocument )
665 {
666 // KSO: Why is a document a XContentCreator? This is quite unusual.
667 dstUncPath = getParentName( m_aUncPath );
668 }
669 else
670 dstUncPath = m_aUncPath;
671
672 BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
673 return Reference< XContent >( p );
674 }
675
676
677 ////////////////////////////////////////////////////////////////////////////////
678 // XPropertySetInfoChangeNotifier
679 ////////////////////////////////////////////////////////////////////////////////
680
681
682 void SAL_CALL
addPropertySetInfoChangeListener(const Reference<beans::XPropertySetInfoChangeListener> & Listener)683 BaseContent::addPropertySetInfoChangeListener(
684 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
685 {
686 osl::MutexGuard aGuard( m_aMutex );
687 if( ! m_pPropertySetInfoChangeListeners )
688 m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
689
690 m_pPropertySetInfoChangeListeners->addInterface( Listener );
691 }
692
693
694 void SAL_CALL
removePropertySetInfoChangeListener(const Reference<beans::XPropertySetInfoChangeListener> & Listener)695 BaseContent::removePropertySetInfoChangeListener(
696 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
697 {
698 osl::MutexGuard aGuard( m_aMutex );
699
700 if( m_pPropertySetInfoChangeListeners )
701 m_pPropertySetInfoChangeListeners->removeInterface( Listener );
702 }
703
704
705 ////////////////////////////////////////////////////////////////////////////////
706 // XChild
707 ////////////////////////////////////////////////////////////////////////////////
708
709 Reference< XInterface > SAL_CALL
getParent(void)710 BaseContent::getParent(
711 void )
712 {
713 rtl::OUString ParentUnq = getParentName( m_aUncPath );
714 rtl::OUString ParentUrl;
715
716
717 sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
718 if( err )
719 return Reference< XInterface >( 0 );
720
721 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
722 Reference< XContentIdentifier > Identifier( p );
723
724 try
725 {
726 Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
727 return Reference<XInterface>(content,UNO_QUERY);
728 }
729 catch( IllegalIdentifierException )
730 {
731 return Reference< XInterface >();
732 }
733 }
734
735
736 void SAL_CALL
setParent(const Reference<XInterface> &)737 BaseContent::setParent(
738 const Reference< XInterface >& )
739 {
740 throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
741 }
742
743
744 //////////////////////////////////////////////////////////////////////////////////////////
745 // Private Methods
746 //////////////////////////////////////////////////////////////////////////////////////////
747
748
749 Reference< XCommandInfo > SAL_CALL
getCommandInfo()750 BaseContent::getCommandInfo()
751 {
752 if( m_nState & Deleted )
753 return Reference< XCommandInfo >();
754
755 return m_pMyShell->info_c();
756 }
757
758
759 Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo(sal_Int32)760 BaseContent::getPropertySetInfo(
761 sal_Int32 )
762 {
763 if( m_nState & Deleted )
764 return Reference< beans::XPropertySetInfo >();
765
766 return m_pMyShell->info_p( m_aUncPath );
767 }
768
769
770
771
772 Reference< sdbc::XRow > SAL_CALL
getPropertyValues(sal_Int32 nMyCommandIdentifier,const Sequence<beans::Property> & PropertySet)773 BaseContent::getPropertyValues(
774 sal_Int32 nMyCommandIdentifier,
775 const Sequence< beans::Property >& PropertySet )
776 {
777 sal_Int32 nProps = PropertySet.getLength();
778 if ( !nProps )
779 return Reference< sdbc::XRow >();
780
781 if( m_nState & Deleted )
782 {
783 Sequence< Any > aValues( nProps );
784 return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
785 }
786
787 if( m_nState & JustInserted )
788 {
789 Sequence< Any > aValues( nProps );
790 Any* pValues = aValues.getArray();
791
792 const beans::Property* pProps = PropertySet.getConstArray();
793
794 for ( sal_Int32 n = 0; n < nProps; ++n )
795 {
796 const beans::Property& rProp = pProps[ n ];
797 Any& rValue = pValues[ n ];
798
799 if( rProp.Name.compareToAscii( "ContentType" ) == 0 )
800 {
801 rValue <<= m_bFolder ? m_pMyShell->FolderContentType
802 : m_pMyShell->FileContentType;
803 }
804 else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 )
805 {
806 rValue <<= m_bFolder;
807 }
808 else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 )
809 {
810 rValue <<= sal_Bool( !m_bFolder );
811 }
812 }
813
814 return Reference< sdbc::XRow >(
815 new XRow_impl( m_pMyShell, aValues ) );
816 }
817
818 return m_pMyShell->getv( nMyCommandIdentifier,
819 m_aUncPath,
820 PropertySet );
821 }
822
823
824 Sequence< Any > SAL_CALL
setPropertyValues(sal_Int32 nMyCommandIdentifier,const Sequence<beans::PropertyValue> & Values)825 BaseContent::setPropertyValues(
826 sal_Int32 nMyCommandIdentifier,
827 const Sequence< beans::PropertyValue >& Values )
828 throw()
829 {
830 if( m_nState & Deleted )
831 { // To do
832 return Sequence< Any >( Values.getLength() );
833 }
834
835 const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" );
836
837 // Special handling for files which have to be inserted
838 if( m_nState & JustInserted )
839 {
840 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
841 {
842 if( Values[i].Name == Title )
843 {
844 rtl::OUString NewTitle;
845 if( Values[i].Value >>= NewTitle )
846 {
847 if ( m_nState & NameForInsertionSet )
848 {
849 // User wants to set another Title before "insert".
850 // m_aUncPath contains previous own URI.
851
852 sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
853 bool bTrailingSlash = false;
854 if ( nLastSlash == m_aUncPath.getLength() - 1 )
855 {
856 bTrailingSlash = true;
857 nLastSlash
858 = m_aUncPath.lastIndexOf( '/', nLastSlash );
859 }
860
861 OSL_ENSURE( nLastSlash != -1,
862 "BaseContent::setPropertyValues: "
863 "Invalid URL!" );
864
865 rtl::OUStringBuffer aBuf(
866 m_aUncPath.copy( 0, nLastSlash + 1 ) );
867
868 if ( NewTitle.getLength() > 0 )
869 {
870 aBuf.append( NewTitle );
871 if ( bTrailingSlash )
872 aBuf.append( sal_Unicode( '/' ) );
873 }
874 else
875 {
876 m_nState &= ~NameForInsertionSet;
877 }
878
879 m_aUncPath = aBuf.makeStringAndClear();
880 }
881 else
882 {
883 if ( NewTitle.getLength() > 0 )
884 {
885 // Initial Title before "insert".
886 // m_aUncPath contains parent's URI.
887
888 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
889 m_aUncPath += rtl::OUString::createFromAscii("/");
890
891 m_aUncPath += rtl::Uri::encode( NewTitle,
892 rtl_UriCharClassPchar,
893 rtl_UriEncodeIgnoreEscapes,
894 RTL_TEXTENCODING_UTF8 );
895 m_nState |= NameForInsertionSet;
896 }
897 }
898 }
899 }
900 }
901
902 return Sequence< Any >( Values.getLength() );
903 }
904 else
905 {
906 Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
907 Values );
908
909 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
910 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
911 {
912 if( Values[i].Name != Title )
913 continue; // handled by setv
914
915 rtl::OUString NewTitle;
916 if( !( Values[i].Value >>= NewTitle ) )
917 {
918 ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
919 break;
920 }
921 else if( ! NewTitle.getLength() )
922 {
923 ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
924 break;
925 }
926
927
928 rtl::OUString aDstName = getParentName( m_aUncPath );
929 if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
930 aDstName += rtl::OUString::createFromAscii("/");
931
932 aDstName += rtl::Uri::encode( NewTitle,
933 rtl_UriCharClassPchar,
934 rtl_UriEncodeIgnoreEscapes,
935 RTL_TEXTENCODING_UTF8 );
936
937 m_pMyShell->move( nMyCommandIdentifier, // move notifies the childs also;
938 m_aUncPath,
939 aDstName,
940 NameClash::KEEP );
941
942 try
943 {
944 endTask( nMyCommandIdentifier );
945 }
946 catch( const Exception& e )
947 {
948 ret[i] <<= e;
949 }
950
951 // NameChanges come back through a ContentEvent
952 break; // only handling Title
953 } // end for
954
955 return ret;
956 }
957 }
958
959
960
961 Reference< XDynamicResultSet > SAL_CALL
open(sal_Int32 nMyCommandIdentifier,const OpenCommandArgument2 & aCommandArgument)962 BaseContent::open(
963 sal_Int32 nMyCommandIdentifier,
964 const OpenCommandArgument2& aCommandArgument )
965 throw()
966 {
967 Reference< XDynamicResultSet > retValue( 0 );
968
969 if( ( m_nState & Deleted ) )
970 {
971 m_pMyShell->installError( nMyCommandIdentifier,
972 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
973 }
974 else if( m_nState & JustInserted )
975 {
976 m_pMyShell->installError( nMyCommandIdentifier,
977 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
978 }
979 else
980 {
981 if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
982 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
983
984 {
985 Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
986 if( outputStream.is() )
987 {
988 m_pMyShell->page( nMyCommandIdentifier,
989 m_aUncPath,
990 outputStream );
991 }
992
993 sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
994
995 Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
996 if( activeDataSink.is() )
997 {
998 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
999 m_aUncPath,
1000 bLock ) );
1001 }
1002
1003 Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
1004 if( activeDataStreamer.is() )
1005 {
1006 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
1007 m_aUncPath,
1008 bLock ) );
1009 }
1010 }
1011 else if ( aCommandArgument.Mode == OpenMode::ALL ||
1012 aCommandArgument.Mode == OpenMode::FOLDERS ||
1013 aCommandArgument.Mode == OpenMode::DOCUMENTS )
1014 {
1015 retValue = m_pMyShell->ls( nMyCommandIdentifier,
1016 m_aUncPath,
1017 aCommandArgument.Mode,
1018 aCommandArgument.Properties,
1019 aCommandArgument.SortingInfo );
1020 }
1021 // else if( aCommandArgument.Mode ==
1022 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
1023 // aCommandArgument.Mode ==
1024 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1025 // m_pMyShell->installError( nMyCommandIdentifier,
1026 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1027 // aCommandArgument.Mode);
1028 else
1029 m_pMyShell->installError( nMyCommandIdentifier,
1030 TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1031 aCommandArgument.Mode);
1032 }
1033
1034 return retValue;
1035 }
1036
1037
1038
1039 void SAL_CALL
deleteContent(sal_Int32 nMyCommandIdentifier)1040 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
1041 throw()
1042 {
1043 if( m_nState & Deleted )
1044 return;
1045
1046 if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
1047 {
1048 osl::MutexGuard aGuard( m_aMutex );
1049 m_nState |= Deleted;
1050 }
1051 }
1052
1053
1054
1055 void SAL_CALL
transfer(sal_Int32 nMyCommandIdentifier,const TransferInfo & aTransferInfo)1056 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
1057 const TransferInfo& aTransferInfo )
1058 throw()
1059 {
1060 if( m_nState & Deleted )
1061 return;
1062
1063 if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
1064 {
1065 m_pMyShell->installError( nMyCommandIdentifier,
1066 TASKHANDLING_TRANSFER_INVALIDSCHEME );
1067 return;
1068 }
1069
1070 rtl::OUString srcUnc;
1071 if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
1072 {
1073 m_pMyShell->installError( nMyCommandIdentifier,
1074 TASKHANDLING_TRANSFER_INVALIDURL );
1075 return;
1076 }
1077
1078 rtl::OUString srcUncPath = srcUnc;
1079
1080 // Determine the new title !
1081 rtl::OUString NewTitle;
1082 if( aTransferInfo.NewTitle.getLength() )
1083 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
1084 rtl_UriCharClassPchar,
1085 rtl_UriEncodeIgnoreEscapes,
1086 RTL_TEXTENCODING_UTF8 );
1087 else
1088 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
1089
1090 // Is destination a document or a folder ?
1091 Sequence< beans::Property > seq(1);
1092 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1093 -1,
1094 getCppuType( static_cast< sal_Bool* >(0) ),
1095 0 );
1096 Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
1097 sal_Bool IsDocument = xRow->getBoolean( 1 );
1098 if( xRow->wasNull() )
1099 { // Destination file type could not be determined
1100 m_pMyShell->installError( nMyCommandIdentifier,
1101 TASKHANDLING_TRANSFER_DESTFILETYPE );
1102 return;
1103 }
1104
1105 rtl::OUString dstUncPath;
1106 if( IsDocument )
1107 { // as sibling
1108 sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
1109 dstUncPath = m_aUncPath.copy(0,lastSlash );
1110 }
1111 else
1112 // as child
1113 dstUncPath = m_aUncPath;
1114
1115 dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle );
1116
1117 sal_Int32 NameClash = aTransferInfo.NameClash;
1118
1119 if( aTransferInfo.MoveData )
1120 m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1121 else
1122 m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1123 }
1124
1125
1126
1127
insert(sal_Int32 nMyCommandIdentifier,const InsertCommandArgument & aInsertArgument)1128 void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
1129 const InsertCommandArgument& aInsertArgument )
1130 throw()
1131 {
1132 if( m_nState & FullFeatured )
1133 {
1134 m_pMyShell->write( nMyCommandIdentifier,
1135 m_aUncPath,
1136 aInsertArgument.ReplaceExisting,
1137 aInsertArgument.Data );
1138 return;
1139 }
1140
1141 if( ! ( m_nState & JustInserted ) )
1142 {
1143 m_pMyShell->installError( nMyCommandIdentifier,
1144 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
1145 return;
1146 }
1147
1148 // Inserts the content, which has the flag m_bIsFresh
1149
1150 if ( !m_nState | !NameForInsertionSet )
1151 {
1152 m_pMyShell->installError( nMyCommandIdentifier,
1153 TASKHANDLING_NONAMESET_INSERT_COMMAND );
1154 return;
1155 }
1156
1157 // Inserting a document or a file?
1158 sal_Bool bDocument = false;
1159
1160 Sequence< beans::Property > seq(1);
1161 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1162 -1,
1163 getCppuType( static_cast< sal_Bool* >(0) ),
1164 0 );
1165
1166 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
1167
1168 bool contentTypeSet = true; // is set to false, if contentType not set
1169 try
1170 {
1171 bDocument = xRow->getBoolean( 1 );
1172 if( xRow->wasNull() )
1173 contentTypeSet = false;
1174
1175 }
1176 catch ( sdbc::SQLException const & )
1177 {
1178 OSL_ENSURE( false,
1179 "BaseContent::insert - Caught SQLException!" );
1180 contentTypeSet = false;
1181 }
1182
1183 if( ! contentTypeSet )
1184 {
1185 m_pMyShell->installError( nMyCommandIdentifier,
1186 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1187 return;
1188 }
1189
1190
1191 sal_Bool success = false;
1192 if( bDocument )
1193 success = m_pMyShell->mkfil( nMyCommandIdentifier,
1194 m_aUncPath,
1195 aInsertArgument.ReplaceExisting,
1196 aInsertArgument.Data );
1197 else
1198 {
1199 while( ! success )
1200 {
1201 success = m_pMyShell->mkdir( nMyCommandIdentifier,
1202 m_aUncPath,
1203 aInsertArgument.ReplaceExisting );
1204 if( success )
1205 break;
1206
1207 XInteractionRequestImpl *aRequestImpl =
1208 new XInteractionRequestImpl(
1209 rtl::Uri::decode(
1210 getTitle(m_aUncPath),
1211 rtl_UriDecodeWithCharset,
1212 RTL_TEXTENCODING_UTF8),
1213 (cppu::OWeakObject*)this,
1214 m_pMyShell,nMyCommandIdentifier);
1215 uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
1216
1217 m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
1218 if( aRequestImpl->aborted() ||
1219 !aRequestImpl->newName().getLength() )
1220 // means aborting
1221 break;
1222
1223 // determine new uncpath
1224 m_pMyShell->clearError( nMyCommandIdentifier );
1225 m_aUncPath = getParentName( m_aUncPath );
1226 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
1227 m_aUncPath += rtl::OUString::createFromAscii("/");
1228
1229 m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
1230 rtl_UriCharClassPchar,
1231 rtl_UriEncodeIgnoreEscapes,
1232 RTL_TEXTENCODING_UTF8 );
1233 }
1234 }
1235
1236 if ( ! success )
1237 return;
1238
1239 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
1240 m_xContentIdentifier = Reference< XContentIdentifier >( p );
1241
1242 m_pMyShell->registerNotifier( m_aUncPath,this );
1243 m_pMyShell->insertDefaultProperties( m_aUncPath );
1244
1245 osl::MutexGuard aGuard( m_aMutex );
1246 m_nState = FullFeatured;
1247 }
1248
1249
1250
endTask(sal_Int32 CommandId)1251 void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
1252 {
1253 // This is the only function allowed to throw an exception
1254 m_pMyShell->endTask( CommandId,m_aUncPath,this );
1255 }
1256
1257
1258
1259 ContentEventNotifier*
cDEL(void)1260 BaseContent::cDEL( void )
1261 {
1262 osl::MutexGuard aGuard( m_aMutex );
1263
1264 m_nState |= Deleted;
1265
1266 ContentEventNotifier* p;
1267 if( m_pContentEventListeners )
1268 p = new ContentEventNotifier( m_pMyShell,
1269 this,
1270 m_xContentIdentifier,
1271 m_pContentEventListeners->getElements() );
1272 else
1273 p = 0;
1274
1275 return p;
1276 }
1277
1278
1279 ContentEventNotifier*
cEXC(const rtl::OUString aNewName)1280 BaseContent::cEXC( const rtl::OUString aNewName )
1281 {
1282 osl::MutexGuard aGuard( m_aMutex );
1283
1284 Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1285 m_aUncPath = aNewName;
1286 FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
1287 m_xContentIdentifier = Reference< XContentIdentifier >( pp );
1288
1289 ContentEventNotifier* p = 0;
1290 if( m_pContentEventListeners )
1291 p = new ContentEventNotifier( m_pMyShell,
1292 this,
1293 m_xContentIdentifier,
1294 xOldRef,
1295 m_pContentEventListeners->getElements() );
1296
1297 return p;
1298 }
1299
1300
1301 ContentEventNotifier*
cCEL(void)1302 BaseContent::cCEL( void )
1303 {
1304 osl::MutexGuard aGuard( m_aMutex );
1305 ContentEventNotifier* p = 0;
1306 if( m_pContentEventListeners )
1307 p = new ContentEventNotifier( m_pMyShell,
1308 this,
1309 m_xContentIdentifier,
1310 m_pContentEventListeners->getElements() );
1311
1312 return p;
1313 }
1314
1315 PropertySetInfoChangeNotifier*
cPSL(void)1316 BaseContent::cPSL( void )
1317 {
1318 osl::MutexGuard aGuard( m_aMutex );
1319 PropertySetInfoChangeNotifier* p = 0;
1320 if( m_pPropertySetInfoChangeListeners )
1321 p = new PropertySetInfoChangeNotifier( m_pMyShell,
1322 this,
1323 m_xContentIdentifier,
1324 m_pPropertySetInfoChangeListeners->getElements() );
1325
1326 return p;
1327 }
1328
1329
1330
1331 PropertyChangeNotifier*
cPCL(void)1332 BaseContent::cPCL( void )
1333 {
1334 osl::MutexGuard aGuard( m_aMutex );
1335
1336 Sequence< rtl::OUString > seqNames;
1337
1338 if( m_pPropertyListener )
1339 seqNames = m_pPropertyListener->getContainedTypes();
1340
1341 PropertyChangeNotifier* p = 0;
1342
1343 sal_Int32 length = seqNames.getLength();
1344
1345 if( length )
1346 {
1347 ListenerMap* listener = new ListenerMap();
1348 for( sal_Int32 i = 0; i < length; ++i )
1349 {
1350 (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
1351 }
1352
1353 p = new PropertyChangeNotifier( m_pMyShell,
1354 this,
1355 m_xContentIdentifier,
1356 listener );
1357 }
1358
1359 return p;
1360 }
1361
1362
getKey(void)1363 rtl::OUString BaseContent::getKey( void )
1364 {
1365 return m_aUncPath;
1366 }
1367
1368 /* vim: set noet sw=4 ts=4: */
1369