xref: /aoo41x/main/svtools/source/config/helpopt.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include <svtools/helpopt.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <unotools/configitem.hxx>
34 #include <tools/debug.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include <vcl/help.hxx>
38 #include <osl/mutex.hxx>
39 #include <comphelper/stl_types.hxx>
40 
41 #include <rtl/logfile.hxx>
42 #include "itemholder2.hxx"
43 
44 using namespace utl;
45 using namespace rtl;
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star;
48 
49 static SvtHelpOptions_Impl* pOptions = NULL;
50 static sal_Int32           nRefCount = 0;
51 
52 #define EXTENDEDHELP		0
53 #define HELPTIPS			1
54 #define AGENT_ENABLED		2
55 #define AGENT_TIMEOUT		3
56 #define AGENT_RETRYLIMIT	4
57 #define LOCALE				5
58 #define SYSTEM				6
59 #define STYLESHEET          7
60 
61 class SvtHelpOptions_Impl : public utl::ConfigItem
62 {
63     IdList*         pList;
64 	sal_Int32		nHelpAgentTimeoutPeriod;
65 	sal_Int32		nHelpAgentRetryLimit;
66     sal_Bool        bExtendedHelp;
67     sal_Bool        bHelpTips;
68     sal_Bool        bHelpAgentEnabled;
69     sal_Bool        bWelcomeScreen;
70 	String			aLocale;
71 	String			aSystem;
72     String          sHelpStyleSheet;
73 
74 	DECLARE_STL_USTRINGACCESS_MAP( sal_Int32, MapString2Int );
75 	MapString2Int	aURLIgnoreCounters;
76 	::osl::Mutex	aIgnoreCounterSafety;
77 
78     Sequence< OUString > GetPropertyNames();
79 
80 public:
81                     SvtHelpOptions_Impl();
82 
83     virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
84     void            Load( const ::com::sun::star::uno::Sequence< ::rtl::OUString>& aPropertyNames);
85     virtual void    Commit();
86 
87     void            SetExtendedHelp( sal_Bool b )           { bExtendedHelp= b; SetModified(); }
88     sal_Bool        IsExtendedHelp() const                  { return bExtendedHelp; }
89     void            SetHelpTips( sal_Bool b )               { bHelpTips = b; SetModified(); }
90     sal_Bool        IsHelpTips() const                      { return bHelpTips; }
91 
92     void            SetHelpAgentEnabled( sal_Bool b	)		{ bHelpAgentEnabled = b; SetModified(); }
93     sal_Bool        IsHelpAgentEnabled() const				{ return bHelpAgentEnabled; }
94 	void			SetHelpAgentTimeoutPeriod( sal_Int32 _nSeconds )	{ nHelpAgentTimeoutPeriod = _nSeconds; SetModified(); }
95 	sal_Int32		GetHelpAgentTimeoutPeriod( ) const		{ return nHelpAgentTimeoutPeriod; }
96 	void			SetHelpAgentRetryLimit( sal_Int32 _nTrials )		{ nHelpAgentRetryLimit = _nTrials; SetModified(); }
97 	sal_Int32		GetHelpAgentRetryLimit( ) const			{ return nHelpAgentRetryLimit; }
98 
99 	sal_Int32		getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
100 	void			decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
101 	void			resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL );
102 	void			resetAgentIgnoreURLCounter();
103 
104     void            SetWelcomeScreen( sal_Bool b )          { bWelcomeScreen = b; SetModified(); }
105     sal_Bool        IsWelcomeScreen() const                 { return bWelcomeScreen; }
106     IdList*         GetPIStarterList()                      { return pList; }
107     void            AddToPIStarterList( sal_Int32 nId );
108     void            RemoveFromPIStarterList( sal_Int32 nId );
109 	String			GetLocale() const						{ return aLocale; }
110 	String			GetSystem() const						{ return aSystem; }
111 
112     const String&   GetHelpStyleSheet()const{return sHelpStyleSheet;}
113     void            SetHelpStyleSheet(const String& rStyleSheet){sHelpStyleSheet = rStyleSheet; SetModified();}
114 
115     static ::osl::Mutex & getInitMutex();
116 
117 protected:
118 	void	implLoadURLCounters();
119 	void	implSaveURLCounters();
120 	// to be called with aIgnoreCounterSafety locked
121 	void	implGetURLCounters( Sequence< ::rtl::OUString >& _rNodeNames, Sequence< Any >& _rURLs, Sequence< Any >& _rCounter );
122 };
123 
124 Sequence< OUString > SvtHelpOptions_Impl::GetPropertyNames()
125 {
126 	static const char* aPropNames[] =
127 	{
128         "ExtendedTip",
129         "Tip",
130 		"HelpAgent/Enabled",
131 		"HelpAgent/Timeout",
132 		"HelpAgent/RetryLimit",
133 		"Locale",
134 		"System",
135         "HelpStyleSheet",
136 //		"HowTo/Show"
137 	};
138 
139     const int nCount = sizeof( aPropNames ) / sizeof( const char* );
140 	Sequence< OUString > aNames( nCount );
141 	OUString* pNames = aNames.getArray();
142 	for ( int i = 0; i < nCount; i++ )
143 		pNames[i] = OUString::createFromAscii( aPropNames[i] );
144 
145 	return aNames;
146 }
147 
148 ::osl::Mutex & SvtHelpOptions_Impl::getInitMutex()
149 {
150     static ::osl::Mutex *pMutex = 0;
151 
152     if( ! pMutex )
153     {
154         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
155         if( ! pMutex )
156         {
157             static ::osl::Mutex mutex;
158             pMutex = &mutex;
159         }
160     }
161     return *pMutex;
162 }
163 
164 
165 // -----------------------------------------------------------------------
166 
167 SvtHelpOptions_Impl::SvtHelpOptions_Impl()
168     : ConfigItem( OUString::createFromAscii("Office.Common/Help") )
169     , pList( 0 )
170     , bExtendedHelp( sal_False )
171     , bHelpTips( sal_True )
172     , bHelpAgentEnabled( sal_False )
173     , bWelcomeScreen( sal_False )
174 {
175 	Sequence< OUString > aNames = GetPropertyNames();
176     Load( aNames );
177     EnableNotification( aNames );
178     implLoadURLCounters();
179 }
180 
181 // -----------------------------------------------------------------------
182 static int lcl_MapPropertyName( const ::rtl::OUString rCompare,
183                 const uno::Sequence< ::rtl::OUString>& aInternalPropertyNames)
184 {
185     for(int nProp = 0; nProp < aInternalPropertyNames.getLength(); ++nProp)
186     {
187         if( aInternalPropertyNames[nProp] == rCompare )
188             return nProp;
189     }
190     return -1;
191 }
192 
193 void  SvtHelpOptions_Impl::Load(const uno::Sequence< ::rtl::OUString>& rPropertyNames)
194 {
195     const uno::Sequence< ::rtl::OUString> aInternalPropertyNames( GetPropertyNames());
196     Sequence< Any > aValues = GetProperties( rPropertyNames );
197     const Any* pValues = aValues.getConstArray();
198     DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" );
199     if ( aValues.getLength() == rPropertyNames.getLength() )
200     {
201         for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
202         {
203             DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
204             if ( pValues[nProp].hasValue() )
205             {
206                 sal_Bool bTmp = sal_Bool();
207                 ::rtl::OUString aTmpStr;
208                 sal_Int32 nTmpInt = 0;
209                 if ( pValues[nProp] >>= bTmp )
210                 {
211                     switch ( lcl_MapPropertyName(rPropertyNames[nProp], aInternalPropertyNames) )
212                     {
213                         case EXTENDEDHELP :
214                             bExtendedHelp = bTmp;
215                             break;
216                         case HELPTIPS :
217                             bHelpTips = bTmp;
218                             break;
219                         case AGENT_ENABLED :
220                             bHelpAgentEnabled = bTmp;
221                             break;
222                         default:
223                             DBG_ERRORFILE( "Wrong Member!" );
224                             break;
225                     }
226                 }
227                 else if ( pValues[nProp] >>= aTmpStr )
228                 {
229                     switch ( nProp )
230                     {
231                         case LOCALE:
232                             aLocale = aTmpStr;
233                             break;
234 
235                         case SYSTEM:
236                             aSystem = aTmpStr;
237                             break;
238                         case STYLESHEET :
239                             sHelpStyleSheet = aTmpStr;
240                         break;
241                         default:
242                             DBG_ERRORFILE( "Wrong Member!" );
243                             break;
244                     }
245                 }
246                 else if ( pValues[nProp] >>= nTmpInt )
247                 {
248                     switch ( nProp )
249                     {
250                         case AGENT_TIMEOUT:
251                             nHelpAgentTimeoutPeriod = nTmpInt;
252                             break;
253 
254                         case AGENT_RETRYLIMIT:
255                             nHelpAgentRetryLimit = nTmpInt;
256                             break;
257 
258                         default:
259                             DBG_ERRORFILE( "Wrong Member!" );
260                             break;
261                     }
262                 }
263                 else
264                 {
265 		    DBG_ERRORFILE( "Wrong Type!" );
266 		}
267             }
268         }
269         if ( IsHelpTips() != Help::IsQuickHelpEnabled() )
270             IsHelpTips() ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
271         if ( IsExtendedHelp() != Help::IsBalloonHelpEnabled() )
272             IsExtendedHelp() ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
273     }
274 }
275 
276 // -----------------------------------------------------------------------
277 
278 void SvtHelpOptions_Impl::implGetURLCounters( Sequence< ::rtl::OUString >& _rNodeNames, Sequence< Any >& _rURLs, Sequence< Any >& _rCounters )
279 {
280 	// the ignore counters for the help agent URLs
281 	const ::rtl::OUString sIgnoreListNodePath = ::rtl::OUString::createFromAscii("HelpAgent/IgnoreList");
282 	const ::rtl::OUString sPathSeparator = ::rtl::OUString::createFromAscii("/");
283 	const ::rtl::OUString sURLLocalPath = ::rtl::OUString::createFromAscii("/Name");
284 	const ::rtl::OUString sCounterLocalPath = ::rtl::OUString::createFromAscii("/Counter");
285 
286 	// get the names of all the nodes containing ignore counters
287 	// collect the node names we have to ask
288 	// first get the node names of all children of HelpAgent/IgnoreList
289 	_rNodeNames = GetNodeNames(sIgnoreListNodePath);
290 	const ::rtl::OUString* pIgnoredURLsNodes = _rNodeNames.getConstArray();
291 	const ::rtl::OUString* pIgnoredURLsNodesEnd = pIgnoredURLsNodes + _rNodeNames.getLength();
292 
293 	// then assemble the two lists (of node paths) for the URLs and the counters
294 	Sequence< ::rtl::OUString > aIgnoredURLs(_rNodeNames.getLength());
295 	Sequence< ::rtl::OUString > aIgnoredURLsCounter(_rNodeNames.getLength());
296 	::rtl::OUString* pIgnoredURLs = aIgnoredURLs.getArray();
297 	::rtl::OUString* pIgnoredURLsCounter = aIgnoredURLsCounter.getArray();
298 	for (;pIgnoredURLsNodes != pIgnoredURLsNodesEnd; ++pIgnoredURLsNodes, ++pIgnoredURLs, ++pIgnoredURLsCounter)
299 	{
300 		::rtl::OUString sLocalURLAccess = sIgnoreListNodePath;
301 		sLocalURLAccess += sPathSeparator;
302 		sLocalURLAccess += *pIgnoredURLsNodes;
303 
304 		// the path to the URL of this specific entry
305 		*pIgnoredURLs = sLocalURLAccess;
306 		*pIgnoredURLs += sURLLocalPath;
307 
308 		// the path of the counter for that URL
309 		*pIgnoredURLsCounter = sLocalURLAccess;
310 		*pIgnoredURLsCounter += sCounterLocalPath;
311 	}
312 
313 	// now collect the values
314 	_rURLs = GetProperties(aIgnoredURLs);
315 	_rCounters = GetProperties(aIgnoredURLsCounter);
316 
317 	sal_Int32 nURLs = _rURLs.getLength();
318 	sal_Int32 nCounters = _rCounters.getLength();
319 	DBG_ASSERT(nURLs == nCounters, "SvtHelpOptions_Impl::implGetURLCounters: inconsistence while retrieving the visited URLs!");
320 
321 	// normalize in case something went wrong
322 	sal_Int32 nKnownURLs = nURLs < nCounters ? nURLs : nCounters;
323 	if (nURLs < nCounters)
324 	{
325 		_rCounters.realloc(nKnownURLs);
326 		_rNodeNames.realloc(nKnownURLs);
327 	}
328 	else if (nURLs > nCounters)
329 	{
330 		_rURLs.realloc(nKnownURLs);
331 		_rNodeNames.realloc(nKnownURLs);
332 	}
333 }
334 
335 // -----------------------------------------------------------------------
336 
337 void SvtHelpOptions_Impl::implSaveURLCounters()
338 {
339 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
340 
341 	const ::rtl::OUString sIgnoreListNodePath = ::rtl::OUString::createFromAscii("HelpAgent/IgnoreList");
342 	const ::rtl::OUString sPathSeparator = ::rtl::OUString::createFromAscii("/");
343 	const ::rtl::OUString sURLLocalPath = ::rtl::OUString::createFromAscii("/Name");
344 	const ::rtl::OUString sCounterLocalPath = ::rtl::OUString::createFromAscii("/Counter");
345 
346 	// get the current URL/counter pairs (as they're persistent at the moment)
347 	Sequence< ::rtl::OUString >	aNodeNames;
348 	Sequence< Any >				aURLs;
349 	Sequence< Any >				aCounters;
350 
351 	implGetURLCounters(aNodeNames, aURLs, aCounters);
352 	sal_Int32 nKnownURLs = aURLs.getLength();
353 
354 	const ::rtl::OUString* pNodeNames	= aNodeNames.getConstArray();
355 	const Any* pURLs					= aURLs.getConstArray();
356 	const Any* pCounters				= aCounters.getConstArray();
357 
358 	// check which of them must be deleted/modified
359 	Sequence< ::rtl::OUString >		aDeleteFromConfig(nKnownURLs);	// names of nodes to be deleted
360 	::rtl::OUString*				pDeleteFromConfig = aDeleteFromConfig.getArray();
361 	::std::set< ::rtl::OUString >	aAlreadyPresent;	// URLs currently persistent
362 
363 	// for modifying already existent nodes
364 	Sequence< ::rtl::OUString >	aNewCounterNodePaths(nKnownURLs);
365 	Sequence< Any >				aNewCounterValues(nKnownURLs);
366 	::rtl::OUString*			pNewCounterNodePaths = aNewCounterNodePaths.getArray();
367 	Any*						pNewCounterValues = aNewCounterValues.getArray();
368 
369 	// temporaries needed inside the loop
370 	::rtl::OUString sCurrentURL, sCurrentURLNodeName;
371 
372 	for (sal_Int32 i=0; i<nKnownURLs; ++i, ++pNodeNames, ++pURLs, ++pCounters)
373 	{
374 		if (!((*pURLs) >>= sCurrentURL))
375 			continue;
376 
377 		ConstMapString2IntIterator aThisURLNewCounter = aURLIgnoreCounters.find(sCurrentURL);
378 		if (aURLIgnoreCounters.end() == aThisURLNewCounter)
379 		{	// we do not know anything about this URL anymore.
380 			// -> have to removed it from the configuration later on
381 			*pDeleteFromConfig = *pNodeNames;
382 			++pDeleteFromConfig;
383 		}
384 		else
385 		{	// we know this URL
386 			sCurrentURLNodeName = sIgnoreListNodePath;
387 			sCurrentURLNodeName += sPathSeparator;
388 			sCurrentURLNodeName += *pNodeNames;
389 
390 			// -> remember this (so we don't need to add a new node for this URL later on)
391 			aAlreadyPresent.insert(sCurrentURL);
392 
393 			sal_Int32 nThisURLPersistentCounter = 0;
394 			(*pCounters) >>= nThisURLPersistentCounter;
395 
396 			if (aThisURLNewCounter->second != nThisURLPersistentCounter)
397 			{	// the counter changed
398 				// -> remember the path and the new counter for the adjustment below
399 				*pNewCounterNodePaths = sCurrentURLNodeName;
400 				*pNewCounterNodePaths += sCounterLocalPath;
401 				++pNewCounterNodePaths;
402 
403 				(*pNewCounterValues) <<= aThisURLNewCounter->second;
404 				++pNewCounterValues;
405 			}
406 		}
407 	}
408 
409 	// delete the nodes which are flagged so ...
410 	aDeleteFromConfig.realloc(pDeleteFromConfig - aDeleteFromConfig.getArray());
411 	if (0 != aDeleteFromConfig.getLength())
412 	{
413 		ClearNodeElements(sIgnoreListNodePath, aDeleteFromConfig);
414 	}
415 
416 	// modify the nodes which need to be
417 	aNewCounterNodePaths.realloc(pNewCounterNodePaths - aNewCounterNodePaths.getArray());
418 	aNewCounterValues.realloc(pNewCounterValues - aNewCounterValues.getArray());
419 	if (0 != aNewCounterNodePaths.getLength())
420 	{
421 		PutProperties(aNewCounterNodePaths, aNewCounterValues);
422 	}
423 
424 	// and for the new ones ...
425 	::rtl::OUString sNewNodeName;
426 	Sequence< ::rtl::OUString > aNewCounterDataNodeNames(2);
427 	Sequence< Any >				aNewCounterDataValues(2);
428 	const ::rtl::OUString sNodeNameBase = ::rtl::OUString::createFromAscii("URL");
429 	for (	ConstMapString2IntIterator aCollectNew = aURLIgnoreCounters.begin();
430 			aCollectNew != aURLIgnoreCounters.end();
431 			++aCollectNew
432 		)
433 	{
434 		if (aAlreadyPresent.end() == aAlreadyPresent.find(aCollectNew->first))
435 		{	// this URL is not persistent, yet
436 			// -> add a new node
437 			sNewNodeName = sNodeNameBase;
438 			if (!getUniqueSetElementName(sIgnoreListNodePath, sNewNodeName))
439 			{
440 				DBG_ERRORFILE( "SvtHelpOptions_Impl::implSaveURLCounters: could not get a free name!" );
441 				continue;
442 			}
443 			AddNode(sIgnoreListNodePath, sNewNodeName);
444 
445 			// and set the URL/counter pair
446 			aNewCounterDataNodeNames[0] = sIgnoreListNodePath;
447 			aNewCounterDataNodeNames[0] += sPathSeparator;
448 			aNewCounterDataNodeNames[0] += sNewNodeName;
449 			aNewCounterDataNodeNames[0] += sURLLocalPath;
450 			aNewCounterDataValues[0]	<<= aCollectNew->first;
451 
452 			aNewCounterDataNodeNames[1] = sIgnoreListNodePath;
453 			aNewCounterDataNodeNames[1] += sPathSeparator;
454 			aNewCounterDataNodeNames[1] += sNewNodeName;
455 			aNewCounterDataNodeNames[1] += sCounterLocalPath;
456 			aNewCounterDataValues[1]	<<= aCollectNew->second;
457 
458 			PutProperties(aNewCounterDataNodeNames, aNewCounterDataValues);
459 		}
460 	}
461 }
462 
463 // -----------------------------------------------------------------------
464 
465 void SvtHelpOptions_Impl::implLoadURLCounters()
466 {
467 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
468 
469 	Sequence< ::rtl::OUString >	aNodeNames;
470 	Sequence< Any >				aURLs;
471 	Sequence< Any >				aCounters;
472 
473 	implGetURLCounters(aNodeNames, aURLs, aCounters);
474 	sal_Int32 nKnownURLs = aURLs.getLength();
475 
476 	const Any* pURLs = aURLs.getConstArray();
477 	const Any* pCounters = aCounters.getConstArray();
478 
479 	::rtl::OUString sCurrentURL;
480 	sal_Int32 nCurrentCounter;
481 	for (sal_Int32 i=0; i<nKnownURLs; ++i, ++pURLs, ++pCounters)
482 	{
483 		(*pURLs) >>= sCurrentURL;
484 		nCurrentCounter = 0;
485 		(*pCounters) >>= nCurrentCounter;
486 		aURLIgnoreCounters[sCurrentURL] = nCurrentCounter;
487 	}
488 }
489 
490 // -----------------------------------------------------------------------
491 
492 void SvtHelpOptions_Impl::Commit()
493 {
494 	Sequence< OUString > aNames = GetPropertyNames();
495 	Sequence< Any > aValues( aNames.getLength() );
496 	Any* pValues = aValues.getArray();
497 	for ( int nProp = 0; nProp < aNames.getLength(); nProp++ )
498 	{
499         switch ( nProp )
500         {
501             case EXTENDEDHELP :
502                 pValues[nProp] <<= bExtendedHelp;
503                 break;
504 
505             case HELPTIPS :
506                 pValues[nProp] <<= bHelpTips;
507                 break;
508 
509             case AGENT_ENABLED :
510                 pValues[nProp] <<= bHelpAgentEnabled;
511                 break;
512 
513 			case AGENT_TIMEOUT:
514                 pValues[nProp] <<= nHelpAgentTimeoutPeriod;
515                 break;
516 
517 			case AGENT_RETRYLIMIT:
518                 pValues[nProp] <<= nHelpAgentRetryLimit;
519                 break;
520 
521 			case LOCALE:
522                 pValues[nProp] <<= ::rtl::OUString(aLocale);
523                 break;
524 
525 			case SYSTEM:
526                 pValues[nProp] <<= ::rtl::OUString(aSystem);
527                 break;
528             case STYLESHEET :
529                 pValues[nProp] <<= ::rtl::OUString(sHelpStyleSheet);
530             break;
531 
532         }
533 	}
534 
535 	PutProperties( aNames, aValues );
536 
537 	implSaveURLCounters();
538 }
539 
540 // -----------------------------------------------------------------------
541 
542 void SvtHelpOptions_Impl::Notify( const Sequence<rtl::OUString>& aPropertyNames )
543 {
544     Load( aPropertyNames );
545 }
546 
547 SvtHelpOptions::SvtHelpOptions()
548 {
549     // Global access, must be guarded (multithreading)
550     ::osl::MutexGuard aGuard( SvtHelpOptions_Impl::getInitMutex() );
551     ++nRefCount;
552     if ( !pOptions )
553     {
554         RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtHelpOptions_Impl::ctor()");
555         pOptions = new SvtHelpOptions_Impl;
556 
557         ItemHolder2::holdConfigItem(E_HELPOPTIONS);
558     }
559     pImp = pOptions;
560 }
561 
562 // -----------------------------------------------------------------------
563 
564 sal_Int32 SvtHelpOptions_Impl::getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
565 {
566 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
567 	ConstMapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
568 	if (aURLIgnoreCounters.end() == aMapPos)
569 		return GetHelpAgentRetryLimit();
570 	return aMapPos->second;
571 }
572 
573 // -----------------------------------------------------------------------
574 
575 void SvtHelpOptions_Impl::decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
576 {
577 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
578 	MapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
579 	if (aURLIgnoreCounters.end() == aMapPos)
580 	{	// nothing known about this URL 'til now
581 		sal_Int32 nLimit = GetHelpAgentRetryLimit();
582 		sal_Int32 nIgnoreAgain = nLimit > 0 ? nLimit - 1 : 0;
583 		aURLIgnoreCounters[_rURL] = nIgnoreAgain;
584 	}
585 	else
586 	{
587 		sal_Int32& rCounter = aMapPos->second;
588 		if (rCounter)
589 			--rCounter;
590 	}
591 	SetModified();
592 }
593 
594 // -----------------------------------------------------------------------
595 
596 void SvtHelpOptions_Impl::resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
597 {
598 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
599 	MapString2IntIterator aMapPos = aURLIgnoreCounters.find(_rURL);
600 	if (aURLIgnoreCounters.end() != aMapPos)
601 	{
602 		aURLIgnoreCounters.erase(aMapPos);
603 		SetModified();
604 	}
605 }
606 
607 // -----------------------------------------------------------------------
608 
609 void SvtHelpOptions_Impl::resetAgentIgnoreURLCounter()
610 {
611 	::osl::MutexGuard aGuard(aIgnoreCounterSafety);
612 	aURLIgnoreCounters.clear();
613 	SetModified();
614 }
615 
616 // -----------------------------------------------------------------------
617 
618 SvtHelpOptions::~SvtHelpOptions()
619 {
620     // Global access, must be guarded (multithreading)
621     ::osl::MutexGuard aGuard( SvtHelpOptions_Impl::getInitMutex() );
622     if ( !--nRefCount )
623 	{
624 		if ( pOptions->IsModified() )
625 			pOptions->Commit();
626         DELETEZ( pOptions );
627 	}
628 }
629 
630 void SvtHelpOptions::SetExtendedHelp( sal_Bool b )
631 {
632     pImp->SetExtendedHelp( b );
633 }
634 
635 sal_Bool SvtHelpOptions::IsExtendedHelp() const
636 {
637     return pImp->IsExtendedHelp();
638 }
639 
640 void SvtHelpOptions::SetHelpTips( sal_Bool b )
641 {
642     pImp->SetHelpTips( b );
643 }
644 
645 sal_Bool SvtHelpOptions::IsHelpTips() const
646 {
647     return pImp->IsHelpTips();
648 }
649 
650 // -----------------------------------------------------------------------
651 
652 void SvtHelpOptions::SetHelpAgentRetryLimit( sal_Int32 _nTrials )
653 {
654     pImp->SetHelpAgentRetryLimit( _nTrials );
655 }
656 
657 // -----------------------------------------------------------------------
658 
659 sal_Int32 SvtHelpOptions::GetHelpAgentRetryLimit( ) const
660 {
661     return pImp->GetHelpAgentRetryLimit( );
662 }
663 
664 // -----------------------------------------------------------------------
665 
666 void SvtHelpOptions::SetHelpAgentTimeoutPeriod( sal_Int32 _nSeconds )
667 {
668     pImp->SetHelpAgentTimeoutPeriod( _nSeconds );
669 }
670 
671 // -----------------------------------------------------------------------
672 
673 sal_Int32 SvtHelpOptions::GetHelpAgentTimeoutPeriod( ) const
674 {
675     return pImp->GetHelpAgentTimeoutPeriod( );
676 }
677 
678 // -----------------------------------------------------------------------
679 
680 void SvtHelpOptions::SetHelpAgentAutoStartMode( sal_Bool b )
681 {
682     pImp->SetHelpAgentEnabled( b );
683 }
684 
685 // -----------------------------------------------------------------------
686 
687 sal_Bool SvtHelpOptions::IsHelpAgentAutoStartMode() const
688 {
689     return pImp->IsHelpAgentEnabled();
690 }
691 
692 // -----------------------------------------------------------------------
693 
694 sal_Int32 SvtHelpOptions::getAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
695 {
696 	return pImp->getAgentIgnoreURLCounter( _rURL );
697 }
698 
699 // -----------------------------------------------------------------------
700 
701 void SvtHelpOptions::decAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
702 {
703 	pImp->decAgentIgnoreURLCounter( _rURL );
704 }
705 
706 // -----------------------------------------------------------------------
707 
708 void SvtHelpOptions::resetAgentIgnoreURLCounter( const ::rtl::OUString& _rURL )
709 {
710 	pImp->resetAgentIgnoreURLCounter( _rURL );
711 }
712 
713 // -----------------------------------------------------------------------
714 
715 void SvtHelpOptions::resetAgentIgnoreURLCounter()
716 {
717 	pImp->resetAgentIgnoreURLCounter();
718 }
719 
720 // -----------------------------------------------------------------------
721 
722 void SvtHelpOptions::SetWelcomeScreen( sal_Bool b )
723 {
724     pImp->SetWelcomeScreen( b );
725 }
726 
727 sal_Bool SvtHelpOptions::IsWelcomeScreen() const
728 {
729     return pImp->IsWelcomeScreen();
730 }
731 
732 IdList* SvtHelpOptions::GetPIStarterList()
733 {
734     return pImp->GetPIStarterList();
735 }
736 
737 void SvtHelpOptions::AddToPIStarterList( sal_Int32 )
738 {
739 }
740 
741 void SvtHelpOptions::RemoveFromPIStarterList( sal_Int32 )
742 {
743 }
744 
745 String SvtHelpOptions::GetLocale() const
746 {
747     return pImp->GetLocale();
748 }
749 
750 String SvtHelpOptions::GetSystem() const
751 {
752     return pImp->GetSystem();
753 }
754 
755 const String&   SvtHelpOptions::GetHelpStyleSheet()const
756 {
757     return pImp->GetHelpStyleSheet();
758 }
759 
760 void  SvtHelpOptions::SetHelpStyleSheet(const String& rStyleSheet)
761 {
762     pImp->SetHelpStyleSheet(rStyleSheet);
763 }
764 
765