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 <unotools/viewoptions.hxx>
21 #include <com/sun/star/uno/Any.hxx>
22 
23 #include <com/sun/star/beans/NamedValue.hpp>
24 #include <com/sun/star/container/XNameContainer.hpp>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <osl/diagnose.h>
28 #include <sal/log.hxx>
29 #include <unotools/configmgr.hxx>
30 #include <comphelper/configurationhelper.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <tools/diagnose_ex.h>
33 
34 #include "itemholder1.hxx"
35 
36 #define PACKAGE_VIEWS                           "org.openoffice.Office.Views"
37 
38 #define LIST_DIALOGS                            "Dialogs"
39 #define LIST_TABDIALOGS                         "TabDialogs"
40 #define LIST_TABPAGES                           "TabPages"
41 #define LIST_WINDOWS                            "Windows"
42 
43 #define PROPERTY_WINDOWSTATE                    "WindowState"
44 #define PROPERTY_PAGEID                         "PageID"
45 #define PROPERTY_VISIBLE                        "Visible"
46 #define PROPERTY_USERDATA                       "UserData"
47 
48 //#define DEBUG_VIEWOPTIONS
49 
50 #ifdef DEBUG_VIEWOPTIONS
51     #define _LOG_COUNTER_( _SVIEW_, _NREAD_, _NWRITE_ )                                                                                     \
52                 {                                                                                                                           \
53                     FILE* pFile = fopen( "viewdbg.txt", "a" );                                                                              \
54                     fprintf( pFile, "%s[%d, %d]\n", OUStringToOString(_SVIEW_, RTL_TEXTENCODING_UTF8).getStr(), _NREAD_, _NWRITE_ ); \
55                     fclose( pFile );                                                                                                        \
56                 }
57 #endif // DEBUG_VIEWOPTIONS
58 
59 //  initialization!
60 
61 SvtViewOptionsBase_Impl*     SvtViewOptions::m_pDataContainer_Dialogs    =   nullptr    ;
62 sal_Int32                    SvtViewOptions::m_nRefCount_Dialogs         =   0       ;
63 SvtViewOptionsBase_Impl*     SvtViewOptions::m_pDataContainer_TabDialogs =   nullptr    ;
64 sal_Int32                    SvtViewOptions::m_nRefCount_TabDialogs      =   0       ;
65 SvtViewOptionsBase_Impl*     SvtViewOptions::m_pDataContainer_TabPages   =   nullptr    ;
66 sal_Int32                    SvtViewOptions::m_nRefCount_TabPages        =   0       ;
67 SvtViewOptionsBase_Impl*     SvtViewOptions::m_pDataContainer_Windows    =   nullptr    ;
68 sal_Int32                    SvtViewOptions::m_nRefCount_Windows         =   0       ;
69 
70 /*-************************************************************************************************************
71     @descr          Implement base data container for view options elements.
72                     Every item support ALL possible configuration information.
73                     But not every superclass should use them! Because some view types don't
74                     have it really.
75 
76     @attention      We implement a write-through cache! We use it for reading - but write all changes directly to
77                     configuration. (changes are made on internal cache too!). So it's easier to distinguish
78                     between added/changed/removed elements without any complex mask or bool flag information.
79                     Caches from configuration and our own one are synchronized every time - if we do so.
80 *//*-*************************************************************************************************************/
81 class SvtViewOptionsBase_Impl final
82 {
83 
84     public:
85         enum State { STATE_NONE, STATE_FALSE, STATE_TRUE };
86 
87         explicit SvtViewOptionsBase_Impl(const OUString& rList);
88                  ~SvtViewOptionsBase_Impl (                                                                );
89         bool                                            Exists                  ( const OUString&                                sName    );
90         void                                            Delete                  ( const OUString&                                sName    );
91         OUString                                        GetWindowState          ( const OUString&                                sName    );
92         void                                            SetWindowState          ( const OUString&                                sName    ,
93                                                                                   const OUString&                                sState   );
94         css::uno::Sequence< css::beans::NamedValue >    GetUserData             ( const OUString&                                sName    );
95         void                                            SetUserData             ( const OUString&                                sName    ,
96                                                                                   const css::uno::Sequence< css::beans::NamedValue >&   lData    );
97         OString                                         GetPageID               ( const OUString&                                sName    );
98         void                                            SetPageID               ( const OUString&                                sName    ,
99                                                                                   const OString&                                 sID      );
100         State                                           GetVisible              ( const OUString&                                sName    );
101         void                                            SetVisible              ( const OUString&                                sName    ,
102                                                                                         bool                                        bVisible );
103         css::uno::Any                                   GetUserItem             ( const OUString&                                sName    ,
104                                                                                   const OUString&                                sItem    );
105         void                                            SetUserItem             ( const OUString&                                sName    ,
106                                                                                   const OUString&                                sItem    ,
107                                                                                   const css::uno::Any&                                  aValue   );
108 
109     private:
110         css::uno::Reference< css::uno::XInterface > impl_getSetNode( const OUString& sNode           ,
111                                                                            bool         bCreateIfMissing);
112 
113     private:
114         OUString                                           m_sListName;
115         css::uno::Reference< css::container::XNameAccess > m_xRoot;
116         css::uno::Reference< css::container::XNameAccess > m_xSet;
117 
118         #ifdef DEBUG_VIEWOPTIONS
119         sal_Int32           m_nReadCount;
120         sal_Int32           m_nWriteCount;
121         #endif
122 };
123 
124 /*-************************************************************************************************************
125     @descr  Implement the base data container.
126 *//*-*************************************************************************************************************/
127 
128 /*-************************************************************************************************************
129     @short          ctor
130     @descr          We use it to open right configuration file and let configuration objects fill her caches.
131                     Then we read all existing entries from right list and cached it inside our object too.
132                     Normally we should enable notifications for changes on these values too ... but these feature
133                     isn't full implemented in the moment.
134 
135     @seealso        baseclass ::utl::ConfigItem
136     @seealso        method Notify()
137 *//*-*************************************************************************************************************/
SvtViewOptionsBase_Impl(const OUString & sList)138 SvtViewOptionsBase_Impl::SvtViewOptionsBase_Impl( const OUString& sList )
139         :   m_sListName  ( sList )    // we must know, which view type we must support
140         #ifdef DEBUG_VIEWOPTIONS
141         ,   m_nReadCount ( 0     )
142         ,   m_nWriteCount( 0     )
143         #endif
144 {
145     if (utl::ConfigManager::IsFuzzing())
146         return;
147 
148     try
149     {
150         m_xRoot.set( ::comphelper::ConfigurationHelper::openConfig(
151                             ::comphelper::getProcessComponentContext(),
152                             PACKAGE_VIEWS,
153                             ::comphelper::EConfigurationModes::Standard),
154                      css::uno::UNO_QUERY);
155         if (m_xRoot.is())
156             m_xRoot->getByName(sList) >>= m_xSet;
157     }
158     catch(const css::uno::Exception&)
159         {
160             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
161             m_xRoot.clear();
162             m_xSet.clear();
163         }
164 }
165 
166 /*-************************************************************************************************************
167     @short          dtor
168     @descr          clean up something
169 
170     @attention      We implement a write through cache! So we mustn't do it really. All changes was written to cfg directly.
171                     Commit isn't necessary then.
172 
173     @seealso        baseclass ::utl::ConfigItem
174     @seealso        method IsModified()
175     @seealso        method SetModified()
176     @seealso        method Commit()
177 *//*-*************************************************************************************************************/
~SvtViewOptionsBase_Impl()178 SvtViewOptionsBase_Impl::~SvtViewOptionsBase_Impl()
179 {
180     // don't flush configuration changes here to m_xRoot.
181     // That must be done inside every SetXXX() method already !
182     // Here it's too late - DisposedExceptions from used configuration access can occur otherwise.
183 
184     m_xRoot.clear();
185     m_xSet.clear();
186 
187     #ifdef DEBUG_VIEWOPTIONS
188     _LOG_COUNTER_( m_sListName, m_nReadCount, m_nWriteCount )
189     #endif // DEBUG_VIEWOPTIONS
190 }
191 
192 /*-************************************************************************************************************
193     @short          checks for already existing entries
194     @descr          If user don't know, if an entry already exist - he can get this information by calling this method.
195 
196     @seealso        member m_aList
197 
198     @param          "sName", name of entry to check exist state
199     @return         true , if item exist
200                     false, otherwise
201 *//*-*************************************************************************************************************/
Exists(const OUString & sName)202 bool SvtViewOptionsBase_Impl::Exists( const OUString& sName )
203 {
204     bool bExists = false;
205 
206     try
207     {
208         if (m_xSet.is())
209             bExists = m_xSet->hasByName(sName);
210     }
211     catch(const css::uno::Exception&)
212         {
213             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
214             bExists = false;
215         }
216 
217     return bExists;
218 }
219 
220 /*-************************************************************************************************************
221     @short          delete entry
222     @descr          Use it to delete set entry by given name.
223 
224     @seealso        member m_aList
225 
226     @param          "sName", name of entry to delete it
227 *//*-*************************************************************************************************************/
Delete(const OUString & sName)228 void SvtViewOptionsBase_Impl::Delete( const OUString& sName )
229 {
230     #ifdef DEBUG_VIEWOPTIONS
231     ++m_nWriteCount;
232     #endif
233 
234     try
235     {
236         css::uno::Reference< css::container::XNameContainer > xSet(m_xSet, css::uno::UNO_QUERY_THROW);
237         xSet->removeByName(sName);
238         ::comphelper::ConfigurationHelper::flush(m_xRoot);
239     }
240     catch(const css::container::NoSuchElementException&)
241         { }
242     catch(const css::uno::Exception&)
243         {
244             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
245         }
246 }
247 
248 /*-************************************************************************************************************
249     @short          read/write access to cache view items and her properties
250     @descr          Follow methods support read/write access to all cache view items.
251 
252     @seealso        member m_sList
253 *//*-*************************************************************************************************************/
GetWindowState(const OUString & sName)254 OUString SvtViewOptionsBase_Impl::GetWindowState( const OUString& sName )
255 {
256     #ifdef DEBUG_VIEWOPTIONS
257     ++m_nReadCount;
258     #endif
259 
260     OUString sWindowState;
261     try
262     {
263         css::uno::Reference< css::beans::XPropertySet > xNode(
264             impl_getSetNode(sName, false),
265             css::uno::UNO_QUERY);
266         if (xNode.is())
267             xNode->getPropertyValue(PROPERTY_WINDOWSTATE) >>= sWindowState;
268     }
269     catch(const css::uno::Exception&)
270         {
271             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
272             sWindowState.clear();
273         }
274 
275     return sWindowState;
276 }
277 
SetWindowState(const OUString & sName,const OUString & sState)278 void SvtViewOptionsBase_Impl::SetWindowState( const OUString& sName  ,
279                                               const OUString& sState )
280 {
281     #ifdef DEBUG_VIEWOPTIONS
282     ++m_nWriteCount;
283     #endif
284 
285     try
286     {
287         css::uno::Reference< css::beans::XPropertySet > xNode(
288             impl_getSetNode(sName, true),
289             css::uno::UNO_QUERY_THROW);
290         xNode->setPropertyValue(PROPERTY_WINDOWSTATE, css::uno::makeAny(sState));
291         ::comphelper::ConfigurationHelper::flush(m_xRoot);
292     }
293     catch(const css::uno::Exception&)
294         {
295             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
296         }
297 }
298 
GetUserData(const OUString & sName)299 css::uno::Sequence< css::beans::NamedValue > SvtViewOptionsBase_Impl::GetUserData( const OUString& sName )
300 {
301     #ifdef DEBUG_VIEWOPTIONS
302     ++m_nReadCount;
303     #endif
304 
305     try
306     {
307         css::uno::Reference< css::container::XNameAccess > xNode(
308             impl_getSetNode(sName, false),
309             css::uno::UNO_QUERY); // no _THROW ! because we don't create missing items here. So we have to live with zero references .-)
310         css::uno::Reference< css::container::XNameAccess > xUserData;
311         if (xNode.is())
312             xNode->getByName(PROPERTY_USERDATA) >>= xUserData;
313         if (xUserData.is())
314         {
315             const css::uno::Sequence<OUString> lNames = xUserData->getElementNames();
316             sal_Int32 c = lNames.getLength();
317             css::uno::Sequence< css::beans::NamedValue > lUserData(c);
318 
319             std::transform(lNames.begin(), lNames.end(), lUserData.begin(),
320                 [&xUserData](const OUString& rName) -> css::beans::NamedValue {
321                     return { rName, xUserData->getByName(rName) }; });
322 
323             return lUserData;
324         }
325     }
326     catch(const css::uno::Exception&)
327         {
328             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
329         }
330 
331     return css::uno::Sequence< css::beans::NamedValue >();
332 }
333 
SetUserData(const OUString & sName,const css::uno::Sequence<css::beans::NamedValue> & lData)334 void SvtViewOptionsBase_Impl::SetUserData( const OUString&                              sName  ,
335                                            const css::uno::Sequence< css::beans::NamedValue >& lData  )
336 {
337     #ifdef DEBUG_VIEWOPTIONS
338     ++m_nWriteCount;
339     #endif
340 
341     try
342     {
343         css::uno::Reference< css::container::XNameAccess > xNode(
344             impl_getSetNode(sName, true),
345             css::uno::UNO_QUERY_THROW);
346         css::uno::Reference< css::container::XNameContainer > xUserData;
347         xNode->getByName(PROPERTY_USERDATA) >>= xUserData;
348         if (xUserData.is())
349         {
350             for (const css::beans::NamedValue& rData : lData)
351             {
352                 if (xUserData->hasByName(rData.Name))
353                     xUserData->replaceByName(rData.Name, rData.Value);
354                 else
355                     xUserData->insertByName(rData.Name, rData.Value);
356             }
357         }
358         ::comphelper::ConfigurationHelper::flush(m_xRoot);
359     }
360     catch(const css::uno::Exception&)
361         {
362             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
363         }
364 }
365 
GetUserItem(const OUString & sName,const OUString & sItem)366 css::uno::Any SvtViewOptionsBase_Impl::GetUserItem( const OUString& sName ,
367                                                     const OUString& sItem )
368 {
369     #ifdef DEBUG_VIEWOPTIONS
370     ++m_nReadCount;
371     #endif
372 
373     css::uno::Any aItem;
374     try
375     {
376         css::uno::Reference< css::container::XNameAccess > xNode(
377             impl_getSetNode(sName, false),
378             css::uno::UNO_QUERY);
379         css::uno::Reference< css::container::XNameAccess > xUserData;
380         if (xNode.is())
381             xNode->getByName(PROPERTY_USERDATA) >>= xUserData;
382         if (xUserData.is())
383             aItem = xUserData->getByName(sItem);
384     }
385     catch(const css::container::NoSuchElementException&)
386         { aItem.clear(); }
387     catch(const css::uno::Exception&)
388         {
389             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
390             aItem.clear();
391         }
392 
393     return aItem;
394 }
395 
SetUserItem(const OUString & sName,const OUString & sItem,const css::uno::Any & aValue)396 void SvtViewOptionsBase_Impl::SetUserItem( const OUString& sName  ,
397                                            const OUString& sItem  ,
398                                            const css::uno::Any&   aValue )
399 {
400     #ifdef DEBUG_VIEWOPTIONS
401     ++m_nWriteCount;
402     #endif
403 
404     try
405     {
406         css::uno::Reference< css::container::XNameAccess > xNode(
407             impl_getSetNode(sName, true),
408             css::uno::UNO_QUERY_THROW);
409         css::uno::Reference< css::container::XNameContainer > xUserData;
410         xNode->getByName(PROPERTY_USERDATA) >>= xUserData;
411         if (xUserData.is())
412         {
413             if (xUserData->hasByName(sItem))
414                 xUserData->replaceByName(sItem, aValue);
415             else
416                 xUserData->insertByName(sItem, aValue);
417         }
418         ::comphelper::ConfigurationHelper::flush(m_xRoot);
419     }
420     catch(const css::uno::Exception&)
421         {
422             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
423         }
424 }
425 
GetPageID(const OUString & sName)426 OString SvtViewOptionsBase_Impl::GetPageID( const OUString& sName )
427 {
428     #ifdef DEBUG_VIEWOPTIONS
429     ++m_nReadCount;
430     #endif
431 
432     OUString sID;
433     try
434     {
435         css::uno::Reference< css::beans::XPropertySet > xNode(
436             impl_getSetNode(sName, false),
437             css::uno::UNO_QUERY);
438         if (xNode.is())
439             xNode->getPropertyValue(PROPERTY_PAGEID) >>= sID;
440     }
441     catch(const css::uno::Exception&)
442         {
443             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
444         }
445 
446     return sID.toUtf8();
447 }
448 
SetPageID(const OUString & sName,const OString & sID)449 void SvtViewOptionsBase_Impl::SetPageID( const OUString& sName ,
450                                          const OString& sID )
451 {
452     #ifdef DEBUG_VIEWOPTIONS
453     ++m_nWriteCount;
454     #endif
455 
456     try
457     {
458         css::uno::Reference< css::beans::XPropertySet > xNode(
459             impl_getSetNode(sName, true),
460             css::uno::UNO_QUERY_THROW);
461         xNode->setPropertyValue(PROPERTY_PAGEID, css::uno::makeAny(OUString::fromUtf8(sID)));
462         ::comphelper::ConfigurationHelper::flush(m_xRoot);
463     }
464     catch(const css::uno::Exception&)
465         {
466             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
467         }
468 }
469 
GetVisible(const OUString & sName)470 SvtViewOptionsBase_Impl::State SvtViewOptionsBase_Impl::GetVisible( const OUString& sName )
471 {
472     #ifdef DEBUG_VIEWOPTIONS
473     ++m_nReadCount;
474     #endif
475 
476     State eState = STATE_NONE;
477     try
478     {
479         css::uno::Reference< css::beans::XPropertySet > xNode(
480             impl_getSetNode(sName, false),
481             css::uno::UNO_QUERY);
482         if (xNode.is())
483         {
484             bool bVisible = false;
485             if (xNode->getPropertyValue(PROPERTY_VISIBLE) >>= bVisible)
486             {
487                 eState = bVisible ? STATE_TRUE : STATE_FALSE;
488             }
489         }
490     }
491     catch(const css::uno::Exception&)
492         {
493             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
494         }
495 
496     return eState;
497 }
498 
SetVisible(const OUString & sName,bool bVisible)499 void SvtViewOptionsBase_Impl::SetVisible( const OUString& sName    ,
500                                                 bool         bVisible )
501 {
502     #ifdef DEBUG_VIEWOPTIONS
503     ++m_nWriteCount;
504     #endif
505 
506     try
507     {
508         css::uno::Reference< css::beans::XPropertySet > xNode(
509             impl_getSetNode(sName, true),
510             css::uno::UNO_QUERY_THROW);
511         xNode->setPropertyValue(PROPERTY_VISIBLE, css::uno::makeAny(bVisible));
512         ::comphelper::ConfigurationHelper::flush(m_xRoot);
513     }
514     catch(const css::uno::Exception&)
515         {
516             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
517         }
518 }
519 
520 /*-************************************************************************************************************
521     @short          create new set node with default values on disk
522     @descr          To create a new UserData item - the super node of these property must already exist!
523                     You can call this method to create these new entry with default values and change UserData then.
524 
525     @seealso        method impl_writeDirectProp()
526 
527     @param          "sNode", name of new entry
528 *//*-*************************************************************************************************************/
impl_getSetNode(const OUString & sNode,bool bCreateIfMissing)529 css::uno::Reference< css::uno::XInterface > SvtViewOptionsBase_Impl::impl_getSetNode( const OUString& sNode           ,
530                                                                                             bool         bCreateIfMissing)
531 {
532     css::uno::Reference< css::uno::XInterface > xNode;
533 
534     try
535     {
536         if (bCreateIfMissing)
537             xNode = ::comphelper::ConfigurationHelper::makeSureSetNodeExists(m_xRoot, m_sListName, sNode);
538         else
539         {
540             if (m_xSet.is() && m_xSet->hasByName(sNode) )
541                 m_xSet->getByName(sNode) >>= xNode;
542         }
543     }
544     catch(const css::container::NoSuchElementException&)
545         { xNode.clear(); }
546     catch(const css::uno::Exception&)
547         {
548             TOOLS_WARN_EXCEPTION("unotools", "Unexpected exception");
549             xNode.clear();
550         }
551 
552     return xNode;
553 }
554 
555 //  constructor
556 
SvtViewOptions(EViewType eType,const OUString & sViewName)557 SvtViewOptions::SvtViewOptions(       EViewType        eType     ,
558                                 const OUString& sViewName )
559     :   m_eViewType ( eType     )
560     ,   m_sViewName ( sViewName )
561 {
562     // Global access, must be guarded (multithreading!)
563     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
564 
565     // Search for right dat container for this view type and initialize right data container or set right ref count!
566     switch( eType )
567     {
568         case EViewType::Dialog: {
569                                     // Increase ref count for dialog data container first.
570                                     ++m_nRefCount_Dialogs;
571                                     // If these instance the first user of the dialog data container - create these impl static container!
572                                     if( m_nRefCount_Dialogs == 1 )
573                                     {
574                                         //m_pDataContainer_Dialogs = new SvtViewDialogOptions_Impl( LIST_DIALOGS );
575                                         m_pDataContainer_Dialogs = new SvtViewOptionsBase_Impl( LIST_DIALOGS );
576                                         ItemHolder1::holdConfigItem(EItem::ViewOptionsDialog);
577                                     }
578                                 }
579                                 break;
580         case EViewType::TabDialog: {
581                                     // Increase ref count for tab-dialog data container first.
582                                     ++m_nRefCount_TabDialogs;
583                                     // If these instance the first user of the tab-dialog data container - create these impl static container!
584                                     if( m_nRefCount_TabDialogs == 1 )
585                                     {
586                                         m_pDataContainer_TabDialogs = new SvtViewOptionsBase_Impl( LIST_TABDIALOGS );
587                                         ItemHolder1::holdConfigItem(EItem::ViewOptionsTabDialog);
588                                     }
589                                 }
590                                 break;
591         case EViewType::TabPage:{
592                                     // Increase ref count for tab-page data container first.
593                                     ++m_nRefCount_TabPages;
594                                     // If these instance the first user of the tab-page data container - create these impl static container!
595                                     if( m_nRefCount_TabPages == 1 )
596                                     {
597                                         m_pDataContainer_TabPages = new SvtViewOptionsBase_Impl( LIST_TABPAGES );
598                                         ItemHolder1::holdConfigItem(EItem::ViewOptionsTabPage);
599                                     }
600                                 }
601                                 break;
602         case EViewType::Window: {
603                                     // Increase ref count for window data container first.
604                                     ++m_nRefCount_Windows;
605                                     // If these instance the first user of the window data container - create these impl static container!
606                                     if( m_nRefCount_Windows == 1 )
607                                     {
608                                         m_pDataContainer_Windows = new SvtViewOptionsBase_Impl( LIST_WINDOWS );
609                                         ItemHolder1::holdConfigItem(EItem::ViewOptionsWindow);
610                                     }
611                                 }
612                                 break;
613         default             :   OSL_FAIL( "SvtViewOptions::SvtViewOptions()\nThese view type is unknown! All following calls at these instance will do nothing!" );
614     }
615 }
616 
617 //  destructor
618 
~SvtViewOptions()619 SvtViewOptions::~SvtViewOptions()
620 {
621     // Global access, must be guarded (multithreading!)
622     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
623 
624     // Search for right dat container for this view type and deinitialize right data container or set right ref count!
625     switch( m_eViewType )
626     {
627         case EViewType::Dialog: {
628                                     // Decrease ref count for dialog data container first.
629                                     --m_nRefCount_Dialogs;
630                                     // If these instance the last user of the dialog data container - delete these impl static container!
631                                     if( m_nRefCount_Dialogs == 0 )
632                                     {
633                                         delete m_pDataContainer_Dialogs;
634                                         m_pDataContainer_Dialogs = nullptr;
635                                     }
636                                 }
637                                 break;
638         case EViewType::TabDialog: {
639                                     // Decrease ref count for tab-dialog data container first.
640                                     --m_nRefCount_TabDialogs;
641                                     // If these instance the last user of the tab-dialog data container - delete these impl static container!
642                                     if( m_nRefCount_TabDialogs == 0 )
643                                     {
644                                         delete m_pDataContainer_TabDialogs;
645                                         m_pDataContainer_TabDialogs = nullptr;
646                                     }
647                                 }
648                                 break;
649         case EViewType::TabPage:{
650                                     // Decrease ref count for tab-page data container first.
651                                     --m_nRefCount_TabPages;
652                                     // If these instance the last user of the tab-page data container - delete these impl static container!
653                                     if( m_nRefCount_TabPages == 0 )
654                                     {
655                                         delete m_pDataContainer_TabPages;
656                                         m_pDataContainer_TabPages = nullptr;
657                                     }
658                                 }
659                                 break;
660         case EViewType::Window: {
661                                     // Decrease ref count for window data container first.
662                                     --m_nRefCount_Windows;
663                                     // If these instance the last user of the window data container - delete these impl static container!
664                                     if( m_nRefCount_Windows == 0 )
665                                     {
666                                         delete m_pDataContainer_Windows;
667                                         m_pDataContainer_Windows = nullptr;
668                                     }
669                                 }
670                                 break;
671     }
672 }
673 
674 //  public method
675 
Exists() const676 bool SvtViewOptions::Exists() const
677 {
678     // Ready for multithreading
679     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
680 
681     bool bExists = false;
682     switch( m_eViewType )
683     {
684         case EViewType::Dialog: {
685                                     bExists = m_pDataContainer_Dialogs->Exists( m_sViewName );
686                                 }
687                                 break;
688         case EViewType::TabDialog: {
689                                     bExists = m_pDataContainer_TabDialogs->Exists( m_sViewName );
690                                 }
691                                 break;
692         case EViewType::TabPage:{
693                                     bExists = m_pDataContainer_TabPages->Exists( m_sViewName );
694                                 }
695                                 break;
696         case EViewType::Window: {
697                                     bExists = m_pDataContainer_Windows->Exists( m_sViewName );
698                                 }
699                                 break;
700     }
701     return bExists;
702 }
703 
704 //  public method
705 
Delete()706 void SvtViewOptions::Delete()
707 {
708     // Ready for multithreading
709     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
710 
711     switch( m_eViewType )
712     {
713         case EViewType::Dialog    :  m_pDataContainer_Dialogs->Delete( m_sViewName );
714                             break;
715         case EViewType::TabDialog :  m_pDataContainer_TabDialogs->Delete( m_sViewName );
716                             break;
717         case EViewType::TabPage   :  m_pDataContainer_TabPages->Delete( m_sViewName );
718                             break;
719         case EViewType::Window    :  m_pDataContainer_Windows->Delete( m_sViewName );
720                             break;
721     }
722 }
723 
724 //  public method
725 
GetWindowState() const726 OUString SvtViewOptions::GetWindowState() const
727 {
728     // Ready for multithreading
729     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
730 
731     OUString sState;
732     switch( m_eViewType )
733     {
734         case EViewType::Dialog: {
735                                     sState = m_pDataContainer_Dialogs->GetWindowState( m_sViewName );
736                                 }
737                                 break;
738         case EViewType::TabDialog:{
739                                     sState = m_pDataContainer_TabDialogs->GetWindowState( m_sViewName );
740                                 }
741                                 break;
742         case EViewType::TabPage:{
743                                     sState = m_pDataContainer_TabPages->GetWindowState( m_sViewName );
744                                 }
745                                 break;
746         case EViewType::Window: {
747                                     sState = m_pDataContainer_Windows->GetWindowState( m_sViewName );
748                                 }
749                                 break;
750     }
751     return sState;
752 }
753 
754 //  public method
755 
SetWindowState(const OUString & sState)756 void SvtViewOptions::SetWindowState( const OUString& sState )
757 {
758     // Ready for multithreading
759     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
760 
761     switch( m_eViewType )
762     {
763         case EViewType::Dialog: {
764                                     m_pDataContainer_Dialogs->SetWindowState( m_sViewName, sState );
765                                 }
766                                 break;
767         case EViewType::TabDialog: {
768                                     m_pDataContainer_TabDialogs->SetWindowState( m_sViewName, sState );
769                                 }
770                                 break;
771         case EViewType::TabPage:{
772                                     m_pDataContainer_TabPages->SetWindowState( m_sViewName, sState );
773                                 }
774                                 break;
775         case EViewType::Window: {
776                                     m_pDataContainer_Windows->SetWindowState( m_sViewName, sState );
777                                 }
778                                 break;
779     }
780 }
781 
782 //  public method
783 
GetPageID() const784 OString SvtViewOptions::GetPageID() const
785 {
786     // Ready for multithreading
787     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
788 
789     // Safe impossible cases.
790     // These call isn't allowed for dialogs, tab-pages or windows!
791     OSL_ENSURE( !(m_eViewType==EViewType::Dialog||m_eViewType==EViewType::TabPage||m_eViewType==EViewType::Window), "SvtViewOptions::GetPageID()\nCall not allowed for Dialogs, TabPages or Windows! I do nothing!" );
792 
793     OString sID;
794     if( m_eViewType == EViewType::TabDialog )
795         sID = m_pDataContainer_TabDialogs->GetPageID( m_sViewName );
796     return sID;
797 }
798 
799 //  public method
800 
SetPageID(const OString & rID)801 void SvtViewOptions::SetPageID(const OString& rID)
802 {
803     // Ready for multithreading
804     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
805 
806     // Safe impossible cases.
807     // These call isn't allowed for dialogs, tab-pages or windows!
808     OSL_ENSURE( !(m_eViewType==EViewType::Dialog||m_eViewType==EViewType::TabPage||m_eViewType==EViewType::Window), "SvtViewOptions::SetPageID()\nCall not allowed for Dialogs, TabPages or Windows! I do nothing!" );
809 
810     if( m_eViewType == EViewType::TabDialog )
811         m_pDataContainer_TabDialogs->SetPageID(m_sViewName, rID);
812 }
813 
814 //  public method
815 
IsVisible() const816 bool SvtViewOptions::IsVisible() const
817 {
818     // Ready for multithreading
819     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
820 
821     // Safe impossible cases.
822     // These call isn't allowed for dialogs, tab-dialogs or tab-pages!
823     OSL_ENSURE( !(m_eViewType==EViewType::Dialog||m_eViewType==EViewType::TabDialog||m_eViewType==EViewType::TabPage), "SvtViewOptions::IsVisible()\nCall not allowed for Dialogs, TabDialogs or TabPages! I do nothing!" );
824 
825     bool bState = false;
826     if( m_eViewType == EViewType::Window )
827         bState = m_pDataContainer_Windows->GetVisible( m_sViewName ) == SvtViewOptionsBase_Impl::STATE_TRUE;
828 
829     return bState;
830 }
831 
832 //  public method
833 
SetVisible(bool bState)834 void SvtViewOptions::SetVisible( bool bState )
835 {
836     // Ready for multithreading
837     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
838 
839     // Safe impossible cases.
840     // These call isn't allowed for dialogs, tab-dialogs or tab-pages!
841     OSL_ENSURE( !(m_eViewType==EViewType::Dialog||m_eViewType==EViewType::TabDialog||m_eViewType==EViewType::TabPage), "SvtViewOptions::SetVisible()\nCall not allowed for Dialogs, TabDialogs or TabPages! I do nothing!" );
842 
843     if( m_eViewType == EViewType::Window )
844         m_pDataContainer_Windows->SetVisible( m_sViewName, bState );
845 }
846 
847 //  public method
848 
HasVisible() const849 bool SvtViewOptions::HasVisible() const
850 {
851     // Ready for multithreading
852     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
853 
854     // Safe impossible cases.
855     // These call isn't allowed for dialogs, tab-dialogs or tab-pages!
856     OSL_ENSURE( !(m_eViewType==EViewType::Dialog||m_eViewType==EViewType::TabDialog||m_eViewType==EViewType::TabPage), "SvtViewOptions::IsVisible()\nCall not allowed for Dialogs, TabDialogs or TabPages! I do nothing!" );
857 
858     bool bState = false;
859     if( m_eViewType == EViewType::Window )
860         bState = m_pDataContainer_Windows->GetVisible( m_sViewName ) != SvtViewOptionsBase_Impl::STATE_NONE;
861 
862     return bState;
863 }
864 
GetUserData() const865 css::uno::Sequence< css::beans::NamedValue > SvtViewOptions::GetUserData() const
866 {
867     // Ready for multithreading
868     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
869 
870     css::uno::Sequence< css::beans::NamedValue > lData;
871     switch( m_eViewType )
872     {
873         case EViewType::Dialog: {
874                                     lData = m_pDataContainer_Dialogs->GetUserData( m_sViewName );
875                                 }
876                                 break;
877         case EViewType::TabDialog: {
878                                     lData = m_pDataContainer_TabDialogs->GetUserData( m_sViewName );
879                                 }
880                                 break;
881         case EViewType::TabPage:{
882                                     lData = m_pDataContainer_TabPages->GetUserData( m_sViewName );
883                                 }
884                                 break;
885         case EViewType::Window: {
886                                     lData = m_pDataContainer_Windows->GetUserData( m_sViewName );
887                                 }
888                                 break;
889     }
890     return lData;
891 }
892 
SetUserData(const css::uno::Sequence<css::beans::NamedValue> & lData)893 void SvtViewOptions::SetUserData( const css::uno::Sequence< css::beans::NamedValue >& lData )
894 {
895     // Ready for multithreading
896     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
897 
898     switch( m_eViewType )
899     {
900         case EViewType::Dialog: {
901                                     m_pDataContainer_Dialogs->SetUserData( m_sViewName, lData );
902                                 }
903                                 break;
904         case EViewType::TabDialog: {
905                                     m_pDataContainer_TabDialogs->SetUserData( m_sViewName, lData );
906                                 }
907                                 break;
908         case EViewType::TabPage:{
909                                     m_pDataContainer_TabPages->SetUserData( m_sViewName, lData );
910                                 }
911                                 break;
912         case EViewType::Window: {
913                                     m_pDataContainer_Windows->SetUserData( m_sViewName, lData );
914                                 }
915                                 break;
916     }
917 }
918 
GetUserItem(const OUString & sName) const919 css::uno::Any SvtViewOptions::GetUserItem( const OUString& sName ) const
920 {
921     // Ready for multithreading
922     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
923 
924     css::uno::Any aItem;
925     switch( m_eViewType )
926     {
927         case EViewType::Dialog: {
928                                     aItem = m_pDataContainer_Dialogs->GetUserItem( m_sViewName, sName );
929                                 }
930                                 break;
931         case EViewType::TabDialog: {
932                                     aItem = m_pDataContainer_TabDialogs->GetUserItem( m_sViewName, sName );
933                                 }
934                                 break;
935         case EViewType::TabPage:{
936                                     aItem = m_pDataContainer_TabPages->GetUserItem( m_sViewName, sName );
937                                 }
938                                 break;
939         case EViewType::Window: {
940                                     aItem = m_pDataContainer_Windows->GetUserItem( m_sViewName, sName );
941                                 }
942                                 break;
943     }
944     return aItem;
945 }
946 
SetUserItem(const OUString & sName,const css::uno::Any & aValue)947 void SvtViewOptions::SetUserItem( const OUString& sName  ,
948                                   const css::uno::Any&   aValue )
949 {
950     // Ready for multithreading
951     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
952 
953     switch( m_eViewType )
954     {
955         case EViewType::Dialog: {
956                                     m_pDataContainer_Dialogs->SetUserItem( m_sViewName, sName, aValue );
957                                 }
958                                 break;
959         case EViewType::TabDialog: {
960                                     m_pDataContainer_TabDialogs->SetUserItem( m_sViewName, sName, aValue );
961                                 }
962                                 break;
963         case EViewType::TabPage:{
964                                     m_pDataContainer_TabPages->SetUserItem( m_sViewName, sName, aValue );
965                                 }
966                                 break;
967         case EViewType::Window: {
968                                     m_pDataContainer_Windows->SetUserItem( m_sViewName, sName, aValue );
969                                 }
970                                 break;
971     }
972 }
973 
974 namespace
975 {
976     class theViewOptionsMutex : public rtl::Static<osl::Mutex, theViewOptionsMutex>{};
977 }
978 
979 //  private method
980 
GetOwnStaticMutex()981 ::osl::Mutex& SvtViewOptions::GetOwnStaticMutex()
982 {
983     return theViewOptionsMutex::get();
984 }
985 
AcquireOptions()986 void SvtViewOptions::AcquireOptions()
987 {
988     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
989     if( ++m_nRefCount_Dialogs == 1 )
990     {
991         m_pDataContainer_Dialogs = new SvtViewOptionsBase_Impl( LIST_DIALOGS );
992         ItemHolder1::holdConfigItem(EItem::ViewOptionsDialog);
993     }
994     if( ++m_nRefCount_TabDialogs == 1 )
995     {
996         m_pDataContainer_TabDialogs = new SvtViewOptionsBase_Impl( LIST_TABDIALOGS );
997         ItemHolder1::holdConfigItem(EItem::ViewOptionsTabDialog);
998     }
999     if( ++m_nRefCount_TabPages == 1 )
1000     {
1001         m_pDataContainer_TabPages = new SvtViewOptionsBase_Impl( LIST_TABPAGES );
1002         ItemHolder1::holdConfigItem(EItem::ViewOptionsTabPage);
1003     }
1004     if( ++m_nRefCount_Windows == 1 )
1005     {
1006         m_pDataContainer_Windows = new SvtViewOptionsBase_Impl( LIST_WINDOWS );
1007         ItemHolder1::holdConfigItem(EItem::ViewOptionsWindow);
1008     }
1009 }
1010 
ReleaseOptions()1011 void SvtViewOptions::ReleaseOptions()
1012 {
1013     ::osl::MutexGuard aGuard( GetOwnStaticMutex() );
1014     if( --m_nRefCount_Dialogs == 0 )
1015     {
1016         delete m_pDataContainer_Dialogs;
1017         m_pDataContainer_Dialogs = nullptr;
1018     }
1019     if( --m_nRefCount_TabDialogs == 0 )
1020     {
1021         delete m_pDataContainer_TabDialogs;
1022         m_pDataContainer_TabDialogs = nullptr;
1023     }
1024     if( --m_nRefCount_TabPages == 0 )
1025     {
1026         delete m_pDataContainer_TabPages;
1027         m_pDataContainer_TabPages = nullptr;
1028     }
1029     if( --m_nRefCount_Windows == 0 )
1030     {
1031         delete m_pDataContainer_Windows;
1032         m_pDataContainer_Windows = nullptr;
1033     }
1034 }
1035 
1036 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1037