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 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 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 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 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 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 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 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 241 const SvtAcceleratorItemList& SvtAcceleratorConfiguration::GetItems() 242 { 243 return pImp->aList; 244 } 245 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 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 274 String SvtAcceleratorConfiguration::GetStreamName() 275 { 276 return String::CreateFromAscii("KeyBindings.xml"); 277 } 278 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