21#include <rtl/character.hxx>
22#include <rtl/ustrbuf.hxx>
26#include <osl/diagnose.h>
29#include <osl/file.hxx>
31#include <com/sun/star/configuration/theDefaultProvider.hpp>
32#include <com/sun/star/ucb/SimpleFileAccess.hpp>
36#include <com/sun/star/deployment/thePackageManagerFactory.hpp>
37#include <com/sun/star/util/theMacroExpander.hpp>
38#include <com/sun/star/uri/UriReferenceFactory.hpp>
39#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
78 return const_cast<TVDom*
>(
this);
94 RTL_TEXTENCODING_UTF8 );
99 title += OUString( itle,
101 RTL_TEXTENCODING_UTF8 );
106 title += OUString( itle,
108 RTL_TEXTENCODING_UTF8 );
115 RTL_TEXTENCODING_UTF8 );
122 RTL_TEXTENCODING_UTF8 );
166ConfigData::ConfigData()
172 sal_Int32
idx = -1,k = 0,off;
174 OUStringBuffer aStrBuf( 0 );
176 while( (
idx = oustring.indexOf(
'%', ++
idx ) ) != -1 )
196 aStrBuf.ensureCapacity( 256 );
199 aStrBuf.append( &oustring.getStr()[k],
idx - k );
207 if( k < oustring.getLength() )
208 aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
209 oustring = aStrBuf.makeStringAndClear();
225 if( !tvDom->
anchor.isEmpty() )
243 if(
aName ==
"Title" )
245 else if(
aName ==
"TargetURL" )
247 else if(
aName ==
"Children" )
250 aAny <<= Reference< XInterface >(
p );
258 throw NoSuchElementException();
264 return {
"Title",
"TargetURL",
"Children" };
270 if(
aName ==
"Title" ||
271 aName ==
"TargetURL" ||
272 aName ==
"Children" )
284 if(
aName.startsWith(
"Children/", &aRest) )
285 return Children->getByHierarchicalName( aRest );
294 if(
aName.startsWith(
"Children/", &aRest) )
295 return Children->hasByHierarchicalName( aRest );
309 const XML_Char *name,
310 const XML_Char **atts)
314 if( strcmp(
name,
"help_section" ) == 0 ||
315 strcmp(
name,
"node" ) == 0 )
317 else if( strcmp(
name,
"topic" ) == 0 )
322 TVDom **tvDom =
static_cast< TVDom**
>( userData );
326 *tvDom =
p->newChild();
332 if( strcmp( *atts,
"application" ) == 0 )
333 p->setApplication( *(atts+1) );
334 else if( strcmp( *atts,
"title" ) == 0 )
335 p->setTitle( *(atts+1) );
336 else if( strcmp( *atts,
"id" ) == 0 )
337 p->setId( *(atts+1) );
338 else if( strcmp( *atts,
"anchor" ) == 0 )
339 p->setAnchor( *(atts+1) );
346 SAL_UNUSED_PARAMETER
const XML_Char * )
348 TVDom **tvDom =
static_cast< TVDom**
>( userData );
356 TVDom **tvDom =
static_cast< TVDom**
>( userData );
357 if( (*tvDom)->isLeaf() )
374 if( configData.
locale.isEmpty() || configData.
system.isEmpty() )
377 sal_uInt64 ret,len = 0;
381 TVDom* pTVDom = &tvDom;
386 std::unique_ptr<char[]> s(
new char[
int(len) ]);
387 osl::File aFile( configData.
vFileURL[j] );
388 (void)aFile.open( osl_File_OpenFlag_Read );
389 aFile.read( s.get(),len,ret );
392 XML_Parser
parser = XML_ParserCreate(
nullptr );
393 XML_SetElementHandler( parser,
396 XML_SetCharacterDataHandler( parser,
398 XML_SetUserData( parser,&pTVDom );
400 XML_Status
const parsed = XML_Parse(parser, s.get(),
int(len), j==0);
402 "TVChildTarget::TVChildTarget(): Tree file parsing failed");
404 XML_ParserFree( parser );
429 while((i<tvDom->children.size()-1) && (!
h))
436 for(
auto & k :
p->children)
441 tvDom->
children[
i]->newChild(std::move(tmp));
452std::unique_ptr<TVDom>
455 if (
p->isLeaf())
return p;
460 std::vector< std::unique_ptr<TVDom> >::iterator max_It,
i;
464 sal_Int32 p_int =
p->id.toInt32();
467 if (!((*i)->isLeaf()) &&
468 ((*i)->id.getLength() ==
p->id.getLength()) &&
469 (
p->id.replaceAt((*i)->parent->id.getLength(),
p->id.getLength()-(*i)->parent->id.getLength(),
u"") == (*i)->parent->id))
472 c_int = (*i)->id.toInt32();
476 (*(tvDom->
children.insert(
i+1, std::move(
p))))->parent = tvDom;
479 else if(c_int>
max && c_int < p_int)
487 (*(tvDom->
children.insert(max_It, std::move(
p))))->parent = tvDom;
505 std::u16string_view num(
aName.subView( 2,
aName.getLength()-4 ) );
508 throw NoSuchElementException();
518 auto seqRange = asNonConstRange(seq);
520 seqRange[
i] = OUString::number( 1+
i );
528 std::u16string_view num(
aName.subView( 2,
aName.getLength()-4 ) );
543 if( (
idx =
aName.indexOf(
'/' ) ) != -1 )
545 std::u16string_view num(
aName.subView( 2,
idx-4 ) );
549 throw NoSuchElementException();
562 if( (
idx =
aName.indexOf(
'/' ) ) != -1 )
564 std::u16string_view num(
aName.subView( 2,
idx-4 ) );
585 "org.openoffice.Office.Common" ) );
586 OUString system(
getKey( xHierAccess,
"Help/System" ) );
587 bool showBasic(
getBooleanKey(xHierAccess,
"Help/ShowBasic") );
588 OUString instPath(
getKey( xHierAccess,
"Path/Current/Help" ) );
589 if( instPath.isEmpty() )
591 instPath =
"$(instpath)/help";
601 "org.openoffice.Setup" );
603 OUString setupversion(
getKey( xHierAccess,
"Product/ooSetupVersion" ) );
604 OUString setupextension;
612 {
"nodepath",
uno::Any(OUString(
"/org.openoffice.Setup/Product"))}
616 uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
617 "com.sun.star.configuration.ConfigurationAccess",
620 uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
621 uno::Any aRet = xDirectAccess->getByName(
"ooSetupExtension");
623 aRet >>= setupextension;
625 catch ( uno::Exception& )
629 OUString productVersion( setupversion +
" " + setupextension );
630 OUString locale(
getKey( xHierAccess,
"L10N/ooLocale" ) );
634 osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url );
635 if( errFile != osl::FileBase::E_None )
return configData;
636 if( !url.endsWith(
"/") )
640 osl::DirectoryItem aDirItem;
641 if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) )
643 else if( ( (
idx = locale.indexOf(
'-' ) ) != -1 ||
644 (
idx = locale.indexOf(
'_' ) ) != -1 ) &&
645 osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.subView( 0,
idx ),
647 ret = locale.copy( 0,
idx );
664 if( aTreeFile.isEmpty() )
666 configData.
vFileLen.push_back( nFileSize );
667 configData.
vFileURL.push_back( aTreeFile );
670 osl::Directory aDirectory( url );
671 osl::FileStatus aFileStatus(
672 osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_FileURL );
673 if( osl::Directory::E_None == aDirectory.open() )
675 OUString aFileUrl, aFileName;
676 while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None &&
677 aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
678 aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) &&
679 aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
681 aFileUrl = aFileStatus.getFileURL();
682 aFileName = aFileStatus.getFileName();
683 int idx_ = aFileName.lastIndexOf(
'.' );
689 if( aFileName.getLength() == idx_ + 5 &&
690 ( str[idx_ + 1] ==
't' || str[idx_ + 1] ==
'T' ) &&
691 ( str[idx_ + 2] ==
'r' || str[idx_ + 2] ==
'R' ) &&
692 ( str[idx_ + 3] ==
'e' || str[idx_ + 3] ==
'E' ) &&
693 ( str[idx_ + 4] ==
'e' || str[idx_ + 4] ==
'E' ) )
695 OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase();
696 if(! showBasic && baseName ==
"sbasic" )
698 osl::File aFile( aFileUrl );
699 if( osl::FileBase::E_None == aFile.open( osl_File_OpenFlag_Read ) )
704 aFile.getSize( nSize );
705 configData.
vFileLen.push_back( nSize );
706 configData.
vFileURL.push_back( aFileUrl );
714 configData.
m_vAdd[0] = 12;
715 configData.
m_vAdd[1] = 15;
716 configData.
m_vAdd[2] = 11;
717 configData.
m_vAdd[3] = 14;
718 configData.
m_vAdd[4] = 12;
723 configData.
system = system;
724 configData.
locale = locale;
743 xProvider = theDefaultProvider::get( rxContext );
745 catch(
const css::uno::Exception& )
747 OSL_ENSURE( xProvider.is(),
"can not instantiate configuration" );
766 ( sProvider->createInstanceWithArguments(
"com.sun.star.configuration.ConfigurationAccess", { Any(OUString::createFromAscii(file)) }),
769 catch(
const css::uno::Exception& )
782 if( xHierAccess.is() )
788 xHierAccess->getByHierarchicalName( OUString::createFromAscii( key ) );
790 catch(
const css::container::NoSuchElementException& )
800 XHierarchicalNameAccess >& xHierAccess,
804 if( xHierAccess.is() )
810 xHierAccess->getByHierarchicalName(
811 OUString::createFromAscii(key));
813 catch(
const css::container::NoSuchElementException& )
832 , m_aLanguage(
std::move( aLanguage ))
834 m_xContext = ::comphelper::getProcessComponentContext();
837 throw RuntimeException(
"TreeFileIterator::TreeFileIterator(), no XComponentContext" );
853 o_xParentPackageBundle.clear();
860 beans::Optional< beans::Ambiguous<sal_Bool> >
option( xPackage->isRegistered
862 bool bRegistered =
false;
865 beans::Ambiguous<sal_Bool>
const & reg =
option.Value;
866 if( !reg.IsAmbiguous && reg.Value )
872 if( xPackage->isBundle() )
876 auto pSubPkg = std::find_if(aPkgSeq.begin(), aPkgSeq.end(),
878 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
879 OUString aMediaType = xPackageTypeInfo->getMediaType();
880 return aMediaType == aHelpMediaType;
882 if (pSubPkg != aPkgSeq.end())
884 xHelpPackage = *pSubPkg;
885 o_xParentPackageBundle = xPackage;
891 OUString aMediaType = xPackageTypeInfo->getMediaType();
893 xHelpPackage = xPackage;
907 thePackageManagerFactory::get(
m_xContext )->getPackageManager(
"user");
922 OSL_ENSURE( xPackage.is(),
"TreeFileIterator::implGetNextUserHelpPackage(): Invalid package" );
937 thePackageManagerFactory::get(
m_xContext )->getPackageManager(
"shared");
952 OSL_ENSURE( xPackage.is(),
"TreeFileIterator::implGetNextSharedHelpPackage(): Invalid package" );
967 thePackageManagerFactory::get(
m_xContext )->getPackageManager(
"bundled");
982 OSL_ENSURE( xPackage.is(),
"TreeFileIterator::implGetNextBundledHelpPackage(): Invalid package" );
991 return rtl::isAsciiAlpha(c);
995 const css::uno::Reference< css::deployment::XPackage >& xPackage )
998 OUString aExtensionPath = xPackage->getURL();
1001 for(
const OUString& aEntry : aEntrySeq )
1003 if(
m_xSFA->isFolder( aEntry ) )
1005 sal_Int32 nLastSlash = aEntry.lastIndexOf(
'/' );
1006 if( nLastSlash != -1 )
1008 OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
1011 int nLen = aPureEntry.getLength();
1014 bool bIsLanguage = bStartCanBeLanguage &&
1017 rv.push_back( aPureEntry );
1036 if( !xHelpPackage.is() )
1047 if( !xHelpPackage.is() )
1057 if( !xHelpPackage.is() )
1065 OSL_FAIL(
"DataBaseIterator::nextTreeFile(): Invalid case IteratorState::EndReached" );
1078 std::scoped_lock aGuard(
m_aMutex );
1080 if( !xMacroExpander.is() || !xFac.is() )
1082 xFac = uri::UriReferenceFactory::create(
m_xContext );
1084 xMacroExpander = util::theMacroExpander::get(
m_xContext);
1087 OUString aRetURL =
aURL;
1091 uriRef = xFac->parse( aRetURL );
1098 aRetURL = sxUri->expand( xMacroExpander );
1109 for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
1111 aRetFile =
expandURL( xPackage->getURL() +
"/" + aLanguage +
"/help.tree" );
1114 if(
m_xSFA->exists( aRetFile ) )
1117 ::std::vector< OUString > av;
1120 if( pFound != av.end() )
1121 aLanguage = *pFound;
1126 if(
m_xSFA->exists( aRetFile ) )
1127 rnFileSize =
m_xSFA->getSize( aRetFile );
::std::vector< OUString >::const_iterator getFallback(const ::std::vector< OUString > &rList, const OUString &rReference)
OUString SubstituteVariable(const OUString &rVar) const
void replaceName(OUString &oustring) const
std::vector< OUString > vFileURL
std::vector< sal_uInt64 > vFileLen
OUString m_vReplacement[5]
friend class TVChildTarget
static css::uno::Reference< css::container::XHierarchicalNameAccess > getHierAccess(const css::uno::Reference< css::lang::XMultiServiceFactory > &rxProvider, const char *file)
static void subst(OUString &instpath)
virtual css::uno::Any SAL_CALL getByHierarchicalName(const OUString &aName) override
std::unique_ptr< TVDom > SearchAndInsert(std::unique_ptr< TVDom > p, TVDom *tvDom)
virtual ~TVChildTarget() override
static OUString getKey(const css::uno::Reference< css::container::XHierarchicalNameAccess > &xHierAccess, const char *key)
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
static css::uno::Reference< css::lang::XMultiServiceFactory > getConfiguration(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
static ConfigData init(const css::uno::Reference< css::uno::XComponentContext > &xContext)
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
virtual sal_Bool SAL_CALL hasByHierarchicalName(const OUString &aName) override
std::vector< rtl::Reference< TVRead > > Elements
static bool getBooleanKey(const css::uno::Reference< css::container::XHierarchicalNameAccess > &xHierAccess, const char *key)
std::vector< std::unique_ptr< TVDom > > children
void setTitle(const XML_Char *itle, int len)
void setTitle(const char *itle)
void setAnchor(const char *nchor)
void setApplication(const char *appl)
TVDom * getParent() const
OUString const & getTargetURL()
void newChild(std::unique_ptr< TVDom > p)
TVDom(TVDom *arent=nullptr)
void setId(const char *d)
TVRead(const ConfigData &configData, TVDom *tvDom)
virtual css::uno::Any SAL_CALL getByHierarchicalName(const OUString &aName) override
virtual ~TVRead() override
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
rtl::Reference< TVChildTarget > Children
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
friend class TVChildTarget
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
virtual sal_Bool SAL_CALL hasByHierarchicalName(const OUString &aName) override
TreeFileIterator(OUString aLanguage)
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aSharedPackagesSeq
OUString expandURL(const OUString &aURL)
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aBundledPackagesSeq
css::uno::Reference< css::uno::XComponentContext > m_xContext
bool m_bUserPackagesLoaded
OUString nextTreeFile(sal_Int32 &rnFileSize)
css::uno::Reference< css::deployment::XPackage > implGetNextSharedHelpPackage(css::uno::Reference< css::deployment::XPackage > &o_xParentPackageBundle)
bool m_bSharedPackagesLoaded
static css::uno::Reference< css::deployment::XPackage > implGetHelpPackageFromPackage(const css::uno::Reference< css::deployment::XPackage > &xPackage, css::uno::Reference< css::deployment::XPackage > &o_xParentPackageBundle)
css::uno::Reference< css::deployment::XPackage > implGetNextUserHelpPackage(css::uno::Reference< css::deployment::XPackage > &o_xParentPackageBundle)
void implGetLanguageVectorFromPackage(::std::vector< OUString > &rv, const css::uno::Reference< css::deployment::XPackage > &xPackage)
css::uno::Reference< css::deployment::XPackage > implGetNextBundledHelpPackage(css::uno::Reference< css::deployment::XPackage > &o_xParentPackageBundle)
bool m_bBundledPackagesLoaded
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aUserPackagesSeq
css::uno::Reference< css::ucb::XSimpleFileAccess3 > m_xSFA
OUString implGetTreeFileFromPackage(sal_Int32 &rnFileSize, const css::uno::Reference< css::deployment::XPackage > &xPackage)
static OUString getProductName()
#define SAL_WARN_IF(condition, area, stream)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
static void start_handler(void *userData, const XML_Char *name, const XML_Char **atts)
static bool isLetter(sal_Unicode c)
const char aHelpMediaType[]
static void data_handler(void *userData, const XML_Char *s, int len)
static void end_handler(void *userData, SAL_UNUSED_PARAMETER const XML_Char *)