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

Generated by: LCOV version 1.10