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