1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
31 #include <string_view>
32 #if !defined WIN32_LEAN_AND_MEAN
33 # define WIN32_LEAN_AND_MEAN
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
;
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
;
84 uno::Any
PrivateProfileStringListener::getValueEvent()
86 // get the private profile string
88 if(maFileName
.isEmpty())
90 // get key/value from Windows registry
92 HKEY hBaseKey
= nullptr;
94 lcl_getRegKeyInfo( maGroupName
, hBaseKey
, sSubKey
);
95 if( hBaseKey
!= 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
);
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
);
116 throw uno::RuntimeException(u
"Only support on Windows"_ustr
);
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
134 if(maFileName
.isEmpty())
136 //set value into Windows registry
138 HKEY hBaseKey
= nullptr;
140 lcl_getRegKeyInfo( maGroupName
, hBaseKey
, sSubKey
);
141 if( hBaseKey
!= 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
);
158 throw uno::RuntimeException(u
"Not implemented"_ustr
);
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()
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
;
194 return word::WdCursorType::wdCursorNormal
;
199 SwVbaSystem::setCursor( sal_Int32 _cursor
)
205 case word::WdCursorType::wdCursorNorthwestArrow
:
207 setCursorHelper( static_cast<SfxBaseModel
*>(getCurrentWordDoc(mxContext
).get()), PointerStyle::Arrow
, false );
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 );
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 );
222 case word::WdCursorType::wdCursorNormal
:
224 setCursorHelper( static_cast<SfxBaseModel
*>(getCurrentWordDoc( mxContext
).get()), PointerStyle::Null
, false );
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
& )
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
244 if( !rFilename
.isEmpty() )
247 aObj
.SetURL( rFilename
);
248 bool bIsURL
= aObj
.GetProtocol() != INetProtocol::NotValid
;
250 sFileUrl
= rFilename
;
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
) ) );
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: */