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