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
36using namespace ::ooo::vba;
37using namespace ::com::sun::star;
38
40{
41}
42
43void 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
50static 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
126void 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
167SwVbaSystem::SwVbaSystem( uno::Reference<uno::XComponentContext > const & xContext ): SwVbaSystem_BASE( uno::Reference< XHelperInterface >(), xContext )
168{
169}
170
172{
173}
174
175sal_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
195void SAL_CALL
196SwVbaSystem::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
235uno::Any SAL_CALL
236SwVbaSystem::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
259OUString
261{
262 return "SwVbaSystem";
263}
264
265uno::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: */
void SetGroup(const OString &rGroup)
OString ReadKey(const OString &rKey) const
void WriteKey(const OString &rKey, const OString &rValue)
INetProtocol GetProtocol() const
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
css::uno::Reference< css::uno::XComponentContext > mxContext
virtual css::uno::Any getValueEvent() override
Definition: vbasystem.cxx:81
virtual void setValueEvent(const css::uno::Any &value) override
Definition: vbasystem.cxx:126
virtual ~PrivateProfileStringListener()
Definition: vbasystem.cxx:39
void Initialize(const OUString &rFileName, const OString &rGroupName, const OString &rKey)
Definition: vbasystem.cxx:43
virtual css::uno::Any SAL_CALL PrivateProfileString(const OUString &rFilename, const OUString &rSection, const OUString &rKey) override
Definition: vbasystem.cxx:236
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbasystem.cxx:266
SwVbaSystem(css::uno::Reference< css::uno::XComponentContext > const &m_xContext)
Definition: vbasystem.cxx:167
virtual ~SwVbaSystem() override
Definition: vbasystem.cxx:171
virtual sal_Int32 SAL_CALL getCursor() override
Definition: vbasystem.cxx:176
virtual void SAL_CALL setCursor(sal_Int32 _cursor) override
Definition: vbasystem.cxx:196
PrivateProfileStringListener maPrivateProfileStringListener
Definition: vbasystem.hxx:47
virtual OUString getServiceImplName() override
Definition: vbasystem.cxx:260
Any value
Sequence< OUString > aServiceNames
#define SAL_N_ELEMENTS(arr)
Reference
VBAHELPER_DLLPUBLIC css::uno::Reference< css::frame::XModel > getCurrentWordDoc(const css::uno::Reference< css::uno::XComponentContext > &xContext)
VBAHELPER_DLLPUBLIC PointerStyle getPointerStyle(const css::uno::Reference< css::frame::XModel > &)
VBAHELPER_DLLPUBLIC void setCursorHelper(const css::uno::Reference< css::frame::XModel > &xModel, PointerStyle nPointer, bool bOverWrite)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
PointerStyle
LONG
unsigned char BYTE