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