| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmlhelp.hxx" |
| |
| #include <string.h> |
| #include <rtl/ustrbuf.hxx> |
| #ifndef _VOS_DIAGNOSE_HXX_ |
| #include <vos/diagnose.hxx> |
| #endif |
| #include "tvread.hxx" |
| #include <expat.h> |
| #include <osl/file.hxx> |
| #include <com/sun/star/frame/XConfigManager.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| |
| #include <comphelper/processfactory.hxx> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include "com/sun/star/deployment/thePackageManagerFactory.hpp" |
| #include <com/sun/star/util/XMacroExpander.hpp> |
| #include <com/sun/star/uri/XUriReferenceFactory.hpp> |
| #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> |
| #include <comphelper/locale.hxx> |
| |
| namespace treeview { |
| |
| |
| class TVDom |
| { |
| friend class TVChildTarget; |
| friend class TVRead; |
| |
| public: |
| |
| TVDom( TVDom* arent = 0 ) |
| : kind( other ), |
| parent( arent ), |
| childs( 0 ) |
| { |
| } |
| |
| ~TVDom() |
| { |
| for( unsigned i = 0; i < childs.size(); ++i ) |
| delete childs[i]; |
| } |
| |
| |
| TVDom* newChild() |
| { |
| childs.push_back( new TVDom( this ) ); |
| return childs.back(); |
| } |
| |
| |
| TVDom* getParent() const |
| { |
| if( parent ) |
| return parent; |
| else |
| return const_cast<TVDom*>(this); // I am my own parent, if I am the root |
| } |
| |
| enum Kind { |
| tree_view, |
| tree_node, |
| tree_leaf, |
| other |
| }; |
| |
| bool isLeaf() const { return kind == TVDom::tree_leaf; } |
| void setKind( Kind ind ) { kind = ind; } |
| Kind getKind( ) const { return kind; } |
| |
| |
| void setApplication( const char* appl ) |
| { |
| application = rtl::OUString( (sal_Char*)(appl), |
| strlen( appl ), |
| RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| void setTitle( const char* itle ) |
| { |
| title += rtl::OUString( (sal_Char*)(itle), |
| strlen( itle ), |
| RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| void setTitle( const XML_Char* itle,int len ) |
| { |
| title += rtl::OUString( (sal_Char*)(itle), |
| len, |
| RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| void setId( const char* d ) |
| { |
| id = rtl::OUString( (sal_Char*)(d), |
| strlen( d ), |
| RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| void setAnchor( const char* nchor ) |
| { |
| anchor = rtl::OUString( (sal_Char*)(nchor), |
| strlen( nchor ), |
| RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| rtl::OUString getTargetURL() |
| { |
| if( ! targetURL.getLength() ) |
| { |
| sal_Int32 len; |
| for ( const TVDom* p = this;; p = p->parent ) |
| { |
| len = p->application.getLength(); |
| if ( len != 0 ) |
| break; |
| } |
| |
| rtl::OUStringBuffer strBuff( 22 + len + id.getLength() ); |
| strBuff.appendAscii( |
| "vnd.sun.star.help://" |
| ).append(id); |
| |
| targetURL = strBuff.makeStringAndClear(); |
| } |
| |
| return targetURL; |
| } |
| |
| private: |
| |
| Kind kind; |
| rtl::OUString application; |
| rtl::OUString title; |
| rtl::OUString id; |
| rtl::OUString anchor; |
| rtl::OUString targetURL; |
| |
| TVDom *parent; |
| std::vector< TVDom* > childs; |
| }; |
| |
| } |
| |
| |
| |
| using namespace treeview; |
| using namespace com::sun::star; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::util; |
| using namespace com::sun::star::frame; |
| using namespace com::sun::star::container; |
| using namespace com::sun::star::deployment; |
| |
| |
| ConfigData::ConfigData() |
| : prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ), |
| prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ), |
| vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ), |
| vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ), |
| vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ) |
| { |
| } |
| |
| void SAL_CALL ConfigData::replaceName( rtl::OUString& oustring ) const |
| { |
| sal_Int32 idx = -1,k = 0,off; |
| bool cap = false; |
| rtl::OUStringBuffer aStrBuf( 0 ); |
| |
| while( ( idx = oustring.indexOf( sal_Unicode('%'),++idx ) ) != -1 ) |
| { |
| if( oustring.indexOf( prodName,idx ) == idx ) |
| off = PRODUCTNAME; |
| else if( oustring.indexOf( prodVersion,idx ) == idx ) |
| off = PRODUCTVERSION; |
| else if( oustring.indexOf( vendName,idx ) == idx ) |
| off = VENDORNAME; |
| else if( oustring.indexOf( vendVersion,idx ) == idx ) |
| off = VENDORVERSION; |
| else if( oustring.indexOf( vendShort,idx ) == idx ) |
| off = VENDORSHORT; |
| else |
| off = -1; |
| |
| if( off != -1 ) |
| { |
| if( ! cap ) |
| { |
| cap = true; |
| aStrBuf.ensureCapacity( 256 ); |
| } |
| |
| aStrBuf.append( &oustring.getStr()[k],idx - k ); |
| aStrBuf.append( m_vReplacement[off] ); |
| k = idx + m_vAdd[off]; |
| } |
| } |
| |
| if( cap ) |
| { |
| if( k < oustring.getLength() ) |
| aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k ); |
| oustring = aStrBuf.makeStringAndClear(); |
| } |
| } |
| |
| |
| |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // XInterface |
| ////////////////////////////////////////////////////////////////////////// |
| |
| |
| void SAL_CALL |
| TVBase::acquire( |
| void ) |
| throw() |
| { |
| OWeakObject::acquire(); |
| } |
| |
| |
| void SAL_CALL |
| TVBase::release( |
| void ) |
| throw() |
| { |
| OWeakObject::release(); |
| } |
| |
| |
| Any SAL_CALL |
| TVBase::queryInterface( |
| const Type& rType ) |
| throw( RuntimeException ) |
| { |
| Any aRet = cppu::queryInterface( rType, |
| SAL_STATIC_CAST( XTypeProvider*, this ), |
| SAL_STATIC_CAST( XNameAccess*, this ), |
| SAL_STATIC_CAST( XHierarchicalNameAccess*, this ), |
| SAL_STATIC_CAST( XChangesNotifier*, this ), |
| SAL_STATIC_CAST( XComponent*, this ) ); |
| |
| return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // XTypeProvider methods. |
| |
| XTYPEPROVIDER_IMPL_5( TVBase, |
| XTypeProvider, |
| XNameAccess, |
| XHierarchicalNameAccess, |
| XChangesNotifier, |
| XComponent ); |
| |
| |
| |
| |
| |
| |
| // TVRead |
| |
| |
| TVRead::TVRead( const ConfigData& configData,TVDom* tvDom ) |
| { |
| if( ! tvDom ) |
| return; |
| |
| Title = tvDom->title; |
| configData.replaceName( Title ); |
| if( tvDom->isLeaf() ) |
| { |
| TargetURL = ( tvDom->getTargetURL() + configData.appendix ); |
| if( tvDom->anchor.getLength() ) |
| TargetURL += ( rtl::OUString::createFromAscii( "#" ) + |
| tvDom->anchor ); |
| } |
| else |
| Children = new TVChildTarget( configData,tvDom ); |
| } |
| |
| |
| |
| TVRead::~TVRead() |
| { |
| } |
| |
| |
| |
| |
| |
| |
| // XNameAccess |
| |
| Any SAL_CALL |
| TVRead::getByName( const rtl::OUString& aName ) |
| throw( NoSuchElementException, |
| WrappedTargetException, |
| RuntimeException ) |
| { |
| bool found( true ); |
| Any aAny; |
| if( aName.compareToAscii( "Title" ) == 0 ) |
| aAny <<= Title; |
| else if( aName.compareToAscii( "TargetURL" ) == 0 ) |
| aAny <<= TargetURL; |
| else if( aName.compareToAscii( "Children" ) == 0 ) |
| { |
| cppu::OWeakObject* p = Children.get(); |
| aAny <<= Reference< XInterface >( p ); |
| } |
| else |
| found = false; |
| |
| if( found ) |
| return aAny; |
| |
| throw NoSuchElementException(); |
| } |
| |
| |
| |
| |
| Sequence< rtl::OUString > SAL_CALL |
| TVRead::getElementNames( ) |
| throw( RuntimeException ) |
| { |
| Sequence< rtl::OUString > seq( 3 ); |
| |
| seq[0] = rtl::OUString::createFromAscii( "Title" ); |
| seq[1] = rtl::OUString::createFromAscii( "TargetURL" ); |
| seq[2] = rtl::OUString::createFromAscii( "Children" ); |
| |
| return seq; |
| } |
| |
| |
| |
| sal_Bool SAL_CALL |
| TVRead::hasByName( const rtl::OUString& aName ) |
| throw( RuntimeException ) |
| { |
| if( aName.compareToAscii( "Title" ) == 0 || |
| aName.compareToAscii( "TargetURL" ) == 0 || |
| aName.compareToAscii( "Children" ) == 0 ) |
| return true; |
| |
| return false; |
| } |
| |
| |
| // XHierarchicalNameAccess |
| |
| Any SAL_CALL |
| TVRead::getByHierarchicalName( const rtl::OUString& aName ) |
| throw( NoSuchElementException, |
| RuntimeException ) |
| { |
| sal_Int32 idx; |
| rtl::OUString name( aName ); |
| |
| if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 && |
| name.copy( 0,idx ).compareToAscii( "Children" ) == 0 ) |
| return Children->getByHierarchicalName( name.copy( 1 + idx ) ); |
| |
| return getByName( name ); |
| } |
| |
| |
| |
| |
| sal_Bool SAL_CALL |
| TVRead::hasByHierarchicalName( const rtl::OUString& aName ) |
| throw( RuntimeException ) |
| { |
| sal_Int32 idx; |
| rtl::OUString name( aName ); |
| |
| if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 && |
| name.copy( 0,idx ).compareToAscii( "Children" ) == 0 ) |
| return Children->hasByHierarchicalName( name.copy( 1 + idx ) ); |
| |
| return hasByName( name ); |
| } |
| |
| |
| |
| /**************************************************************************/ |
| /* */ |
| /* TVChildTarget */ |
| /* */ |
| /**************************************************************************/ |
| |
| |
| |
| |
| extern "C" void start_handler(void *userData, |
| const XML_Char *name, |
| const XML_Char **atts) |
| { |
| TVDom::Kind kind; |
| |
| if( strcmp( name,"help_section" ) == 0 || |
| strcmp( name,"node" ) == 0 ) |
| kind = TVDom::tree_node; |
| else if( strcmp( name,"topic" ) == 0 ) |
| kind = TVDom::tree_leaf; |
| else |
| return; |
| |
| TVDom **tvDom = static_cast< TVDom** >( userData ); |
| TVDom *p; |
| p = *tvDom; |
| |
| *tvDom = p->newChild(); |
| p = *tvDom; |
| |
| p->setKind( kind ); |
| while( *atts ) |
| { |
| if( strcmp( *atts,"application" ) == 0 ) |
| p->setApplication( *(atts+1) ); |
| else if( strcmp( *atts,"title" ) == 0 ) |
| p->setTitle( *(atts+1) ); |
| else if( strcmp( *atts,"id" ) == 0 ) |
| p->setId( *(atts+1) ); |
| else if( strcmp( *atts,"anchor" ) == 0 ) |
| p->setAnchor( *(atts+1) ); |
| |
| atts+=2; |
| } |
| } |
| |
| |
| extern "C" void end_handler(void *userData, |
| const XML_Char *name ) |
| { |
| (void)name; |
| |
| TVDom **tvDom = static_cast< TVDom** >( userData ); |
| *tvDom = (*tvDom)->getParent(); |
| } |
| |
| |
| extern "C" void data_handler( void *userData, |
| const XML_Char *s, |
| int len) |
| { |
| TVDom **tvDom = static_cast< TVDom** >( userData ); |
| if( (*tvDom)->isLeaf() ) |
| (*tvDom)->setTitle( s,len ); |
| } |
| |
| |
| |
| TVChildTarget::TVChildTarget( const ConfigData& configData,TVDom* tvDom ) |
| { |
| Elements.resize( tvDom->childs.size() ); |
| for( unsigned i = 0; i < Elements.size(); ++i ) |
| Elements[i] = new TVRead( configData,tvDom->childs[i] ); |
| } |
| |
| |
| |
| |
| |
| TVChildTarget::TVChildTarget( const Reference< XMultiServiceFactory >& xMSF ) |
| { |
| ConfigData configData = init( xMSF ); |
| |
| if( ! configData.locale.getLength() || |
| ! configData.system.getLength() ) |
| return; |
| |
| sal_uInt64 ret,len = 0; |
| int j = configData.vFileURL.size(); |
| |
| TVDom tvDom; |
| TVDom* pTVDom = &tvDom; |
| |
| while( j ) |
| { |
| len = configData.vFileLen[--j]; |
| char* s = new char[ int(len) ]; // the buffer to hold the installed files |
| osl::File aFile( configData.vFileURL[j] ); |
| aFile.open( OpenFlag_Read ); |
| aFile.read( s,len,ret ); |
| aFile.close(); |
| |
| XML_Parser parser = XML_ParserCreate( 0 ); |
| XML_SetElementHandler( parser, |
| start_handler, |
| end_handler ); |
| XML_SetCharacterDataHandler( parser, |
| data_handler); |
| XML_SetUserData( parser,&pTVDom ); // does not return this |
| |
| int parsed = XML_Parse( parser,s,int( len ),j==0 ); |
| (void)parsed; |
| OSL_ENSURE( parsed, "TVChildTarget::TVChildTarget(): Tree file parsing failed" ); |
| |
| XML_ParserFree( parser ); |
| delete[] s; |
| } |
| |
| // now TVDom holds the relevant information |
| |
| Elements.resize( tvDom.childs.size() ); |
| for( unsigned i = 0; i < Elements.size(); ++i ) |
| Elements[i] = new TVRead( configData,tvDom.childs[i] ); |
| } |
| |
| |
| TVChildTarget::~TVChildTarget() |
| { |
| } |
| |
| |
| |
| Any SAL_CALL |
| TVChildTarget::getByName( const rtl::OUString& aName ) |
| throw( NoSuchElementException, |
| WrappedTargetException, |
| RuntimeException ) |
| { |
| rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); |
| sal_Int32 idx = num.toInt32() - 1; |
| if( idx < 0 || Elements.size() <= sal_uInt32( idx ) ) |
| throw NoSuchElementException(); |
| |
| Any aAny; |
| cppu::OWeakObject* p = Elements[idx].get(); |
| aAny <<= Reference< XInterface >( p ); |
| return aAny; |
| } |
| |
| |
| |
| |
| Sequence< rtl::OUString > SAL_CALL |
| TVChildTarget::getElementNames( ) |
| throw( RuntimeException ) |
| { |
| Sequence< rtl::OUString > seq( Elements.size() ); |
| for( unsigned i = 0; i < Elements.size(); ++i ) |
| seq[i] = rtl::OUString::valueOf( sal_Int32( 1+i ) ); |
| |
| return seq; |
| } |
| |
| |
| |
| sal_Bool SAL_CALL |
| TVChildTarget::hasByName( const rtl::OUString& aName ) |
| throw( RuntimeException ) |
| { |
| rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); |
| sal_Int32 idx = num.toInt32() - 1; |
| if( idx < 0 || Elements.size() <= sal_uInt32( idx ) ) |
| return false; |
| |
| return true; |
| } |
| |
| |
| |
| // XHierarchicalNameAccess |
| |
| Any SAL_CALL |
| TVChildTarget::getByHierarchicalName( const rtl::OUString& aName ) |
| throw( NoSuchElementException, |
| RuntimeException ) |
| { |
| sal_Int32 idx; |
| rtl::OUString name( aName ); |
| |
| if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 ) |
| { |
| rtl::OUString num( name.getStr()+2,idx-4 ); |
| sal_Int32 pref = num.toInt32() - 1; |
| |
| if( pref < 0 || Elements.size() <= sal_uInt32( pref ) ) |
| throw NoSuchElementException(); |
| |
| return Elements[pref]->getByHierarchicalName( name.copy( 1 + idx ) ); |
| } |
| else |
| return getByName( name ); |
| } |
| |
| |
| |
| sal_Bool SAL_CALL |
| TVChildTarget::hasByHierarchicalName( const rtl::OUString& aName ) |
| throw( RuntimeException ) |
| { |
| sal_Int32 idx; |
| rtl::OUString name( aName ); |
| |
| if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 ) |
| { |
| rtl::OUString num( name.getStr()+2,idx-4 ); |
| sal_Int32 pref = num.toInt32() - 1; |
| if( pref < 0 || Elements.size() <= sal_uInt32( pref ) ) |
| return false; |
| |
| return Elements[pref]->hasByHierarchicalName( name.copy( 1 + idx ) ); |
| } |
| else |
| return hasByName( name ); |
| } |
| |
| |
| |
| |
| |
| |
| ConfigData TVChildTarget::init( const Reference< XMultiServiceFactory >& xSMgr ) |
| { |
| ConfigData configData; |
| Reference< XMultiServiceFactory > sProvider( getConfiguration(xSMgr) ); |
| |
| /**********************************************************************/ |
| /* reading Office.Common */ |
| /**********************************************************************/ |
| |
| Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider, |
| "org.openoffice.Office.Common" ) ); |
| rtl::OUString system( getKey( xHierAccess,"Help/System" ) ); |
| sal_Bool showBasic( getBooleanKey(xHierAccess,"Help/ShowBasic") ); |
| rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) ); |
| if( ! instPath.getLength() ) |
| // try to determine path from default |
| instPath = rtl::OUString::createFromAscii( "$(instpath)/help" ); |
| |
| // replace anything like $(instpath); |
| subst( xSMgr,instPath ); |
| |
| /**********************************************************************/ |
| /* reading setup */ |
| /**********************************************************************/ |
| |
| xHierAccess = getHierAccess( sProvider, |
| "org.openoffice.Setup" ); |
| |
| rtl::OUString productName( getKey( xHierAccess,"Product/ooName" ) ); |
| rtl::OUString setupversion( getKey( xHierAccess,"Product/ooSetupVersion" ) ); |
| rtl::OUString setupextension; |
| |
| try |
| { |
| uno::Reference< lang::XMultiServiceFactory > xConfigProvider( |
| xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW); |
| |
| uno::Sequence < uno::Any > lParams(1); |
| beans::PropertyValue aParam ; |
| aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); |
| aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product"); |
| lParams[0] = uno::makeAny(aParam); |
| |
| // open it |
| uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( |
| ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), |
| lParams) ); |
| |
| uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY); |
| uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension")); |
| |
| aRet >>= setupextension; |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| rtl::OUString productVersion( setupversion + |
| rtl::OUString::createFromAscii( " " ) + |
| setupextension ); |
| rtl::OUString locale( getKey( xHierAccess,"L10N/ooLocale" ) ); |
| |
| |
| // Determine fileurl from url and locale |
| rtl::OUString url; |
| osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url ); |
| if( errFile != osl::FileBase::E_None ) return configData; |
| if( url.lastIndexOf( sal_Unicode( '/' ) ) != url.getLength() - 1 ) |
| url += rtl::OUString::createFromAscii( "/" ); |
| rtl::OUString ret; |
| sal_Int32 idx; |
| osl::DirectoryItem aDirItem; |
| if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) ) |
| ret = locale; |
| else if( ( ( idx = locale.indexOf( '-' ) ) != -1 || |
| ( idx = locale.indexOf( '_' ) ) != -1 ) && |
| osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.copy( 0,idx ), |
| aDirItem ) ) |
| ret = locale.copy( 0,idx ); |
| else |
| { |
| locale = rtl::OUString::createFromAscii( "en-US" ); |
| ret = rtl::OUString::createFromAscii("en"); |
| } |
| url = url + ret; |
| |
| // first of all, try do determine whether there are any *.tree files present |
| |
| // Start with extensions to set them at the end of the list |
| TreeFileIterator aTreeIt( locale ); |
| rtl::OUString aTreeFile; |
| sal_Int32 nFileSize; |
| while( (aTreeFile = aTreeIt.nextTreeFile( nFileSize ) ).getLength() > 0 ) |
| { |
| configData.vFileLen.push_back( nFileSize ); |
| configData.vFileURL.push_back( aTreeFile ); |
| } |
| |
| osl::Directory aDirectory( url ); |
| osl::FileStatus aFileStatus( FileStatusMask_FileName | FileStatusMask_FileSize | FileStatusMask_FileURL ); |
| if( osl::Directory::E_None == aDirectory.open() ) |
| { |
| int idx_ = 0; |
| rtl::OUString aFileUrl, aFileName; |
| while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None && |
| aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None && |
| aFileStatus.isValid( FileStatusMask_FileURL ) && |
| aFileStatus.isValid( FileStatusMask_FileName ) ) |
| { |
| aFileUrl = aFileStatus.getFileURL(); |
| aFileName = aFileStatus.getFileName(); |
| idx_ = aFileName.lastIndexOf( sal_Unicode( '.' ) ); |
| if( idx_ == -1 ) |
| continue; |
| |
| const sal_Unicode* str = aFileName.getStr(); |
| |
| if( aFileName.getLength() == idx_ + 5 && |
| ( str[idx_ + 1] == 't' || str[idx_ + 1] == 'T' ) && |
| ( str[idx_ + 2] == 'r' || str[idx_ + 2] == 'R' ) && |
| ( str[idx_ + 3] == 'e' || str[idx_ + 3] == 'E' ) && |
| ( str[idx_ + 4] == 'e' || str[idx_ + 4] == 'E' ) ) |
| { |
| OSL_ENSURE( aFileStatus.isValid( FileStatusMask_FileSize ), |
| "invalid file size" ); |
| |
| rtl::OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase(); |
| if(! showBasic && baseName.compareToAscii("sbasic") == 0 ) |
| continue; |
| |
| configData.vFileLen.push_back( aFileStatus.getFileSize() ); |
| configData.vFileURL.push_back( aFileUrl ); |
| } |
| } |
| aDirectory.close(); |
| } |
| |
| configData.m_vAdd[0] = 12; |
| configData.m_vAdd[1] = 15; |
| configData.m_vAdd[2] = 11; |
| configData.m_vAdd[3] = 14; |
| configData.m_vAdd[4] = 12; |
| configData.m_vReplacement[0] = productName; |
| configData.m_vReplacement[1] = productVersion; |
| // m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings |
| |
| configData.system = system; |
| configData.locale = locale; |
| configData.appendix = |
| rtl::OUString::createFromAscii( "?Language=" ) + |
| configData.locale + |
| rtl::OUString::createFromAscii( "&System=" ) + |
| configData.system + |
| rtl::OUString::createFromAscii( "&UseDB=no" ) ; |
| |
| return configData; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Reference< XMultiServiceFactory > |
| TVChildTarget::getConfiguration(const Reference< XMultiServiceFactory >& m_xSMgr) const |
| { |
| Reference< XMultiServiceFactory > sProvider; |
| if( m_xSMgr.is() ) |
| { |
| try |
| { |
| rtl::OUString sProviderService = |
| rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ); |
| sProvider = |
| Reference< XMultiServiceFactory >( |
| m_xSMgr->createInstance( sProviderService ), |
| UNO_QUERY ); |
| } |
| catch( const com::sun::star::uno::Exception& ) |
| { |
| OSL_ENSURE( sProvider.is(),"cant instantiate configuration" ); |
| } |
| } |
| |
| return sProvider; |
| } |
| |
| |
| |
| Reference< XHierarchicalNameAccess > |
| TVChildTarget::getHierAccess( const Reference< XMultiServiceFactory >& sProvider, |
| const char* file ) const |
| { |
| Reference< XHierarchicalNameAccess > xHierAccess; |
| |
| if( sProvider.is() ) |
| { |
| Sequence< Any > seq(1); |
| rtl::OUString sReaderService = |
| rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ); |
| |
| seq[0] <<= rtl::OUString::createFromAscii( file ); |
| |
| try |
| { |
| xHierAccess = |
| Reference< XHierarchicalNameAccess > |
| ( sProvider->createInstanceWithArguments( sReaderService,seq ), |
| UNO_QUERY ); |
| } |
| catch( const com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| return xHierAccess; |
| } |
| |
| |
| |
| rtl::OUString |
| TVChildTarget::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess, |
| const char* key ) const |
| { |
| rtl::OUString instPath; |
| if( xHierAccess.is() ) |
| { |
| Any aAny; |
| try |
| { |
| aAny = |
| xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) ); |
| } |
| catch( const com::sun::star::container::NoSuchElementException& ) |
| { |
| } |
| aAny >>= instPath; |
| } |
| return instPath; |
| } |
| |
| |
| sal_Bool |
| TVChildTarget::getBooleanKey(const Reference< |
| XHierarchicalNameAccess >& xHierAccess, |
| const char* key) const |
| { |
| sal_Bool ret = sal_False; |
| if( xHierAccess.is() ) |
| { |
| Any aAny; |
| try |
| { |
| aAny = |
| xHierAccess->getByHierarchicalName( |
| rtl::OUString::createFromAscii(key)); |
| } |
| catch( const com::sun::star::container::NoSuchElementException& ) |
| { |
| } |
| aAny >>= ret; |
| } |
| return ret; |
| } |
| |
| |
| void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr, |
| rtl::OUString& instpath ) const |
| { |
| Reference< XConfigManager > xCfgMgr; |
| if( m_xSMgr.is() ) |
| { |
| try |
| { |
| xCfgMgr = |
| Reference< XConfigManager >( |
| m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ), |
| UNO_QUERY ); |
| } |
| catch( const com::sun::star::uno::Exception& ) |
| { |
| OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " ); |
| } |
| } |
| |
| OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" ); |
| |
| if( xCfgMgr.is() ) |
| instpath = xCfgMgr->substituteVariables( instpath ); |
| } |
| |
| |
| //=================================================================== |
| // class ExtensionIteratorBase |
| |
| static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); |
| static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) ); |
| static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) ); |
| |
| ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage ) |
| : m_eState( USER_EXTENSIONS ) |
| , m_aLanguage( aLanguage ) |
| { |
| init(); |
| } |
| |
| void ExtensionIteratorBase::init() |
| { |
| Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); |
| Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); |
| OSL_ASSERT( xProps.is() ); |
| if (xProps.is()) |
| { |
| xProps->getPropertyValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext; |
| OSL_ASSERT( m_xContext.is() ); |
| } |
| if( !m_xContext.is() ) |
| { |
| throw RuntimeException( |
| ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ), |
| Reference< XInterface >() ); |
| } |
| |
| Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); |
| m_xSFA = Reference< ucb::XSimpleFileAccess >( |
| xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), |
| m_xContext ), UNO_QUERY_THROW ); |
| |
| m_bUserPackagesLoaded = false; |
| m_bSharedPackagesLoaded = false; |
| m_bBundledPackagesLoaded = false; |
| m_iUserPackage = 0; |
| m_iSharedPackage = 0; |
| m_iBundledPackage = 0; |
| } |
| |
| Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage |
| ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle ) |
| { |
| o_xParentPackageBundle.clear(); |
| |
| Reference< deployment::XPackage > xHelpPackage; |
| if( !xPackage.is() ) |
| return xHelpPackage; |
| |
| // Check if parent package is registered |
| beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered |
| ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) ); |
| bool bRegistered = false; |
| if( option.IsPresent ) |
| { |
| beans::Ambiguous<sal_Bool> const & reg = option.Value; |
| if( !reg.IsAmbiguous && reg.Value ) |
| bRegistered = true; |
| } |
| if( !bRegistered ) |
| return xHelpPackage; |
| |
| if( xPackage->isBundle() ) |
| { |
| Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle |
| ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ); |
| sal_Int32 nPkgCount = aPkgSeq.getLength(); |
| const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray(); |
| for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg ) |
| { |
| const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; |
| const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType(); |
| rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); |
| if( aMediaType.equals( aHelpMediaType ) ) |
| { |
| xHelpPackage = xSubPkg; |
| o_xParentPackageBundle = xPackage; |
| break; |
| } |
| } |
| } |
| else |
| { |
| const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType(); |
| rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); |
| if( aMediaType.equals( aHelpMediaType ) ) |
| xHelpPackage = xPackage; |
| } |
| |
| return xHelpPackage; |
| } |
| |
| Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage |
| ( Reference< deployment::XPackage >& o_xParentPackageBundle ) |
| { |
| Reference< deployment::XPackage > xHelpPackage; |
| |
| if( !m_bUserPackagesLoaded ) |
| { |
| Reference< XPackageManager > xUserManager = |
| thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") ); |
| m_aUserPackagesSeq = xUserManager->getDeployedPackages |
| ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); |
| |
| m_bUserPackagesLoaded = true; |
| } |
| |
| if( m_iUserPackage == m_aUserPackagesSeq.getLength() ) |
| { |
| m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE |
| } |
| else |
| { |
| const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); |
| Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ]; |
| VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" ); |
| xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); |
| } |
| |
| return xHelpPackage; |
| } |
| |
| Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage |
| ( Reference< deployment::XPackage >& o_xParentPackageBundle ) |
| { |
| Reference< deployment::XPackage > xHelpPackage; |
| |
| if( !m_bSharedPackagesLoaded ) |
| { |
| Reference< XPackageManager > xSharedManager = |
| thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") ); |
| m_aSharedPackagesSeq = xSharedManager->getDeployedPackages |
| ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); |
| |
| m_bSharedPackagesLoaded = true; |
| } |
| |
| if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) |
| { |
| m_eState = BUNDLED_EXTENSIONS; |
| } |
| else |
| { |
| const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); |
| Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ]; |
| VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" ); |
| xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); |
| } |
| |
| return xHelpPackage; |
| } |
| |
| Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage |
| ( Reference< deployment::XPackage >& o_xParentPackageBundle ) |
| { |
| Reference< deployment::XPackage > xHelpPackage; |
| |
| if( !m_bBundledPackagesLoaded ) |
| { |
| Reference< XPackageManager > xBundledManager = |
| thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("bundled") ); |
| m_aBundledPackagesSeq = xBundledManager->getDeployedPackages |
| ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); |
| |
| m_bBundledPackagesLoaded = true; |
| } |
| |
| if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() ) |
| { |
| m_eState = END_REACHED; |
| } |
| else |
| { |
| const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray(); |
| Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ]; |
| VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" ); |
| xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); |
| } |
| |
| return xHelpPackage; |
| } |
| |
| inline bool isLetter( sal_Unicode c ) |
| { |
| bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); |
| return bLetter; |
| } |
| |
| void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, |
| com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ) |
| { |
| rv.clear(); |
| rtl::OUString aExtensionPath = xPackage->getURL(); |
| Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true ); |
| |
| const rtl::OUString* pSeq = aEntrySeq.getConstArray(); |
| sal_Int32 nCount = aEntrySeq.getLength(); |
| for( sal_Int32 i = 0 ; i < nCount ; ++i ) |
| { |
| rtl::OUString aEntry = pSeq[i]; |
| if( m_xSFA->isFolder( aEntry ) ) |
| { |
| sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' ); |
| if( nLastSlash != -1 ) |
| { |
| rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 ); |
| |
| // Check language sceme |
| int nLen = aPureEntry.getLength(); |
| const sal_Unicode* pc = aPureEntry.getStr(); |
| bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) ); |
| bool bIsLanguage = bStartCanBeLanguage && |
| ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) ); |
| if( bIsLanguage ) |
| rv.push_back( aPureEntry ); |
| } |
| } |
| } |
| } |
| |
| |
| //=================================================================== |
| // class TreeFileIterator |
| |
| rtl::OUString TreeFileIterator::nextTreeFile( sal_Int32& rnFileSize ) |
| { |
| rtl::OUString aRetFile; |
| |
| while( !aRetFile.getLength() && m_eState != END_REACHED ) |
| { |
| switch( m_eState ) |
| { |
| case USER_EXTENSIONS: |
| { |
| Reference< deployment::XPackage > xParentPackageBundle; |
| Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); |
| if( !xHelpPackage.is() ) |
| break; |
| |
| aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage ); |
| break; |
| } |
| |
| case SHARED_EXTENSIONS: |
| { |
| Reference< deployment::XPackage > xParentPackageBundle; |
| Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); |
| if( !xHelpPackage.is() ) |
| break; |
| |
| aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage ); |
| break; |
| } |
| case BUNDLED_EXTENSIONS: |
| { |
| Reference< deployment::XPackage > xParentPackageBundle; |
| Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle ); |
| if( !xHelpPackage.is() ) |
| break; |
| |
| aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage ); |
| break; |
| } |
| |
| case END_REACHED: |
| VOS_ENSURE( false, "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" ); |
| break; |
| } |
| } |
| |
| return aRetFile; |
| } |
| |
| rtl::OUString TreeFileIterator::expandURL( const rtl::OUString& aURL ) |
| { |
| static Reference< util::XMacroExpander > xMacroExpander; |
| static Reference< uri::XUriReferenceFactory > xFac; |
| |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| if( !xMacroExpander.is() || !xFac.is() ) |
| { |
| Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); |
| |
| xFac = Reference< uri::XUriReferenceFactory >( |
| xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( |
| "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); |
| if( !xFac.is() ) |
| { |
| throw RuntimeException( |
| ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ), |
| Reference< XInterface >() ); |
| } |
| |
| xMacroExpander = Reference< util::XMacroExpander >( |
| m_xContext->getValueByName( |
| ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), |
| UNO_QUERY_THROW ); |
| } |
| |
| rtl::OUString aRetURL = aURL; |
| if( xMacroExpander.is() ) |
| { |
| Reference< uri::XUriReference > uriRef; |
| for (;;) |
| { |
| uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); |
| if ( uriRef.is() ) |
| { |
| Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); |
| if( !sxUri.is() ) |
| break; |
| |
| aRetURL = sxUri->expand( xMacroExpander ); |
| } |
| } |
| } |
| return aRetURL; |
| } |
| |
| rtl::OUString TreeFileIterator::implGetTreeFileFromPackage |
| ( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage ) |
| { |
| rtl::OUString aRetFile; |
| rtl::OUString aLanguage = m_aLanguage; |
| for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass ) |
| { |
| rtl::OUStringBuffer aStrBuf; |
| aStrBuf.append( xPackage->getURL() ); |
| aStrBuf.append( aSlash ); |
| aStrBuf.append( aLanguage ); |
| aStrBuf.append( aSlash ); |
| aStrBuf.append( aHelpFilesBaseName ); |
| aStrBuf.appendAscii( ".tree" ); |
| |
| aRetFile = expandURL( aStrBuf.makeStringAndClear() ); |
| if( iPass == 0 ) |
| { |
| if( m_xSFA->exists( aRetFile ) ) |
| break; |
| |
| ::std::vector< ::rtl::OUString > av; |
| implGetLanguageVectorFromPackage( av, xPackage ); |
| ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); |
| try |
| { |
| pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); |
| } |
| catch( ::comphelper::Locale::MalFormedLocaleException& ) |
| {} |
| if( pFound != av.end() ) |
| aLanguage = *pFound; |
| } |
| } |
| |
| rnFileSize = 0; |
| if( m_xSFA->exists( aRetFile ) ) |
| rnFileSize = m_xSFA->getSize( aRetFile ); |
| else |
| aRetFile = rtl::OUString(); |
| |
| return aRetFile; |
| } |
| |
| |
| |