xref: /trunk/main/svtools/source/config/helpopt.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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