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

Generated by: LCOV version 1.11