File: | home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx |
Warning: | line 1077, column 5 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||
20 | #include <vcl/errinf.hxx> | ||||
21 | #include <tools/stream.hxx> | ||||
22 | #include <sot/storage.hxx> | ||||
23 | #include <tools/urlobj.hxx> | ||||
24 | #include <svl/hint.hxx> | ||||
25 | #include <basic/sbx.hxx> | ||||
26 | #include <basic/sbmeth.hxx> | ||||
27 | #include <sot/storinfo.hxx> | ||||
28 | #include <unotools/pathoptions.hxx> | ||||
29 | #include <tools/debug.hxx> | ||||
30 | #include <tools/diagnose_ex.h> | ||||
31 | #include <basic/sbmod.hxx> | ||||
32 | #include <unotools/transliterationwrapper.hxx> | ||||
33 | #include <sal/log.hxx> | ||||
34 | |||||
35 | #include <basic/sberrors.hxx> | ||||
36 | #include <basic/sbuno.hxx> | ||||
37 | #include <basic/basmgr.hxx> | ||||
38 | #include <global.hxx> | ||||
39 | #include <com/sun/star/script/XLibraryContainer.hpp> | ||||
40 | #include <com/sun/star/script/XPersistentLibraryContainer.hpp> | ||||
41 | |||||
42 | #include <memory> | ||||
43 | #include <vector> | ||||
44 | |||||
45 | #define LIB_SEP0x01 0x01 | ||||
46 | #define LIBINFO_SEP0x02 0x02 | ||||
47 | #define LIBINFO_ID0x1491 0x1491 | ||||
48 | #define PASSWORD_MARKER0x31452134 0x31452134 | ||||
49 | |||||
50 | |||||
51 | // Library API, implemented for XML import/export | ||||
52 | |||||
53 | #include <com/sun/star/container/XNameContainer.hpp> | ||||
54 | #include <com/sun/star/container/XContainer.hpp> | ||||
55 | #include <com/sun/star/script/XStarBasicAccess.hpp> | ||||
56 | #include <com/sun/star/script/XStarBasicModuleInfo.hpp> | ||||
57 | #include <com/sun/star/script/XStarBasicDialogInfo.hpp> | ||||
58 | #include <com/sun/star/script/XStarBasicLibraryInfo.hpp> | ||||
59 | #include <com/sun/star/script/XLibraryContainerPassword.hpp> | ||||
60 | #include <com/sun/star/script/ModuleInfo.hpp> | ||||
61 | #include <com/sun/star/script/vba/XVBACompatibility.hpp> | ||||
62 | #include <com/sun/star/script/vba/XVBAModuleInfo.hpp> | ||||
63 | #include <com/sun/star/ucb/ContentCreationException.hpp> | ||||
64 | |||||
65 | #include <cppuhelper/implbase.hxx> | ||||
66 | |||||
67 | using com::sun::star::uno::Reference; | ||||
68 | using namespace com::sun::star; | ||||
69 | using namespace com::sun::star::script; | ||||
70 | using namespace cppu; | ||||
71 | |||||
72 | typedef WeakImplHelper< container::XNameContainer > NameContainerHelper; | ||||
73 | typedef WeakImplHelper< script::XStarBasicModuleInfo > ModuleInfoHelper; | ||||
74 | typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper; | ||||
75 | |||||
76 | // Version 1 | ||||
77 | // sal_uInt32 nEndPos | ||||
78 | // sal_uInt16 nId | ||||
79 | // sal_uInt16 nVer | ||||
80 | // bool bDoLoad | ||||
81 | // String LibName | ||||
82 | // String AbsStorageName | ||||
83 | // String RelStorageName | ||||
84 | // Version 2 | ||||
85 | // + bool bReference | ||||
86 | |||||
87 | const char szStdLibName[] = "Standard"; | ||||
88 | const char szBasicStorage[] = "StarBASIC"; | ||||
89 | const char szOldManagerStream[] = "BasicManager"; | ||||
90 | const char szManagerStream[] = "BasicManager2"; | ||||
91 | const char szImbedded[] = "LIBIMBEDDED"; | ||||
92 | const char szCryptingKey[] = "CryptedBasic"; | ||||
93 | |||||
94 | |||||
95 | const StreamMode eStreamReadMode = StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL; | ||||
96 | const StreamMode eStorageReadMode = StreamMode::READ | StreamMode::SHARE_DENYWRITE; | ||||
97 | |||||
98 | |||||
99 | // BasicManager impl data | ||||
100 | struct BasicManagerImpl | ||||
101 | { | ||||
102 | LibraryContainerInfo maContainerInfo; | ||||
103 | |||||
104 | std::vector<std::unique_ptr<BasicLibInfo>> aLibs; | ||||
105 | OUString aBasicLibPath; | ||||
106 | |||||
107 | BasicManagerImpl() | ||||
108 | {} | ||||
109 | }; | ||||
110 | |||||
111 | // BasMgrContainerListenerImpl | ||||
112 | |||||
113 | |||||
114 | typedef ::cppu::WeakImplHelper< container::XContainerListener > ContainerListenerHelper; | ||||
115 | |||||
116 | class BasMgrContainerListenerImpl: public ContainerListenerHelper | ||||
117 | { | ||||
118 | BasicManager* mpMgr; | ||||
119 | OUString maLibName; // empty -> no lib, but lib container | ||||
120 | |||||
121 | public: | ||||
122 | BasMgrContainerListenerImpl( BasicManager* pMgr, const OUString& aLibName ) | ||||
123 | : mpMgr( pMgr ) | ||||
124 | , maLibName( aLibName ) {} | ||||
125 | |||||
126 | static void insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, BasicManager* pMgr, | ||||
127 | const uno::Any& aLibAny, const OUString& aLibName ); | ||||
128 | static void addLibraryModulesImpl( BasicManager const * pMgr, const uno::Reference< container::XNameAccess >& xLibNameAccess, | ||||
129 | const OUString& aLibName ); | ||||
130 | |||||
131 | |||||
132 | // XEventListener | ||||
133 | virtual void SAL_CALL disposing( const lang::EventObject& Source ) override; | ||||
134 | |||||
135 | // XContainerListener | ||||
136 | virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) override; | ||||
137 | virtual void SAL_CALL elementReplaced( const container::ContainerEvent& Event ) override; | ||||
138 | virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) override; | ||||
139 | }; | ||||
140 | |||||
141 | |||||
142 | // BasMgrContainerListenerImpl | ||||
143 | |||||
144 | |||||
145 | void BasMgrContainerListenerImpl::insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, | ||||
146 | BasicManager* pMgr, const uno::Any& aLibAny, const OUString& aLibName ) | ||||
147 | { | ||||
148 | Reference< container::XNameAccess > xLibNameAccess; | ||||
149 | aLibAny >>= xLibNameAccess; | ||||
150 | |||||
151 | if( !pMgr->GetLib( aLibName ) ) | ||||
152 | { | ||||
153 | StarBASIC* pLib = | ||||
154 | pMgr->CreateLibForLibContainer( aLibName, xScriptCont ); | ||||
155 | DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "155" ": "), "%s", "XML Import: Basic library could not be created" ); } } while (false); | ||||
156 | } | ||||
157 | |||||
158 | uno::Reference< container::XContainer> xLibContainer( xLibNameAccess, uno::UNO_QUERY ); | ||||
159 | if( xLibContainer.is() ) | ||||
160 | { | ||||
161 | // Register listener for library | ||||
162 | Reference< container::XContainerListener > xLibraryListener | ||||
163 | = new BasMgrContainerListenerImpl( pMgr, aLibName ); | ||||
164 | xLibContainer->addContainerListener( xLibraryListener ); | ||||
165 | } | ||||
166 | |||||
167 | if( xScriptCont->isLibraryLoaded( aLibName ) ) | ||||
168 | { | ||||
169 | addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName ); | ||||
170 | } | ||||
171 | } | ||||
172 | |||||
173 | |||||
174 | void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager const * pMgr, | ||||
175 | const uno::Reference< container::XNameAccess >& xLibNameAccess, const OUString& aLibName ) | ||||
176 | { | ||||
177 | uno::Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames(); | ||||
178 | sal_Int32 nModuleCount = aModuleNames.getLength(); | ||||
179 | |||||
180 | StarBASIC* pLib = pMgr->GetLib( aLibName ); | ||||
181 | DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "181" ": "), "%s", "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!" ); } } while (false); | ||||
182 | if( !pLib ) | ||||
183 | return; | ||||
184 | |||||
185 | const OUString* pNames = aModuleNames.getConstArray(); | ||||
186 | for( sal_Int32 j = 0 ; j < nModuleCount ; j++ ) | ||||
187 | { | ||||
188 | OUString aModuleName = pNames[ j ]; | ||||
189 | uno::Any aElement = xLibNameAccess->getByName( aModuleName ); | ||||
190 | OUString aMod; | ||||
191 | aElement >>= aMod; | ||||
192 | uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, uno::UNO_QUERY ); | ||||
193 | if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) ) | ||||
194 | { | ||||
195 | ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aModuleName ); | ||||
196 | pLib->MakeModule( aModuleName, aInfo, aMod ); | ||||
197 | } | ||||
198 | else | ||||
199 | pLib->MakeModule( aModuleName, aMod ); | ||||
200 | } | ||||
201 | |||||
202 | pLib->SetModified( false ); | ||||
203 | } | ||||
204 | |||||
205 | |||||
206 | // XEventListener | ||||
207 | |||||
208 | |||||
209 | void SAL_CALL BasMgrContainerListenerImpl::disposing( const lang::EventObject& ) {} | ||||
210 | |||||
211 | // XContainerListener | ||||
212 | |||||
213 | |||||
214 | void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const container::ContainerEvent& Event ) | ||||
215 | { | ||||
216 | bool bLibContainer = maLibName.isEmpty(); | ||||
217 | OUString aName; | ||||
218 | Event.Accessor >>= aName; | ||||
219 | |||||
220 | if( bLibContainer ) | ||||
221 | { | ||||
222 | uno::Reference< script::XLibraryContainer > xScriptCont( Event.Source, uno::UNO_QUERY ); | ||||
223 | if (xScriptCont.is()) | ||||
224 | insertLibraryImpl(xScriptCont, mpMgr, Event.Element, aName); | ||||
225 | StarBASIC* pLib = mpMgr->GetLib( aName ); | ||||
226 | if ( pLib ) | ||||
227 | { | ||||
228 | uno::Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, uno::UNO_QUERY ); | ||||
229 | if ( xVBACompat.is() ) | ||||
230 | pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() ); | ||||
231 | } | ||||
232 | } | ||||
233 | else | ||||
234 | { | ||||
235 | |||||
236 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | ||||
237 | DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "237" ": "), "%s", "BasMgrContainerListenerImpl::elementInserted: Unknown lib!" ); } } while (false); | ||||
238 | if( pLib ) | ||||
239 | { | ||||
240 | SbModule* pMod = pLib->FindModule( aName ); | ||||
241 | if( !pMod ) | ||||
242 | { | ||||
243 | OUString aMod; | ||||
244 | Event.Element >>= aMod; | ||||
245 | uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, uno::UNO_QUERY ); | ||||
246 | if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) ) | ||||
247 | { | ||||
248 | ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aName ); | ||||
249 | pLib->MakeModule( aName, aInfo, aMod ); | ||||
250 | } | ||||
251 | else | ||||
252 | pLib->MakeModule( aName, aMod ); | ||||
253 | pLib->SetModified( false ); | ||||
254 | } | ||||
255 | } | ||||
256 | } | ||||
257 | } | ||||
258 | |||||
259 | |||||
260 | void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const container::ContainerEvent& Event ) | ||||
261 | { | ||||
262 | OUString aName; | ||||
263 | Event.Accessor >>= aName; | ||||
264 | |||||
265 | // Replace not possible for library container | ||||
266 | DBG_ASSERT( !maLibName.isEmpty(), "library container fired elementReplaced()")do { if (true && (!(!maLibName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "266" ": "), "%s", "library container fired elementReplaced()" ); } } while (false); | ||||
267 | |||||
268 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | ||||
269 | if( !pLib ) | ||||
270 | return; | ||||
271 | |||||
272 | SbModule* pMod = pLib->FindModule( aName ); | ||||
273 | OUString aMod; | ||||
274 | Event.Element >>= aMod; | ||||
275 | |||||
276 | if( pMod ) | ||||
277 | pMod->SetSource32( aMod ); | ||||
278 | else | ||||
279 | pLib->MakeModule( aName, aMod ); | ||||
280 | |||||
281 | pLib->SetModified( false ); | ||||
282 | } | ||||
283 | |||||
284 | |||||
285 | void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const container::ContainerEvent& Event ) | ||||
286 | { | ||||
287 | OUString aName; | ||||
288 | Event.Accessor >>= aName; | ||||
289 | |||||
290 | bool bLibContainer = maLibName.isEmpty(); | ||||
291 | if( bLibContainer ) | ||||
292 | { | ||||
293 | StarBASIC* pLib = mpMgr->GetLib( aName ); | ||||
294 | if( pLib ) | ||||
295 | { | ||||
296 | sal_uInt16 nLibId = mpMgr->GetLibId( aName ); | ||||
297 | mpMgr->RemoveLib( nLibId, false ); | ||||
298 | } | ||||
299 | } | ||||
300 | else | ||||
301 | { | ||||
302 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | ||||
303 | SbModule* pMod = pLib ? pLib->FindModule( aName ) : nullptr; | ||||
304 | if( pMod ) | ||||
305 | { | ||||
306 | pLib->Remove( pMod ); | ||||
307 | pLib->SetModified( false ); | ||||
308 | } | ||||
309 | } | ||||
310 | } | ||||
311 | |||||
312 | BasicError::BasicError( ErrCode nId, BasicErrorReason nR ) | ||||
313 | { | ||||
314 | nErrorId = nId; | ||||
315 | nReason = nR; | ||||
316 | } | ||||
317 | |||||
318 | BasicError::BasicError( const BasicError& rErr ) | ||||
319 | { | ||||
320 | nErrorId = rErr.nErrorId; | ||||
321 | nReason = rErr.nReason; | ||||
322 | } | ||||
323 | |||||
324 | |||||
325 | class BasicLibInfo | ||||
326 | { | ||||
327 | private: | ||||
328 | StarBASICRef xLib; | ||||
329 | OUString aLibName; | ||||
330 | OUString aStorageName; // string is sufficient, unique at runtime | ||||
331 | OUString aRelStorageName; | ||||
332 | OUString aPassword; | ||||
333 | |||||
334 | bool bDoLoad; | ||||
335 | bool bReference; | ||||
336 | |||||
337 | // Lib represents library in new UNO library container | ||||
338 | uno::Reference< script::XLibraryContainer > mxScriptCont; | ||||
339 | |||||
340 | public: | ||||
341 | BasicLibInfo(); | ||||
342 | |||||
343 | bool IsReference() const { return bReference; } | ||||
344 | void SetReference(bool b) { bReference = b; } | ||||
345 | |||||
346 | bool IsExtern() const { return aStorageName != szImbedded; } | ||||
347 | |||||
348 | void SetStorageName( const OUString& rName ) { aStorageName = rName; } | ||||
349 | const OUString& GetStorageName() const { return aStorageName; } | ||||
350 | |||||
351 | void SetRelStorageName( const OUString& rN ) { aRelStorageName = rN; } | ||||
352 | const OUString& GetRelStorageName() const { return aRelStorageName; } | ||||
353 | |||||
354 | StarBASICRef GetLib() const | ||||
355 | { | ||||
356 | if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) && | ||||
357 | !mxScriptCont->isLibraryLoaded( aLibName ) ) | ||||
358 | return StarBASICRef(); | ||||
359 | return xLib; | ||||
360 | } | ||||
361 | StarBASICRef& GetLibRef() { return xLib; } | ||||
362 | void SetLib( StarBASIC* pBasic ) { xLib = pBasic; } | ||||
363 | |||||
364 | const OUString& GetLibName() const { return aLibName; } | ||||
365 | void SetLibName( const OUString& rName ) { aLibName = rName; } | ||||
366 | |||||
367 | // Only temporary for Load/Save | ||||
368 | bool DoLoad() { return bDoLoad; } | ||||
369 | |||||
370 | bool HasPassword() const { return !aPassword.isEmpty(); } | ||||
371 | const OUString& GetPassword() const { return aPassword; } | ||||
372 | void SetPassword( const OUString& rNewPassword ) | ||||
373 | { aPassword = rNewPassword; } | ||||
374 | |||||
375 | static BasicLibInfo* Create( SotStorageStream& rSStream ); | ||||
376 | |||||
377 | const uno::Reference< script::XLibraryContainer >& GetLibraryContainer() const | ||||
378 | { return mxScriptCont; } | ||||
379 | void SetLibraryContainer( const uno::Reference< script::XLibraryContainer >& xScriptCont ) | ||||
380 | { mxScriptCont = xScriptCont; } | ||||
381 | }; | ||||
382 | |||||
383 | |||||
384 | BasicLibInfo::BasicLibInfo() | ||||
385 | : aStorageName(szImbedded) | ||||
386 | , aRelStorageName(szImbedded) | ||||
387 | , bDoLoad(false) | ||||
388 | , bReference(false) | ||||
389 | { | ||||
390 | } | ||||
391 | |||||
392 | BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream ) | ||||
393 | { | ||||
394 | BasicLibInfo* pInfo = new BasicLibInfo; | ||||
395 | |||||
396 | sal_uInt32 nEndPos; | ||||
397 | sal_uInt16 nId; | ||||
398 | sal_uInt16 nVer; | ||||
399 | |||||
400 | rSStream.ReadUInt32( nEndPos ); | ||||
401 | rSStream.ReadUInt16( nId ); | ||||
402 | rSStream.ReadUInt16( nVer ); | ||||
403 | |||||
404 | DBG_ASSERT( nId == LIBINFO_ID, "No BasicLibInfo?!" )do { if (true && (!(nId == 0x1491))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "404" ": "), "%s", "No BasicLibInfo?!"); } } while (false ); | ||||
405 | if( nId == LIBINFO_ID0x1491 ) | ||||
406 | { | ||||
407 | // Reload? | ||||
408 | bool bDoLoad; | ||||
409 | rSStream.ReadCharAsBool( bDoLoad ); | ||||
410 | pInfo->bDoLoad = bDoLoad; | ||||
411 | |||||
412 | // The name of the lib... | ||||
413 | OUString aName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | ||||
414 | pInfo->SetLibName( aName ); | ||||
415 | |||||
416 | // Absolute path... | ||||
417 | OUString aStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | ||||
418 | pInfo->SetStorageName( aStorageName ); | ||||
419 | |||||
420 | // Relative path... | ||||
421 | OUString aRelStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | ||||
422 | pInfo->SetRelStorageName( aRelStorageName ); | ||||
423 | |||||
424 | if ( nVer >= 2 ) | ||||
425 | { | ||||
426 | bool bReferenz; | ||||
427 | rSStream.ReadCharAsBool( bReferenz ); | ||||
428 | pInfo->SetReference(bReferenz); | ||||
429 | } | ||||
430 | |||||
431 | rSStream.Seek( nEndPos ); | ||||
432 | } | ||||
433 | return pInfo; | ||||
434 | } | ||||
435 | |||||
436 | BasicManager::BasicManager( SotStorage& rStorage, const OUString& rBaseURL, StarBASIC* pParentFromStdLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr ) | ||||
437 | { | ||||
438 | Init(); | ||||
439 | |||||
440 | if( pLibPath ) | ||||
441 | { | ||||
442 | mpImpl->aBasicLibPath = *pLibPath; | ||||
443 | } | ||||
444 | OUString aStorName( rStorage.GetName() ); | ||||
445 | maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | ||||
446 | |||||
447 | |||||
448 | // If there is no Manager Stream, no further actions are necessary | ||||
449 | if ( rStorage.IsStream( szManagerStream ) ) | ||||
450 | { | ||||
451 | LoadBasicManager( rStorage, rBaseURL ); | ||||
452 | // StdLib contains Parent: | ||||
453 | StarBASIC* pStdLib = GetStdLib(); | ||||
454 | DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" )do { if (true && (!(pStdLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "454" ": "), "%s", "Standard-Lib not loaded?"); } } while (false); | ||||
455 | if ( !pStdLib ) | ||||
456 | { | ||||
457 | // Should never happen, but if it happens we won't crash... | ||||
458 | pStdLib = new StarBASIC( nullptr, mbDocMgr ); | ||||
459 | |||||
460 | if (mpImpl->aLibs.empty()) | ||||
461 | CreateLibInfo(); | ||||
462 | |||||
463 | BasicLibInfo& rStdLibInfo = *mpImpl->aLibs.front(); | ||||
464 | |||||
465 | rStdLibInfo.SetLib( pStdLib ); | ||||
466 | StarBASICRef xStdLib = rStdLibInfo.GetLib(); | ||||
467 | xStdLib->SetName( szStdLibName ); | ||||
468 | rStdLibInfo.SetLibName( szStdLibName ); | ||||
469 | xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | ||||
470 | xStdLib->SetModified( false ); | ||||
471 | } | ||||
472 | else | ||||
473 | { | ||||
474 | pStdLib->SetParent( pParentFromStdLib ); | ||||
475 | // The other get StdLib as parent: | ||||
476 | |||||
477 | for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ ) | ||||
478 | { | ||||
479 | StarBASIC* pBasic = GetLib( nBasic ); | ||||
480 | if ( pBasic ) | ||||
481 | { | ||||
482 | pStdLib->Insert( pBasic ); | ||||
483 | pBasic->SetFlag( SbxFlagBits::ExtSearch ); | ||||
484 | } | ||||
485 | } | ||||
486 | // Modified through insert | ||||
487 | pStdLib->SetModified( false ); | ||||
488 | } | ||||
489 | } | ||||
490 | else | ||||
491 | { | ||||
492 | ImpCreateStdLib( pParentFromStdLib ); | ||||
493 | if ( rStorage.IsStream( szOldManagerStream ) ) | ||||
494 | LoadOldBasicManager( rStorage ); | ||||
495 | } | ||||
496 | } | ||||
497 | |||||
498 | static void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo ) | ||||
499 | { | ||||
500 | uno::Reference< script::XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() ); | ||||
501 | if ( !xScriptCont.is() ) | ||||
502 | return; | ||||
503 | |||||
504 | OUString aLibName = pBasic->GetName(); | ||||
505 | if( !xScriptCont->hasByName( aLibName ) ) | ||||
506 | xScriptCont->createLibrary( aLibName ); | ||||
507 | |||||
508 | uno::Any aLibAny = xScriptCont->getByName( aLibName ); | ||||
509 | uno::Reference< container::XNameContainer > xLib; | ||||
510 | aLibAny >>= xLib; | ||||
511 | if ( !xLib.is() ) | ||||
512 | return; | ||||
513 | |||||
514 | for ( const auto& pModule: pBasic->GetModules() ) | ||||
515 | { | ||||
516 | OUString aModName = pModule->GetName(); | ||||
517 | if( !xLib->hasByName( aModName ) ) | ||||
518 | { | ||||
519 | OUString aSource = pModule->GetSource32(); | ||||
520 | uno::Any aSourceAny; | ||||
521 | aSourceAny <<= aSource; | ||||
522 | xLib->insertByName( aModName, aSourceAny ); | ||||
523 | } | ||||
524 | } | ||||
525 | } | ||||
526 | |||||
527 | const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const | ||||
528 | { | ||||
529 | return mpImpl->maContainerInfo.mxDialogCont; | ||||
530 | } | ||||
531 | |||||
532 | const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const | ||||
533 | { | ||||
534 | return mpImpl->maContainerInfo.mxScriptCont; | ||||
535 | } | ||||
536 | |||||
537 | void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo ) | ||||
538 | { | ||||
539 | mpImpl->maContainerInfo = rInfo; | ||||
540 | |||||
541 | uno::Reference< script::XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() ); | ||||
542 | if( xScriptCont.is() ) | ||||
543 | { | ||||
544 | // Register listener for lib container | ||||
545 | uno::Reference< container::XContainerListener > xLibContainerListener | ||||
546 | = new BasMgrContainerListenerImpl( this, "" ); | ||||
547 | |||||
548 | uno::Reference< container::XContainer> xLibContainer( xScriptCont, uno::UNO_QUERY ); | ||||
549 | xLibContainer->addContainerListener( xLibContainerListener ); | ||||
550 | |||||
551 | const uno::Sequence< OUString > aScriptLibNames = xScriptCont->getElementNames(); | ||||
552 | |||||
553 | if( aScriptLibNames.hasElements() ) | ||||
554 | { | ||||
555 | for(const auto& rScriptLibName : aScriptLibNames) | ||||
556 | { | ||||
557 | uno::Any aLibAny = xScriptCont->getByName( rScriptLibName ); | ||||
558 | |||||
559 | if ( rScriptLibName == "Standard" || rScriptLibName == "VBAProject") | ||||
560 | xScriptCont->loadLibrary( rScriptLibName ); | ||||
561 | |||||
562 | BasMgrContainerListenerImpl::insertLibraryImpl | ||||
563 | ( xScriptCont, this, aLibAny, rScriptLibName ); | ||||
564 | } | ||||
565 | } | ||||
566 | else | ||||
567 | { | ||||
568 | // No libs? Maybe an 5.2 document already loaded | ||||
569 | for (auto const& rpBasLibInfo : mpImpl->aLibs) | ||||
570 | { | ||||
571 | StarBASIC* pLib = rpBasLibInfo->GetLib().get(); | ||||
572 | if( !pLib ) | ||||
573 | { | ||||
574 | bool bLoaded = ImpLoadLibrary( rpBasLibInfo.get(), nullptr ); | ||||
575 | if( bLoaded ) | ||||
576 | pLib = rpBasLibInfo->GetLib().get(); | ||||
577 | } | ||||
578 | if( pLib ) | ||||
579 | { | ||||
580 | copyToLibraryContainer( pLib, mpImpl->maContainerInfo ); | ||||
581 | if (rpBasLibInfo->HasPassword()) | ||||
582 | { | ||||
583 | OldBasicPassword* pOldBasicPassword = | ||||
584 | mpImpl->maContainerInfo.mpOldBasicPassword; | ||||
585 | if( pOldBasicPassword ) | ||||
586 | { | ||||
587 | pOldBasicPassword->setLibraryPassword( | ||||
588 | pLib->GetName(), rpBasLibInfo->GetPassword() ); | ||||
589 | } | ||||
590 | } | ||||
591 | } | ||||
592 | } | ||||
593 | } | ||||
594 | } | ||||
595 | |||||
596 | SetGlobalUNOConstant( "BasicLibraries", uno::Any( mpImpl->maContainerInfo.mxScriptCont ) ); | ||||
597 | SetGlobalUNOConstant( "DialogLibraries", uno::Any( mpImpl->maContainerInfo.mxDialogCont ) ); | ||||
598 | } | ||||
599 | |||||
600 | BasicManager::BasicManager( StarBASIC* pSLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr ) | ||||
601 | { | ||||
602 | Init(); | ||||
603 | DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" )do { if (true && (!(pSLib))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "603" ": "), "%s", "BasicManager cannot be created with a NULL-Pointer!" ); } } while (false); | ||||
604 | |||||
605 | if( pLibPath ) | ||||
606 | { | ||||
607 | mpImpl->aBasicLibPath = *pLibPath; | ||||
608 | } | ||||
609 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | ||||
610 | pStdLibInfo->SetLib( pSLib ); | ||||
611 | StarBASICRef xStdLib = pStdLibInfo->GetLib(); | ||||
612 | xStdLib->SetName(szStdLibName); | ||||
613 | pStdLibInfo->SetLibName(szStdLibName ); | ||||
614 | pSLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | ||||
615 | |||||
616 | // Save is only necessary if basic has changed | ||||
617 | xStdLib->SetModified( false ); | ||||
618 | } | ||||
619 | |||||
620 | void BasicManager::ImpMgrNotLoaded( const OUString& rStorageName ) | ||||
621 | { | ||||
622 | // pErrInf is only destroyed if the error os processed by an | ||||
623 | // ErrorHandler | ||||
624 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), rStorageName, DialogMask::ButtonsOk ); | ||||
625 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM); | ||||
626 | |||||
627 | // Create a stdlib otherwise we crash! | ||||
628 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | ||||
629 | pStdLibInfo->SetLib( new StarBASIC( nullptr, mbDocMgr ) ); | ||||
630 | StarBASICRef xStdLib = pStdLibInfo->GetLib(); | ||||
631 | xStdLib->SetName( szStdLibName ); | ||||
632 | pStdLibInfo->SetLibName( szStdLibName ); | ||||
633 | xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | ||||
634 | xStdLib->SetModified( false ); | ||||
635 | } | ||||
636 | |||||
637 | |||||
638 | void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib ) | ||||
639 | { | ||||
640 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | ||||
641 | StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr ); | ||||
642 | pStdLibInfo->SetLib( pStdLib ); | ||||
643 | pStdLib->SetName( szStdLibName ); | ||||
644 | pStdLibInfo->SetLibName( szStdLibName ); | ||||
645 | pStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | ||||
646 | } | ||||
647 | |||||
648 | void BasicManager::LoadBasicManager( SotStorage& rStorage, const OUString& rBaseURL ) | ||||
649 | { | ||||
650 | tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szManagerStream, eStreamReadMode ); | ||||
651 | |||||
652 | OUString aStorName( rStorage.GetName() ); | ||||
653 | // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); | ||||
654 | |||||
655 | if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) ) | ||||
656 | { | ||||
657 | ImpMgrNotLoaded( aStorName ); | ||||
658 | return; | ||||
659 | } | ||||
660 | |||||
661 | maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | ||||
662 | // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name"); | ||||
663 | |||||
664 | OUString aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL | ||||
665 | |||||
666 | if ( !rBaseURL.isEmpty() ) | ||||
667 | { | ||||
668 | INetURLObject aObj( rBaseURL ); | ||||
669 | if ( aObj.GetProtocol() == INetProtocol::File ) | ||||
670 | { | ||||
671 | aRealStorageName = aObj.PathToFileName(); | ||||
672 | } | ||||
673 | } | ||||
674 | |||||
675 | xManagerStream->SetBufferSize( 1024 ); | ||||
676 | xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | ||||
677 | |||||
678 | sal_uInt32 nEndPos; | ||||
679 | xManagerStream->ReadUInt32( nEndPos ); | ||||
680 | |||||
681 | sal_uInt16 nLibs; | ||||
682 | xManagerStream->ReadUInt16( nLibs ); | ||||
683 | // Plausibility! | ||||
684 | if( nLibs & 0xF000 ) | ||||
685 | { | ||||
686 | SAL_WARN( "basic", "BasicManager-Stream defect!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager-Stream defect!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BasicManager-Stream defect!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager-Stream defect!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BasicManager-Stream defect!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
687 | return; | ||||
688 | } | ||||
689 | const size_t nMinBasicLibSize(8); | ||||
690 | const size_t nMaxPossibleLibs = xManagerStream->remainingSize() / nMinBasicLibSize; | ||||
691 | if (nLibs > nMaxPossibleLibs) | ||||
692 | { | ||||
693 | SAL_WARN("basic", "Parsing error: " << nMaxPossibleLibs <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||
694 | " max possible entries, but " << nLibs << " claimed, truncating")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
695 | nLibs = nMaxPossibleLibs; | ||||
696 | } | ||||
697 | for (sal_uInt16 nL = 0; nL < nLibs; ++nL) | ||||
698 | { | ||||
699 | BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream ); | ||||
700 | |||||
701 | // Correct absolute pathname if relative is existing. | ||||
702 | // Always try relative first if there are two stands on disk | ||||
703 | if ( !pInfo->GetRelStorageName().isEmpty() && pInfo->GetRelStorageName() != szImbedded ) | ||||
704 | { | ||||
705 | INetURLObject aObj( aRealStorageName, INetProtocol::File ); | ||||
706 | aObj.removeSegment(); | ||||
707 | bool bWasAbsolute = false; | ||||
708 | aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute ); | ||||
709 | |||||
710 | //*** TODO: Replace if still necessary | ||||
711 | //*** TODO-End | ||||
712 | if ( ! mpImpl->aBasicLibPath.isEmpty() ) | ||||
713 | { | ||||
714 | // Search lib in path | ||||
715 | OUString aSearchFile = pInfo->GetRelStorageName(); | ||||
716 | OUString aSearchFileOldFormat(aSearchFile); | ||||
717 | SvtPathOptions aPathCFG; | ||||
718 | if( aPathCFG.SearchFile( aSearchFileOldFormat, SvtPathOptions::PATH_BASIC ) ) | ||||
719 | { | ||||
720 | pInfo->SetStorageName( aSearchFile ); | ||||
721 | } | ||||
722 | } | ||||
723 | } | ||||
724 | |||||
725 | mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInfo)); | ||||
726 | // Libs from external files should be loaded only when necessary. | ||||
727 | // But references are loaded at once, otherwise some big customers get into trouble | ||||
728 | if ( pInfo->DoLoad() && | ||||
729 | ( !pInfo->IsExtern() || pInfo->IsReference())) | ||||
730 | { | ||||
731 | ImpLoadLibrary( pInfo, &rStorage ); | ||||
732 | } | ||||
733 | } | ||||
734 | |||||
735 | xManagerStream->Seek( nEndPos ); | ||||
736 | xManagerStream->SetBufferSize( 0 ); | ||||
737 | xManagerStream.clear(); | ||||
738 | } | ||||
739 | |||||
740 | void BasicManager::LoadOldBasicManager( SotStorage& rStorage ) | ||||
741 | { | ||||
742 | tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szOldManagerStream, eStreamReadMode ); | ||||
743 | |||||
744 | OUString aStorName( rStorage.GetName() ); | ||||
745 | DBG_ASSERT( aStorName.getLength(), "No Storage Name!" )do { if (true && (!(aStorName.getLength()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "745" ": "), "%s", "No Storage Name!"); } } while (false ); | ||||
746 | |||||
747 | if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) ) | ||||
748 | { | ||||
749 | ImpMgrNotLoaded( aStorName ); | ||||
750 | return; | ||||
751 | } | ||||
752 | |||||
753 | xManagerStream->SetBufferSize( 1024 ); | ||||
754 | xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | ||||
755 | sal_uInt32 nBasicStartOff, nBasicEndOff; | ||||
756 | xManagerStream->ReadUInt32( nBasicStartOff ); | ||||
757 | xManagerStream->ReadUInt32( nBasicEndOff ); | ||||
758 | |||||
759 | DBG_ASSERT( !xManagerStream->GetError(), "Invalid Manager-Stream!" )do { if (true && (!(!xManagerStream->GetError()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "759" ": "), "%s", "Invalid Manager-Stream!"); } } while (false); | ||||
760 | |||||
761 | xManagerStream->Seek( nBasicStartOff ); | ||||
762 | if (!ImplLoadBasic( *xManagerStream, mpImpl->aLibs.front()->GetLibRef() )) | ||||
763 | { | ||||
764 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), aStorName, DialogMask::ButtonsOk ); | ||||
765 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM); | ||||
766 | // and it proceeds ... | ||||
767 | } | ||||
768 | xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator | ||||
769 | OUString aLibs = xManagerStream->ReadUniOrByteString(xManagerStream->GetStreamCharSet()); | ||||
770 | xManagerStream->SetBufferSize( 0 ); | ||||
771 | xManagerStream.clear(); // Close stream | ||||
772 | |||||
773 | if ( aLibs.isEmpty() ) | ||||
774 | return; | ||||
775 | |||||
776 | INetURLObject aCurStorage( aStorName, INetProtocol::File ); | ||||
777 | sal_Int32 nLibPos {0}; | ||||
778 | do { | ||||
779 | const OUString aLibInfo(aLibs.getToken(0, LIB_SEP0x01, nLibPos)); | ||||
780 | sal_Int32 nInfoPos {0}; | ||||
781 | const OUString aLibName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | ||||
782 | DBG_ASSERT( nInfoPos >= 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "782" ": "), "%s", "Invalid Lib-Info!"); } } while (false ); | ||||
783 | const OUString aLibAbsStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | ||||
784 | // TODO: fail also here if there are no more tokens? | ||||
785 | const OUString aLibRelStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | ||||
786 | DBG_ASSERT( nInfoPos < 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos < 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "786" ": "), "%s", "Invalid Lib-Info!"); } } while (false ); | ||||
787 | INetURLObject aLibAbsStorage( aLibAbsStorageName, INetProtocol::File ); | ||||
788 | |||||
789 | INetURLObject aLibRelStorage( aStorName ); | ||||
790 | aLibRelStorage.removeSegment(); | ||||
791 | bool bWasAbsolute = false; | ||||
792 | aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute); | ||||
793 | DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" )do { if (true && (!(!bWasAbsolute))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "793" ": "), "%s", "RelStorageName was absolute!"); } } while (false); | ||||
794 | |||||
795 | tools::SvRef<SotStorage> xStorageRef; | ||||
796 | if ( aLibAbsStorage == aCurStorage || aLibRelStorageName == szImbedded ) | ||||
797 | { | ||||
798 | xStorageRef = &rStorage; | ||||
799 | } | ||||
800 | else | ||||
801 | { | ||||
802 | xStorageRef = new SotStorage( false, aLibAbsStorage.GetMainURL | ||||
803 | ( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode ); | ||||
804 | if ( xStorageRef->GetError() != ERRCODE_NONEErrCode(0) ) | ||||
805 | xStorageRef = new SotStorage( false, aLibRelStorage. | ||||
806 | GetMainURL( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode ); | ||||
807 | } | ||||
808 | if ( xStorageRef.is() ) | ||||
809 | { | ||||
810 | AddLib( *xStorageRef, aLibName, false ); | ||||
811 | } | ||||
812 | else | ||||
813 | { | ||||
814 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), aStorName, DialogMask::ButtonsOk ); | ||||
815 | aErrors.emplace_back(*pErrInf, BasicErrorReason::STORAGENOTFOUND); | ||||
816 | } | ||||
817 | } while (nLibPos>=0); | ||||
818 | } | ||||
819 | |||||
820 | BasicManager::~BasicManager() | ||||
821 | { | ||||
822 | // Notify listener if something needs to be saved | ||||
823 | Broadcast( SfxHint( SfxHintId::Dying) ); | ||||
824 | } | ||||
825 | |||||
826 | bool BasicManager::HasExeCode( const OUString& sLib ) | ||||
827 | { | ||||
828 | StarBASIC* pLib = GetLib(sLib); | ||||
829 | if ( pLib ) | ||||
830 | { | ||||
831 | for (const auto& pModule: pLib->GetModules()) | ||||
832 | { | ||||
833 | if (pModule->HasExeCode()) | ||||
834 | return true; | ||||
835 | } | ||||
836 | } | ||||
837 | return false; | ||||
838 | } | ||||
839 | |||||
840 | void BasicManager::Init() | ||||
841 | { | ||||
842 | mpImpl.reset( new BasicManagerImpl ); | ||||
843 | } | ||||
844 | |||||
845 | BasicLibInfo* BasicManager::CreateLibInfo() | ||||
846 | { | ||||
847 | BasicLibInfo* pInf(new BasicLibInfo); | ||||
848 | mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInf)); | ||||
849 | return pInf; | ||||
850 | } | ||||
851 | |||||
852 | bool BasicManager::ImpLoadLibrary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage ) | ||||
853 | { | ||||
854 | try { | ||||
855 | DBG_ASSERT( pLibInfo, "LibInfo!?" )do { if (true && (!(pLibInfo))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "855" ": "), "%s", "LibInfo!?"); } } while (false); | ||||
856 | |||||
857 | OUString aStorageName( pLibInfo->GetStorageName() ); | ||||
858 | if ( aStorageName.isEmpty() || aStorageName == szImbedded ) | ||||
859 | { | ||||
860 | aStorageName = GetStorageName(); | ||||
861 | } | ||||
862 | tools::SvRef<SotStorage> xStorage; | ||||
863 | // The current must not be opened again... | ||||
864 | if ( pCurStorage ) | ||||
865 | { | ||||
866 | OUString aStorName( pCurStorage->GetName() ); | ||||
867 | // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); | ||||
868 | |||||
869 | INetURLObject aCurStorageEntry(aStorName, INetProtocol::File); | ||||
870 | // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name"); | ||||
871 | |||||
872 | INetURLObject aStorageEntry(aStorageName, INetProtocol::File); | ||||
873 | // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name"); | ||||
874 | |||||
875 | if ( aCurStorageEntry == aStorageEntry ) | ||||
876 | { | ||||
877 | xStorage = pCurStorage; | ||||
878 | } | ||||
879 | } | ||||
880 | |||||
881 | if ( !xStorage.is() ) | ||||
882 | { | ||||
883 | xStorage = new SotStorage( false, aStorageName, eStorageReadMode ); | ||||
884 | } | ||||
885 | tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage( szBasicStorage, eStorageReadMode, false ); | ||||
886 | |||||
887 | if ( !xBasicStorage.is() || xBasicStorage->GetError() ) | ||||
888 | { | ||||
889 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), xStorage->GetName(), DialogMask::ButtonsOk ); | ||||
890 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE); | ||||
891 | } | ||||
892 | else | ||||
893 | { | ||||
894 | // In the Basic-Storage every lib is in a Stream... | ||||
895 | tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode ); | ||||
896 | if ( !xBasicStream.is() || xBasicStream->GetError() ) | ||||
897 | { | ||||
898 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124) , pLibInfo->GetLibName(), DialogMask::ButtonsOk ); | ||||
899 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTREAM); | ||||
900 | } | ||||
901 | else | ||||
902 | { | ||||
903 | bool bLoaded = false; | ||||
904 | if ( xBasicStream->TellEnd() != 0 ) | ||||
905 | { | ||||
906 | if ( !pLibInfo->GetLib().is() ) | ||||
907 | { | ||||
908 | pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) ); | ||||
909 | } | ||||
910 | xBasicStream->SetBufferSize( 1024 ); | ||||
911 | xBasicStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | ||||
912 | bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() ); | ||||
913 | xBasicStream->SetBufferSize( 0 ); | ||||
914 | StarBASICRef xStdLib = pLibInfo->GetLib(); | ||||
915 | xStdLib->SetName( pLibInfo->GetLibName() ); | ||||
916 | xStdLib->SetModified( false ); | ||||
917 | xStdLib->SetFlag( SbxFlagBits::DontStore ); | ||||
918 | } | ||||
919 | if ( !bLoaded ) | ||||
920 | { | ||||
921 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), pLibInfo->GetLibName(), DialogMask::ButtonsOk ); | ||||
922 | aErrors.emplace_back(*pErrInf, BasicErrorReason::BASICLOADERROR); | ||||
923 | } | ||||
924 | else | ||||
925 | { | ||||
926 | // Perhaps there are additional information in the stream... | ||||
927 | xBasicStream->SetCryptMaskKey(szCryptingKey); | ||||
928 | xBasicStream->RefreshBuffer(); | ||||
929 | sal_uInt32 nPasswordMarker = 0; | ||||
930 | xBasicStream->ReadUInt32( nPasswordMarker ); | ||||
931 | if ( ( nPasswordMarker == PASSWORD_MARKER0x31452134 ) && !xBasicStream->eof() ) | ||||
932 | { | ||||
933 | OUString aPassword = xBasicStream->ReadUniOrByteString( | ||||
934 | xBasicStream->GetStreamCharSet()); | ||||
935 | pLibInfo->SetPassword( aPassword ); | ||||
936 | } | ||||
937 | xBasicStream->SetCryptMaskKey(OString()); | ||||
938 | CheckModules( pLibInfo->GetLib().get(), pLibInfo->IsReference() ); | ||||
939 | } | ||||
940 | return bLoaded; | ||||
941 | } | ||||
942 | } | ||||
943 | } | ||||
944 | catch (const css::ucb::ContentCreationException&) | ||||
945 | { | ||||
946 | } | ||||
947 | return false; | ||||
948 | } | ||||
949 | |||||
950 | bool BasicManager::ImplEncryptStream( SvStream& rStrm ) | ||||
951 | { | ||||
952 | sal_uInt64 const nPos = rStrm.Tell(); | ||||
953 | sal_uInt32 nCreator; | ||||
954 | rStrm.ReadUInt32( nCreator ); | ||||
955 | rStrm.Seek( nPos ); | ||||
956 | bool bProtected = false; | ||||
957 | if ( nCreator != SBXCR_SBX ) | ||||
958 | { | ||||
959 | // Should only be the case for encrypted Streams | ||||
960 | bProtected = true; | ||||
961 | rStrm.SetCryptMaskKey(szCryptingKey); | ||||
962 | rStrm.RefreshBuffer(); | ||||
963 | } | ||||
964 | return bProtected; | ||||
965 | } | ||||
966 | |||||
967 | // This code is necessary to load the BASIC of Beta 1 | ||||
968 | // TODO: Which Beta 1? | ||||
969 | bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const | ||||
970 | { | ||||
971 | bool bProtected = ImplEncryptStream( rStrm ); | ||||
972 | SbxBaseRef xNew = SbxBase::Load( rStrm ); | ||||
973 | bool bLoaded = false; | ||||
974 | if( xNew.is() ) | ||||
975 | { | ||||
976 | if( auto pNew = dynamic_cast<StarBASIC*>( xNew.get() ) ) | ||||
977 | { | ||||
978 | // Use the Parent of the old BASICs | ||||
979 | if( rOldBasic.is() ) | ||||
980 | { | ||||
981 | pNew->SetParent( rOldBasic->GetParent() ); | ||||
982 | if( pNew->GetParent() ) | ||||
983 | { | ||||
984 | pNew->GetParent()->Insert( pNew ); | ||||
985 | } | ||||
986 | pNew->SetFlag( SbxFlagBits::ExtSearch ); | ||||
987 | } | ||||
988 | rOldBasic = pNew; | ||||
989 | |||||
990 | // Fill new library container (5.2 -> 6.0) | ||||
991 | copyToLibraryContainer( pNew, mpImpl->maContainerInfo ); | ||||
992 | |||||
993 | pNew->SetModified( false ); | ||||
994 | bLoaded = true; | ||||
995 | } | ||||
996 | } | ||||
997 | if ( bProtected ) | ||||
998 | { | ||||
999 | rStrm.SetCryptMaskKey(OString()); | ||||
1000 | } | ||||
1001 | return bLoaded; | ||||
1002 | } | ||||
1003 | |||||
1004 | void BasicManager::CheckModules( StarBASIC* pLib, bool bReference ) | ||||
1005 | { | ||||
1006 | if ( !pLib ) | ||||
1007 | { | ||||
1008 | return; | ||||
1009 | } | ||||
1010 | bool bModified = pLib->IsModified(); | ||||
1011 | |||||
1012 | for ( const auto& pModule: pLib->GetModules() ) | ||||
1013 | { | ||||
1014 | DBG_ASSERT(pModule, "Module not received!")do { if (true && (!(pModule))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1014" ": "), "%s", "Module not received!"); } } while ( false); | ||||
1015 | if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() ) | ||||
1016 | { | ||||
1017 | pModule->Compile(); | ||||
1018 | } | ||||
1019 | } | ||||
1020 | |||||
1021 | // #67477, AB 8.12.99 On demand compile in referenced libs should not | ||||
1022 | // cause modified | ||||
1023 | if( !bModified && bReference ) | ||||
1024 | { | ||||
1025 | OSL_FAIL( "Referenced basic library is not compiled!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1025" ": "), "%s", "Referenced basic library is not compiled!" ); } } while (false); | ||||
1026 | pLib->SetModified( false ); | ||||
1027 | } | ||||
1028 | } | ||||
1029 | |||||
1030 | StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const OUString& rLibName, bool bReference ) | ||||
1031 | { | ||||
1032 | OUString aStorName( rStorage.GetName() ); | ||||
1033 | DBG_ASSERT( !aStorName.isEmpty(), "No Storage Name!" )do { if (true && (!(!aStorName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1033" ": "), "%s", "No Storage Name!"); } } while (false ); | ||||
1034 | |||||
1035 | OUString aStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | ||||
1036 | DBG_ASSERT(!aStorageName.isEmpty(), "Bad storage name")do { if (true && (!(!aStorageName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1036" ": "), "%s", "Bad storage name"); } } while (false ); | ||||
1037 | |||||
1038 | OUString aNewLibName( rLibName ); | ||||
1039 | while ( HasLib( aNewLibName ) ) | ||||
1040 | { | ||||
1041 | aNewLibName += "_"; | ||||
1042 | } | ||||
1043 | BasicLibInfo* pLibInfo = CreateLibInfo(); | ||||
1044 | // Use original name otherwise ImpLoadLibrary fails... | ||||
1045 | pLibInfo->SetLibName( rLibName ); | ||||
1046 | // but doesn't work this way if name exists twice | ||||
1047 | sal_uInt16 nLibId = static_cast<sal_uInt16>(mpImpl->aLibs.size()) - 1; | ||||
1048 | |||||
1049 | // Set StorageName before load because it is compared with pCurStorage | ||||
1050 | pLibInfo->SetStorageName( aStorageName ); | ||||
1051 | bool bLoaded = ImpLoadLibrary( pLibInfo, &rStorage ); | ||||
1052 | |||||
1053 | if ( bLoaded
| ||||
1054 | { | ||||
1055 | if ( aNewLibName != rLibName ) | ||||
1056 | { | ||||
1057 | pLibInfo->SetLibName(aNewLibName); | ||||
1058 | } | ||||
1059 | if ( bReference
| ||||
1060 | { | ||||
1061 | pLibInfo->GetLib()->SetModified( false ); // Don't save in this case | ||||
1062 | pLibInfo->SetRelStorageName( OUString() ); | ||||
1063 | pLibInfo->SetReference(true); | ||||
1064 | } | ||||
1065 | else | ||||
1066 | { | ||||
1067 | pLibInfo->GetLib()->SetModified( true ); // Must be saved after Add! | ||||
1068 | pLibInfo->SetStorageName( szImbedded ); // Save in BasicManager-Storage | ||||
1069 | } | ||||
1070 | } | ||||
1071 | else | ||||
1072 | { | ||||
1073 | RemoveLib( nLibId, false ); | ||||
1074 | pLibInfo = nullptr; | ||||
1075 | } | ||||
1076 | |||||
1077 | return pLibInfo
| ||||
| |||||
1078 | |||||
1079 | } | ||||
1080 | |||||
1081 | bool BasicManager::IsReference( sal_uInt16 nLib ) | ||||
1082 | { | ||||
1083 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1083" ": "), "%s", "Lib does not exist!"); } } while (false ); | ||||
1084 | if ( nLib < mpImpl->aLibs.size() ) | ||||
1085 | { | ||||
1086 | return mpImpl->aLibs[nLib]->IsReference(); | ||||
1087 | } | ||||
1088 | return false; | ||||
1089 | } | ||||
1090 | |||||
1091 | void BasicManager::RemoveLib( sal_uInt16 nLib ) | ||||
1092 | { | ||||
1093 | // Only physical deletion if no reference | ||||
1094 | RemoveLib( nLib, !IsReference( nLib ) ); | ||||
1095 | } | ||||
1096 | |||||
1097 | bool BasicManager::RemoveLib( sal_uInt16 nLib, bool bDelBasicFromStorage ) | ||||
1098 | { | ||||
1099 | DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" )do { if (true && (!(nLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1099" ": "), "%s", "Standard-Lib cannot be removed!"); } } while (false); | ||||
1100 | |||||
1101 | DBG_ASSERT( !nLib || nLib < mpImpl->aLibs.size(), "Lib not found!" )do { if (true && (!(!nLib || nLib < mpImpl->aLibs .size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN) , ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1101" ": "), "%s", "Lib not found!"); } } while (false); | ||||
1102 | |||||
1103 | if( !nLib || nLib < mpImpl->aLibs.size() ) | ||||
1104 | { | ||||
1105 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk ); | ||||
1106 | aErrors.emplace_back(*pErrInf, BasicErrorReason::STDLIB); | ||||
1107 | return false; | ||||
1108 | } | ||||
1109 | |||||
1110 | auto const itLibInfo = mpImpl->aLibs.begin() + nLib; | ||||
1111 | |||||
1112 | // If one of the streams cannot be opened, this is not an error, | ||||
1113 | // because BASIC was never written before... | ||||
1114 | if (bDelBasicFromStorage && !(*itLibInfo)->IsReference() && | ||||
1115 | (!(*itLibInfo)->IsExtern() || SotStorage::IsStorageFile((*itLibInfo)->GetStorageName()))) | ||||
1116 | { | ||||
1117 | tools::SvRef<SotStorage> xStorage; | ||||
1118 | try | ||||
1119 | { | ||||
1120 | if (!(*itLibInfo)->IsExtern()) | ||||
1121 | { | ||||
1122 | xStorage = new SotStorage(false, GetStorageName()); | ||||
1123 | } | ||||
1124 | else | ||||
1125 | { | ||||
1126 | xStorage = new SotStorage(false, (*itLibInfo)->GetStorageName()); | ||||
1127 | } | ||||
1128 | } | ||||
1129 | catch (const css::ucb::ContentCreationException&) | ||||
1130 | { | ||||
1131 | TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | ||||
1132 | } | ||||
1133 | |||||
1134 | if (xStorage.is() && xStorage->IsStorage(szBasicStorage)) | ||||
1135 | { | ||||
1136 | tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage | ||||
1137 | ( szBasicStorage, StreamMode::STD_READWRITE, false ); | ||||
1138 | |||||
1139 | if ( !xBasicStorage.is() || xBasicStorage->GetError() ) | ||||
1140 | { | ||||
1141 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk ); | ||||
1142 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE); | ||||
1143 | } | ||||
1144 | else if (xBasicStorage->IsStream((*itLibInfo)->GetLibName())) | ||||
1145 | { | ||||
1146 | xBasicStorage->Remove((*itLibInfo)->GetLibName()); | ||||
1147 | xBasicStorage->Commit(); | ||||
1148 | |||||
1149 | // If no further stream available, | ||||
1150 | // delete the SubStorage. | ||||
1151 | SvStorageInfoList aInfoList; | ||||
1152 | xBasicStorage->FillInfoList( &aInfoList ); | ||||
1153 | if ( aInfoList.empty() ) | ||||
1154 | { | ||||
1155 | xBasicStorage.clear(); | ||||
1156 | xStorage->Remove( szBasicStorage ); | ||||
1157 | xStorage->Commit(); | ||||
1158 | // If no further Streams or SubStorages available, | ||||
1159 | // delete the Storage, too. | ||||
1160 | aInfoList.clear(); | ||||
1161 | xStorage->FillInfoList( &aInfoList ); | ||||
1162 | if ( aInfoList.empty() ) | ||||
1163 | { | ||||
1164 | //OUString aName_( xStorage->GetName() ); | ||||
1165 | xStorage.clear(); | ||||
1166 | //*** TODO: Replace if still necessary | ||||
1167 | //SfxContentHelper::Kill( aName ); | ||||
1168 | //*** TODO-End | ||||
1169 | } | ||||
1170 | } | ||||
1171 | } | ||||
1172 | } | ||||
1173 | } | ||||
1174 | if ((*itLibInfo)->GetLib().is()) | ||||
1175 | { | ||||
1176 | GetStdLib()->Remove( (*itLibInfo)->GetLib().get() ); | ||||
1177 | } | ||||
1178 | mpImpl->aLibs.erase(itLibInfo); | ||||
1179 | return true; // Remove was successful, del unimportant | ||||
1180 | } | ||||
1181 | |||||
1182 | sal_uInt16 BasicManager::GetLibCount() const | ||||
1183 | { | ||||
1184 | return static_cast<sal_uInt16>(mpImpl->aLibs.size()); | ||||
1185 | } | ||||
1186 | |||||
1187 | StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const | ||||
1188 | { | ||||
1189 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1189" ": "), "%s", "Lib does not exist!"); } } while (false ); | ||||
1190 | if ( nLib < mpImpl->aLibs.size() ) | ||||
1191 | { | ||||
1192 | return mpImpl->aLibs[nLib]->GetLib().get(); | ||||
1193 | } | ||||
1194 | return nullptr; | ||||
1195 | } | ||||
1196 | |||||
1197 | StarBASIC* BasicManager::GetStdLib() const | ||||
1198 | { | ||||
1199 | StarBASIC* pLib = GetLib( 0 ); | ||||
1200 | return pLib; | ||||
1201 | } | ||||
1202 | |||||
1203 | StarBASIC* BasicManager::GetLib( const OUString& rName ) const | ||||
1204 | { | ||||
1205 | for (auto const& rpLib : mpImpl->aLibs) | ||||
1206 | { | ||||
1207 | if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available... | ||||
1208 | { | ||||
1209 | return rpLib->GetLib().get(); | ||||
1210 | } | ||||
1211 | } | ||||
1212 | return nullptr; | ||||
1213 | } | ||||
1214 | |||||
1215 | sal_uInt16 BasicManager::GetLibId( const OUString& rName ) const | ||||
1216 | { | ||||
1217 | for (size_t i = 0; i < mpImpl->aLibs.size(); i++) | ||||
1218 | { | ||||
1219 | if (mpImpl->aLibs[i]->GetLibName().equalsIgnoreAsciiCase( rName )) | ||||
1220 | { | ||||
1221 | return static_cast<sal_uInt16>(i); | ||||
1222 | } | ||||
1223 | } | ||||
1224 | return LIB_NOTFOUND0xFFFF; | ||||
1225 | } | ||||
1226 | |||||
1227 | bool BasicManager::HasLib( const OUString& rName ) const | ||||
1228 | { | ||||
1229 | for (const auto& rpLib : mpImpl->aLibs) | ||||
1230 | { | ||||
1231 | if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available... | ||||
1232 | { | ||||
1233 | return true; | ||||
1234 | } | ||||
1235 | } | ||||
1236 | return false; | ||||
1237 | } | ||||
1238 | |||||
1239 | OUString BasicManager::GetLibName( sal_uInt16 nLib ) | ||||
1240 | { | ||||
1241 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1241" ": "), "%s", "Lib?!"); } } while (false); | ||||
1242 | if ( nLib < mpImpl->aLibs.size() ) | ||||
1243 | { | ||||
1244 | return mpImpl->aLibs[nLib]->GetLibName(); | ||||
1245 | } | ||||
1246 | return OUString(); | ||||
1247 | } | ||||
1248 | |||||
1249 | bool BasicManager::LoadLib( sal_uInt16 nLib ) | ||||
1250 | { | ||||
1251 | bool bDone = false; | ||||
1252 | DBG_ASSERT( nLib < mpImpl->aLibs.size() , "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1252" ": "), "%s", "Lib?!"); } } while (false); | ||||
1253 | if ( nLib < mpImpl->aLibs.size() ) | ||||
1254 | { | ||||
1255 | BasicLibInfo& rLibInfo = *mpImpl->aLibs[nLib]; | ||||
1256 | uno::Reference< script::XLibraryContainer > xLibContainer = rLibInfo.GetLibraryContainer(); | ||||
1257 | if( xLibContainer.is() ) | ||||
1258 | { | ||||
1259 | OUString aLibName = rLibInfo.GetLibName(); | ||||
1260 | xLibContainer->loadLibrary( aLibName ); | ||||
1261 | bDone = xLibContainer->isLibraryLoaded( aLibName ); | ||||
1262 | } | ||||
1263 | else | ||||
1264 | { | ||||
1265 | bDone = ImpLoadLibrary( &rLibInfo, nullptr ); | ||||
1266 | StarBASIC* pLib = GetLib( nLib ); | ||||
1267 | if ( pLib ) | ||||
1268 | { | ||||
1269 | GetStdLib()->Insert( pLib ); | ||||
1270 | pLib->SetFlag( SbxFlagBits::ExtSearch ); | ||||
1271 | } | ||||
1272 | } | ||||
1273 | } | ||||
1274 | else | ||||
1275 | { | ||||
1276 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), OUString(), DialogMask::ButtonsOk ); | ||||
1277 | aErrors.emplace_back(*pErrInf, BasicErrorReason::LIBNOTFOUND); | ||||
1278 | } | ||||
1279 | return bDone; | ||||
1280 | } | ||||
1281 | |||||
1282 | StarBASIC* BasicManager::CreateLib( const OUString& rLibName ) | ||||
1283 | { | ||||
1284 | if ( GetLib( rLibName ) ) | ||||
1285 | { | ||||
1286 | return nullptr; | ||||
1287 | } | ||||
1288 | BasicLibInfo* pLibInfo = CreateLibInfo(); | ||||
1289 | StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); | ||||
1290 | GetStdLib()->Insert( pNew ); | ||||
1291 | pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore ); | ||||
1292 | pLibInfo->SetLib( pNew ); | ||||
1293 | pLibInfo->SetLibName( rLibName ); | ||||
1294 | pLibInfo->GetLib()->SetName( rLibName ); | ||||
1295 | return pLibInfo->GetLib().get(); | ||||
1296 | } | ||||
1297 | |||||
1298 | // For XML import/export: | ||||
1299 | StarBASIC* BasicManager::CreateLib( const OUString& rLibName, const OUString& Password, | ||||
1300 | const OUString& LinkTargetURL ) | ||||
1301 | { | ||||
1302 | // Ask if lib exists because standard lib is always there | ||||
1303 | StarBASIC* pLib = GetLib( rLibName ); | ||||
1304 | if( !pLib ) | ||||
1305 | { | ||||
1306 | if( !LinkTargetURL.isEmpty()) | ||||
1307 | { | ||||
1308 | try | ||||
1309 | { | ||||
1310 | tools::SvRef<SotStorage> xStorage = new SotStorage(false, LinkTargetURL, StreamMode::READ | StreamMode::SHARE_DENYWRITE); | ||||
1311 | if (!xStorage->GetError()) | ||||
1312 | { | ||||
1313 | pLib = AddLib(*xStorage, rLibName, true); | ||||
1314 | } | ||||
1315 | } | ||||
1316 | catch (const css::ucb::ContentCreationException&) | ||||
1317 | { | ||||
1318 | TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | ||||
1319 | } | ||||
1320 | DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1320" ": "), "%s", "XML Import: Linked basic library could not be loaded" ); } } while (false); | ||||
1321 | } | ||||
1322 | else | ||||
1323 | { | ||||
1324 | pLib = CreateLib( rLibName ); | ||||
1325 | if( Password.isEmpty()) | ||||
1326 | { | ||||
1327 | BasicLibInfo* pLibInfo = FindLibInfo( pLib ); | ||||
1328 | pLibInfo ->SetPassword( Password ); | ||||
1329 | } | ||||
1330 | } | ||||
1331 | //ExternalSourceURL ? | ||||
1332 | } | ||||
1333 | return pLib; | ||||
1334 | } | ||||
1335 | |||||
1336 | StarBASIC* BasicManager::CreateLibForLibContainer( const OUString& rLibName, | ||||
1337 | const uno::Reference< script::XLibraryContainer >& xScriptCont ) | ||||
1338 | { | ||||
1339 | if ( GetLib( rLibName ) ) | ||||
1340 | { | ||||
1341 | return nullptr; | ||||
1342 | } | ||||
1343 | BasicLibInfo* pLibInfo = CreateLibInfo(); | ||||
1344 | StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); | ||||
1345 | GetStdLib()->Insert( pNew ); | ||||
1346 | pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore ); | ||||
1347 | pLibInfo->SetLib( pNew ); | ||||
1348 | pLibInfo->SetLibName( rLibName ); | ||||
1349 | pLibInfo->GetLib()->SetName( rLibName ); | ||||
1350 | pLibInfo->SetLibraryContainer( xScriptCont ); | ||||
1351 | return pNew; | ||||
1352 | } | ||||
1353 | |||||
1354 | |||||
1355 | BasicLibInfo* BasicManager::FindLibInfo( StarBASIC const * pBasic ) | ||||
1356 | { | ||||
1357 | for (auto const& rpLib : mpImpl->aLibs) | ||||
1358 | { | ||||
1359 | if (rpLib->GetLib().get() == pBasic) | ||||
1360 | { | ||||
1361 | return rpLib.get(); | ||||
1362 | } | ||||
1363 | } | ||||
1364 | return nullptr; | ||||
1365 | } | ||||
1366 | |||||
1367 | |||||
1368 | bool BasicManager::IsBasicModified() const | ||||
1369 | { | ||||
1370 | for (auto const& rpLib : mpImpl->aLibs) | ||||
1371 | { | ||||
1372 | if (rpLib->GetLib().is() && rpLib->GetLib()->IsModified()) | ||||
1373 | { | ||||
1374 | return true; | ||||
1375 | } | ||||
1376 | } | ||||
1377 | return false; | ||||
1378 | } | ||||
1379 | |||||
1380 | |||||
1381 | bool BasicManager::GetGlobalUNOConstant( const OUString& rName, uno::Any& aOut ) | ||||
1382 | { | ||||
1383 | bool bRes = false; | ||||
1384 | StarBASIC* pStandardLib = GetStdLib(); | ||||
1385 | OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1385" ": "), "%s", "BasicManager::GetGlobalUNOConstant: no lib to read from!" ); } } while (false); | ||||
1386 | if ( pStandardLib ) | ||||
1387 | bRes = pStandardLib->GetUNOConstant( rName, aOut ); | ||||
1388 | return bRes; | ||||
1389 | } | ||||
1390 | |||||
1391 | uno::Any BasicManager::SetGlobalUNOConstant( const OUString& rName, const uno::Any& _rValue ) | ||||
1392 | { | ||||
1393 | uno::Any aOldValue; | ||||
1394 | |||||
1395 | StarBASIC* pStandardLib = GetStdLib(); | ||||
1396 | OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1396" ": "), "%s", "BasicManager::SetGlobalUNOConstant: no lib to insert into!" ); } } while (false); | ||||
1397 | if ( !pStandardLib ) | ||||
1398 | return aOldValue; | ||||
1399 | |||||
1400 | // obtain the old value | ||||
1401 | SbxVariable* pVariable = pStandardLib->Find( rName, SbxClassType::Object ); | ||||
1402 | if ( pVariable ) | ||||
1403 | aOldValue = sbxToUnoValue( pVariable ); | ||||
1404 | SbxObjectRef xUnoObj = GetSbUnoObject( _rValue.getValueType ().getTypeName () , _rValue ); | ||||
1405 | xUnoObj->SetName(rName); | ||||
1406 | xUnoObj->SetFlag( SbxFlagBits::DontStore ); | ||||
1407 | pStandardLib->Insert( xUnoObj.get() ); | ||||
1408 | |||||
1409 | return aOldValue; | ||||
1410 | } | ||||
1411 | |||||
1412 | bool BasicManager::LegacyPsswdBinaryLimitExceeded( std::vector< OUString >& _out_rModuleNames ) | ||||
1413 | { | ||||
1414 | try | ||||
1415 | { | ||||
1416 | uno::Reference< container::XNameAccess > xScripts( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW ); | ||||
1417 | uno::Reference< script::XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW ); | ||||
1418 | |||||
1419 | const uno::Sequence< OUString > aNames( xScripts->getElementNames() ); | ||||
1420 | for ( auto const & scriptElementName : aNames ) | ||||
1421 | { | ||||
1422 | if( !xPassword->isLibraryPasswordProtected( scriptElementName ) ) | ||||
1423 | continue; | ||||
1424 | |||||
1425 | StarBASIC* pBasicLib = GetLib( scriptElementName ); | ||||
1426 | if ( !pBasicLib ) | ||||
1427 | continue; | ||||
1428 | |||||
1429 | uno::Reference< container::XNameAccess > xScriptLibrary( xScripts->getByName( scriptElementName ), uno::UNO_QUERY_THROW ); | ||||
1430 | const uno::Sequence< OUString > aElementNames( xScriptLibrary->getElementNames() ); | ||||
1431 | sal_Int32 nLen = aElementNames.getLength(); | ||||
1432 | |||||
1433 | std::vector< OUString > aBigModules( nLen ); | ||||
1434 | sal_Int32 nBigModules = 0; | ||||
1435 | |||||
1436 | for ( auto const & libraryElementName : aElementNames ) | ||||
1437 | { | ||||
1438 | SbModule* pMod = pBasicLib->FindModule( libraryElementName ); | ||||
1439 | if ( pMod && pMod->ExceedsLegacyModuleSize() ) | ||||
1440 | aBigModules[ nBigModules++ ] = libraryElementName; | ||||
1441 | } | ||||
1442 | |||||
1443 | if ( nBigModules ) | ||||
1444 | { | ||||
1445 | _out_rModuleNames.swap(aBigModules); | ||||
1446 | return true; | ||||
1447 | } | ||||
1448 | } | ||||
1449 | } | ||||
1450 | catch( const uno::Exception& ) | ||||
1451 | { | ||||
1452 | DBG_UNHANDLED_EXCEPTION("basic")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1452" ": ", "basic" );; | ||||
1453 | } | ||||
1454 | return false; | ||||
1455 | } | ||||
1456 | |||||
1457 | |||||
1458 | namespace | ||||
1459 | { | ||||
1460 | SbMethod* lcl_queryMacro( BasicManager* i_manager, OUString const& i_fullyQualifiedName ) | ||||
1461 | { | ||||
1462 | sal_Int32 nLast = 0; | ||||
1463 | const OUString sLibName {i_fullyQualifiedName.getToken( 0, '.', nLast )}; | ||||
1464 | const OUString sModule {i_fullyQualifiedName.getToken( 0, '.', nLast )}; | ||||
1465 | OUString sMacro; | ||||
1466 | if(nLast >= 0) | ||||
1467 | { | ||||
1468 | sMacro = i_fullyQualifiedName.copy(nLast); | ||||
1469 | } | ||||
1470 | else | ||||
1471 | { | ||||
1472 | sMacro = i_fullyQualifiedName; | ||||
1473 | } | ||||
1474 | |||||
1475 | utl::TransliterationWrapper& rTransliteration = SbGlobal::GetTransliteration(); | ||||
1476 | sal_uInt16 nLibCount = i_manager->GetLibCount(); | ||||
1477 | for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib ) | ||||
1478 | { | ||||
1479 | if ( rTransliteration.isEqual( i_manager->GetLibName( nLib ), sLibName ) ) | ||||
1480 | { | ||||
1481 | StarBASIC* pLib = i_manager->GetLib( nLib ); | ||||
1482 | if( !pLib ) | ||||
1483 | { | ||||
1484 | bool const bLoaded = i_manager->LoadLib( nLib ); | ||||
1485 | if (bLoaded) | ||||
1486 | { | ||||
1487 | pLib = i_manager->GetLib( nLib ); | ||||
1488 | } | ||||
1489 | } | ||||
1490 | |||||
1491 | if( pLib ) | ||||
1492 | { | ||||
1493 | for ( const auto& pMod: pLib->GetModules() ) | ||||
1494 | { | ||||
1495 | if ( rTransliteration.isEqual( pMod->GetName(), sModule ) ) | ||||
1496 | { | ||||
1497 | SbMethod* pMethod = static_cast<SbMethod*>(pMod->Find( sMacro, SbxClassType::Method )); | ||||
1498 | if( pMethod ) | ||||
1499 | { | ||||
1500 | return pMethod; | ||||
1501 | } | ||||
1502 | } | ||||
1503 | } | ||||
1504 | } | ||||
1505 | } | ||||
1506 | } | ||||
1507 | return nullptr; | ||||
1508 | } | ||||
1509 | } | ||||
1510 | |||||
1511 | bool BasicManager::HasMacro( OUString const& i_fullyQualifiedName ) const | ||||
1512 | { | ||||
1513 | return ( lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) != nullptr ); | ||||
1514 | } | ||||
1515 | |||||
1516 | ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue ) | ||||
1517 | { | ||||
1518 | SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); | ||||
1519 | ErrCode nError = ERRCODE_NONEErrCode(0); | ||||
1520 | if ( pMethod ) | ||||
1521 | { | ||||
1522 | if ( i_arguments ) | ||||
1523 | pMethod->SetParameters( i_arguments ); | ||||
1524 | nError = pMethod->Call( i_retValue ); | ||||
1525 | } | ||||
1526 | else | ||||
1527 | nError = ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8); | ||||
1528 | return nError; | ||||
1529 | } | ||||
1530 | |||||
1531 | ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, OUString const& i_commaSeparatedArgs, SbxValue* i_retValue ) | ||||
1532 | { | ||||
1533 | SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); | ||||
1534 | if ( !pMethod ) | ||||
1535 | { | ||||
1536 | return ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8); | ||||
1537 | } | ||||
1538 | // arguments must be quoted | ||||
1539 | OUString sQuotedArgs; | ||||
1540 | OUStringBuffer sArgs( i_commaSeparatedArgs ); | ||||
1541 | if ( sArgs.getLength()<2 || sArgs[1] == '\"') | ||||
1542 | { | ||||
1543 | // no args or already quoted args | ||||
1544 | sQuotedArgs = sArgs.makeStringAndClear(); | ||||
1545 | } | ||||
1546 | else | ||||
1547 | { | ||||
1548 | // quote parameters | ||||
1549 | sArgs.remove( 0, 1 ); | ||||
1550 | sArgs.remove( sArgs.getLength() - 1, 1 ); | ||||
1551 | |||||
1552 | OUStringBuffer aBuff; | ||||
1553 | OUString sArgs2 = sArgs.makeStringAndClear(); | ||||
1554 | |||||
1555 | aBuff.append("("); | ||||
1556 | if (!sArgs2.isEmpty()) | ||||
1557 | { | ||||
1558 | |||||
1559 | sal_Int32 nPos {0}; | ||||
1560 | for (;;) | ||||
1561 | { | ||||
1562 | aBuff.append( "\"" ); | ||||
1563 | aBuff.append( sArgs2.getToken(0, ',', nPos) ); | ||||
1564 | aBuff.append( "\"" ); | ||||
1565 | if (nPos<0) | ||||
1566 | break; | ||||
1567 | aBuff.append( "," ); | ||||
1568 | } | ||||
1569 | } | ||||
1570 | aBuff.append( ")" ); | ||||
1571 | |||||
1572 | sQuotedArgs = aBuff.makeStringAndClear(); | ||||
1573 | } | ||||
1574 | |||||
1575 | // add quoted arguments and do the call | ||||
1576 | OUString sCall = "[" | ||||
1577 | + pMethod->GetName() | ||||
1578 | + sQuotedArgs | ||||
1579 | + "]"; | ||||
1580 | |||||
1581 | SbxVariable* pRet = pMethod->GetParent()->Execute( sCall ); | ||||
1582 | if ( pRet && ( pRet != pMethod ) ) | ||||
1583 | { | ||||
1584 | *i_retValue = *pRet; | ||||
1585 | } | ||||
1586 | return SbxBase::GetError(); | ||||
1587 | } | ||||
1588 | |||||
1589 | namespace { | ||||
1590 | |||||
1591 | class ModuleInfo_Impl : public ModuleInfoHelper | ||||
1592 | { | ||||
1593 | OUString maName; | ||||
1594 | OUString maLanguage; | ||||
1595 | OUString maSource; | ||||
1596 | |||||
1597 | public: | ||||
1598 | ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource ) | ||||
1599 | : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {} | ||||
1600 | |||||
1601 | // Methods XStarBasicModuleInfo | ||||
1602 | virtual OUString SAL_CALL getName() override | ||||
1603 | { return maName; } | ||||
1604 | virtual OUString SAL_CALL getLanguage() override | ||||
1605 | { return maLanguage; } | ||||
1606 | virtual OUString SAL_CALL getSource() override | ||||
1607 | { return maSource; } | ||||
1608 | }; | ||||
1609 | |||||
1610 | |||||
1611 | class DialogInfo_Impl : public WeakImplHelper< script::XStarBasicDialogInfo > | ||||
1612 | { | ||||
1613 | OUString maName; | ||||
1614 | uno::Sequence< sal_Int8 > mData; | ||||
1615 | |||||
1616 | public: | ||||
1617 | DialogInfo_Impl( const OUString& aName, const uno::Sequence< sal_Int8 >& Data ) | ||||
1618 | : maName( aName ), mData( Data ) {} | ||||
1619 | |||||
1620 | // Methods XStarBasicDialogInfo | ||||
1621 | virtual OUString SAL_CALL getName() override | ||||
1622 | { return maName; } | ||||
1623 | virtual uno::Sequence< sal_Int8 > SAL_CALL getData() override | ||||
1624 | { return mData; } | ||||
1625 | }; | ||||
1626 | |||||
1627 | |||||
1628 | class LibraryInfo_Impl : public WeakImplHelper< script::XStarBasicLibraryInfo > | ||||
1629 | { | ||||
1630 | OUString maName; | ||||
1631 | uno::Reference< container::XNameContainer > mxModuleContainer; | ||||
1632 | uno::Reference< container::XNameContainer > mxDialogContainer; | ||||
1633 | OUString maPassword; | ||||
1634 | OUString maExternaleSourceURL; | ||||
1635 | OUString maLinkTargetURL; | ||||
1636 | |||||
1637 | public: | ||||
1638 | LibraryInfo_Impl | ||||
1639 | ( | ||||
1640 | const OUString& aName, | ||||
1641 | uno::Reference< container::XNameContainer > const & xModuleContainer, | ||||
1642 | uno::Reference< container::XNameContainer > const & xDialogContainer, | ||||
1643 | const OUString& aPassword, | ||||
1644 | const OUString& aExternaleSourceURL, | ||||
1645 | const OUString& aLinkTargetURL | ||||
1646 | ) | ||||
1647 | : maName( aName ) | ||||
1648 | , mxModuleContainer( xModuleContainer ) | ||||
1649 | , mxDialogContainer( xDialogContainer ) | ||||
1650 | , maPassword( aPassword ) | ||||
1651 | , maExternaleSourceURL( aExternaleSourceURL ) | ||||
1652 | , maLinkTargetURL( aLinkTargetURL ) | ||||
1653 | {} | ||||
1654 | |||||
1655 | // Methods XStarBasicLibraryInfo | ||||
1656 | virtual OUString SAL_CALL getName() override | ||||
1657 | { return maName; } | ||||
1658 | virtual uno::Reference< container::XNameContainer > SAL_CALL getModuleContainer() override | ||||
1659 | { return mxModuleContainer; } | ||||
1660 | virtual uno::Reference< container::XNameContainer > SAL_CALL getDialogContainer() override | ||||
1661 | { return mxDialogContainer; } | ||||
1662 | virtual OUString SAL_CALL getPassword() override | ||||
1663 | { return maPassword; } | ||||
1664 | virtual OUString SAL_CALL getExternalSourceURL() override | ||||
1665 | { return maExternaleSourceURL; } | ||||
1666 | virtual OUString SAL_CALL getLinkTargetURL() override | ||||
1667 | { return maLinkTargetURL; } | ||||
1668 | }; | ||||
1669 | |||||
1670 | |||||
1671 | class ModuleContainer_Impl : public NameContainerHelper | ||||
1672 | { | ||||
1673 | StarBASIC* mpLib; | ||||
1674 | |||||
1675 | public: | ||||
1676 | explicit ModuleContainer_Impl( StarBASIC* pLib ) | ||||
1677 | :mpLib( pLib ) {} | ||||
1678 | |||||
1679 | // Methods XElementAccess | ||||
1680 | virtual uno::Type SAL_CALL getElementType() override; | ||||
1681 | virtual sal_Bool SAL_CALL hasElements() override; | ||||
1682 | |||||
1683 | // Methods XNameAccess | ||||
1684 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | ||||
1685 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | ||||
1686 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | ||||
1687 | |||||
1688 | // Methods XNameReplace | ||||
1689 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1690 | |||||
1691 | // Methods XNameContainer | ||||
1692 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1693 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | ||||
1694 | }; | ||||
1695 | |||||
1696 | } | ||||
1697 | |||||
1698 | // Methods XElementAccess | ||||
1699 | uno::Type ModuleContainer_Impl::getElementType() | ||||
1700 | { | ||||
1701 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get(); | ||||
1702 | return aModuleType; | ||||
1703 | } | ||||
1704 | |||||
1705 | sal_Bool ModuleContainer_Impl::hasElements() | ||||
1706 | { | ||||
1707 | return mpLib && !mpLib->GetModules().empty(); | ||||
1708 | } | ||||
1709 | |||||
1710 | // Methods XNameAccess | ||||
1711 | uno::Any ModuleContainer_Impl::getByName( const OUString& aName ) | ||||
1712 | { | ||||
1713 | SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr; | ||||
1714 | if( !pMod ) | ||||
1715 | throw container::NoSuchElementException(); | ||||
1716 | uno::Reference< script::XStarBasicModuleInfo > xMod = new ModuleInfo_Impl( aName, "StarBasic", pMod->GetSource32() ); | ||||
1717 | uno::Any aRetAny; | ||||
1718 | aRetAny <<= xMod; | ||||
1719 | return aRetAny; | ||||
1720 | } | ||||
1721 | |||||
1722 | uno::Sequence< OUString > ModuleContainer_Impl::getElementNames() | ||||
1723 | { | ||||
1724 | sal_uInt16 nMods = mpLib ? mpLib->GetModules().size() : 0; | ||||
1725 | uno::Sequence< OUString > aRetSeq( nMods ); | ||||
1726 | OUString* pRetSeq = aRetSeq.getArray(); | ||||
1727 | for( sal_uInt16 i = 0 ; i < nMods ; i++ ) | ||||
1728 | { | ||||
1729 | pRetSeq[i] = mpLib->GetModules()[i]->GetName(); | ||||
1730 | } | ||||
1731 | return aRetSeq; | ||||
1732 | } | ||||
1733 | |||||
1734 | sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName ) | ||||
1735 | { | ||||
1736 | SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr; | ||||
1737 | bool bRet = (pMod != nullptr); | ||||
1738 | return bRet; | ||||
1739 | } | ||||
1740 | |||||
1741 | |||||
1742 | // Methods XNameReplace | ||||
1743 | void ModuleContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | ||||
1744 | { | ||||
1745 | removeByName( aName ); | ||||
1746 | insertByName( aName, aElement ); | ||||
1747 | } | ||||
1748 | |||||
1749 | |||||
1750 | // Methods XNameContainer | ||||
1751 | void ModuleContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement ) | ||||
1752 | { | ||||
1753 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get(); | ||||
1754 | const uno::Type& aAnyType = aElement.getValueType(); | ||||
1755 | if( aModuleType != aAnyType ) | ||||
1756 | { | ||||
1757 | throw lang::IllegalArgumentException(); | ||||
1758 | } | ||||
1759 | uno::Reference< script::XStarBasicModuleInfo > xMod; | ||||
1760 | aElement >>= xMod; | ||||
1761 | mpLib->MakeModule( aName, xMod->getSource() ); | ||||
1762 | } | ||||
1763 | |||||
1764 | void ModuleContainer_Impl::removeByName( const OUString& Name ) | ||||
1765 | { | ||||
1766 | SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : nullptr; | ||||
1767 | if( !pMod ) | ||||
1768 | { | ||||
1769 | throw container::NoSuchElementException(); | ||||
1770 | } | ||||
1771 | mpLib->Remove( pMod ); | ||||
1772 | } | ||||
1773 | |||||
1774 | |||||
1775 | static uno::Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog ) | ||||
1776 | { | ||||
1777 | SvMemoryStream aMemStream; | ||||
1778 | pDialog->Store( aMemStream ); | ||||
1779 | sal_Int32 nLen = aMemStream.Tell(); | ||||
1780 | if (nLen < 0) { abort(); } | ||||
1781 | uno::Sequence< sal_Int8 > aData( nLen ); | ||||
1782 | sal_Int8* pDestData = aData.getArray(); | ||||
1783 | const sal_Int8* pSrcData = static_cast<const sal_Int8*>(aMemStream.GetData()); | ||||
1784 | memcpy( pDestData, pSrcData, nLen ); | ||||
1785 | return aData; | ||||
1786 | } | ||||
1787 | |||||
1788 | static SbxObject* implCreateDialog( const uno::Sequence< sal_Int8 >& aData ) | ||||
1789 | { | ||||
1790 | sal_Int8* pData = const_cast< uno::Sequence< sal_Int8 >& >(aData).getArray(); | ||||
1791 | SvMemoryStream aMemStream( pData, aData.getLength(), StreamMode::READ ); | ||||
1792 | SbxBase* pBase = SbxBase::Load( aMemStream ); | ||||
1793 | return dynamic_cast<SbxObject*>(pBase); | ||||
1794 | } | ||||
1795 | |||||
1796 | // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx | ||||
1797 | // which we can't include here, we have to use the value directly | ||||
1798 | #define SBXID_DIALOG101 101 | ||||
1799 | |||||
1800 | namespace { | ||||
1801 | |||||
1802 | class DialogContainer_Impl : public NameContainerHelper | ||||
1803 | { | ||||
1804 | StarBASIC* mpLib; | ||||
1805 | |||||
1806 | public: | ||||
1807 | explicit DialogContainer_Impl( StarBASIC* pLib ) | ||||
1808 | :mpLib( pLib ) {} | ||||
1809 | |||||
1810 | // Methods XElementAccess | ||||
1811 | virtual uno::Type SAL_CALL getElementType() override; | ||||
1812 | virtual sal_Bool SAL_CALL hasElements() override; | ||||
1813 | |||||
1814 | // Methods XNameAccess | ||||
1815 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | ||||
1816 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | ||||
1817 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | ||||
1818 | |||||
1819 | // Methods XNameReplace | ||||
1820 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1821 | |||||
1822 | // Methods XNameContainer | ||||
1823 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1824 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | ||||
1825 | }; | ||||
1826 | |||||
1827 | } | ||||
1828 | |||||
1829 | // Methods XElementAccess | ||||
1830 | uno::Type DialogContainer_Impl::getElementType() | ||||
1831 | { | ||||
1832 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get(); | ||||
1833 | return aModuleType; | ||||
1834 | } | ||||
1835 | |||||
1836 | sal_Bool DialogContainer_Impl::hasElements() | ||||
1837 | { | ||||
1838 | bool bRet = false; | ||||
1839 | |||||
1840 | sal_Int32 nCount = mpLib->GetObjects()->Count32(); | ||||
1841 | for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ ) | ||||
1842 | { | ||||
1843 | SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj ); | ||||
1844 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | ||||
1845 | if ( pObj && (pObj->GetSbxId() == SBXID_DIALOG101 ) ) | ||||
1846 | { | ||||
1847 | bRet = true; | ||||
1848 | break; | ||||
1849 | } | ||||
1850 | } | ||||
1851 | return bRet; | ||||
1852 | } | ||||
1853 | |||||
1854 | // Methods XNameAccess | ||||
1855 | uno::Any DialogContainer_Impl::getByName( const OUString& aName ) | ||||
1856 | { | ||||
1857 | SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare ); | ||||
1858 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | ||||
1859 | if( !( pObj && pObj->GetSbxId() == SBXID_DIALOG101 ) ) | ||||
1860 | { | ||||
1861 | throw container::NoSuchElementException(); | ||||
1862 | } | ||||
1863 | |||||
1864 | uno::Reference< script::XStarBasicDialogInfo > xDialog = | ||||
1865 | new DialogInfo_Impl(aName, implGetDialogData(pObj)); | ||||
1866 | |||||
1867 | uno::Any aRetAny; | ||||
1868 | aRetAny <<= xDialog; | ||||
1869 | return aRetAny; | ||||
1870 | } | ||||
1871 | |||||
1872 | uno::Sequence< OUString > DialogContainer_Impl::getElementNames() | ||||
1873 | { | ||||
1874 | sal_Int32 nCount = mpLib->GetObjects()->Count32(); | ||||
1875 | uno::Sequence< OUString > aRetSeq( nCount ); | ||||
1876 | OUString* pRetSeq = aRetSeq.getArray(); | ||||
1877 | sal_Int32 nDialogCounter = 0; | ||||
1878 | |||||
1879 | for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ ) | ||||
1880 | { | ||||
1881 | SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj ); | ||||
1882 | SbxObject* pObj = dynamic_cast<SbxObject*> (pVar); | ||||
1883 | if ( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) | ||||
1884 | { | ||||
1885 | pRetSeq[ nDialogCounter ] = pVar->GetName(); | ||||
1886 | nDialogCounter++; | ||||
1887 | } | ||||
1888 | } | ||||
1889 | aRetSeq.realloc( nDialogCounter ); | ||||
1890 | return aRetSeq; | ||||
1891 | } | ||||
1892 | |||||
1893 | sal_Bool DialogContainer_Impl::hasByName( const OUString& aName ) | ||||
1894 | { | ||||
1895 | bool bRet = false; | ||||
1896 | SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare ); | ||||
1897 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | ||||
1898 | if( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) | ||||
1899 | { | ||||
1900 | bRet = true; | ||||
1901 | } | ||||
1902 | return bRet; | ||||
1903 | } | ||||
1904 | |||||
1905 | |||||
1906 | // Methods XNameReplace | ||||
1907 | void DialogContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | ||||
1908 | { | ||||
1909 | removeByName( aName ); | ||||
1910 | insertByName( aName, aElement ); | ||||
1911 | } | ||||
1912 | |||||
1913 | |||||
1914 | // Methods XNameContainer | ||||
1915 | void DialogContainer_Impl::insertByName( const OUString&, const uno::Any& aElement ) | ||||
1916 | { | ||||
1917 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get(); | ||||
1918 | const uno::Type& aAnyType = aElement.getValueType(); | ||||
1919 | if( aModuleType != aAnyType ) | ||||
1920 | { | ||||
1921 | throw lang::IllegalArgumentException(); | ||||
1922 | } | ||||
1923 | uno::Reference< script::XStarBasicDialogInfo > xMod; | ||||
1924 | aElement >>= xMod; | ||||
1925 | SbxObjectRef xDialog = implCreateDialog( xMod->getData() ); | ||||
1926 | mpLib->Insert( xDialog.get() ); | ||||
1927 | } | ||||
1928 | |||||
1929 | void DialogContainer_Impl::removeByName( const OUString& Name ) | ||||
1930 | { | ||||
1931 | SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxClassType::DontCare ); | ||||
1932 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | ||||
1933 | if( !( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) ) | ||||
1934 | { | ||||
1935 | throw container::NoSuchElementException(); | ||||
1936 | } | ||||
1937 | mpLib->Remove( pVar ); | ||||
1938 | } | ||||
1939 | |||||
1940 | |||||
1941 | class LibraryContainer_Impl : public NameContainerHelper | ||||
1942 | { | ||||
1943 | BasicManager* mpMgr; | ||||
1944 | |||||
1945 | public: | ||||
1946 | explicit LibraryContainer_Impl( BasicManager* pMgr ) | ||||
1947 | :mpMgr( pMgr ) {} | ||||
1948 | |||||
1949 | // Methods XElementAccess | ||||
1950 | virtual uno::Type SAL_CALL getElementType() override; | ||||
1951 | virtual sal_Bool SAL_CALL hasElements() override; | ||||
1952 | |||||
1953 | // Methods XNameAccess | ||||
1954 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | ||||
1955 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | ||||
1956 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | ||||
1957 | |||||
1958 | // Methods XNameReplace | ||||
1959 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1960 | |||||
1961 | // Methods XNameContainer | ||||
1962 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | ||||
1963 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | ||||
1964 | }; | ||||
1965 | |||||
1966 | |||||
1967 | // Methods XElementAccess | ||||
1968 | uno::Type LibraryContainer_Impl::getElementType() | ||||
1969 | { | ||||
1970 | uno::Type aType = cppu::UnoType<script::XStarBasicLibraryInfo>::get(); | ||||
1971 | return aType; | ||||
1972 | } | ||||
1973 | |||||
1974 | sal_Bool LibraryContainer_Impl::hasElements() | ||||
1975 | { | ||||
1976 | sal_Int32 nLibs = mpMgr->GetLibCount(); | ||||
1977 | bool bRet = (nLibs > 0); | ||||
1978 | return bRet; | ||||
1979 | } | ||||
1980 | |||||
1981 | // Methods XNameAccess | ||||
1982 | uno::Any LibraryContainer_Impl::getByName( const OUString& aName ) | ||||
1983 | { | ||||
1984 | uno::Any aRetAny; | ||||
1985 | if( !mpMgr->HasLib( aName ) ) | ||||
1986 | throw container::NoSuchElementException(); | ||||
1987 | StarBASIC* pLib = mpMgr->GetLib( aName ); | ||||
1988 | |||||
1989 | uno::Reference< container::XNameContainer > xModuleContainer = | ||||
1990 | new ModuleContainer_Impl( pLib ); | ||||
1991 | |||||
1992 | uno::Reference< container::XNameContainer > xDialogContainer = | ||||
1993 | new DialogContainer_Impl( pLib ); | ||||
1994 | |||||
1995 | BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib ); | ||||
1996 | |||||
1997 | OUString aPassword = pLibInfo->GetPassword(); | ||||
1998 | |||||
1999 | // TODO Only provide extern info! | ||||
2000 | OUString aExternaleSourceURL; | ||||
2001 | OUString aLinkTargetURL; | ||||
2002 | if( pLibInfo->IsReference() ) | ||||
2003 | { | ||||
2004 | aLinkTargetURL = pLibInfo->GetStorageName(); | ||||
2005 | } | ||||
2006 | else if( pLibInfo->IsExtern() ) | ||||
2007 | { | ||||
2008 | aExternaleSourceURL = pLibInfo->GetStorageName(); | ||||
2009 | } | ||||
2010 | uno::Reference< script::XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl | ||||
2011 | ( | ||||
2012 | aName, | ||||
2013 | xModuleContainer, | ||||
2014 | xDialogContainer, | ||||
2015 | aPassword, | ||||
2016 | aExternaleSourceURL, | ||||
2017 | aLinkTargetURL | ||||
2018 | ); | ||||
2019 | |||||
2020 | aRetAny <<= xLibInfo; | ||||
2021 | return aRetAny; | ||||
2022 | } | ||||
2023 | |||||
2024 | uno::Sequence< OUString > LibraryContainer_Impl::getElementNames() | ||||
2025 | { | ||||
2026 | sal_uInt16 nLibs = mpMgr->GetLibCount(); | ||||
2027 | uno::Sequence< OUString > aRetSeq( nLibs ); | ||||
2028 | OUString* pRetSeq = aRetSeq.getArray(); | ||||
2029 | for( sal_uInt16 i = 0 ; i < nLibs ; i++ ) | ||||
2030 | { | ||||
2031 | pRetSeq[i] = mpMgr->GetLibName( i ); | ||||
2032 | } | ||||
2033 | return aRetSeq; | ||||
2034 | } | ||||
2035 | |||||
2036 | sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName ) | ||||
2037 | { | ||||
2038 | bool bRet = mpMgr->HasLib( aName ); | ||||
2039 | return bRet; | ||||
2040 | } | ||||
2041 | |||||
2042 | // Methods XNameReplace | ||||
2043 | void LibraryContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | ||||
2044 | { | ||||
2045 | removeByName( aName ); | ||||
2046 | insertByName( aName, aElement ); | ||||
2047 | } | ||||
2048 | |||||
2049 | // Methods XNameContainer | ||||
2050 | void LibraryContainer_Impl::insertByName( const OUString&, const uno::Any& ) | ||||
2051 | { | ||||
2052 | // TODO: Insert a complete Library?! | ||||
2053 | } | ||||
2054 | |||||
2055 | void LibraryContainer_Impl::removeByName( const OUString& Name ) | ||||
2056 | { | ||||
2057 | StarBASIC* pLib = mpMgr->GetLib( Name ); | ||||
2058 | if( !pLib ) | ||||
2059 | { | ||||
2060 | throw container::NoSuchElementException(); | ||||
2061 | } | ||||
2062 | sal_uInt16 nLibId = mpMgr->GetLibId( Name ); | ||||
2063 | mpMgr->RemoveLib( nLibId ); | ||||
2064 | } | ||||
2065 | |||||
2066 | |||||
2067 | typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper; | ||||
2068 | |||||
2069 | |||||
2070 | class StarBasicAccess_Impl : public StarBasicAccessHelper | ||||
2071 | { | ||||
2072 | BasicManager* mpMgr; | ||||
2073 | uno::Reference< container::XNameContainer > mxLibContainer; | ||||
2074 | |||||
2075 | public: | ||||
2076 | explicit StarBasicAccess_Impl( BasicManager* pMgr ) | ||||
2077 | :mpMgr( pMgr ) {} | ||||
2078 | |||||
2079 | public: | ||||
2080 | // Methods | ||||
2081 | virtual uno::Reference< container::XNameContainer > SAL_CALL getLibraryContainer() override; | ||||
2082 | virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password, | ||||
2083 | const OUString& ExternalSourceURL, const OUString& LinkTargetURL ) override; | ||||
2084 | virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName, | ||||
2085 | const OUString& Language, const OUString& Source ) override; | ||||
2086 | virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName, | ||||
2087 | const uno::Sequence< sal_Int8 >& Data ) override; | ||||
2088 | }; | ||||
2089 | |||||
2090 | uno::Reference< container::XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer() | ||||
2091 | { | ||||
2092 | if( !mxLibContainer.is() ) | ||||
2093 | mxLibContainer = new LibraryContainer_Impl( mpMgr ); | ||||
2094 | return mxLibContainer; | ||||
2095 | } | ||||
2096 | |||||
2097 | void SAL_CALL StarBasicAccess_Impl::createLibrary | ||||
2098 | ( | ||||
2099 | const OUString& LibName, | ||||
2100 | const OUString& Password, | ||||
2101 | const OUString&, | ||||
2102 | const OUString& LinkTargetURL | ||||
2103 | ) | ||||
2104 | { | ||||
2105 | StarBASIC* pLib = mpMgr->CreateLib( LibName, Password, LinkTargetURL ); | ||||
| |||||
2106 | DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "2106" ": "), "%s", "XML Import: Basic library could not be created" ); } } while (false); | ||||
2107 | } | ||||
2108 | |||||
2109 | void SAL_CALL StarBasicAccess_Impl::addModule | ||||
2110 | ( | ||||
2111 | const OUString& LibraryName, | ||||
2112 | const OUString& ModuleName, | ||||
2113 | const OUString&, | ||||
2114 | const OUString& Source | ||||
2115 | ) | ||||
2116 | { | ||||
2117 | StarBASIC* pLib = mpMgr->GetLib( LibraryName ); | ||||
2118 | DBG_ASSERT( pLib, "XML Import: Lib for module unknown")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "2118" ": "), "%s", "XML Import: Lib for module unknown" ); } } while (false); | ||||
2119 | if( pLib ) | ||||
2120 | { | ||||
2121 | pLib->MakeModule( ModuleName, Source ); | ||||
2122 | } | ||||
2123 | } | ||||
2124 | |||||
2125 | void SAL_CALL StarBasicAccess_Impl::addDialog | ||||
2126 | ( | ||||
2127 | const OUString&, | ||||
2128 | const OUString&, | ||||
2129 | const uno::Sequence< sal_Int8 >& | ||||
2130 | ) | ||||
2131 | {} | ||||
2132 | |||||
2133 | // Basic XML Import/Export | ||||
2134 | uno::Reference< script::XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr ) | ||||
2135 | { | ||||
2136 | uno::Reference< script::XStarBasicAccess > xRet = | ||||
2137 | new StarBasicAccess_Impl( pMgr ); | ||||
2138 | return xRet; | ||||
2139 | } | ||||
2140 | |||||
2141 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_TOOLS_REF_HXX |
20 | #define INCLUDED_TOOLS_REF_HXX |
21 | |
22 | #include <sal/config.h> |
23 | #include <cassert> |
24 | #include <tools/toolsdllapi.h> |
25 | #include <utility> |
26 | |
27 | /** |
28 | This implements similar functionality to boost::intrusive_ptr |
29 | */ |
30 | |
31 | namespace tools { |
32 | |
33 | /** T must be a class that extends SvRefBase */ |
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { |
35 | public: |
36 | SvRef(): pObj(nullptr) {} |
37 | |
38 | SvRef(SvRef&& rObj) noexcept |
39 | { |
40 | pObj = rObj.pObj; |
41 | rObj.pObj = nullptr; |
42 | } |
43 | |
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) |
45 | { |
46 | if (pObj != nullptr) pObj->AddNextRef(); |
47 | } |
48 | |
49 | SvRef(T * pObjP): pObj(pObjP) |
50 | { |
51 | if (pObj != nullptr) pObj->AddFirstRef(); |
52 | } |
53 | |
54 | ~SvRef() |
55 | { |
56 | if (pObj != nullptr) pObj->ReleaseRef(); |
57 | } |
58 | |
59 | void clear() |
60 | { |
61 | if (pObj != nullptr) { |
62 | T * pRefObj = pObj; |
63 | pObj = nullptr; |
64 | pRefObj->ReleaseRef(); |
65 | } |
66 | } |
67 | |
68 | SvRef & operator =(SvRef const & rObj) |
69 | { |
70 | if (rObj.pObj != nullptr) { |
71 | rObj.pObj->AddNextRef(); |
72 | } |
73 | T * pRefObj = pObj; |
74 | pObj = rObj.pObj; |
75 | if (pRefObj != nullptr) { |
76 | pRefObj->ReleaseRef(); |
77 | } |
78 | return *this; |
79 | } |
80 | |
81 | SvRef & operator =(SvRef && rObj) |
82 | { |
83 | if (pObj != nullptr) { |
84 | pObj->ReleaseRef(); |
85 | } |
86 | pObj = rObj.pObj; |
87 | rObj.pObj = nullptr; |
88 | return *this; |
89 | } |
90 | |
91 | bool is() const { return pObj != nullptr; } |
92 | |
93 | explicit operator bool() const { return is(); } |
94 | |
95 | T * get() const { return pObj; } |
96 | |
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } |
98 | |
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } |
100 | |
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } |
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } |
103 | |
104 | private: |
105 | T * pObj; |
106 | }; |
107 | |
108 | /** |
109 | * This implements similar functionality to std::make_shared. |
110 | */ |
111 | template<typename T, typename... Args> |
112 | SvRef<T> make_ref(Args&& ... args) |
113 | { |
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); |
115 | } |
116 | |
117 | } |
118 | |
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ |
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase |
121 | { |
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* |
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object |
124 | unsigned int nRefCount : 31; |
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields |
126 | unsigned int bNoDelete : 1; |
127 | |
128 | protected: |
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; |
130 | |
131 | public: |
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} |
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} |
134 | |
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } |
136 | |
137 | void RestoreNoDelete() |
138 | { bNoDelete = 1; } |
139 | |
140 | void AddNextRef() |
141 | { |
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); |
143 | ++nRefCount; |
144 | } |
145 | |
146 | void AddFirstRef() |
147 | { |
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); |
149 | if( bNoDelete ) |
150 | bNoDelete = 0; |
151 | ++nRefCount; |
152 | } |
153 | |
154 | void ReleaseRef() |
155 | { |
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); |
157 | if( --nRefCount == 0 && !bNoDelete) |
158 | { |
159 | // I'm not sure about the original purpose of this line, but right now |
160 | // it serves the purpose that anything that attempts to do an AddRef() |
161 | // after an object is deleted will trip an assert. |
162 | nRefCount = 1 << 30; |
163 | delete this; |
164 | } |
165 | } |
166 | |
167 | unsigned int GetRefCount() const |
168 | { return nRefCount; } |
169 | }; |
170 | |
171 | template<typename T> |
172 | class SvCompatWeakBase; |
173 | |
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. |
175 | */ |
176 | template<typename T> |
177 | class SvCompatWeakHdl final : public SvRefBase |
178 | { |
179 | friend class SvCompatWeakBase<T>; |
180 | T* _pObj; |
181 | |
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} |
183 | |
184 | public: |
185 | void ResetWeakBase( ) { _pObj = nullptr; } |
186 | T* GetObj() { return _pObj; } |
187 | }; |
188 | |
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. |
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. |
191 | */ |
192 | template<typename T> |
193 | class SvCompatWeakBase |
194 | { |
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
196 | |
197 | public: |
198 | /** Does not use initializer due to compiler warnings, |
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. |
200 | */ |
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } |
202 | |
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } |
204 | |
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } |
206 | }; |
207 | |
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. |
209 | */ |
210 | template<typename T> |
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef |
212 | { |
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
214 | public: |
215 | SvCompatWeakRef( ) {} |
216 | SvCompatWeakRef( T* pObj ) |
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } |
218 | #if defined(__COVERITY__) |
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} |
220 | #endif |
221 | SvCompatWeakRef& operator = ( T * pObj ) |
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } |
223 | bool is() const |
224 | { return _xHdl.is() && _xHdl->GetObj(); } |
225 | explicit operator bool() const { return is(); } |
226 | T* operator -> () const |
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
228 | operator T* () const |
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
230 | }; |
231 | |
232 | #endif |
233 | |
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |