sc: factor out some more code
[LibreOffice.git] / sw / source / ui / vba / vbasystem.cxx
blob7bd0e54957e1f8a4c9c3ed2db444ede3091e481b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #include "vbasystem.hxx"
21 #include <ooo/vba/word/WdCursorType.hpp>
22 #include <tools/config.hxx>
23 #include <osl/file.hxx>
24 #include <tools/urlobj.hxx>
25 #include <o3tl/char16_t2wchar_t.hxx>
26 #include "wordvbahelper.hxx"
27 #include <unotxdoc.hxx>
29 #ifdef _WIN32
30 #include <cstddef>
31 #include <string_view>
32 #if !defined WIN32_LEAN_AND_MEAN
33 # define WIN32_LEAN_AND_MEAN
34 #endif
35 #include <windows.h>
36 #endif
38 using namespace ::ooo::vba;
39 using namespace ::ooo::vba::word;
40 using namespace ::com::sun::star;
42 PrivateProfileStringListener::~PrivateProfileStringListener()
46 void PrivateProfileStringListener::Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey )
48 maFileName = rFileName;
49 maGroupName = rGroupName;
50 maKey = rKey;
52 #ifdef _WIN32
53 static void lcl_getRegKeyInfo( std::string_view sKeyInfo, HKEY& hBaseKey, OString& sSubKey )
55 std::size_t nBaseKeyIndex = sKeyInfo.find('\\');
56 if( nBaseKeyIndex != std::string_view::npos )
58 std::string_view sBaseKey = sKeyInfo.substr( 0, nBaseKeyIndex );
59 sSubKey = OString(sKeyInfo.substr( nBaseKeyIndex + 1 ));
60 if( sBaseKey == "HKEY_CURRENT_USER" )
62 hBaseKey = HKEY_CURRENT_USER;
64 else if( sBaseKey == "HKEY_LOCAL_MACHINE" )
66 hBaseKey = HKEY_LOCAL_MACHINE;
68 else if( sBaseKey == "HKEY_CLASSES_ROOT" )
70 hBaseKey = HKEY_CLASSES_ROOT;
72 else if( sBaseKey == "HKEY_USERS" )
74 hBaseKey = HKEY_USERS;
76 else if( sBaseKey == "HKEY_CURRENT_CONFIG" )
78 hBaseKey = HKEY_CURRENT_CONFIG;
82 #endif
84 uno::Any PrivateProfileStringListener::getValueEvent()
86 // get the private profile string
87 OUString sValue;
88 if(maFileName.isEmpty())
90 // get key/value from Windows registry
91 #ifdef _WIN32
92 HKEY hBaseKey = nullptr;
93 OString sSubKey;
94 lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
95 if( hBaseKey != nullptr )
97 HKEY hKey = nullptr;
98 LPCSTR lpSubKey = sSubKey.getStr();
99 // We use RegOpenKeyExA here for convenience, because we already have subkey name as 8-bit string
100 LONG lResult = RegOpenKeyExA( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
101 if( ERROR_SUCCESS == lResult )
103 OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
104 LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
105 WCHAR szBuffer[1024];
106 DWORD cbData = sizeof(szBuffer);
107 lResult = RegQueryValueExW( hKey, lpValueName, nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &cbData );
108 RegCloseKey( hKey );
109 // https://msdn.microsoft.com/en-us/ms724911 mentions that
110 // "the string may not have been stored with the proper terminating null characters"
111 szBuffer[std::min(size_t(cbData / sizeof(szBuffer[0])), SAL_N_ELEMENTS(szBuffer)-1)] = 0;
112 sValue = o3tl::toU(szBuffer);
115 #else
116 throw uno::RuntimeException(u"Only support on Windows"_ustr );
117 #endif
120 // get key/value from a file
121 Config aCfg( maFileName );
122 aCfg.SetGroup( maGroupName );
123 sValue = OStringToOUString(aCfg.ReadKey(maKey), RTL_TEXTENCODING_DONTKNOW);
126 return uno::Any( sValue );
129 void PrivateProfileStringListener::setValueEvent( const css::uno::Any& value )
131 // set the private profile string
132 OUString aValue;
133 value >>= aValue;
134 if(maFileName.isEmpty())
136 //set value into Windows registry
137 #ifdef _WIN32
138 HKEY hBaseKey = nullptr;
139 OString sSubKey;
140 lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
141 if( hBaseKey != nullptr )
143 HKEY hKey = nullptr;
144 LPCSTR lpSubKey = sSubKey.getStr();
145 // We use RegCreateKeyExA here for convenience, because we already have subkey name as 8-bit string
146 LONG lResult = RegCreateKeyExA( hBaseKey, lpSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &hKey, nullptr );
147 if( ERROR_SUCCESS == lResult )
149 DWORD cbData = sizeof(WCHAR) * (aValue.getLength() + 1);
150 OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
151 LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
152 lResult = RegSetValueExW( hKey, lpValueName, 0 /* Reserved */, REG_SZ, reinterpret_cast<BYTE const *>(aValue.getStr()), cbData );
153 RegCloseKey( hKey );
156 return;
157 #else
158 throw uno::RuntimeException(u"Not implemented"_ustr );
159 #endif
162 // set value into a file
163 Config aCfg( maFileName );
164 aCfg.SetGroup( maGroupName );
165 aCfg.WriteKey( maKey, OUStringToOString(aValue, RTL_TEXTENCODING_DONTKNOW) );
170 SwVbaSystem::SwVbaSystem( uno::Reference<uno::XComponentContext > const & xContext ): SwVbaSystem_BASE( uno::Reference< XHelperInterface >(), xContext )
174 SwVbaSystem::~SwVbaSystem()
178 sal_Int32 SAL_CALL
179 SwVbaSystem::getCursor()
181 PointerStyle nPointerStyle = getPointerStyle( static_cast<SfxBaseModel*>(getCurrentWordDoc(mxContext).get()) );
183 switch( nPointerStyle )
185 case PointerStyle::Arrow:
186 return word::WdCursorType::wdCursorNorthwestArrow;
187 case PointerStyle::Null:
188 return word::WdCursorType::wdCursorNormal;
189 case PointerStyle::Wait:
190 return word::WdCursorType::wdCursorWait;
191 case PointerStyle::Text:
192 return word::WdCursorType::wdCursorIBeam;
193 default:
194 return word::WdCursorType::wdCursorNormal;
198 void SAL_CALL
199 SwVbaSystem::setCursor( sal_Int32 _cursor )
203 switch( _cursor )
205 case word::WdCursorType::wdCursorNorthwestArrow:
207 setCursorHelper( static_cast<SfxBaseModel*>(getCurrentWordDoc(mxContext).get()), PointerStyle::Arrow, false );
208 break;
210 case word::WdCursorType::wdCursorWait:
212 //It will set the edit window, toobar and statusbar's mouse pointer.
213 setCursorHelper( static_cast<SfxBaseModel*>(getCurrentWordDoc(mxContext).get()), PointerStyle::Wait, true );
214 break;
216 case word::WdCursorType::wdCursorIBeam:
218 //It will set the edit window, toobar and statusbar's mouse pointer.
219 setCursorHelper( static_cast<SfxBaseModel*>(getCurrentWordDoc( mxContext ).get()), PointerStyle::Text, true );
220 break;
222 case word::WdCursorType::wdCursorNormal:
224 setCursorHelper( static_cast<SfxBaseModel*>(getCurrentWordDoc( mxContext ).get()), PointerStyle::Null, false );
225 break;
227 default:
228 throw uno::RuntimeException(u"Unknown value for Cursor pointer"_ustr );
229 // TODO: isn't this a flaw in the API? It should be allowed to throw an
230 // IllegalArgumentException, or so
233 catch( const uno::Exception& )
238 uno::Any SAL_CALL
239 SwVbaSystem::PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey )
241 // FIXME: need to detect whether it is a relative file path
242 // we need to detect if this is a URL, if not then assume it's a file path
243 OUString sFileUrl;
244 if( !rFilename.isEmpty() )
246 INetURLObject aObj;
247 aObj.SetURL( rFilename );
248 bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
249 if ( bIsURL )
250 sFileUrl = rFilename;
251 else
252 osl::FileBase::getFileURLFromSystemPath( rFilename, sFileUrl);
255 OString aGroupName(OUStringToOString(rSection, RTL_TEXTENCODING_DONTKNOW));
256 OString aKey(OUStringToOString(rKey, RTL_TEXTENCODING_DONTKNOW));
257 maPrivateProfileStringListener.Initialize( sFileUrl, aGroupName, aKey );
259 return uno::Any( uno::Reference< XPropValue > ( new ScVbaPropValue( &maPrivateProfileStringListener ) ) );
262 OUString
263 SwVbaSystem::getServiceImplName()
265 return u"SwVbaSystem"_ustr;
268 uno::Sequence< OUString >
269 SwVbaSystem::getServiceNames()
271 static uno::Sequence< OUString > const aServiceNames
273 u"ooo.vba.word.System"_ustr
275 return aServiceNames;
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */