xref: /AOO41X/main/xmlhelp/source/treeview/tvread.cxx (revision 89dcb3da00a29b2b7b028d5bd430e2099844a09e)
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 
23 
24 
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_xmlhelp.hxx"
27 
28 #include <string.h>
29 #include <rtl/ustrbuf.hxx>
30 #ifndef _VOS_DIAGNOSE_HXX_
31 #include <vos/diagnose.hxx>
32 #endif
33 #include "tvread.hxx"
34 #include <expat.h>
35 #include <osl/file.hxx>
36 #include <com/sun/star/frame/XConfigManager.hpp>
37 #include <com/sun/star/beans/PropertyValue.hpp>
38 
39 #include <comphelper/processfactory.hxx>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
42 #include <com/sun/star/util/XMacroExpander.hpp>
43 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
44 #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
45 #include <comphelper/locale.hxx>
46 
47 namespace treeview {
48 
49 
50     class TVDom
51     {
52         friend class TVChildTarget;
53         friend class TVRead;
54 
55     public:
56 
TVDom(TVDom * arent=0)57         TVDom( TVDom* arent = 0 )
58             : kind( other ),
59               parent( arent ),
60               childs( 0 )
61         {
62         }
63 
~TVDom()64         ~TVDom()
65         {
66             for( unsigned i = 0; i < childs.size(); ++i )
67                 delete childs[i];
68         }
69 
70 
newChild()71         TVDom* newChild()
72         {
73             childs.push_back( new TVDom( this ) );
74             return childs.back();
75         }
76 
77 
getParent() const78         TVDom* getParent() const
79         {
80             if( parent )
81                 return parent;
82             else
83                 return const_cast<TVDom*>(this);    // I am my own parent, if I am the root
84         }
85 
86         enum Kind {
87             tree_view,
88             tree_node,
89             tree_leaf,
90             other
91         };
92 
isLeaf() const93         bool isLeaf() const { return kind == TVDom::tree_leaf; }
setKind(Kind ind)94         void setKind( Kind ind ) { kind = ind; }
getKind() const95         Kind getKind( ) const { return kind; }
96 
97 
setApplication(const char * appl)98         void setApplication( const char* appl )
99         {
100             application = rtl::OUString( (sal_Char*)(appl),
101                                          strlen( appl ),
102                                          RTL_TEXTENCODING_UTF8 );
103         }
104 
setTitle(const char * itle)105         void setTitle( const char* itle )
106         {
107             title += rtl::OUString( (sal_Char*)(itle),
108                                     strlen( itle ),
109                                     RTL_TEXTENCODING_UTF8 );
110         }
111 
setTitle(const XML_Char * itle,int len)112         void setTitle( const XML_Char* itle,int len )
113         {
114             title += rtl::OUString( (sal_Char*)(itle),
115                                     len,
116                                     RTL_TEXTENCODING_UTF8 );
117         }
118 
setId(const char * d)119         void setId( const char* d )
120         {
121             id = rtl::OUString( (sal_Char*)(d),
122                                 strlen( d ),
123                                 RTL_TEXTENCODING_UTF8 );
124         }
125 
setAnchor(const char * nchor)126         void setAnchor( const char* nchor )
127         {
128             anchor = rtl::OUString( (sal_Char*)(nchor),
129                                     strlen( nchor ),
130                                     RTL_TEXTENCODING_UTF8 );
131         }
132 
getTargetURL()133         rtl::OUString getTargetURL()
134         {
135             if( ! targetURL.getLength() )
136             {
137                 sal_Int32 len;
138                 for ( const TVDom* p = this;; p = p->parent )
139                 {
140                     len = p->application.getLength();
141                     if ( len != 0 )
142                         break;
143                 }
144 
145                 rtl::OUStringBuffer strBuff( 22 + len + id.getLength() );
146                 strBuff.appendAscii(
147                                     "vnd.sun.star.help://"
148                                     ).append(id);
149 
150                 targetURL = strBuff.makeStringAndClear();
151             }
152 
153             return targetURL;
154         }
155 
156     private:
157 
158         Kind   kind;
159         rtl::OUString  application;
160         rtl::OUString  title;
161         rtl::OUString  id;
162         rtl::OUString  anchor;
163         rtl::OUString  targetURL;
164 
165         TVDom *parent;
166         std::vector< TVDom* > childs;
167     };
168 
169 }
170 
171 
172 
173 using namespace treeview;
174 using namespace com::sun::star;
175 using namespace com::sun::star::uno;
176 using namespace com::sun::star::beans;
177 using namespace com::sun::star::lang;
178 using namespace com::sun::star::util;
179 using namespace com::sun::star::frame;
180 using namespace com::sun::star::container;
181 using namespace com::sun::star::deployment;
182 
183 
ConfigData()184 ConfigData::ConfigData()
185     : prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ),
186       prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ),
187       vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ),
188       vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ),
189       vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) )
190 {
191 }
192 
replaceName(rtl::OUString & oustring) const193 void SAL_CALL ConfigData::replaceName( rtl::OUString& oustring ) const
194 {
195     sal_Int32 idx = -1,k = 0,off;
196     bool cap = false;
197     rtl::OUStringBuffer aStrBuf( 0 );
198 
199     while( ( idx = oustring.indexOf( sal_Unicode('%'),++idx ) ) != -1 )
200     {
201         if( oustring.indexOf( prodName,idx ) == idx )
202             off = PRODUCTNAME;
203         else if( oustring.indexOf( prodVersion,idx ) == idx )
204             off = PRODUCTVERSION;
205         else if( oustring.indexOf( vendName,idx ) == idx )
206             off = VENDORNAME;
207         else if( oustring.indexOf( vendVersion,idx ) == idx )
208             off = VENDORVERSION;
209         else if( oustring.indexOf( vendShort,idx ) == idx )
210             off = VENDORSHORT;
211         else
212             off = -1;
213 
214         if( off != -1 )
215         {
216             if( ! cap )
217             {
218                 cap = true;
219                 aStrBuf.ensureCapacity( 256 );
220             }
221 
222             aStrBuf.append( &oustring.getStr()[k],idx - k );
223             aStrBuf.append( m_vReplacement[off] );
224             k = idx + m_vAdd[off];
225         }
226     }
227 
228     if( cap )
229     {
230         if( k < oustring.getLength() )
231             aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
232         oustring = aStrBuf.makeStringAndClear();
233     }
234 }
235 
236 
237 
238 
239 //////////////////////////////////////////////////////////////////////////
240 // XInterface
241 //////////////////////////////////////////////////////////////////////////
242 
243 
244 void SAL_CALL
acquire(void)245 TVBase::acquire(
246     void )
247     throw()
248 {
249   OWeakObject::acquire();
250 }
251 
252 
253 void SAL_CALL
release(void)254 TVBase::release(
255               void )
256   throw()
257 {
258   OWeakObject::release();
259 }
260 
261 
262 Any SAL_CALL
queryInterface(const Type & rType)263 TVBase::queryInterface(
264     const Type& rType )
265     throw( RuntimeException )
266 {
267     Any aRet = cppu::queryInterface( rType,
268                                      SAL_STATIC_CAST( XTypeProvider*, this ),
269                                      SAL_STATIC_CAST( XNameAccess*, this ),
270                                      SAL_STATIC_CAST( XHierarchicalNameAccess*, this ),
271                                      SAL_STATIC_CAST( XChangesNotifier*, this ),
272                                      SAL_STATIC_CAST( XComponent*, this ) );
273 
274     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
275 }
276 
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 //
280 // XTypeProvider methods.
281 
282 XTYPEPROVIDER_IMPL_5( TVBase,
283                       XTypeProvider,
284                       XNameAccess,
285                       XHierarchicalNameAccess,
286                       XChangesNotifier,
287                       XComponent );
288 
289 
290 
291 
292 
293 
294 // TVRead
295 
296 
TVRead(const ConfigData & configData,TVDom * tvDom)297 TVRead::TVRead( const ConfigData& configData,TVDom* tvDom )
298 {
299     if( ! tvDom )
300         return;
301 
302     Title = tvDom->title;
303     configData.replaceName( Title );
304     if( tvDom->isLeaf() )
305     {
306         TargetURL = ( tvDom->getTargetURL() + configData.appendix );
307         if( tvDom->anchor.getLength() )
308             TargetURL += ( rtl::OUString::createFromAscii( "#" ) +
309                            tvDom->anchor );
310     }
311     else
312         Children = new TVChildTarget( configData,tvDom );
313 }
314 
315 
316 
~TVRead()317 TVRead::~TVRead()
318 {
319 }
320 
321 
322 
323 
324 
325 
326 // XNameAccess
327 
328 Any SAL_CALL
getByName(const rtl::OUString & aName)329 TVRead::getByName( const rtl::OUString& aName )
330     throw( NoSuchElementException,
331            WrappedTargetException,
332            RuntimeException )
333 {
334     bool found( true );
335     Any aAny;
336     if( aName.compareToAscii( "Title" ) == 0 )
337         aAny <<= Title;
338     else if( aName.compareToAscii( "TargetURL" ) == 0 )
339         aAny <<= TargetURL;
340     else if( aName.compareToAscii( "Children" ) == 0 )
341     {
342         cppu::OWeakObject* p = Children.get();
343         aAny <<= Reference< XInterface >( p );
344     }
345     else
346         found = false;
347 
348     if( found )
349         return aAny;
350 
351     throw NoSuchElementException();
352 }
353 
354 
355 
356 
357 Sequence< rtl::OUString > SAL_CALL
getElementNames()358 TVRead::getElementNames( )
359     throw( RuntimeException )
360 {
361     Sequence< rtl::OUString > seq( 3 );
362 
363     seq[0] = rtl::OUString::createFromAscii( "Title" );
364     seq[1] = rtl::OUString::createFromAscii( "TargetURL" );
365     seq[2] = rtl::OUString::createFromAscii( "Children" );
366 
367     return seq;
368 }
369 
370 
371 
372 sal_Bool SAL_CALL
hasByName(const rtl::OUString & aName)373 TVRead::hasByName( const rtl::OUString& aName )
374     throw( RuntimeException )
375 {
376     if( aName.compareToAscii( "Title" ) == 0        ||
377         aName.compareToAscii( "TargetURL" ) == 0    ||
378         aName.compareToAscii( "Children" ) == 0 )
379         return true;
380 
381     return false;
382 }
383 
384 
385 // XHierarchicalNameAccess
386 
387 Any SAL_CALL
getByHierarchicalName(const rtl::OUString & aName)388 TVRead::getByHierarchicalName( const rtl::OUString& aName )
389     throw( NoSuchElementException,
390            RuntimeException )
391 {
392     sal_Int32 idx;
393     rtl::OUString name( aName );
394 
395     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
396         name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
397         return Children->getByHierarchicalName( name.copy( 1 + idx ) );
398 
399     return getByName( name );
400 }
401 
402 
403 
404 
405 sal_Bool SAL_CALL
hasByHierarchicalName(const rtl::OUString & aName)406 TVRead::hasByHierarchicalName( const rtl::OUString& aName )
407     throw( RuntimeException )
408 {
409     sal_Int32 idx;
410     rtl::OUString name( aName );
411 
412     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
413         name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
414         return Children->hasByHierarchicalName( name.copy( 1 + idx ) );
415 
416     return hasByName( name );
417 }
418 
419 
420 
421 /**************************************************************************/
422 /*                                                                        */
423 /*                      TVChildTarget                                     */
424 /*                                                                        */
425 /**************************************************************************/
426 
427 
428 
429 
start_handler(void * userData,const XML_Char * name,const XML_Char ** atts)430 extern "C" void start_handler(void *userData,
431                    const XML_Char *name,
432                    const XML_Char **atts)
433 {
434     TVDom::Kind kind;
435 
436     if( strcmp( name,"help_section" ) == 0  ||
437         strcmp( name,"node" ) == 0 )
438         kind = TVDom::tree_node;
439     else if( strcmp( name,"topic" ) == 0 )
440         kind = TVDom::tree_leaf;
441     else
442         return;
443 
444     TVDom **tvDom = static_cast< TVDom** >( userData );
445     TVDom  *p;
446     p = *tvDom;
447 
448     *tvDom = p->newChild();
449     p = *tvDom;
450 
451     p->setKind( kind );
452     while( *atts )
453     {
454         if( strcmp( *atts,"application" ) == 0 )
455             p->setApplication( *(atts+1) );
456         else if( strcmp( *atts,"title" ) == 0 )
457             p->setTitle( *(atts+1) );
458         else if( strcmp( *atts,"id" ) == 0 )
459             p->setId( *(atts+1) );
460         else if( strcmp( *atts,"anchor" ) == 0 )
461             p->setAnchor( *(atts+1) );
462 
463         atts+=2;
464     }
465 }
466 
467 
end_handler(void * userData,const XML_Char * name)468 extern "C" void end_handler(void *userData,
469                  const XML_Char *name )
470 {
471     (void)name;
472 
473     TVDom **tvDom = static_cast< TVDom** >( userData );
474     *tvDom = (*tvDom)->getParent();
475 }
476 
477 
data_handler(void * userData,const XML_Char * s,int len)478 extern "C" void data_handler( void *userData,
479                    const XML_Char *s,
480                    int len)
481 {
482     TVDom **tvDom = static_cast< TVDom** >( userData );
483     if( (*tvDom)->isLeaf() )
484         (*tvDom)->setTitle( s,len );
485 }
486 
487 
488 
TVChildTarget(const ConfigData & configData,TVDom * tvDom)489 TVChildTarget::TVChildTarget( const ConfigData& configData,TVDom* tvDom )
490 {
491     Elements.resize( tvDom->childs.size() );
492     for( unsigned i = 0; i < Elements.size(); ++i )
493         Elements[i] = new TVRead( configData,tvDom->childs[i] );
494 }
495 
496 
497 
498 
499 
TVChildTarget(const Reference<XMultiServiceFactory> & xMSF)500 TVChildTarget::TVChildTarget( const Reference< XMultiServiceFactory >& xMSF )
501 {
502     ConfigData configData = init( xMSF );
503 
504     if( ! configData.locale.getLength()  ||
505         ! configData.system.getLength() )
506         return;
507 
508     sal_uInt64  ret,len = 0;
509     int j = configData.vFileURL.size();
510 
511     TVDom tvDom;
512     TVDom* pTVDom = &tvDom;
513 
514     while( j )
515     {
516         len = configData.vFileLen[--j];
517         char* s = new char[ int(len) ];  // the buffer to hold the installed files
518         osl::File aFile( configData.vFileURL[j] );
519         aFile.open( OpenFlag_Read );
520         aFile.read( s,len,ret );
521         aFile.close();
522 
523         XML_Parser parser = XML_ParserCreate( 0 );
524         XML_SetElementHandler( parser,
525                                start_handler,
526                                end_handler );
527         XML_SetCharacterDataHandler( parser,
528                                      data_handler);
529         XML_SetUserData( parser,&pTVDom ); // does not return this
530 
531         int parsed = XML_Parse( parser,s,int( len ),j==0 );
532         (void)parsed;
533         OSL_ENSURE( parsed, "TVChildTarget::TVChildTarget(): Tree file parsing failed" );
534 
535         XML_ParserFree( parser );
536         delete[] s;
537     }
538 
539     // now TVDom holds the relevant information
540 
541     Elements.resize( tvDom.childs.size() );
542     for( unsigned i = 0; i < Elements.size(); ++i )
543         Elements[i] = new TVRead( configData,tvDom.childs[i] );
544 }
545 
546 
~TVChildTarget()547 TVChildTarget::~TVChildTarget()
548 {
549 }
550 
551 
552 
553 Any SAL_CALL
getByName(const rtl::OUString & aName)554 TVChildTarget::getByName( const rtl::OUString& aName )
555     throw( NoSuchElementException,
556            WrappedTargetException,
557            RuntimeException )
558 {
559     rtl::OUString num( aName.getStr()+2,aName.getLength()-4 );
560     sal_Int32 idx = num.toInt32() - 1;
561     if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
562         throw NoSuchElementException();
563 
564     Any aAny;
565     cppu::OWeakObject* p = Elements[idx].get();
566     aAny <<= Reference< XInterface >( p );
567     return aAny;
568 }
569 
570 
571 
572 
573 Sequence< rtl::OUString > SAL_CALL
getElementNames()574 TVChildTarget::getElementNames( )
575     throw( RuntimeException )
576 {
577     Sequence< rtl::OUString > seq( Elements.size() );
578     for( unsigned i = 0; i < Elements.size(); ++i )
579         seq[i] = rtl::OUString::valueOf( sal_Int32( 1+i ) );
580 
581     return seq;
582 }
583 
584 
585 
586 sal_Bool SAL_CALL
hasByName(const rtl::OUString & aName)587 TVChildTarget::hasByName( const rtl::OUString& aName )
588     throw( RuntimeException )
589 {
590     rtl::OUString num( aName.getStr()+2,aName.getLength()-4 );
591     sal_Int32 idx = num.toInt32() - 1;
592     if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
593         return false;
594 
595     return true;
596 }
597 
598 
599 
600 // XHierarchicalNameAccess
601 
602 Any SAL_CALL
getByHierarchicalName(const rtl::OUString & aName)603 TVChildTarget::getByHierarchicalName( const rtl::OUString& aName )
604     throw( NoSuchElementException,
605            RuntimeException )
606 {
607     sal_Int32 idx;
608     rtl::OUString name( aName );
609 
610     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
611     {
612         rtl::OUString num( name.getStr()+2,idx-4 );
613         sal_Int32 pref = num.toInt32() - 1;
614 
615         if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
616             throw NoSuchElementException();
617 
618         return Elements[pref]->getByHierarchicalName( name.copy( 1 + idx ) );
619     }
620     else
621         return getByName( name );
622 }
623 
624 
625 
626 sal_Bool SAL_CALL
hasByHierarchicalName(const rtl::OUString & aName)627 TVChildTarget::hasByHierarchicalName( const rtl::OUString& aName )
628     throw( RuntimeException )
629 {
630     sal_Int32 idx;
631     rtl::OUString name( aName );
632 
633     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
634     {
635         rtl::OUString num( name.getStr()+2,idx-4 );
636         sal_Int32 pref = num.toInt32() - 1;
637         if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
638             return false;
639 
640         return Elements[pref]->hasByHierarchicalName( name.copy( 1 + idx ) );
641     }
642     else
643         return hasByName( name );
644 }
645 
646 
647 
648 
649 
650 
init(const Reference<XMultiServiceFactory> & xSMgr)651 ConfigData TVChildTarget::init( const Reference< XMultiServiceFactory >& xSMgr )
652 {
653     ConfigData configData;
654     Reference< XMultiServiceFactory >  sProvider( getConfiguration(xSMgr) );
655 
656     /**********************************************************************/
657     /*                       reading Office.Common                        */
658     /**********************************************************************/
659 
660     Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider,
661                                                                      "org.openoffice.Office.Common" ) );
662     rtl::OUString system( getKey( xHierAccess,"Help/System" ) );
663     sal_Bool showBasic( getBooleanKey(xHierAccess,"Help/ShowBasic") );
664     rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
665     if( ! instPath.getLength() )
666       // try to determine path from default
667       instPath = rtl::OUString::createFromAscii( "$(instpath)/help" );
668 
669     // replace anything like $(instpath);
670     subst( xSMgr,instPath );
671 
672     /**********************************************************************/
673     /*                       reading setup                                */
674     /**********************************************************************/
675 
676     xHierAccess = getHierAccess( sProvider,
677                                  "org.openoffice.Setup" );
678 
679     rtl::OUString productName( getKey(  xHierAccess,"Product/ooName" ) );
680     rtl::OUString setupversion( getKey( xHierAccess,"Product/ooSetupVersion" ) );
681     rtl::OUString setupextension;
682 
683     try
684     {
685         uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
686               xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW);
687 
688         uno::Sequence < uno::Any > lParams(1);
689         beans::PropertyValue                       aParam ;
690         aParam.Name    = ::rtl::OUString::createFromAscii("nodepath");
691         aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product");
692         lParams[0] = uno::makeAny(aParam);
693 
694         // open it
695         uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
696                     ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"),
697                     lParams) );
698 
699         uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
700         uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension"));
701 
702         aRet >>= setupextension;
703     }
704     catch ( uno::Exception& )
705     {
706     }
707 
708     rtl::OUString productVersion( setupversion +
709                                   rtl::OUString::createFromAscii( " " ) +
710                                   setupextension );
711     rtl::OUString locale( getKey( xHierAccess,"L10N/ooLocale" ) );
712 
713 
714     // Determine fileurl from url and locale
715     rtl::OUString url;
716     osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url );
717     if( errFile != osl::FileBase::E_None ) return configData;
718     if( url.lastIndexOf( sal_Unicode( '/' ) ) != url.getLength() - 1 )
719         url += rtl::OUString::createFromAscii( "/" );
720     rtl::OUString ret;
721     sal_Int32 idx;
722     osl::DirectoryItem aDirItem;
723     if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) )
724         ret = locale;
725     else if( ( ( idx = locale.indexOf( '-' ) ) != -1 ||
726                ( idx = locale.indexOf( '_' ) ) != -1 ) &&
727              osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.copy( 0,idx ),
728                                                                aDirItem ) )
729         ret = locale.copy( 0,idx );
730     else
731         {
732         locale = rtl::OUString::createFromAscii( "en-US" );
733         ret = rtl::OUString::createFromAscii("en");
734         }
735     url = url + ret;
736 
737     // first of all, try do determine whether there are any *.tree files present
738 
739     // Start with extensions to set them at the end of the list
740     TreeFileIterator aTreeIt( locale );
741     rtl::OUString aTreeFile;
742     sal_Int32 nFileSize;
743     while( (aTreeFile = aTreeIt.nextTreeFile( nFileSize ) ).getLength() > 0 )
744     {
745         configData.vFileLen.push_back( nFileSize );
746         configData.vFileURL.push_back( aTreeFile );
747     }
748 
749     osl::Directory aDirectory( url );
750     osl::FileStatus aFileStatus( FileStatusMask_FileName | FileStatusMask_FileSize | FileStatusMask_FileURL );
751     if( osl::Directory::E_None == aDirectory.open() )
752     {
753         int idx_ = 0;
754         rtl::OUString aFileUrl, aFileName;
755         while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None &&
756                aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
757                aFileStatus.isValid( FileStatusMask_FileURL ) &&
758                aFileStatus.isValid( FileStatusMask_FileName ) )
759           {
760             aFileUrl = aFileStatus.getFileURL();
761             aFileName = aFileStatus.getFileName();
762             idx_ = aFileName.lastIndexOf( sal_Unicode( '.' ) );
763             if( idx_ == -1 )
764               continue;
765 
766             const sal_Unicode* str = aFileName.getStr();
767 
768             if( aFileName.getLength() == idx_ + 5                   &&
769                 ( str[idx_ + 1] == 't' || str[idx_ + 1] == 'T' )    &&
770                 ( str[idx_ + 2] == 'r' || str[idx_ + 2] == 'R' )    &&
771                 ( str[idx_ + 3] == 'e' || str[idx_ + 3] == 'E' )    &&
772                 ( str[idx_ + 4] == 'e' || str[idx_ + 4] == 'E' ) )
773               {
774                 OSL_ENSURE( aFileStatus.isValid( FileStatusMask_FileSize ),
775                             "invalid file size" );
776 
777                 rtl::OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase();
778                 if(! showBasic && baseName.compareToAscii("sbasic") == 0 )
779                   continue;
780 
781                 configData.vFileLen.push_back( aFileStatus.getFileSize() );
782                 configData.vFileURL.push_back( aFileUrl );
783               }
784           }
785         aDirectory.close();
786     }
787 
788     configData.m_vAdd[0] = 12;
789     configData.m_vAdd[1] = 15;
790     configData.m_vAdd[2] = 11;
791     configData.m_vAdd[3] = 14;
792     configData.m_vAdd[4] = 12;
793     configData.m_vReplacement[0] = productName;
794     configData.m_vReplacement[1] = productVersion;
795     // m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings
796 
797     configData.system = system;
798     configData.locale = locale;
799     configData.appendix =
800         rtl::OUString::createFromAscii( "?Language=" ) +
801         configData.locale +
802         rtl::OUString::createFromAscii( "&System=" ) +
803         configData.system +
804         rtl::OUString::createFromAscii( "&UseDB=no" ) ;
805 
806     return configData;
807 }
808 
809 
810 
811 
812 
813 
814 
815 
816 
817 Reference< XMultiServiceFactory >
getConfiguration(const Reference<XMultiServiceFactory> & m_xSMgr) const818 TVChildTarget::getConfiguration(const Reference< XMultiServiceFactory >& m_xSMgr) const
819 {
820     Reference< XMultiServiceFactory > sProvider;
821     if( m_xSMgr.is() )
822     {
823         try
824         {
825             rtl::OUString sProviderService =
826                 rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
827             sProvider =
828                 Reference< XMultiServiceFactory >(
829                     m_xSMgr->createInstance( sProviderService ),
830                     UNO_QUERY );
831         }
832         catch( const com::sun::star::uno::Exception& )
833         {
834             OSL_ENSURE( sProvider.is(),"cant instantiate configuration" );
835         }
836     }
837 
838     return sProvider;
839 }
840 
841 
842 
843 Reference< XHierarchicalNameAccess >
getHierAccess(const Reference<XMultiServiceFactory> & sProvider,const char * file) const844 TVChildTarget::getHierAccess( const Reference< XMultiServiceFactory >& sProvider,
845                               const char* file ) const
846 {
847     Reference< XHierarchicalNameAccess > xHierAccess;
848 
849     if( sProvider.is() )
850     {
851         Sequence< Any > seq(1);
852         rtl::OUString sReaderService =
853             rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );
854 
855         seq[0] <<= rtl::OUString::createFromAscii( file );
856 
857         try
858         {
859             xHierAccess =
860                 Reference< XHierarchicalNameAccess >
861                 ( sProvider->createInstanceWithArguments( sReaderService,seq ),
862                   UNO_QUERY );
863         }
864         catch( const com::sun::star::uno::Exception& )
865         {
866         }
867     }
868 
869     return xHierAccess;
870 }
871 
872 
873 
874 rtl::OUString
getKey(const Reference<XHierarchicalNameAccess> & xHierAccess,const char * key) const875 TVChildTarget::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess,
876                        const char* key ) const
877 {
878     rtl::OUString instPath;
879     if( xHierAccess.is() )
880     {
881         Any aAny;
882         try
883         {
884             aAny =
885                 xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) );
886         }
887         catch( const com::sun::star::container::NoSuchElementException& )
888         {
889         }
890         aAny >>= instPath;
891     }
892     return instPath;
893 }
894 
895 
896 sal_Bool
getBooleanKey(const Reference<XHierarchicalNameAccess> & xHierAccess,const char * key) const897 TVChildTarget::getBooleanKey(const Reference<
898                              XHierarchicalNameAccess >& xHierAccess,
899                              const char* key) const
900 {
901   sal_Bool ret = sal_False;
902   if( xHierAccess.is() )
903     {
904       Any aAny;
905       try
906         {
907           aAny =
908             xHierAccess->getByHierarchicalName(
909                                                rtl::OUString::createFromAscii(key));
910         }
911       catch( const com::sun::star::container::NoSuchElementException& )
912         {
913         }
914       aAny >>= ret;
915     }
916   return ret;
917 }
918 
919 
subst(const Reference<XMultiServiceFactory> & m_xSMgr,rtl::OUString & instpath) const920 void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr,
921                            rtl::OUString& instpath ) const
922 {
923     Reference< XConfigManager >  xCfgMgr;
924     if( m_xSMgr.is() )
925     {
926         try
927         {
928             xCfgMgr =
929                 Reference< XConfigManager >(
930                     m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ),
931                     UNO_QUERY );
932         }
933         catch( const com::sun::star::uno::Exception& )
934         {
935             OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " );
936         }
937     }
938 
939     OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );
940 
941     if( xCfgMgr.is() )
942         instpath = xCfgMgr->substituteVariables( instpath );
943 }
944 
945 
946 //===================================================================
947 // class ExtensionIteratorBase
948 
949 static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
950 static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
951 static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );
952 
ExtensionIteratorBase(const rtl::OUString & aLanguage)953 ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage )
954         : m_eState( USER_EXTENSIONS )
955         , m_aLanguage( aLanguage )
956 {
957     init();
958 }
959 
init()960 void ExtensionIteratorBase::init()
961 {
962     Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
963     Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
964     OSL_ASSERT( xProps.is() );
965     if (xProps.is())
966     {
967         xProps->getPropertyValue(
968             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
969         OSL_ASSERT( m_xContext.is() );
970     }
971     if( !m_xContext.is() )
972     {
973         throw RuntimeException(
974             ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ),
975             Reference< XInterface >() );
976     }
977 
978     Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
979     m_xSFA = Reference< ucb::XSimpleFileAccess >(
980         xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
981         m_xContext ), UNO_QUERY_THROW );
982 
983     m_bUserPackagesLoaded = false;
984     m_bSharedPackagesLoaded = false;
985     m_bBundledPackagesLoaded = false;
986     m_iUserPackage = 0;
987     m_iSharedPackage = 0;
988     m_iBundledPackage = 0;
989 }
990 
implGetHelpPackageFromPackage(Reference<deployment::XPackage> xPackage,Reference<deployment::XPackage> & o_xParentPackageBundle)991 Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage
992     ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle )
993 {
994     o_xParentPackageBundle.clear();
995 
996     Reference< deployment::XPackage > xHelpPackage;
997     if( !xPackage.is() )
998         return xHelpPackage;
999 
1000     // Check if parent package is registered
1001     beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
1002         ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
1003     bool bRegistered = false;
1004     if( option.IsPresent )
1005     {
1006         beans::Ambiguous<sal_Bool> const & reg = option.Value;
1007         if( !reg.IsAmbiguous && reg.Value )
1008             bRegistered = true;
1009     }
1010     if( !bRegistered )
1011         return xHelpPackage;
1012 
1013     if( xPackage->isBundle() )
1014     {
1015         Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
1016             ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
1017         sal_Int32 nPkgCount = aPkgSeq.getLength();
1018         const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
1019         for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
1020         {
1021             const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
1022             const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
1023             rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
1024             if( aMediaType.equals( aHelpMediaType ) )
1025             {
1026                 xHelpPackage = xSubPkg;
1027                 o_xParentPackageBundle = xPackage;
1028                 break;
1029             }
1030         }
1031     }
1032     else
1033     {
1034         const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
1035         rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
1036         if( aMediaType.equals( aHelpMediaType ) )
1037             xHelpPackage = xPackage;
1038     }
1039 
1040     return xHelpPackage;
1041 }
1042 
implGetNextUserHelpPackage(Reference<deployment::XPackage> & o_xParentPackageBundle)1043 Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage
1044     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1045 {
1046     Reference< deployment::XPackage > xHelpPackage;
1047 
1048     if( !m_bUserPackagesLoaded )
1049     {
1050         Reference< XPackageManager > xUserManager =
1051             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") );
1052         m_aUserPackagesSeq = xUserManager->getDeployedPackages
1053             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
1054 
1055         m_bUserPackagesLoaded = true;
1056     }
1057 
1058     if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
1059     {
1060         m_eState = SHARED_EXTENSIONS;       // Later: SHARED_MODULE
1061     }
1062     else
1063     {
1064         const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
1065         Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ];
1066         VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
1067         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1068     }
1069 
1070     return xHelpPackage;
1071 }
1072 
implGetNextSharedHelpPackage(Reference<deployment::XPackage> & o_xParentPackageBundle)1073 Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage
1074     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1075 {
1076     Reference< deployment::XPackage > xHelpPackage;
1077 
1078     if( !m_bSharedPackagesLoaded )
1079     {
1080         Reference< XPackageManager > xSharedManager =
1081             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") );
1082         m_aSharedPackagesSeq = xSharedManager->getDeployedPackages
1083             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
1084 
1085         m_bSharedPackagesLoaded = true;
1086     }
1087 
1088     if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
1089     {
1090         m_eState = BUNDLED_EXTENSIONS;
1091     }
1092     else
1093     {
1094         const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
1095         Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ];
1096         VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
1097         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1098     }
1099 
1100     return xHelpPackage;
1101 }
1102 
implGetNextBundledHelpPackage(Reference<deployment::XPackage> & o_xParentPackageBundle)1103 Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage
1104     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1105 {
1106     Reference< deployment::XPackage > xHelpPackage;
1107 
1108     if( !m_bBundledPackagesLoaded )
1109     {
1110         Reference< XPackageManager > xBundledManager =
1111             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("bundled") );
1112         m_aBundledPackagesSeq = xBundledManager->getDeployedPackages
1113             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
1114 
1115         m_bBundledPackagesLoaded = true;
1116     }
1117 
1118     if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
1119     {
1120         m_eState = END_REACHED;
1121     }
1122     else
1123     {
1124         const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
1125         Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ];
1126         VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" );
1127         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1128     }
1129 
1130     return xHelpPackage;
1131 }
1132 
isLetter(sal_Unicode c)1133 inline bool isLetter( sal_Unicode c )
1134 {
1135     bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
1136     return bLetter;
1137 }
1138 
implGetLanguageVectorFromPackage(::std::vector<::rtl::OUString> & rv,com::sun::star::uno::Reference<com::sun::star::deployment::XPackage> xPackage)1139 void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
1140     com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
1141 {
1142     rv.clear();
1143     rtl::OUString aExtensionPath = xPackage->getURL();
1144     Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
1145 
1146     const rtl::OUString* pSeq = aEntrySeq.getConstArray();
1147     sal_Int32 nCount = aEntrySeq.getLength();
1148     for( sal_Int32 i = 0 ; i < nCount ; ++i )
1149     {
1150         rtl::OUString aEntry = pSeq[i];
1151         if( m_xSFA->isFolder( aEntry ) )
1152         {
1153             sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
1154             if( nLastSlash != -1 )
1155             {
1156                 rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
1157 
1158                 // Check language sceme
1159                 int nLen = aPureEntry.getLength();
1160                 const sal_Unicode* pc = aPureEntry.getStr();
1161                 bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
1162                 bool bIsLanguage = bStartCanBeLanguage &&
1163                     ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
1164                 if( bIsLanguage )
1165                     rv.push_back( aPureEntry );
1166             }
1167         }
1168     }
1169 }
1170 
1171 
1172 //===================================================================
1173 // class TreeFileIterator
1174 
nextTreeFile(sal_Int32 & rnFileSize)1175 rtl::OUString TreeFileIterator::nextTreeFile( sal_Int32& rnFileSize )
1176 {
1177     rtl::OUString aRetFile;
1178 
1179     while( !aRetFile.getLength() && m_eState != END_REACHED )
1180     {
1181         switch( m_eState )
1182         {
1183             case USER_EXTENSIONS:
1184             {
1185                 Reference< deployment::XPackage > xParentPackageBundle;
1186                 Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
1187                 if( !xHelpPackage.is() )
1188                     break;
1189 
1190                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
1191                 break;
1192             }
1193 
1194             case SHARED_EXTENSIONS:
1195             {
1196                 Reference< deployment::XPackage > xParentPackageBundle;
1197                 Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
1198                 if( !xHelpPackage.is() )
1199                     break;
1200 
1201                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
1202                 break;
1203             }
1204             case BUNDLED_EXTENSIONS:
1205             {
1206                 Reference< deployment::XPackage > xParentPackageBundle;
1207                 Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
1208                 if( !xHelpPackage.is() )
1209                     break;
1210 
1211                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
1212                 break;
1213             }
1214 
1215         case END_REACHED:
1216                 VOS_ENSURE( false, "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" );
1217                 break;
1218         }
1219     }
1220 
1221     return aRetFile;
1222 }
1223 
expandURL(const rtl::OUString & aURL)1224 rtl::OUString TreeFileIterator::expandURL( const rtl::OUString& aURL )
1225 {
1226     static Reference< util::XMacroExpander > xMacroExpander;
1227     static Reference< uri::XUriReferenceFactory > xFac;
1228 
1229     osl::MutexGuard aGuard( m_aMutex );
1230 
1231     if( !xMacroExpander.is() || !xFac.is() )
1232     {
1233         Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
1234 
1235         xFac = Reference< uri::XUriReferenceFactory >(
1236             xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii(
1237             "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY );
1238         if( !xFac.is() )
1239         {
1240             throw RuntimeException(
1241                 ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ),
1242                 Reference< XInterface >() );
1243         }
1244 
1245         xMacroExpander = Reference< util::XMacroExpander >(
1246             m_xContext->getValueByName(
1247             ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
1248             UNO_QUERY_THROW );
1249     }
1250 
1251     rtl::OUString aRetURL = aURL;
1252     if( xMacroExpander.is() )
1253     {
1254         Reference< uri::XUriReference > uriRef;
1255         for (;;)
1256         {
1257             uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
1258             if ( uriRef.is() )
1259             {
1260                 Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
1261                 if( !sxUri.is() )
1262                     break;
1263 
1264                 aRetURL = sxUri->expand( xMacroExpander );
1265             }
1266         }
1267     }
1268     return aRetURL;
1269 }
1270 
implGetTreeFileFromPackage(sal_Int32 & rnFileSize,Reference<deployment::XPackage> xPackage)1271 rtl::OUString TreeFileIterator::implGetTreeFileFromPackage
1272     ( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage )
1273 {
1274     rtl::OUString aRetFile;
1275     rtl::OUString aLanguage = m_aLanguage;
1276     for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
1277     {
1278         rtl::OUStringBuffer aStrBuf;
1279         aStrBuf.append( xPackage->getURL() );
1280         aStrBuf.append( aSlash );
1281         aStrBuf.append( aLanguage );
1282         aStrBuf.append( aSlash );
1283         aStrBuf.append( aHelpFilesBaseName );
1284         aStrBuf.appendAscii( ".tree" );
1285 
1286         aRetFile = expandURL( aStrBuf.makeStringAndClear() );
1287         if( iPass == 0 )
1288         {
1289             if( m_xSFA->exists( aRetFile ) )
1290                 break;
1291 
1292             ::std::vector< ::rtl::OUString > av;
1293             implGetLanguageVectorFromPackage( av, xPackage );
1294             ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
1295             try
1296             {
1297                 pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
1298             }
1299             catch( ::comphelper::Locale::MalFormedLocaleException& )
1300             {}
1301             if( pFound != av.end() )
1302                 aLanguage = *pFound;
1303         }
1304     }
1305 
1306     rnFileSize = 0;
1307     if( m_xSFA->exists( aRetFile ) )
1308         rnFileSize = m_xSFA->getSize( aRetFile );
1309     else
1310         aRetFile = rtl::OUString();
1311 
1312     return aRetFile;
1313 }
1314 
1315 
1316 
1317