LCOV - code coverage report
Current view: top level - xmlhelp/source/treeview - tvread.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 594 0.0 %
Date: 2014-04-14 Functions: 0 56 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10