1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tvread.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_xmlhelp.hxx"
36 #include <rtl/ustrbuf.hxx>
37 #ifndef _VOS_DIAGNOSE_HXX_
38 #include <vos/diagnose.hxx>
44 #include <expat/xmlparse.h>
46 #include <osl/file.hxx>
47 #include <unotools/configmgr.hxx>
48 #include <com/sun/star/frame/XConfigManager.hpp>
49 #include <com/sun/star/beans/PropertyValue.hpp>
50 #include <com/sun/star/beans/PropertyState.hpp>
52 #include <comphelper/processfactory.hxx>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
55 #include <com/sun/star/util/XMacroExpander.hpp>
56 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
57 #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
58 #include <comphelper/locale.hxx>
65 friend class TVChildTarget
;
70 TVDom( TVDom
* arent
= 0 )
79 for( unsigned i
= 0; i
< childs
.size(); ++i
)
86 childs
.push_back( new TVDom( this ) );
91 TVDom
* getParent() const
96 return const_cast<TVDom
*>(this); // I am my own parent, if I am the root
106 bool isLeaf() const { return kind
== TVDom::tree_leaf
; }
107 void setKind( Kind ind
) { kind
= ind
; }
108 Kind
getKind( ) const { return kind
; }
111 void setApplication( const char* appl
)
113 application
= rtl::OUString( (sal_Char
*)(appl
),
115 RTL_TEXTENCODING_UTF8
);
118 void setTitle( const char* itle
)
120 title
+= rtl::OUString( (sal_Char
*)(itle
),
122 RTL_TEXTENCODING_UTF8
);
125 void setTitle( const XML_Char
* itle
,int len
)
127 title
+= rtl::OUString( (sal_Char
*)(itle
),
129 RTL_TEXTENCODING_UTF8
);
132 void setId( const char* d
)
134 id
= rtl::OUString( (sal_Char
*)(d
),
136 RTL_TEXTENCODING_UTF8
);
139 void setAnchor( const char* nchor
)
141 anchor
= rtl::OUString( (sal_Char
*)(nchor
),
143 RTL_TEXTENCODING_UTF8
);
146 rtl::OUString
getTargetURL()
148 if( ! targetURL
.getLength() )
151 for ( const TVDom
* p
= this;; p
= p
->parent
)
153 len
= p
->application
.getLength();
158 rtl::OUStringBuffer
strBuff( 22 + len
+ id
.getLength() );
160 "vnd.sun.star.help://"
163 targetURL
= strBuff
.makeStringAndClear();
172 rtl::OUString application
;
175 rtl::OUString anchor
;
176 rtl::OUString targetURL
;
179 std::vector
< TVDom
* > childs
;
186 using namespace treeview
;
187 using namespace com::sun::star
;
188 using namespace com::sun::star::uno
;
189 using namespace com::sun::star::beans
;
190 using namespace com::sun::star::lang
;
191 using namespace com::sun::star::util
;
192 using namespace com::sun::star::frame
;
193 using namespace com::sun::star::container
;
194 using namespace com::sun::star::deployment
;
197 ConfigData::ConfigData()
198 : prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ),
199 prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ),
200 vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ),
201 vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ),
202 vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) )
206 void SAL_CALL
ConfigData::replaceName( rtl::OUString
& oustring
) const
208 sal_Int32 idx
= -1,k
= 0,off
;
210 rtl::OUStringBuffer
aStrBuf( 0 );
212 while( ( idx
= oustring
.indexOf( sal_Unicode('%'),++idx
) ) != -1 )
214 if( oustring
.indexOf( prodName
,idx
) == idx
)
216 else if( oustring
.indexOf( prodVersion
,idx
) == idx
)
217 off
= PRODUCTVERSION
;
218 else if( oustring
.indexOf( vendName
,idx
) == idx
)
220 else if( oustring
.indexOf( vendVersion
,idx
) == idx
)
222 else if( oustring
.indexOf( vendShort
,idx
) == idx
)
232 aStrBuf
.ensureCapacity( 256 );
235 aStrBuf
.append( &oustring
.getStr()[k
],idx
- k
);
236 aStrBuf
.append( m_vReplacement
[off
] );
237 k
= idx
+ m_vAdd
[off
];
243 if( k
< oustring
.getLength() )
244 aStrBuf
.append( &oustring
.getStr()[k
],oustring
.getLength()-k
);
245 oustring
= aStrBuf
.makeStringAndClear();
252 //////////////////////////////////////////////////////////////////////////
254 //////////////////////////////////////////////////////////////////////////
262 OWeakObject::acquire();
271 OWeakObject::release();
276 TVBase::queryInterface(
278 throw( RuntimeException
)
280 Any aRet
= cppu::queryInterface( rType
,
281 SAL_STATIC_CAST( XTypeProvider
*, this ),
282 SAL_STATIC_CAST( XNameAccess
*, this ),
283 SAL_STATIC_CAST( XHierarchicalNameAccess
*, this ),
284 SAL_STATIC_CAST( XChangesNotifier
*, this ),
285 SAL_STATIC_CAST( XComponent
*, this ) );
287 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
291 ////////////////////////////////////////////////////////////////////////////////
293 // XTypeProvider methods.
295 XTYPEPROVIDER_IMPL_5( TVBase
,
298 XHierarchicalNameAccess
,
310 TVRead::TVRead( const ConfigData
& configData
,TVDom
* tvDom
)
315 Title
= tvDom
->title
;
316 configData
.replaceName( Title
);
317 if( tvDom
->isLeaf() )
319 TargetURL
= ( tvDom
->getTargetURL() + configData
.appendix
);
320 if( tvDom
->anchor
.getLength() )
321 TargetURL
+= ( rtl::OUString::createFromAscii( "#" ) +
325 Children
= new TVChildTarget( configData
,tvDom
);
342 TVRead::getByName( const rtl::OUString
& aName
)
343 throw( NoSuchElementException
,
344 WrappedTargetException
,
349 if( aName
.compareToAscii( "Title" ) == 0 )
351 else if( aName
.compareToAscii( "TargetURL" ) == 0 )
353 else if( aName
.compareToAscii( "Children" ) == 0 )
355 cppu::OWeakObject
* p
= Children
.get();
356 aAny
<<= Reference
< XInterface
>( p
);
364 throw NoSuchElementException();
370 Sequence
< rtl::OUString
> SAL_CALL
371 TVRead::getElementNames( )
372 throw( RuntimeException
)
374 Sequence
< rtl::OUString
> seq( 3 );
376 seq
[0] = rtl::OUString::createFromAscii( "Title" );
377 seq
[1] = rtl::OUString::createFromAscii( "TargetURL" );
378 seq
[2] = rtl::OUString::createFromAscii( "Children" );
386 TVRead::hasByName( const rtl::OUString
& aName
)
387 throw( RuntimeException
)
389 if( aName
.compareToAscii( "Title" ) == 0 ||
390 aName
.compareToAscii( "TargetURL" ) == 0 ||
391 aName
.compareToAscii( "Children" ) == 0 )
398 // XHierarchicalNameAccess
401 TVRead::getByHierarchicalName( const rtl::OUString
& aName
)
402 throw( NoSuchElementException
,
406 rtl::OUString
name( aName
);
408 if( ( idx
= name
.indexOf( sal_Unicode( '/' ) ) ) != -1 &&
409 name
.copy( 0,idx
).compareToAscii( "Children" ) == 0 )
410 return Children
->getByHierarchicalName( name
.copy( 1 + idx
) );
412 return getByName( name
);
419 TVRead::hasByHierarchicalName( const rtl::OUString
& aName
)
420 throw( RuntimeException
)
423 rtl::OUString
name( aName
);
425 if( ( idx
= name
.indexOf( sal_Unicode( '/' ) ) ) != -1 &&
426 name
.copy( 0,idx
).compareToAscii( "Children" ) == 0 )
427 return Children
->hasByHierarchicalName( name
.copy( 1 + idx
) );
429 return hasByName( name
);
434 /**************************************************************************/
438 /**************************************************************************/
443 extern "C" void start_handler(void *userData
,
444 const XML_Char
*name
,
445 const XML_Char
**atts
)
449 if( strcmp( name
,"help_section" ) == 0 ||
450 strcmp( name
,"node" ) == 0 )
451 kind
= TVDom::tree_node
;
452 else if( strcmp( name
,"topic" ) == 0 )
453 kind
= TVDom::tree_leaf
;
457 TVDom
**tvDom
= static_cast< TVDom
** >( userData
);
461 *tvDom
= p
->newChild();
467 if( strcmp( *atts
,"application" ) == 0 )
468 p
->setApplication( *(atts
+1) );
469 else if( strcmp( *atts
,"title" ) == 0 )
470 p
->setTitle( *(atts
+1) );
471 else if( strcmp( *atts
,"id" ) == 0 )
472 p
->setId( *(atts
+1) );
473 else if( strcmp( *atts
,"anchor" ) == 0 )
474 p
->setAnchor( *(atts
+1) );
481 extern "C" void end_handler(void *userData
,
482 const XML_Char
*name
)
486 TVDom
**tvDom
= static_cast< TVDom
** >( userData
);
487 *tvDom
= (*tvDom
)->getParent();
491 extern "C" void data_handler( void *userData
,
495 TVDom
**tvDom
= static_cast< TVDom
** >( userData
);
496 if( (*tvDom
)->isLeaf() )
497 (*tvDom
)->setTitle( s
,len
);
502 TVChildTarget::TVChildTarget( const ConfigData
& configData
,TVDom
* tvDom
)
504 Elements
.resize( tvDom
->childs
.size() );
505 for( unsigned i
= 0; i
< Elements
.size(); ++i
)
506 Elements
[i
] = new TVRead( configData
,tvDom
->childs
[i
] );
513 TVChildTarget::TVChildTarget( const Reference
< XMultiServiceFactory
>& xMSF
)
515 ConfigData configData
= init( xMSF
);
517 if( ! configData
.locale
.getLength() ||
518 ! configData
.system
.getLength() )
521 sal_uInt64 ret
,len
= 0;
522 int j
= configData
.vFileURL
.size();
525 TVDom
* pTVDom
= &tvDom
;
529 len
= configData
.vFileLen
[--j
];
530 char* s
= new char[ int(len
) ]; // the buffer to hold the installed files
531 osl::File
aFile( configData
.vFileURL
[j
] );
532 aFile
.open( OpenFlag_Read
);
533 aFile
.read( s
,len
,ret
);
536 XML_Parser parser
= XML_ParserCreate( 0 );
537 XML_SetElementHandler( parser
,
540 XML_SetCharacterDataHandler( parser
,
542 XML_SetUserData( parser
,&pTVDom
); // does not return this
544 int parsed
= XML_Parse( parser
,s
,int( len
),j
==0 );
546 OSL_ENSURE( parsed
, "TVChildTarget::TVChildTarget(): Tree file parsing failed" );
548 XML_ParserFree( parser
);
552 // now TVDom holds the relevant information
554 Elements
.resize( tvDom
.childs
.size() );
555 for( unsigned i
= 0; i
< Elements
.size(); ++i
)
556 Elements
[i
] = new TVRead( configData
,tvDom
.childs
[i
] );
560 TVChildTarget::~TVChildTarget()
567 TVChildTarget::getByName( const rtl::OUString
& aName
)
568 throw( NoSuchElementException
,
569 WrappedTargetException
,
572 rtl::OUString
num( aName
.getStr()+2,aName
.getLength()-4 );
573 sal_Int32 idx
= num
.toInt32() - 1;
574 if( idx
< 0 || Elements
.size() <= sal_uInt32( idx
) )
575 throw NoSuchElementException();
578 cppu::OWeakObject
* p
= Elements
[idx
].get();
579 aAny
<<= Reference
< XInterface
>( p
);
586 Sequence
< rtl::OUString
> SAL_CALL
587 TVChildTarget::getElementNames( )
588 throw( RuntimeException
)
590 Sequence
< rtl::OUString
> seq( Elements
.size() );
591 for( unsigned i
= 0; i
< Elements
.size(); ++i
)
592 seq
[i
] = rtl::OUString::valueOf( sal_Int32( 1+i
) );
600 TVChildTarget::hasByName( const rtl::OUString
& aName
)
601 throw( RuntimeException
)
603 rtl::OUString
num( aName
.getStr()+2,aName
.getLength()-4 );
604 sal_Int32 idx
= num
.toInt32() - 1;
605 if( idx
< 0 || Elements
.size() <= sal_uInt32( idx
) )
613 // XHierarchicalNameAccess
616 TVChildTarget::getByHierarchicalName( const rtl::OUString
& aName
)
617 throw( NoSuchElementException
,
621 rtl::OUString
name( aName
);
623 if( ( idx
= name
.indexOf( sal_Unicode( '/' ) ) ) != -1 )
625 rtl::OUString
num( name
.getStr()+2,idx
-4 );
626 sal_Int32 pref
= num
.toInt32() - 1;
628 if( pref
< 0 || Elements
.size() <= sal_uInt32( pref
) )
629 throw NoSuchElementException();
631 return Elements
[pref
]->getByHierarchicalName( name
.copy( 1 + idx
) );
634 return getByName( name
);
640 TVChildTarget::hasByHierarchicalName( const rtl::OUString
& aName
)
641 throw( RuntimeException
)
644 rtl::OUString
name( aName
);
646 if( ( idx
= name
.indexOf( sal_Unicode( '/' ) ) ) != -1 )
648 rtl::OUString
num( name
.getStr()+2,idx
-4 );
649 sal_Int32 pref
= num
.toInt32() - 1;
650 if( pref
< 0 || Elements
.size() <= sal_uInt32( pref
) )
653 return Elements
[pref
]->hasByHierarchicalName( name
.copy( 1 + idx
) );
656 return hasByName( name
);
664 ConfigData
TVChildTarget::init( const Reference
< XMultiServiceFactory
>& xSMgr
)
666 ConfigData configData
;
667 Reference
< XMultiServiceFactory
> sProvider( getConfiguration(xSMgr
) );
669 /**********************************************************************/
670 /* reading Office.Common */
671 /**********************************************************************/
673 Reference
< XHierarchicalNameAccess
> xHierAccess( getHierAccess( sProvider
,
674 "org.openoffice.Office.Common" ) );
675 rtl::OUString
system( getKey( xHierAccess
,"Help/System" ) );
676 sal_Bool
showBasic( getBooleanKey(xHierAccess
,"Help/ShowBasic") );
677 rtl::OUString
instPath( getKey( xHierAccess
,"Path/Current/Help" ) );
678 if( ! instPath
.getLength() )
679 // try to determine path from default
680 instPath
= rtl::OUString::createFromAscii( "$(instpath)/help" );
682 // replace anything like $(instpath);
683 subst( xSMgr
,instPath
);
686 /**********************************************************************/
687 /* reading Webtop.Common */
688 /**********************************************************************/
690 xHierAccess
= getHierAccess( sProvider
,
691 "org.openoffice.Webtop.Common" );
692 rtl::OUString
vendorName( getKey( xHierAccess
,"Product/ooName" ) );
694 rtl::OUString
setupversion( getKey( xHierAccess
,"Product/ooSetupVersion" ) );
695 rtl::OUString
setupextension( getKey( xHierAccess
,"Product/ooSetupExtension") );
696 rtl::OUString
vendorVersion( setupversion
+
697 rtl::OUString::createFromAscii( " " ) +
699 rtl::OUString vendorShort
= vendorName
;
701 /**********************************************************************/
703 /**********************************************************************/
705 xHierAccess
= getHierAccess( sProvider
,
706 "org.openoffice.Setup" );
708 rtl::OUString
productName( getKey( xHierAccess
,"Product/ooName" ) );
709 setupversion
= getKey( xHierAccess
,"Product/ooSetupVersion" );
710 setupextension
= rtl::OUString();
711 utl::ConfigManager
* mgr
= utl::ConfigManager::GetConfigManager();
713 mgr
->GetDirectConfigProperty(utl::ConfigManager::PRODUCTEXTENSION
) >>=
716 rtl::OUString
productVersion( setupversion
+
717 rtl::OUString::createFromAscii( " " ) +
719 rtl::OUString
locale( getKey( xHierAccess
,"L10N/ooLocale" ) );
722 // Determine fileurl from url and locale
724 osl::FileBase::RC errFile
= osl::FileBase::getFileURLFromSystemPath( instPath
,url
);
725 if( errFile
!= osl::FileBase::E_None
) return configData
;
726 if( url
.lastIndexOf( sal_Unicode( '/' ) ) != url
.getLength() - 1 )
727 url
+= rtl::OUString::createFromAscii( "/" );
730 osl::DirectoryItem aDirItem
;
731 if( osl::FileBase::E_None
== osl::DirectoryItem::get( url
+ locale
,aDirItem
) )
733 else if( ( ( idx
= locale
.indexOf( '-' ) ) != -1 ||
734 ( idx
= locale
.indexOf( '_' ) ) != -1 ) &&
735 osl::FileBase::E_None
== osl::DirectoryItem::get( url
+ locale
.copy( 0,idx
),
737 ret
= locale
.copy( 0,idx
);
740 locale
= rtl::OUString::createFromAscii( "en-US" );
741 ret
= rtl::OUString::createFromAscii("en");
745 // first of all, try do determine whether there are any *.tree files present
747 // Start with extensions to set them at the end of the list
748 TreeFileIterator
aTreeIt( locale
);
749 rtl::OUString aTreeFile
;
751 while( (aTreeFile
= aTreeIt
.nextTreeFile( nFileSize
) ).getLength() > 0 )
753 configData
.vFileLen
.push_back( nFileSize
);
754 configData
.vFileURL
.push_back( aTreeFile
);
757 osl::Directory
aDirectory( url
);
758 osl::FileStatus
aFileStatus( FileStatusMask_FileName
| FileStatusMask_FileSize
| FileStatusMask_FileURL
);
759 if( osl::Directory::E_None
== aDirectory
.open() )
762 rtl::OUString aFileUrl
, aFileName
;
763 while( aDirectory
.getNextItem( aDirItem
) == osl::FileBase::E_None
&&
764 aDirItem
.getFileStatus( aFileStatus
) == osl::FileBase::E_None
&&
765 aFileStatus
.isValid( FileStatusMask_FileURL
) &&
766 aFileStatus
.isValid( FileStatusMask_FileName
) )
768 aFileUrl
= aFileStatus
.getFileURL();
769 aFileName
= aFileStatus
.getFileName();
770 idx_
= aFileName
.lastIndexOf( sal_Unicode( '.' ) );
774 const sal_Unicode
* str
= aFileName
.getStr();
776 if( aFileName
.getLength() == idx_
+ 5 &&
777 ( str
[idx_
+ 1] == 't' || str
[idx_
+ 1] == 'T' ) &&
778 ( str
[idx_
+ 2] == 'r' || str
[idx_
+ 2] == 'R' ) &&
779 ( str
[idx_
+ 3] == 'e' || str
[idx_
+ 3] == 'E' ) &&
780 ( str
[idx_
+ 4] == 'e' || str
[idx_
+ 4] == 'E' ) )
782 OSL_ENSURE( aFileStatus
.isValid( FileStatusMask_FileSize
),
783 "invalid file size" );
785 rtl::OUString baseName
= aFileName
.copy(0,idx_
).toAsciiLowerCase();
786 if(! showBasic
&& baseName
.compareToAscii("sbasic") == 0 )
788 osl::File
aFile( aFileUrl
);
789 if( osl::FileBase::E_None
== aFile
.open( OpenFlag_Read
) )
792 aFile
.getSize( nSize
);
793 configData
.vFileLen
.push_back( aFileStatus
.getFileSize() );
794 configData
.vFileURL
.push_back( aFileUrl
);
802 configData
.m_vAdd
[0] = 12;
803 configData
.m_vAdd
[1] = 15;
804 configData
.m_vAdd
[2] = 11;
805 configData
.m_vAdd
[3] = 14;
806 configData
.m_vAdd
[4] = 12;
807 configData
.m_vReplacement
[0] = productName
;
808 configData
.m_vReplacement
[1] = productVersion
;
809 configData
.m_vReplacement
[2] = vendorName
;
810 configData
.m_vReplacement
[3] = vendorVersion
;
811 configData
.m_vReplacement
[4] = vendorShort
;
813 configData
.system
= system
;
814 configData
.locale
= locale
;
815 configData
.appendix
=
816 rtl::OUString::createFromAscii( "?Language=" ) +
818 rtl::OUString::createFromAscii( "&System=" ) +
820 rtl::OUString::createFromAscii( "&UseDB=no" ) ;
833 Reference
< XMultiServiceFactory
>
834 TVChildTarget::getConfiguration(const Reference
< XMultiServiceFactory
>& m_xSMgr
) const
836 Reference
< XMultiServiceFactory
> sProvider
;
840 aAny
<<= rtl::OUString::createFromAscii( "plugin" );
841 PropertyValue
aProp( rtl::OUString::createFromAscii( "servertype" ),
844 PropertyState_DIRECT_VALUE
);
846 Sequence
< Any
> seq(1);
851 rtl::OUString sProviderService
=
852 rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
854 Reference
< XMultiServiceFactory
>(
855 m_xSMgr
->createInstanceWithArguments( sProviderService
,seq
),
858 catch( const com::sun::star::uno::Exception
& )
860 OSL_ENSURE( sProvider
.is(),"cant instantiate configuration" );
869 Reference
< XHierarchicalNameAccess
>
870 TVChildTarget::getHierAccess( const Reference
< XMultiServiceFactory
>& sProvider
,
871 const char* file
) const
873 Reference
< XHierarchicalNameAccess
> xHierAccess
;
877 Sequence
< Any
> seq(1);
878 rtl::OUString sReaderService
=
879 rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );
881 seq
[0] <<= rtl::OUString::createFromAscii( file
);
886 Reference
< XHierarchicalNameAccess
>
887 ( sProvider
->createInstanceWithArguments( sReaderService
,seq
),
890 catch( const com::sun::star::uno::Exception
& )
901 TVChildTarget::getKey( const Reference
< XHierarchicalNameAccess
>& xHierAccess
,
902 const char* key
) const
904 rtl::OUString instPath
;
905 if( xHierAccess
.is() )
911 xHierAccess
->getByHierarchicalName( rtl::OUString::createFromAscii( key
) );
913 catch( const com::sun::star::container::NoSuchElementException
& )
923 TVChildTarget::getBooleanKey(const Reference
<
924 XHierarchicalNameAccess
>& xHierAccess
,
925 const char* key
) const
927 sal_Bool ret
= sal_False
;
928 if( xHierAccess
.is() )
934 xHierAccess
->getByHierarchicalName(
935 rtl::OUString::createFromAscii(key
));
937 catch( const com::sun::star::container::NoSuchElementException
& )
946 void TVChildTarget::subst( const Reference
< XMultiServiceFactory
>& m_xSMgr
,
947 rtl::OUString
& instpath
) const
949 Reference
< XConfigManager
> xCfgMgr
;
955 Reference
< XConfigManager
>(
956 m_xSMgr
->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ),
959 catch( const com::sun::star::uno::Exception
& )
961 OSL_ENSURE( xCfgMgr
.is()," cant instantiate the special config manager " );
965 OSL_ENSURE( xCfgMgr
.is(), "specialconfigmanager not found\n" );
968 instpath
= xCfgMgr
->substituteVariables( instpath
);
972 //===================================================================
973 // class ExtensionIteratorBase
975 static rtl::OUString
aSlash( rtl::OUString::createFromAscii( "/" ) );
976 static rtl::OUString
aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
977 static rtl::OUString
aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );
979 ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString
& aLanguage
)
980 : m_eState( USER_EXTENSIONS
)
981 , m_aLanguage( aLanguage
)
986 void ExtensionIteratorBase::init()
988 Reference
< XMultiServiceFactory
> xFactory
= comphelper::getProcessServiceFactory();
989 Reference
< XPropertySet
> xProps( xFactory
, UNO_QUERY
);
990 OSL_ASSERT( xProps
.is() );
993 xProps
->getPropertyValue(
994 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext
;
995 OSL_ASSERT( m_xContext
.is() );
997 if( !m_xContext
.is() )
999 throw RuntimeException(
1000 ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ),
1001 Reference
< XInterface
>() );
1004 Reference
< XMultiComponentFactory
> xSMgr( m_xContext
->getServiceManager(), UNO_QUERY
);
1005 m_xSFA
= Reference
< ucb::XSimpleFileAccess
>(
1006 xSMgr
->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
1007 m_xContext
), UNO_QUERY_THROW
);
1009 m_bUserPackagesLoaded
= false;
1010 m_bSharedPackagesLoaded
= false;
1012 m_iSharedPackage
= 0;
1015 Reference
< deployment::XPackage
> ExtensionIteratorBase::implGetHelpPackageFromPackage
1016 ( Reference
< deployment::XPackage
> xPackage
, Reference
< deployment::XPackage
>& o_xParentPackageBundle
)
1018 o_xParentPackageBundle
.clear();
1020 Reference
< deployment::XPackage
> xHelpPackage
;
1021 if( !xPackage
.is() )
1022 return xHelpPackage
;
1024 // Check if parent package is registered
1025 beans::Optional
< beans::Ambiguous
<sal_Bool
> > option( xPackage
->isRegistered
1026 ( Reference
<task::XAbortChannel
>(), Reference
<ucb::XCommandEnvironment
>() ) );
1027 bool bRegistered
= false;
1028 if( option
.IsPresent
)
1030 beans::Ambiguous
<sal_Bool
> const & reg
= option
.Value
;
1031 if( !reg
.IsAmbiguous
&& reg
.Value
)
1035 return xHelpPackage
;
1037 if( xPackage
->isBundle() )
1039 Sequence
< Reference
< deployment::XPackage
> > aPkgSeq
= xPackage
->getBundle
1040 ( Reference
<task::XAbortChannel
>(), Reference
<ucb::XCommandEnvironment
>() );
1041 sal_Int32 nPkgCount
= aPkgSeq
.getLength();
1042 const Reference
< deployment::XPackage
>* pSeq
= aPkgSeq
.getConstArray();
1043 for( sal_Int32 iPkg
= 0 ; iPkg
< nPkgCount
; ++iPkg
)
1045 const Reference
< deployment::XPackage
> xSubPkg
= pSeq
[ iPkg
];
1046 const Reference
< deployment::XPackageTypeInfo
> xPackageTypeInfo
= xSubPkg
->getPackageType();
1047 rtl::OUString aMediaType
= xPackageTypeInfo
->getMediaType();
1048 if( aMediaType
.equals( aHelpMediaType
) )
1050 xHelpPackage
= xSubPkg
;
1051 o_xParentPackageBundle
= xPackage
;
1058 const Reference
< deployment::XPackageTypeInfo
> xPackageTypeInfo
= xPackage
->getPackageType();
1059 rtl::OUString aMediaType
= xPackageTypeInfo
->getMediaType();
1060 if( aMediaType
.equals( aHelpMediaType
) )
1061 xHelpPackage
= xPackage
;
1064 return xHelpPackage
;
1067 Reference
< deployment::XPackage
> ExtensionIteratorBase::implGetNextUserHelpPackage
1068 ( Reference
< deployment::XPackage
>& o_xParentPackageBundle
)
1070 Reference
< deployment::XPackage
> xHelpPackage
;
1072 if( !m_bUserPackagesLoaded
)
1074 Reference
< XPackageManager
> xUserManager
=
1075 thePackageManagerFactory::get( m_xContext
)->getPackageManager( rtl::OUString::createFromAscii("user") );
1076 m_aUserPackagesSeq
= xUserManager
->getDeployedPackages
1077 ( Reference
< task::XAbortChannel
>(), Reference
< ucb::XCommandEnvironment
>() );
1079 m_bUserPackagesLoaded
= true;
1082 if( m_iUserPackage
== m_aUserPackagesSeq
.getLength() )
1084 m_eState
= SHARED_EXTENSIONS
; // Later: SHARED_MODULE
1088 const Reference
< deployment::XPackage
>* pUserPackages
= m_aUserPackagesSeq
.getConstArray();
1089 Reference
< deployment::XPackage
> xPackage
= pUserPackages
[ m_iUserPackage
++ ];
1090 VOS_ENSURE( xPackage
.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
1091 xHelpPackage
= implGetHelpPackageFromPackage( xPackage
, o_xParentPackageBundle
);
1094 return xHelpPackage
;
1097 Reference
< deployment::XPackage
> ExtensionIteratorBase::implGetNextSharedHelpPackage
1098 ( Reference
< deployment::XPackage
>& o_xParentPackageBundle
)
1100 Reference
< deployment::XPackage
> xHelpPackage
;
1102 if( !m_bSharedPackagesLoaded
)
1104 Reference
< XPackageManager
> xSharedManager
=
1105 thePackageManagerFactory::get( m_xContext
)->getPackageManager( rtl::OUString::createFromAscii("shared") );
1106 m_aSharedPackagesSeq
= xSharedManager
->getDeployedPackages
1107 ( Reference
< task::XAbortChannel
>(), Reference
< ucb::XCommandEnvironment
>() );
1109 m_bSharedPackagesLoaded
= true;
1112 if( m_iSharedPackage
== m_aSharedPackagesSeq
.getLength() )
1114 m_eState
= END_REACHED
;
1118 const Reference
< deployment::XPackage
>* pSharedPackages
= m_aSharedPackagesSeq
.getConstArray();
1119 Reference
< deployment::XPackage
> xPackage
= pSharedPackages
[ m_iSharedPackage
++ ];
1120 VOS_ENSURE( xPackage
.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
1121 xHelpPackage
= implGetHelpPackageFromPackage( xPackage
, o_xParentPackageBundle
);
1124 return xHelpPackage
;
1127 inline bool isLetter( sal_Unicode c
)
1129 bool bLetter
= ((c
>= 'A' && c
<= 'Z') || (c
>= 'a' && c
<= 'z'));
1133 void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector
< ::rtl::OUString
> &rv
,
1134 com::sun::star::uno::Reference
< com::sun::star::deployment::XPackage
> xPackage
)
1137 rtl::OUString aExtensionPath
= xPackage
->getURL();
1138 Sequence
< rtl::OUString
> aEntrySeq
= m_xSFA
->getFolderContents( aExtensionPath
, true );
1140 const rtl::OUString
* pSeq
= aEntrySeq
.getConstArray();
1141 sal_Int32 nCount
= aEntrySeq
.getLength();
1142 for( sal_Int32 i
= 0 ; i
< nCount
; ++i
)
1144 rtl::OUString aEntry
= pSeq
[i
];
1145 if( m_xSFA
->isFolder( aEntry
) )
1147 sal_Int32 nLastSlash
= aEntry
.lastIndexOf( '/' );
1148 if( nLastSlash
!= -1 )
1150 rtl::OUString aPureEntry
= aEntry
.copy( nLastSlash
+ 1 );
1152 // Check language sceme
1153 int nLen
= aPureEntry
.getLength();
1154 const sal_Unicode
* pc
= aPureEntry
.getStr();
1155 bool bStartCanBeLanguage
= ( nLen
>= 2 && isLetter( pc
[0] ) && isLetter( pc
[1] ) );
1156 bool bIsLanguage
= bStartCanBeLanguage
&&
1157 ( nLen
== 2 || (nLen
== 5 && pc
[2] == '-' && isLetter( pc
[3] ) && isLetter( pc
[4] )) );
1159 rv
.push_back( aPureEntry
);
1166 //===================================================================
1167 // class TreeFileIterator
1169 rtl::OUString
TreeFileIterator::nextTreeFile( sal_Int32
& rnFileSize
)
1171 rtl::OUString aRetFile
;
1173 while( !aRetFile
.getLength() && m_eState
!= END_REACHED
)
1177 case USER_EXTENSIONS
:
1179 Reference
< deployment::XPackage
> xParentPackageBundle
;
1180 Reference
< deployment::XPackage
> xHelpPackage
= implGetNextUserHelpPackage( xParentPackageBundle
);
1181 if( !xHelpPackage
.is() )
1184 aRetFile
= implGetTreeFileFromPackage( rnFileSize
, xHelpPackage
);
1188 case SHARED_EXTENSIONS
:
1190 Reference
< deployment::XPackage
> xParentPackageBundle
;
1191 Reference
< deployment::XPackage
> xHelpPackage
= implGetNextSharedHelpPackage( xParentPackageBundle
);
1192 if( !xHelpPackage
.is() )
1195 aRetFile
= implGetTreeFileFromPackage( rnFileSize
, xHelpPackage
);
1199 VOS_ENSURE( false, "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" );
1207 rtl::OUString
TreeFileIterator::expandURL( const rtl::OUString
& aURL
)
1209 static Reference
< util::XMacroExpander
> xMacroExpander
;
1210 static Reference
< uri::XUriReferenceFactory
> xFac
;
1212 osl::MutexGuard
aGuard( m_aMutex
);
1214 if( !xMacroExpander
.is() || !xFac
.is() )
1216 Reference
< XMultiComponentFactory
> xSMgr( m_xContext
->getServiceManager(), UNO_QUERY
);
1218 xFac
= Reference
< uri::XUriReferenceFactory
>(
1219 xSMgr
->createInstanceWithContext( rtl::OUString::createFromAscii(
1220 "com.sun.star.uri.UriReferenceFactory"), m_xContext
) , UNO_QUERY
);
1223 throw RuntimeException(
1224 ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ),
1225 Reference
< XInterface
>() );
1228 xMacroExpander
= Reference
< util::XMacroExpander
>(
1229 m_xContext
->getValueByName(
1230 ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
1234 rtl::OUString aRetURL
= aURL
;
1235 if( xMacroExpander
.is() )
1237 Reference
< uri::XUriReference
> uriRef
;
1240 uriRef
= Reference
< uri::XUriReference
>( xFac
->parse( aRetURL
), UNO_QUERY
);
1243 Reference
< uri::XVndSunStarExpandUrl
> sxUri( uriRef
, UNO_QUERY
);
1247 aRetURL
= sxUri
->expand( xMacroExpander
);
1254 rtl::OUString
TreeFileIterator::implGetTreeFileFromPackage
1255 ( sal_Int32
& rnFileSize
, Reference
< deployment::XPackage
> xPackage
)
1257 rtl::OUString aRetFile
;
1258 rtl::OUString aLanguage
= m_aLanguage
;
1259 for( sal_Int32 iPass
= 0 ; iPass
< 2 ; ++iPass
)
1261 rtl::OUStringBuffer aStrBuf
;
1262 aStrBuf
.append( xPackage
->getURL() );
1263 aStrBuf
.append( aSlash
);
1264 aStrBuf
.append( aLanguage
);
1265 aStrBuf
.append( aSlash
);
1266 aStrBuf
.append( aHelpFilesBaseName
);
1267 aStrBuf
.appendAscii( ".tree" );
1269 aRetFile
= expandURL( aStrBuf
.makeStringAndClear() );
1272 if( m_xSFA
->exists( aRetFile
) )
1275 ::std::vector
< ::rtl::OUString
> av
;
1276 implGetLanguageVectorFromPackage( av
, xPackage
);
1277 ::std::vector
< ::rtl::OUString
>::const_iterator pFound
= av
.end();
1280 pFound
= ::comphelper::Locale::getFallback( av
, m_aLanguage
);
1282 catch( ::comphelper::Locale::MalFormedLocaleException
& )
1284 if( pFound
!= av
.end() )
1285 aLanguage
= *pFound
;
1290 if( m_xSFA
->exists( aRetFile
) )
1291 rnFileSize
= m_xSFA
->getSize( aRetFile
);
1293 aRetFile
= rtl::OUString();