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 #ifndef GCC
27 #endif
28 #include "rtl/instance.hxx"
29 #include <com/sun/star/uno/Any.hxx>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/io/XActiveDataSource.hpp>
32 #include <com/sun/star/io/XInputStream.hpp>
33 #include <com/sun/star/io/XOutputStream.hpp>
34 #include <com/sun/star/xml/sax/XParser.hpp>
35 #include <unotools/configmgr.hxx>
36 #include <unotools/configitem.hxx>
37 #include <tools/debug.hxx>
38 
39 #include <osl/mutex.hxx>
40 #include <tools/string.hxx>
41 #include <tools/urlobj.hxx>
42 #include <unotools/streamwrap.hxx>
43 #include <unotools/ucbstreamhelper.hxx>
44 #include <comphelper/processfactory.hxx>
45 
46 #include <unotools/accelcfg.hxx>
47 #include <unotools/xmlaccelcfg.hxx>
48 #include <unotools/pathoptions.hxx>
49 #include "itemholder1.hxx"
50 
51 
52 using namespace utl;
53 using namespace rtl;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::io;
56 using namespace com::sun::star::xml::sax;
57 
58 
59 static SvtAcceleratorConfig_Impl* pOptions = NULL;
60 static sal_Int32           nRefCount = 0;
61 
62 class SvtAcceleratorConfig_Impl
63 {
64 public:
65 
66     SvtAcceleratorItemList aList;
67 	bool			bModified;
68 
SvtAcceleratorConfig_Impl()69                     SvtAcceleratorConfig_Impl()
70                         : bModified( sal_False )
71                     {}
72 
73 					SvtAcceleratorConfig_Impl( Reference< XInputStream >& xInputStream );
74 	bool			Commit( Reference< XOutputStream >& xOutputStream );
75 };
76 
77 // -----------------------------------------------------------------------
78 
SvtAcceleratorConfig_Impl(Reference<XInputStream> & rInputStream)79 SvtAcceleratorConfig_Impl::SvtAcceleratorConfig_Impl( Reference< XInputStream >& rInputStream )
80 		: bModified( false )
81 {
82 	Reference< XParser > xParser( ::comphelper::getProcessServiceFactory()->createInstance(
83 									::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Parser" )),
84 								  UNO_QUERY);
85 
86 	// connect stream to input stream to the parser
87 	InputSource aInputSource;
88 	aInputSource.aInputStream = rInputStream;
89 
90 	// get filter
91 	Reference< XDocumentHandler > xFilter( new OReadAccelatorDocumentHandler( aList ));
92 
93 	// connect parser and filter
94 	xParser->setDocumentHandler( xFilter );
95     xParser->parseStream( aInputSource );
96 }
97 
Commit(Reference<XOutputStream> & rOutputStream)98 bool SvtAcceleratorConfig_Impl::Commit( Reference< XOutputStream >& rOutputStream )
99 {
100 	Reference< XDocumentHandler > xWriter;
101 
102 	xWriter = Reference< XDocumentHandler >( ::comphelper::getProcessServiceFactory()->createInstance(
103 			::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" )), UNO_QUERY) ;
104 
105 	Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
106 	xDataSource->setOutputStream( rOutputStream );
107 	try
108 	{
109 		OWriteAccelatorDocumentHandler aWriteHandler( aList, xWriter );
110 		aWriteHandler.WriteAcceleratorDocument();
111 		rOutputStream->flush();
112 		return true;
113 	}
114 	catch ( RuntimeException& )
115 	{
116 	}
117 	catch ( SAXException& )
118 	{
119 	}
120 	catch ( ::com::sun::star::io::IOException& )
121 	{
122 	}
123 
124 	return false;
125 }
126 
127 namespace
128 {
129     class LocalSingleton : public rtl::Static< osl::Mutex, LocalSingleton >
130     {
131     };
132 }
133 
SvtAcceleratorConfiguration()134 SvtAcceleratorConfiguration::SvtAcceleratorConfiguration()
135 {
136     // Global access, must be guarded (multithreading)
137     ::osl::MutexGuard aGuard( LocalSingleton::get() );
138     if ( !pOptions )
139 	{
140         SvStream* pStream = GetDefaultStream( STREAM_STD_READ );
141     	::utl::OInputStreamWrapper aHelper( *pStream );
142 		com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xOut( &aHelper );
143 
144         try
145         {
146             pOptions = new SvtAcceleratorConfig_Impl( xOut );
147         }
148         catch ( RuntimeException& )
149         {
150             pOptions = new SvtAcceleratorConfig_Impl();
151         }
152         catch( SAXException& )
153         {
154             pOptions = new SvtAcceleratorConfig_Impl();
155         }
156         catch( ::com::sun::star::io::IOException& )
157         {
158             pOptions = new SvtAcceleratorConfig_Impl();
159         }
160 
161 		if (pOptions)
162 			ItemHolder1::holdConfigItem(E_ACCELCFG);
163 
164         delete pStream;
165     }
166 
167     ++nRefCount;
168     pImp = pOptions;
169 }
170 
CreateFromStream(SvStream & rStream)171 SvtAcceleratorConfiguration* SvtAcceleratorConfiguration::CreateFromStream( SvStream& rStream )
172 {
173     SvtAcceleratorConfiguration* pRet = new SvtAcceleratorConfiguration;
174     ::utl::OInputStreamWrapper aHelper( rStream );
175     com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xOut( &aHelper );
176     try
177     {
178         pRet->pImp = new SvtAcceleratorConfig_Impl( xOut );
179     }
180     catch ( RuntimeException& )
181     {
182         DELETEZ( pRet );
183     }
184     catch( SAXException& )
185     {
186         DELETEZ( pRet );
187     }
188     catch( ::com::sun::star::io::IOException& )
189     {
190         DELETEZ( pRet );
191     }
192 
193     return pRet;
194 }
195 
196 // -----------------------------------------------------------------------
197 
~SvtAcceleratorConfiguration()198 SvtAcceleratorConfiguration::~SvtAcceleratorConfiguration()
199 {
200     if ( pImp == pOptions )
201     {
202         // Global access, must be guarded (multithreading)
203         ::osl::MutexGuard aGuard( LocalSingleton::get() );
204         if ( !--nRefCount )
205         {
206 			if ( pImp->bModified )
207 			{
208     			String aUserConfig = SvtPathOptions().GetUserConfigPath();
209     			INetURLObject aObj( aUserConfig );
210     			aObj.insertName( String::CreateFromAscii("GlobalKeyBindings.xml") );
211     			SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READWRITE|STREAM_TRUNC );
212     			::utl::OOutputStreamWrapper aHelper( *pStream );
213 				com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > xOut( &aHelper );
214 				pImp->Commit( xOut );
215 				delete pStream;
216 			}
217 
218             DELETEZ( pOptions );
219         }
220     }
221     else
222     {
223         delete pImp;
224     }
225 }
226 
GetCommand(const::com::sun::star::awt::KeyEvent & rKeyEvent)227 ::rtl::OUString SvtAcceleratorConfiguration::GetCommand( const ::com::sun::star::awt::KeyEvent& rKeyEvent )
228 {
229     sal_Int16 nCode=rKeyEvent.KeyCode, nModifier=rKeyEvent.Modifiers;
230     if ( !nCode )
231         nCode = rKeyEvent.KeyFunc;
232 
233 	std::list< SvtAcceleratorConfigItem>::const_iterator p;
234 	for ( p = pImp->aList.begin(); p != pImp->aList.end(); p++ )
235 		if ( p->nCode == nCode && p->nModifier == nModifier )
236             return p->aCommand;
237 
238 	return ::rtl::OUString();
239 }
240 
GetItems()241 const SvtAcceleratorItemList& SvtAcceleratorConfiguration::GetItems()
242 {
243 	return pImp->aList;
244 }
245 
SetCommand(const SvtAcceleratorConfigItem & rItem)246 void SvtAcceleratorConfiguration::SetCommand( const SvtAcceleratorConfigItem& rItem )
247 {
248 	std::list< SvtAcceleratorConfigItem>::iterator p;
249 	for ( p = pImp->aList.begin(); p != pImp->aList.end(); p++ )
250 		if ( p->nCode == rItem.nCode && p->nModifier == rItem.nModifier )
251 		{
252             p->aCommand = rItem.aCommand;
253 			return;
254 		}
255 
256 	pImp->aList.push_back( rItem );
257 
258 }
259 
SetItems(const SvtAcceleratorItemList & rItems,bool bClear)260 void SvtAcceleratorConfiguration::SetItems( const SvtAcceleratorItemList& rItems, bool bClear )
261 {
262 	if ( bClear )
263 	{
264 		pImp->aList = rItems;
265 	}
266 	else
267 	{
268 		std::list< SvtAcceleratorConfigItem>::const_iterator p;
269 		for ( p = rItems.begin(); p != rItems.end(); p++ )
270             SetCommand( *p );
271 	}
272 }
273 
GetStreamName()274 String SvtAcceleratorConfiguration::GetStreamName()
275 {
276     return String::CreateFromAscii("KeyBindings.xml");
277 }
278 
GetDefaultStream(StreamMode nMode)279 SvStream* SvtAcceleratorConfiguration::GetDefaultStream( StreamMode nMode )
280 {
281 	String aUserConfig = SvtPathOptions().GetUserConfigPath();
282     INetURLObject aObj( aUserConfig );
283     aObj.insertName( GetStreamName() );
284     return ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), nMode );
285 }
286