xref: /trunk/main/unotools/source/config/historyoptions.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_unotools.hxx"
30 #ifndef GCC
31 #endif
32 
33 //_________________________________________________________________________________________________________________
34 // includes
35 //_________________________________________________________________________________________________________________
36 
37 #include <unotools/historyoptions.hxx>
38 #include <unotools/historyoptions_const.hxx>
39 #include <unotools/configmgr.hxx>
40 #include <unotools/configitem.hxx>
41 #include <tools/debug.hxx>
42 #include <com/sun/star/uno/Any.hxx>
43 #include <com/sun/star/uno/Sequence.hxx>
44 
45 #ifndef __SGI_STL_DEQUE
46 #include <deque>
47 #endif
48 
49 #ifndef __SGI_STL_ALGORITHM
50 #include <algorithm>
51 #endif
52 
53 #include <rtl/logfile.hxx>
54 #include "itemholder1.hxx"
55 
56 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
57 #include <com/sun/star/beans/XPropertySet.hpp>
58 #endif
59 
60 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
61 #include <com/sun/star/container/XNameAccess.hpp>
62 #endif
63 
64 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
65 #include <com/sun/star/container/XNameContainer.hpp>
66 #endif
67 
68 #ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
69 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
70 #endif
71 
72 #ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
73 #include <comphelper/configurationhelper.hxx>
74 #endif
75 
76 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
77 #include <unotools/processfactory.hxx>
78 #endif
79 
80 #ifndef _SVT_LOGHELPER_HXX
81 #include <unotools/loghelper.hxx>
82 #endif
83 
84 //_________________________________________________________________________________________________________________
85 // namespaces
86 //_________________________________________________________________________________________________________________
87 
88 using namespace ::std     ;
89 using namespace ::utl     ;
90 using namespace ::rtl     ;
91 using namespace ::osl     ;
92 using namespace ::com::sun::star::uno ;
93 using namespace ::com::sun::star::beans ;
94 
95 namespace css = ::com::sun::star;
96 
97 //_________________________________________________________________________________________________________________
98 // const
99 //_________________________________________________________________________________________________________________
100 
101 namespace {
102     static const ::sal_Int32 s_nOffsetURL               = 0;
103     static const ::sal_Int32 s_nOffsetFilter            = 1;
104     static const ::sal_Int32 s_nOffsetTitle             = 2;
105     static const ::sal_Int32 s_nOffsetPassword          = 3;
106 }
107 
108 //_________________________________________________________________________________________________________________
109 // private declarations!
110 //_________________________________________________________________________________________________________________
111 
112 struct IMPL_THistoryItem
113 {
114     IMPL_THistoryItem()
115     {
116     }
117 
118     IMPL_THistoryItem( const OUString& sNewURL   ,
119         const OUString& sNewFilter  ,
120         const OUString& sNewTitle  ,
121         const OUString& sNewPassword )
122     {
123         sURL  = sNewURL  ;
124         sFilter  = sNewFilter ;
125         sTitle  = sNewTitle  ;
126         sPassword = sNewPassword ;
127     }
128 
129     sal_Bool operator==( const OUString& sSearchedURL )
130     {
131         return( sURL == sSearchedURL );
132     }
133 
134     OUString sURL  ;
135     OUString sFilter  ;
136     OUString sTitle  ;
137     OUString sPassword ;
138 };
139 
140 //*****************************************************************************************************************
141 //  class SvtHistoryOptions_Impl
142 //  redesigned
143 //*****************************************************************************************************************
144 class SvtHistoryOptions_Impl
145 {
146 public:
147     SvtHistoryOptions_Impl();
148     ~SvtHistoryOptions_Impl();
149 
150     sal_uInt32 GetSize( EHistoryType eHistory );
151     void SetSize( EHistoryType eHistory, sal_uInt32 nSize );
152     void Clear( EHistoryType eHistory );
153     Sequence< Sequence< PropertyValue > > GetList( EHistoryType eHistory );
154     void                                  AppendItem(       EHistoryType eHistory ,
155         const OUString&    sURL     ,
156         const OUString&    sFilter  ,
157         const OUString&    sTitle   ,
158         const OUString&    sPassword );
159 
160 private:
161     void impl_truncateList (EHistoryType eHistory, sal_uInt32 nSize);
162 
163 private:
164     css::uno::Reference< css::container::XNameAccess > m_xCfg;
165     css::uno::Reference< css::container::XNameAccess > m_xCommonXCU;
166 };
167 
168 //*****************************************************************************************************************
169 //  constructor
170 //*****************************************************************************************************************
171 SvtHistoryOptions_Impl::SvtHistoryOptions_Impl()
172 {
173     try
174     {
175         m_xCfg = Reference< css::container::XNameAccess > (
176             ::comphelper::ConfigurationHelper::openConfig(
177             utl::getProcessServiceFactory(),
178             s_sHistories,
179             ::comphelper::ConfigurationHelper::E_STANDARD),
180             css::uno::UNO_QUERY );
181 
182         m_xCommonXCU = Reference< css::container::XNameAccess > (
183             ::comphelper::ConfigurationHelper::openConfig(
184             utl::getProcessServiceFactory(),
185             s_sCommonHistory,
186             ::comphelper::ConfigurationHelper::E_STANDARD),
187             css::uno::UNO_QUERY );
188     }
189     catch(const css::uno::Exception& ex)
190     {
191         m_xCfg.clear();
192         m_xCommonXCU.clear();
193 
194         LogHelper::logIt(ex);
195     }
196 }
197 
198 //*****************************************************************************************************************
199 //  destructor
200 //*****************************************************************************************************************
201 SvtHistoryOptions_Impl::~SvtHistoryOptions_Impl()
202 {
203 }
204 
205 //*****************************************************************************************************************
206 //  public method
207 //  Attention: We return the max. size of our internal lists - That is the capacity not the size!
208 //*****************************************************************************************************************
209 sal_uInt32 SvtHistoryOptions_Impl::GetSize( EHistoryType eHistory )
210 {
211     sal_uInt32                                       nSize = 0  ;
212     css::uno::Reference< css::beans::XPropertySet >  xListAccess(m_xCommonXCU, css::uno::UNO_QUERY);
213 
214     try
215     {
216         switch( eHistory )
217         {
218         case ePICKLIST:
219             xListAccess->getPropertyValue(s_sPickListSize) >>= nSize;
220             break;
221 
222         case eHISTORY:
223             xListAccess->getPropertyValue(s_sURLHistorySize) >>= nSize;
224             break;
225 
226         case eHELPBOOKMARKS:
227             xListAccess->getPropertyValue(s_sHelpBookmarksSize) >>= nSize;
228             break;
229 
230         default:
231             break;
232         }
233     }
234     catch(const css::uno::Exception& ex)
235     {
236         LogHelper::logIt(ex);
237     }
238 
239     return nSize;
240 }
241 
242 //*****************************************************************************************************************
243 //  public method
244 //  Attention: We return the max. size of our internal lists - That is the capacity not the size!
245 //*****************************************************************************************************************
246 void SvtHistoryOptions_Impl::SetSize( EHistoryType eHistory, sal_uInt32 nSize )
247 {
248     css::uno::Reference< css::beans::XPropertySet > xListAccess(m_xCommonXCU, css::uno::UNO_QUERY);
249     if (! xListAccess.is ())
250         return;
251 
252     try
253     {
254         switch( eHistory )
255         {
256         case ePICKLIST:
257             if(nSize!=GetSize(ePICKLIST))
258             {
259                 xListAccess->setPropertyValue(s_sPickListSize, css::uno::makeAny(nSize));
260                 ::comphelper::ConfigurationHelper::flush(m_xCommonXCU);
261             }
262             break;
263 
264         case eHISTORY:
265             if(nSize!=GetSize(eHISTORY))
266             {
267                 xListAccess->setPropertyValue(s_sURLHistorySize, css::uno::makeAny(nSize));
268                 ::comphelper::ConfigurationHelper::flush(m_xCommonXCU);
269             }
270             break;
271 
272         case eHELPBOOKMARKS:
273             if(nSize!=GetSize(eHELPBOOKMARKS))
274             {
275                 xListAccess->setPropertyValue(s_sHelpBookmarksSize, css::uno::makeAny(nSize));
276                 ::comphelper::ConfigurationHelper::flush(m_xCommonXCU);
277             }
278             break;
279 
280         default:
281             break;
282         }
283 
284         impl_truncateList (eHistory, nSize);
285     }
286     catch(const css::uno::Exception& ex)
287     {
288         LogHelper::logIt(ex);
289     }
290 }
291 
292 //*****************************************************************************************************************
293 void SvtHistoryOptions_Impl::impl_truncateList ( EHistoryType eHistory, sal_uInt32 nSize )
294 {
295     css::uno::Reference< css::container::XNameAccess >    xList;
296     css::uno::Reference< css::container::XNameContainer > xItemList;
297     css::uno::Reference< css::container::XNameContainer > xOrderList;
298     css::uno::Reference< css::beans::XPropertySet >       xSet;
299 
300     try
301     {
302         switch( eHistory )
303         {
304         case ePICKLIST:
305             m_xCfg->getByName(s_sPickList) >>= xList;
306             break;
307 
308         case eHISTORY:
309             m_xCfg->getByName(s_sURLHistory) >>= xList;
310             break;
311 
312         case eHELPBOOKMARKS:
313             m_xCfg->getByName(s_sHelpBookmarks) >>= xList;
314             break;
315 
316         default:
317             break;
318         }
319 
320         // If too much items in current list ...
321         // truncate the oldest items BEFORE you set the new one.
322         if ( ! xList.is())
323             return;
324 
325         xList->getByName(s_sOrderList) >>= xOrderList;
326         xList->getByName(s_sItemList)  >>= xItemList;
327 
328         const sal_uInt32 nLength = xOrderList->getElementNames().getLength();
329         if (nSize < nLength)
330         {
331             for (sal_uInt32 i=nLength-1; i>=nSize; --i)
332             {
333                 ::rtl::OUString sTmp;
334                 const ::rtl::OUString sRemove = ::rtl::OUString::valueOf((sal_Int32)i);
335                 xOrderList->getByName(sRemove) >>= xSet;
336                 xSet->getPropertyValue(s_sHistoryItemRef) >>= sTmp;
337                 xItemList->removeByName(sTmp);
338                 xOrderList->removeByName(sRemove);
339             }
340 
341             ::comphelper::ConfigurationHelper::flush(m_xCfg);
342         }
343     }
344     catch(const css::uno::Exception& ex)
345     {
346         LogHelper::logIt(ex);
347     }
348 }
349 
350 //*****************************************************************************************************************
351 //  public method
352 //  Clear specified history list
353 //*****************************************************************************************************************
354 void SvtHistoryOptions_Impl::Clear( EHistoryType eHistory )
355 {
356     css::uno::Reference< css::container::XNameAccess >    xListAccess;
357     css::uno::Reference< css::container::XNameContainer > xNode;
358     Sequence< ::rtl::OUString >                           lOrders;
359 
360     try
361     {
362         switch( eHistory )
363         {
364         case ePICKLIST:
365             {
366                 m_xCfg->getByName(s_sPickList) >>= xListAccess;
367                 break;
368             }
369 
370         case eHISTORY:
371             {
372                 m_xCfg->getByName(s_sURLHistory) >>= xListAccess;
373                 break;
374             }
375 
376         case eHELPBOOKMARKS:
377             {
378                 m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess;
379                 break;
380             }
381 
382         default:
383             break;
384         }
385 
386         if (xListAccess.is())
387         {
388             // clear ItemList
389             xListAccess->getByName(s_sItemList)  >>= xNode  ;
390             lOrders = xNode->getElementNames();
391             const sal_Int32 nLength = lOrders.getLength();
392             for(sal_Int32 i=0; i<nLength; ++i)
393                 xNode->removeByName(lOrders[i]);
394 
395             // clear OrderList
396             xListAccess->getByName(s_sOrderList) >>= xNode ;
397             lOrders = xNode->getElementNames();
398             for(sal_Int32 j=0; j<nLength; ++j)
399                 xNode->removeByName(lOrders[j]);
400 
401             ::comphelper::ConfigurationHelper::flush(m_xCfg);
402         }
403     }
404     catch(const css::uno::Exception& ex)
405     {
406         LogHelper::logIt(ex);
407     }
408 }
409 
410 //*****************************************************************************************************************
411 //  public method
412 //  get a sequence list from the items
413 //*****************************************************************************************************************
414 Sequence< Sequence< PropertyValue > > SvtHistoryOptions_Impl::GetList( EHistoryType eHistory )
415 {
416     impl_truncateList (eHistory, GetSize (eHistory));
417 
418     Sequence< Sequence< PropertyValue > > seqReturn; // Set default return value.
419     Sequence< PropertyValue >             seqProperties( 4 );
420     Sequence< ::rtl::OUString >           lOrders;
421 
422     css::uno::Reference< css::container::XNameAccess > xListAccess;
423     css::uno::Reference< css::container::XNameAccess > xItemList;
424     css::uno::Reference< css::container::XNameAccess > xOrderList;
425     css::uno::Reference< css::beans::XPropertySet >    xSet;
426 
427     seqProperties[s_nOffsetURL       ].Name = HISTORY_PROPERTYNAME_URL;
428     seqProperties[s_nOffsetFilter    ].Name = HISTORY_PROPERTYNAME_FILTER;
429     seqProperties[s_nOffsetTitle     ].Name = HISTORY_PROPERTYNAME_TITLE;
430     seqProperties[s_nOffsetPassword  ].Name = HISTORY_PROPERTYNAME_PASSWORD;
431 
432     try
433     {
434         switch( eHistory )
435         {
436         case ePICKLIST:
437             {
438                 m_xCfg->getByName(s_sPickList) >>= xListAccess;
439                 break;
440             }
441 
442         case eHISTORY:
443             {
444                 m_xCfg->getByName(s_sURLHistory) >>= xListAccess;
445                 break;
446             }
447 
448         case eHELPBOOKMARKS:
449             {
450                 m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess;
451                 break;
452             }
453 
454         default:
455             break;
456         }
457 
458         if (xListAccess.is())
459         {
460             xListAccess->getByName(s_sItemList)  >>= xItemList;
461             xListAccess->getByName(s_sOrderList) >>= xOrderList;
462 
463             const sal_Int32 nLength = xOrderList->getElementNames().getLength();
464             Sequence< Sequence< PropertyValue > > aRet(nLength);
465 
466             for(sal_Int32 nItem=0; nItem<nLength; ++nItem)
467             {
468                 ::rtl::OUString sUrl;
469                 xOrderList->getByName(::rtl::OUString::valueOf(nItem)) >>= xSet;
470                 xSet->getPropertyValue(s_sHistoryItemRef) >>= sUrl;
471 
472                 xItemList->getByName(sUrl) >>= xSet;
473                 seqProperties[s_nOffsetURL  ].Value <<= sUrl;
474                 xSet->getPropertyValue(s_sFilter)   >>= seqProperties[s_nOffsetFilter   ].Value;
475                 xSet->getPropertyValue(s_sTitle)    >>= seqProperties[s_nOffsetTitle    ].Value;
476                 xSet->getPropertyValue(s_sPassword) >>= seqProperties[s_nOffsetPassword ].Value;
477                 aRet[nItem] = seqProperties;
478             }
479             seqReturn = aRet;
480         }
481     }
482     catch(const css::uno::Exception& ex)
483     {
484         LogHelper::logIt(ex);
485     }
486 
487     return seqReturn;
488 }
489 
490 //*****************************************************************************************************************
491 //  public method
492 //  implements a deque in XML
493 //*****************************************************************************************************************
494 void SvtHistoryOptions_Impl::AppendItem(       EHistoryType eHistory ,
495                                         const OUString& sURL        ,
496                                         const OUString& sFilter     ,
497                                         const OUString& sTitle      ,
498                                         const OUString& sPassword   )
499 {
500     impl_truncateList (eHistory, GetSize (eHistory));
501 
502     css::uno::Reference< css::container::XNameAccess > xListAccess;
503     sal_Int32             nMaxSize = 0;
504 
505     switch(eHistory)
506     {
507     case ePICKLIST:
508         {
509             m_xCfg->getByName(s_sPickList) >>= xListAccess;
510             nMaxSize = GetSize(ePICKLIST);
511         }
512         break;
513     case eHISTORY:
514         {
515             m_xCfg->getByName(s_sURLHistory) >>= xListAccess;
516             nMaxSize = GetSize(eHISTORY);
517         }
518         break;
519     case eHELPBOOKMARKS:
520         {
521             m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess;
522             nMaxSize = GetSize(eHELPBOOKMARKS);
523         }
524         break;
525     default:
526         break;
527     }
528 
529     if (nMaxSize==0)
530         return;
531 
532     css::uno::Reference< css::container::XNameContainer > xItemList;
533     css::uno::Reference< css::container::XNameContainer > xOrderList;
534     css::uno::Reference< css::beans::XPropertySet >       xSet;
535 
536     try
537     {
538         xListAccess->getByName(s_sItemList)  >>= xItemList;
539         xListAccess->getByName(s_sOrderList) >>= xOrderList;
540         sal_Int32 nLength = xOrderList->getElementNames().getLength();
541 
542         // The item to be appended is already existing!
543         if (xItemList->hasByName(sURL))
544         {
545             for (sal_Int32 i=0; i<nLength; ++i)
546             {
547                 ::rtl::OUString sTmp;
548                 xOrderList->getByName(::rtl::OUString::valueOf(i)) >>= xSet;
549                 xSet->getPropertyValue(s_sHistoryItemRef) >>= sTmp;
550 
551                 if(sURL == sTmp)
552                 {
553                     ::rtl::OUString sFind;
554                     xOrderList->getByName( ::rtl::OUString::valueOf(i) ) >>= xSet;
555                     xSet->getPropertyValue(s_sHistoryItemRef) >>= sFind;
556                     for (sal_Int32 j=i-1; j>=0; --j)
557                     {
558                         css::uno::Reference< css::beans::XPropertySet > xPrevSet;
559                         css::uno::Reference< css::beans::XPropertySet > xNextSet;
560                         xOrderList->getByName( ::rtl::OUString::valueOf(j+1) )   >>= xPrevSet;
561                         xOrderList->getByName( ::rtl::OUString::valueOf(j) )     >>= xNextSet;
562 
563                         ::rtl::OUString sTemp;
564                         xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp;
565                         xPrevSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sTemp));
566                     }
567                     xOrderList->getByName( ::rtl::OUString::valueOf((sal_Int32)0) ) >>= xSet;
568                     xSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sFind));
569 
570                     ::comphelper::ConfigurationHelper::flush(m_xCfg);
571                     break;
572                 }
573             }
574         }
575 
576         // The item to be appended is not existing!
577         else
578         {
579             css::uno::Reference< css::lang::XSingleServiceFactory > xFac;
580             css::uno::Reference< css::uno::XInterface >             xInst;
581             css::uno::Reference< css::beans::XPropertySet > xPrevSet;
582             css::uno::Reference< css::beans::XPropertySet > xNextSet;
583 
584             // Append new item to OrderList.
585             if ( nLength == nMaxSize )
586             {
587                 ::rtl::OUString sRemove;
588                 xOrderList->getByName(::rtl::OUString::valueOf(nLength-1)) >>= xSet;
589                 xSet->getPropertyValue(s_sHistoryItemRef) >>= sRemove;
590                 xItemList->removeByName(sRemove);
591             }
592             if ( nLength != nMaxSize )
593             {
594                 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xOrderList, css::uno::UNO_QUERY);
595                 xInst = xFac->createInstance();
596                 ::rtl::OUString sPush = ::rtl::OUString::valueOf(nLength++);
597                 xOrderList->insertByName(sPush, css::uno::makeAny(xInst));
598             }
599             for (sal_Int32 j=nLength-1; j>0; --j)
600             {
601                 xOrderList->getByName( ::rtl::OUString::valueOf(j) )   >>= xPrevSet;
602                 xOrderList->getByName( ::rtl::OUString::valueOf(j-1) ) >>= xNextSet;
603                 ::rtl::OUString sTemp;
604                 xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp;
605                 xPrevSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sTemp));
606             }
607             xOrderList->getByName( ::rtl::OUString::valueOf((sal_Int32)0) ) >>= xSet;
608             xSet->setPropertyValue(s_sHistoryItemRef, css::uno::makeAny(sURL));
609 
610             // Append the item to ItemList.
611             xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xItemList, css::uno::UNO_QUERY);
612             xInst = xFac->createInstance();
613             xItemList->insertByName(sURL, css::uno::makeAny(xInst));
614             xSet = css::uno::Reference< css::beans::XPropertySet >(xInst, css::uno::UNO_QUERY);
615             xSet->setPropertyValue(s_sFilter, css::uno::makeAny(sFilter));
616             xSet->setPropertyValue(s_sTitle, css::uno::makeAny(sTitle));
617             xSet->setPropertyValue(s_sPassword, css::uno::makeAny(sPassword));
618 
619             ::comphelper::ConfigurationHelper::flush(m_xCfg);
620         }
621     }
622     catch(const css::uno::Exception& ex)
623     {
624         LogHelper::logIt(ex);
625     }
626 }
627 
628 //*****************************************************************************************************************
629 // initialize static member
630 // DON'T DO IT IN YOUR HEADER!
631 // see definition for further informations
632 //*****************************************************************************************************************
633 SvtHistoryOptions_Impl*  SvtHistoryOptions::m_pDataContainer = NULL ;
634 sal_Int32     SvtHistoryOptions::m_nRefCount  = 0  ;
635 
636 //*****************************************************************************************************************
637 // constructor
638 //*****************************************************************************************************************
639 SvtHistoryOptions::SvtHistoryOptions()
640 {
641     // Global access, must be guarded (multithreading!).
642     MutexGuard aGuard( GetOwnStaticMutex() );
643     // Increase ouer refcount ...
644     ++m_nRefCount;
645     // ... and initialize ouer data container only if it not already exist!
646     if( m_pDataContainer == NULL )
647     {
648         RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtHistoryOptions_Impl::ctor()");
649         m_pDataContainer = new SvtHistoryOptions_Impl;
650 
651         ItemHolder1::holdConfigItem(E_HISTORYOPTIONS);
652     }
653 }
654 
655 //*****************************************************************************************************************
656 // destructor
657 //*****************************************************************************************************************
658 SvtHistoryOptions::~SvtHistoryOptions()
659 {
660     // Global access, must be guarded (multithreading!)
661     MutexGuard aGuard( GetOwnStaticMutex() );
662     // Decrease ouer refcount.
663     --m_nRefCount;
664     // If last instance was deleted ...
665     // we must destroy ouer static data container!
666     if( m_nRefCount <= 0 )
667     {
668         delete m_pDataContainer;
669         m_pDataContainer = NULL;
670     }
671 }
672 
673 //*****************************************************************************************************************
674 // public method
675 //*****************************************************************************************************************
676 sal_uInt32 SvtHistoryOptions::GetSize( EHistoryType eHistory ) const
677 {
678     MutexGuard aGuard( GetOwnStaticMutex() );
679     return m_pDataContainer->GetSize( eHistory );
680 }
681 
682 //*****************************************************************************************************************
683 // public method
684 //*****************************************************************************************************************
685 void SvtHistoryOptions::SetSize( EHistoryType eHistory, sal_uInt32 nSize )
686 {
687     MutexGuard aGuard( GetOwnStaticMutex() );
688     m_pDataContainer->SetSize( eHistory, nSize );
689 }
690 
691 //*****************************************************************************************************************
692 // public method
693 //*****************************************************************************************************************
694 void SvtHistoryOptions::Clear( EHistoryType eHistory )
695 {
696     MutexGuard aGuard( GetOwnStaticMutex() );
697     m_pDataContainer->Clear( eHistory );
698 }
699 
700 //*****************************************************************************************************************
701 // public method
702 //*****************************************************************************************************************
703 Sequence< Sequence< PropertyValue > > SvtHistoryOptions::GetList( EHistoryType eHistory ) const
704 {
705     MutexGuard aGuard( GetOwnStaticMutex() );
706     return m_pDataContainer->GetList( eHistory );
707 }
708 
709 //*****************************************************************************************************************
710 // public method
711 //*****************************************************************************************************************
712 void SvtHistoryOptions::AppendItem(   EHistoryType eHistory ,
713                                    const OUString&  sURL  ,
714                                    const OUString&  sFilter  ,
715                                    const OUString&  sTitle  ,
716                                    const OUString&  sPassword )
717 {
718     MutexGuard aGuard( GetOwnStaticMutex() );
719     m_pDataContainer->AppendItem( eHistory, sURL, sFilter, sTitle, sPassword );
720 }
721 
722 //*****************************************************************************************************************
723 // private method
724 //*****************************************************************************************************************
725 Mutex& SvtHistoryOptions::GetOwnStaticMutex()
726 {
727     // Initialize static mutex only for one time!
728     static Mutex* pMutex = NULL;
729     // If these method first called (Mutex not already exist!) ...
730     if( pMutex == NULL )
731     {
732         // ... we must create a new one. Protect follow code with the global mutex -
733         // It must be - we create a static variable!
734         MutexGuard aGuard( Mutex::getGlobalMutex() );
735         // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
736         if( pMutex == NULL )
737         {
738             // Create the new mutex and set it for return on static variable.
739             static Mutex aMutex;
740             pMutex = &aMutex;
741         }
742     }
743     // Return new created or already existing mutex object.
744     return *pMutex;
745 }
746