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>
29 #include <string_view>
30 #if !defined WIN32_LEAN_AND_MEAN
31 # define WIN32_LEAN_AND_MEAN
36 using namespace ::ooo::vba
;
37 using namespace ::com::sun::star
;
39 PrivateProfileStringListener::~PrivateProfileStringListener()
43 void PrivateProfileStringListener::Initialize( const OUString
& rFileName
, const OString
& rGroupName
, const OString
& rKey
)
45 maFileName
= rFileName
;
46 maGroupName
= rGroupName
;
50 static void lcl_getRegKeyInfo( std::string_view sKeyInfo
, HKEY
& hBaseKey
, OString
& sSubKey
)
52 std::size_t nBaseKeyIndex
= sKeyInfo
.find('\\');
53 if( nBaseKeyIndex
!= std::string_view::npos
)
55 std::string_view sBaseKey
= sKeyInfo
.substr( 0, nBaseKeyIndex
);
56 sSubKey
= OString(sKeyInfo
.substr( nBaseKeyIndex
+ 1 ));
57 if( sBaseKey
== "HKEY_CURRENT_USER" )
59 hBaseKey
= HKEY_CURRENT_USER
;
61 else if( sBaseKey
== "HKEY_LOCAL_MACHINE" )
63 hBaseKey
= HKEY_LOCAL_MACHINE
;
65 else if( sBaseKey
== "HKEY_CLASSES_ROOT" )
67 hBaseKey
= HKEY_CLASSES_ROOT
;
69 else if( sBaseKey
== "HKEY_USERS" )
71 hBaseKey
= HKEY_USERS
;
73 else if( sBaseKey
== "HKEY_CURRENT_CONFIG" )
75 hBaseKey
= HKEY_CURRENT_CONFIG
;
81 uno::Any
PrivateProfileStringListener::getValueEvent()
83 // get the private profile string
85 if(maFileName
.isEmpty())
87 // get key/value from Windows registry
89 HKEY hBaseKey
= nullptr;
91 lcl_getRegKeyInfo( maGroupName
, hBaseKey
, sSubKey
);
92 if( hBaseKey
!= 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
)
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
);
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
);
113 throw uno::RuntimeException("Only support on Windows" );
117 // get key/value from a file
118 Config
aCfg( maFileName
);
119 aCfg
.SetGroup( maGroupName
);
120 sValue
= OStringToOUString(aCfg
.ReadKey(maKey
), RTL_TEXTENCODING_DONTKNOW
);
123 return uno::Any( sValue
);
126 void PrivateProfileStringListener::setValueEvent( const css::uno::Any
& value
)
128 // set the private profile string
131 if(maFileName
.isEmpty())
133 //set value into Windows registry
135 HKEY hBaseKey
= nullptr;
137 lcl_getRegKeyInfo( maGroupName
, hBaseKey
, sSubKey
);
138 if( hBaseKey
!= 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
)
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
);
155 throw uno::RuntimeException("Not implemented" );
159 // set value into a file
160 Config
aCfg( maFileName
);
161 aCfg
.SetGroup( maGroupName
);
162 aCfg
.WriteKey( maKey
, OUStringToOString(aValue
, RTL_TEXTENCODING_DONTKNOW
) );
167 SwVbaSystem::SwVbaSystem( uno::Reference
<uno::XComponentContext
> const & xContext
): SwVbaSystem_BASE( uno::Reference
< XHelperInterface
>(), xContext
)
171 SwVbaSystem::~SwVbaSystem()
176 SwVbaSystem::getCursor()
178 PointerStyle nPointerStyle
= getPointerStyle( getCurrentWordDoc(mxContext
) );
180 switch( nPointerStyle
)
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
;
191 return word::WdCursorType::wdCursorNormal
;
196 SwVbaSystem::setCursor( sal_Int32 _cursor
)
202 case word::WdCursorType::wdCursorNorthwestArrow
:
204 setCursorHelper( getCurrentWordDoc(mxContext
), PointerStyle::Arrow
, false );
207 case word::WdCursorType::wdCursorWait
:
209 //It will set the edit window, toobar and statusbar's mouse pointer.
210 setCursorHelper( getCurrentWordDoc(mxContext
), PointerStyle::Wait
, true );
213 case word::WdCursorType::wdCursorIBeam
:
215 //It will set the edit window, toobar and statusbar's mouse pointer.
216 setCursorHelper( getCurrentWordDoc( mxContext
), PointerStyle::Text
, true );
219 case word::WdCursorType::wdCursorNormal
:
221 setCursorHelper( getCurrentWordDoc( mxContext
), PointerStyle::Null
, false );
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
230 catch( const uno::Exception
& )
236 SwVbaSystem::PrivateProfileString( const OUString
& rFilename
, const OUString
& rSection
, const OUString
& rKey
)
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
241 if( !rFilename
.isEmpty() )
244 aObj
.SetURL( rFilename
);
245 bool bIsURL
= aObj
.GetProtocol() != INetProtocol::NotValid
;
247 sFileUrl
= rFilename
;
249 osl::FileBase::getFileURLFromSystemPath( rFilename
, sFileUrl
);
252 OString
aGroupName(OUStringToOString(rSection
, RTL_TEXTENCODING_DONTKNOW
));
253 OString
aKey(OUStringToOString(rKey
, RTL_TEXTENCODING_DONTKNOW
));
254 maPrivateProfileStringListener
.Initialize( sFileUrl
, aGroupName
, aKey
);
256 return uno::Any( uno::Reference
< XPropValue
> ( new ScVbaPropValue( &maPrivateProfileStringListener
) ) );
260 SwVbaSystem::getServiceImplName()
262 return "SwVbaSystem";
265 uno::Sequence
< OUString
>
266 SwVbaSystem::getServiceNames()
268 static uno::Sequence
< OUString
> const aServiceNames
270 "ooo.vba.word.System"
272 return aServiceNames
;
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */