1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_unotools.hxx"
26 
27 #include <unotools/optionsdlg.hxx>
28 #include <unotools/configmgr.hxx>
29 #include <unotools/configitem.hxx>
30 #include <tools/debug.hxx>
31 #include <com/sun/star/uno/Any.hxx>
32 #include <com/sun/star/uno/Sequence.hxx>
33 #include <osl/mutex.hxx>
34 #include <comphelper/stl_types.hxx>
35 
36 #include <hash_map>
37 #include "itemholder1.hxx"
38 
39 using namespace utl;
40 using namespace rtl;
41 using namespace com::sun::star::beans ;
42 using namespace com::sun::star::uno;
43 
44 #define CFG_FILENAME            OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.OptionsDialog" ) )
45 #define ROOT_NODE               OUString( RTL_CONSTASCII_USTRINGPARAM( "OptionsDialogGroups" ) )
46 #define PAGES_NODE              OUString( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) )
47 #define OPTIONS_NODE            OUString( RTL_CONSTASCII_USTRINGPARAM( "Options" ) )
48 #define PROPERTY_HIDE           OUString( RTL_CONSTASCII_USTRINGPARAM( "Hide" ) )
49 
50 static SvtOptionsDlgOptions_Impl*   pOptions = NULL;
51 static sal_Int32                    nRefCount = 0;
52 
53 class SvtOptionsDlgOptions_Impl : public utl::ConfigItem
54 {
55 private:
56     struct OUStringHashCode
57     {
operator ()SvtOptionsDlgOptions_Impl::OUStringHashCode58         size_t operator()( const ::rtl::OUString& sString ) const
59         {
60             return sString.hashCode();
61         }
62     };
63 
64     typedef std::hash_map< OUString, sal_Bool, OUStringHashCode, ::std::equal_to< OUString > > OptionNodeList;
65 
66     OUString        m_sPathDelimiter;
67     OptionNodeList  m_aOptionNodeList;
68 
69     enum NodeType{ NT_Group, NT_Page, NT_Option };
70     void            ReadNode( const OUString& _rNode, NodeType _eType );
71     sal_Bool        IsHidden( const OUString& _rPath ) const;
72 
73 public:
74                     SvtOptionsDlgOptions_Impl();
75 
76     virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
77     virtual void    Commit();
78 
79     static ::osl::Mutex & getInitMutex();
80 
81     sal_Bool        IsGroupHidden   (   const OUString& _rGroup ) const;
82     sal_Bool        IsPageHidden    (   const OUString& _rPage,
83                                         const OUString& _rGroup ) const;
84     sal_Bool        IsOptionHidden  (   const OUString& _rOption,
85                                         const OUString& _rPage,
86                                         const OUString& _rGroup ) const;
87 };
88 
getInitMutex()89 ::osl::Mutex & SvtOptionsDlgOptions_Impl::getInitMutex()
90 {
91     static ::osl::Mutex *pMutex = 0;
92 
93     if( ! pMutex )
94     {
95         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
96         if( ! pMutex )
97         {
98             static ::osl::Mutex mutex;
99             pMutex = &mutex;
100         }
101     }
102     return *pMutex;
103 }
104 
105 // -----------------------------------------------------------------------
106 
SvtOptionsDlgOptions_Impl()107 SvtOptionsDlgOptions_Impl::SvtOptionsDlgOptions_Impl()
108     : ConfigItem( OUString( CFG_FILENAME ) ),
109 
110     m_sPathDelimiter( RTL_CONSTASCII_USTRINGPARAM( "/" ) ),
111     m_aOptionNodeList( OptionNodeList() )
112 
113 {
114     OUString sRootNode( ROOT_NODE );
115     Sequence< OUString > aNodeSeq = GetNodeNames( sRootNode );
116     OUString sNode( sRootNode + m_sPathDelimiter );
117     sal_uInt32 nCount = aNodeSeq.getLength();
118     for ( sal_uInt32 n = 0; n < nCount; n++ )
119     {
120         OUString sSubNode( sNode + aNodeSeq[n] );
121         ReadNode( sSubNode, NT_Group );
122     }
123 }
124 
125 // -----------------------------------------------------------------------
126 
Commit()127 void SvtOptionsDlgOptions_Impl::Commit()
128 {
129     // nothing to commit
130 }
131 
132 // -----------------------------------------------------------------------
133 
Notify(const Sequence<rtl::OUString> &)134 void SvtOptionsDlgOptions_Impl::Notify( const Sequence< rtl::OUString >& )
135 {
136     // nothing to notify
137 }
138 
ReadNode(const OUString & _rNode,NodeType _eType)139 void SvtOptionsDlgOptions_Impl::ReadNode( const OUString& _rNode, NodeType _eType )
140 {
141     OUString sNode( _rNode + m_sPathDelimiter );
142     OUString sSet;
143     sal_Int32 nLen = 0;
144     switch ( _eType )
145     {
146         case NT_Group :
147         {
148             sSet = PAGES_NODE;
149             nLen = 2;
150             break;
151         }
152 
153         case NT_Page :
154         {
155             sSet = OPTIONS_NODE;
156             nLen = 2;
157             break;
158         }
159 
160         case NT_Option :
161         {
162             nLen = 1;
163             break;
164         }
165     }
166 
167     Sequence< OUString > lResult( nLen );
168     lResult[0] = OUString( sNode + PROPERTY_HIDE );
169     if ( _eType != NT_Option )
170         lResult[1] = OUString( sNode + sSet );
171 
172     Sequence< Any > aValues;
173     aValues = GetProperties( lResult );
174     sal_Bool bHide = sal_False;
175     if ( aValues[0] >>= bHide )
176         m_aOptionNodeList.insert( OptionNodeList::value_type( sNode, bHide ) );
177 
178     if ( _eType != NT_Option )
179     {
180         OUString sNodes( sNode + sSet );
181         Sequence< OUString > aNodes = GetNodeNames( sNodes );
182         if ( aNodes.getLength() > 0 )
183         {
184             for ( sal_uInt32 n = 0; n < (sal_uInt32)aNodes.getLength(); ++n )
185             {
186                 OUString sSubNodeName( sNodes + m_sPathDelimiter + aNodes[n] );
187                 ReadNode( sSubNodeName, _eType == NT_Group ? NT_Page : NT_Option );
188             }
189         }
190     }
191 }
192 
193 // -----------------------------------------------------------------------
194 
getGroupPath(const OUString & _rGroup)195 OUString getGroupPath( const OUString& _rGroup )
196 {
197     return OUString( ROOT_NODE + OUString('/') + _rGroup + OUString('/') );
198 }
getPagePath(const OUString & _rPage)199 OUString getPagePath( const OUString& _rPage )
200 {
201     return OUString( PAGES_NODE + OUString('/') + _rPage + OUString('/') );
202 }
getOptionPath(const OUString & _rOption)203 OUString getOptionPath( const OUString& _rOption )
204 {
205     return OUString( OPTIONS_NODE + OUString('/') + _rOption + OUString('/') );
206 }
207 
208 // -----------------------------------------------------------------------
209 
IsHidden(const OUString & _rPath) const210 sal_Bool SvtOptionsDlgOptions_Impl::IsHidden( const OUString& _rPath ) const
211 {
212     sal_Bool bRet = sal_False;
213     OptionNodeList::const_iterator pIter = m_aOptionNodeList.find( _rPath );
214     if ( pIter != m_aOptionNodeList.end() )
215         bRet = pIter->second;
216     return bRet;
217 }
218 
219 // -----------------------------------------------------------------------
220 
IsGroupHidden(const OUString & _rGroup) const221 sal_Bool SvtOptionsDlgOptions_Impl::IsGroupHidden( const OUString& _rGroup ) const
222 {
223     return IsHidden( getGroupPath( _rGroup ) );
224 }
225 
226 // -----------------------------------------------------------------------
227 
IsPageHidden(const OUString & _rPage,const OUString & _rGroup) const228 sal_Bool SvtOptionsDlgOptions_Impl::IsPageHidden( const OUString& _rPage, const OUString& _rGroup ) const
229 {
230     return IsHidden( getGroupPath( _rGroup  ) + getPagePath( _rPage ) );
231 }
232 
233 // -----------------------------------------------------------------------
234 
IsOptionHidden(const OUString & _rOption,const OUString & _rPage,const OUString & _rGroup) const235 sal_Bool SvtOptionsDlgOptions_Impl::IsOptionHidden(
236     const OUString& _rOption, const OUString& _rPage, const OUString& _rGroup ) const
237 {
238     return IsHidden( getGroupPath( _rGroup  ) + getPagePath( _rPage ) + getOptionPath( _rOption ) );
239 }
240 
241 // -----------------------------------------------------------------------
242 
SvtOptionsDialogOptions()243 SvtOptionsDialogOptions::SvtOptionsDialogOptions()
244 {
245     // Global access, must be guarded (multithreading)
246     ::osl::MutexGuard aGuard( SvtOptionsDlgOptions_Impl::getInitMutex() );
247     ++nRefCount;
248     if ( !pOptions )
249     {
250         pOptions = new SvtOptionsDlgOptions_Impl;
251 
252         ItemHolder1::holdConfigItem( E_OPTIONSDLGOPTIONS );
253     }
254     m_pImp = pOptions;
255 }
256 
257 // -----------------------------------------------------------------------
258 
~SvtOptionsDialogOptions()259 SvtOptionsDialogOptions::~SvtOptionsDialogOptions()
260 {
261     // Global access, must be guarded (multithreading)
262     ::osl::MutexGuard aGuard( SvtOptionsDlgOptions_Impl::getInitMutex() );
263     if ( !--nRefCount )
264 	{
265 		if ( pOptions->IsModified() )
266 			pOptions->Commit();
267         DELETEZ( pOptions );
268 	}
269 }
270 
IsGroupHidden(const String & _rGroup) const271 sal_Bool SvtOptionsDialogOptions::IsGroupHidden( const String& _rGroup ) const
272 {
273     return m_pImp->IsGroupHidden( _rGroup );
274 }
275 
IsPageHidden(const String & _rPage,const String & _rGroup) const276 sal_Bool SvtOptionsDialogOptions::IsPageHidden( const String& _rPage, const String& _rGroup ) const
277 {
278     return m_pImp->IsPageHidden( _rPage, _rGroup );
279 }
280 
IsOptionHidden(const String & _rOption,const String & _rPage,const String & _rGroup) const281 sal_Bool SvtOptionsDialogOptions::IsOptionHidden(
282     const String& _rOption, const String& _rPage, const String& _rGroup ) const
283 {
284     return m_pImp->IsOptionHidden( _rOption, _rPage, _rGroup );
285 }
286 
287