LibreOffice Module sw (master)  1
vbasystem.cxx
Go to the documentation of this file.
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 #include "vbasystem.hxx"
20 
21 #include <ooo/vba/word/WdCursorType.hpp>
22 #include <tools/config.hxx>
23 #include <osl/file.hxx>
24 #include <tools/urlobj.hxx>
26 
27 #ifdef _WIN32
28 #if !defined WIN32_LEAN_AND_MEAN
29 # define WIN32_LEAN_AND_MEAN
30 #endif
31 #include <windows.h>
32 #endif
33 
34 using namespace ::ooo::vba;
35 using namespace ::com::sun::star;
36 
38 {
39 }
40 
41 void PrivateProfileStringListener::Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey )
42 {
43  maFileName = rFileName;
44  maGroupName = rGroupName;
45  maKey = rKey;
46 }
47 #ifdef _WIN32
48 static void lcl_getRegKeyInfo( const OString& sKeyInfo, HKEY& hBaseKey, OString& sSubKey )
49 {
50  sal_Int32 nBaseKeyIndex = sKeyInfo.indexOf('\\');
51  if( nBaseKeyIndex > 0 )
52  {
53  OString sBaseKey = sKeyInfo.copy( 0, nBaseKeyIndex );
54  sSubKey = sKeyInfo.copy( nBaseKeyIndex + 1 );
55  if( sBaseKey == "HKEY_CURRENT_USER" )
56  {
57  hBaseKey = HKEY_CURRENT_USER;
58  }
59  else if( sBaseKey == "HKEY_LOCAL_MACHINE" )
60  {
61  hBaseKey = HKEY_LOCAL_MACHINE;
62  }
63  else if( sBaseKey == "HKEY_CLASSES_ROOT" )
64  {
65  hBaseKey = HKEY_CLASSES_ROOT;
66  }
67  else if( sBaseKey == "HKEY_USERS" )
68  {
69  hBaseKey = HKEY_USERS;
70  }
71  else if( sBaseKey == "HKEY_CURRENT_CONFIG" )
72  {
73  hBaseKey = HKEY_CURRENT_CONFIG;
74  }
75  }
76 }
77 #endif
78 
80 {
81  // get the private profile string
82  OUString sValue;
83  if(maFileName.isEmpty())
84  {
85  // get key/value from Windows registry
86 #ifdef _WIN32
87  HKEY hBaseKey = nullptr;
88  OString sSubKey;
89  lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
90  if( hBaseKey != nullptr )
91  {
92  HKEY hKey = nullptr;
93  LPCSTR lpSubKey = sSubKey.getStr();
94  // We use RegOpenKeyExA here for convenience, because we already have subkey name as 8-bit string
95  LONG lResult = RegOpenKeyExA( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
96  if( ERROR_SUCCESS == lResult )
97  {
98  OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
99  LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
100  WCHAR szBuffer[1024];
101  DWORD cbData = sizeof(szBuffer);
102  lResult = RegQueryValueExW( hKey, lpValueName, nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &cbData );
103  RegCloseKey( hKey );
104  // https://msdn.microsoft.com/en-us/ms724911 mentions that
105  // "the string may not have been stored with the proper terminating null characters"
106  szBuffer[std::min(size_t(cbData / sizeof(szBuffer[0])), SAL_N_ELEMENTS(szBuffer)-1)] = 0;
107  sValue = o3tl::toU(szBuffer);
108  }
109  }
110 #else
111  throw uno::RuntimeException("Only support on Windows" );
112 #endif
113  }
114 
115  // get key/value from a file
116  Config aCfg( maFileName );
117  aCfg.SetGroup( maGroupName );
118  sValue = OStringToOUString(aCfg.ReadKey(maKey), RTL_TEXTENCODING_DONTKNOW);
119 
120 
121  return uno::makeAny( sValue );
122 }
123 
124 void PrivateProfileStringListener::setValueEvent( const css::uno::Any& value )
125 {
126  // set the private profile string
127  OUString aValue;
128  value >>= aValue;
129  if(maFileName.isEmpty())
130  {
131  //set value into Windows registry
132 #ifdef _WIN32
133  HKEY hBaseKey = nullptr;
134  OString sSubKey;
135  lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
136  if( hBaseKey != nullptr )
137  {
138  HKEY hKey = nullptr;
139  LPCSTR lpSubKey = sSubKey.getStr();
140  // We use RegCreateKeyExA here for convenience, because we already have subkey name as 8-bit string
141  LONG lResult = RegCreateKeyExA( hBaseKey, lpSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &hKey, nullptr );
142  if( ERROR_SUCCESS == lResult )
143  {
144  DWORD cbData = sizeof(WCHAR) * (aValue.getLength() + 1);
145  OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
146  LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
147  lResult = RegSetValueExW( hKey, lpValueName, 0 /* Reserved */, REG_SZ, reinterpret_cast<BYTE const *>(aValue.getStr()), cbData );
148  RegCloseKey( hKey );
149  }
150  }
151  return;
152 #else
153  throw uno::RuntimeException("Not implemented" );
154 #endif
155  }
156 
157  // set value into a file
158  Config aCfg( maFileName );
159  aCfg.SetGroup( maGroupName );
160  aCfg.WriteKey( maKey, OUStringToOString(aValue, RTL_TEXTENCODING_DONTKNOW) );
161 
162 
163 }
164 
165 SwVbaSystem::SwVbaSystem( uno::Reference<uno::XComponentContext > const & xContext ): SwVbaSystem_BASE( uno::Reference< XHelperInterface >(), xContext )
166 {
167 }
168 
170 {
171 }
172 
173 sal_Int32 SAL_CALL
175 {
177 
178  switch( nPointerStyle )
179  {
180  case PointerStyle::Arrow:
181  return word::WdCursorType::wdCursorNorthwestArrow;
182  case PointerStyle::Null:
183  return word::WdCursorType::wdCursorNormal;
184  case PointerStyle::Wait:
185  return word::WdCursorType::wdCursorWait;
186  case PointerStyle::Text:
187  return word::WdCursorType::wdCursorIBeam;
188  default:
189  return word::WdCursorType::wdCursorNormal;
190  }
191 }
192 
193 void SAL_CALL
194 SwVbaSystem::setCursor( sal_Int32 _cursor )
195 {
196  try
197  {
198  switch( _cursor )
199  {
200  case word::WdCursorType::wdCursorNorthwestArrow:
201  {
202  setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Arrow, false );
203  break;
204  }
205  case word::WdCursorType::wdCursorWait:
206  {
207  //It will set the edit window, toobar and statusbar's mouse pointer.
208  setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Wait, true );
209  break;
210  }
211  case word::WdCursorType::wdCursorIBeam:
212  {
213  //It will set the edit window, toobar and statusbar's mouse pointer.
214  setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Text, true );
215  break;
216  }
217  case word::WdCursorType::wdCursorNormal:
218  {
219  setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Null, false );
220  break;
221  }
222  default:
223  throw uno::RuntimeException("Unknown value for Cursor pointer" );
224  // TODO: isn't this a flaw in the API? It should be allowed to throw an
225  // IllegalArgumentException, or so
226  }
227  }
228  catch( const uno::Exception& )
229  {
230  }
231 }
232 
233 uno::Any SAL_CALL
234 SwVbaSystem::PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey )
235 {
236  // FIXME: need to detect whether it is a relative file path
237  // we need to detect if this is a URL, if not then assume it's a file path
238  OUString sFileUrl;
239  if( !rFilename.isEmpty() )
240  {
241  INetURLObject aObj;
242  aObj.SetURL( rFilename );
243  bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
244  if ( bIsURL )
245  sFileUrl = rFilename;
246  else
247  osl::FileBase::getFileURLFromSystemPath( rFilename, sFileUrl);
248  }
249 
250  OString aGroupName(OUStringToOString(rSection, RTL_TEXTENCODING_DONTKNOW));
251  OString aKey(OUStringToOString(rKey, RTL_TEXTENCODING_DONTKNOW));
252  maPrivateProfileStringListener.Initialize( sFileUrl, aGroupName, aKey );
253 
254  return uno::makeAny( uno::Reference< XPropValue > ( new ScVbaPropValue( &maPrivateProfileStringListener ) ) );
255 }
256 
257 OUString
259 {
260  return "SwVbaSystem";
261 }
262 
263 uno::Sequence< OUString >
265 {
266  static uno::Sequence< OUString > const aServiceNames
267  {
268  "ooo.vba.word.System"
269  };
270  return aServiceNames;
271 }
272 
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString getServiceImplName() override
Definition: vbasystem.cxx:258
virtual css::uno::Any SAL_CALL PrivateProfileString(const OUString &rFilename, const OUString &rSection, const OUString &rKey) override
Definition: vbasystem.cxx:234
virtual void SAL_CALL setCursor(sal_Int32 _cursor) override
Definition: vbasystem.cxx:194
LONG
Reference
Sequence< OUString > aServiceNames
void SetGroup(const OString &rGroup)
virtual css::uno::Any getValueEvent() override
Definition: vbasystem.cxx:79
void setCursorHelper(const uno::Reference< frame::XModel > &xModel, PointerStyle nPointer, bool bOverWrite)
#define SAL_N_ELEMENTS(arr)
OString ReadKey(const OString &rKey) const
virtual ~SwVbaSystem() override
Definition: vbasystem.cxx:169
void WriteKey(const OString &rKey, const OString &rValue)
uno::Reference< frame::XModel > getCurrentWordDoc(const uno::Reference< uno::XComponentContext > &xContext)
PointerStyle getPointerStyle(const uno::Reference< frame::XModel > &xModel)
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
SwVbaSystem(css::uno::Reference< css::uno::XComponentContext > const &m_xContext)
Definition: vbasystem.cxx:165
css::uno::Reference< css::uno::XComponentContext > mxContext
virtual void setValueEvent(const css::uno::Any &value) override
Definition: vbasystem.cxx:124
virtual sal_Int32 SAL_CALL getCursor() override
Definition: vbasystem.cxx:174
INetProtocol GetProtocol() const
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbasystem.cxx:264
PointerStyle
virtual ~PrivateProfileStringListener()
Definition: vbasystem.cxx:37
bool SetURL(OUString const &rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
PrivateProfileStringListener maPrivateProfileStringListener
Definition: vbasystem.hxx:47
void Initialize(const OUString &rFileName, const OString &rGroupName, const OString &rKey)
Definition: vbasystem.cxx:41