From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- basctl/source/basicide/iderdll.cxx | 206 +++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 basctl/source/basicide/iderdll.cxx (limited to 'basctl/source/basicide/iderdll.cxx') diff --git a/basctl/source/basicide/iderdll.cxx b/basctl/source/basicide/iderdll.cxx new file mode 100644 index 000000000..8e8a3dc3e --- /dev/null +++ b/basctl/source/basicide/iderdll.cxx @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include + +#include +#include "iderdll2.hxx" +#include +#include +#include +#include "basdoc.hxx" +#include "basicmod.hxx" + +#include +#include +#include +#include +#include +#include + +namespace basctl +{ + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace +{ + +class Dll +{ + Shell* m_pShell; + std::unique_ptr m_xExtraData; + +public: + Dll (); + + Shell* GetShell() const { return m_pShell; } + void SetShell (Shell* pShell) { m_pShell = pShell; } + ExtraData* GetExtraData (); +}; + +// Holds a basctl::Dll and release it on exit, or dispose of the +//default XComponent, whichever comes first +class DllInstance : public comphelper::unique_disposing_solar_mutex_reset_ptr +{ +public: + DllInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr(Reference( frame::Desktop::create(comphelper::getProcessComponentContext()), UNO_QUERY_THROW), new Dll, true) + { } +}; + +struct theDllInstance : public rtl::Static { }; + +} // namespace + +void EnsureIde () +{ + // coverity[side_effect_free : FALSE] - not actually side-effect-free + theDllInstance::get(); +} + +Shell* GetShell () +{ + if (Dll* pDll = theDllInstance::get().get()) + return pDll->GetShell(); + return nullptr; +} + +void ShellCreated (Shell* pShell) +{ + Dll* pDll = theDllInstance::get().get(); + if (pDll && !pDll->GetShell()) + pDll->SetShell(pShell); +} + +void ShellDestroyed (Shell const * pShell) +{ + Dll* pDll = theDllInstance::get().get(); + if (pDll && pDll->GetShell() == pShell) + pDll->SetShell(nullptr); +} + +ExtraData* GetExtraData() +{ + if (Dll* pDll = theDllInstance::get().get()) + return pDll->GetExtraData(); + return nullptr; +} + +OUString IDEResId(TranslateId aId) +{ + return Translate::get(aId, SfxApplication::GetModule(SfxToolsModule::Basic)->GetResLocale()); +} + +namespace +{ + +Dll::Dll () : + m_pShell(nullptr) +{ + SfxObjectFactory& rFactory = DocShell::Factory(); + + auto pModule = std::make_unique("basctl", &rFactory); + SfxModule* pMod = pModule.get(); + SfxApplication::SetModule(SfxToolsModule::Basic, std::move(pModule)); + + GetExtraData(); // to cause GlobalErrorHdl to be set + + rFactory.SetDocumentServiceName( "com.sun.star.script.BasicIDE" ); + + DocShell::RegisterInterface( pMod ); + Shell::RegisterFactory( SVX_INTERFACE_BASIDE_VIEWSH ); + Shell::RegisterInterface( pMod ); +} + +ExtraData* Dll::GetExtraData () +{ + if (!m_xExtraData) + m_xExtraData.reset(new ExtraData); + return m_xExtraData.get(); +} + +} // namespace + + +// basctl::ExtraData + + +ExtraData::ExtraData () : + m_aLastEntryDesc(EntryDescriptor()), + bChoosingMacro(false), + bShellInCriticalSection(false) +{ + StarBASIC::SetGlobalBreakHdl(LINK(this, ExtraData, GlobalBasicBreakHdl)); +} + +ExtraData::~ExtraData () +{ + // Resetting ErrorHdl is cleaner indeed but this instance is destroyed + // pretty late, after the last Basic, anyway. + // Due to the call there is AppData created then though and not + // destroyed anymore => MLK's at Purify +// StarBASIC::SetGlobalErrorHdl( Link() ); +// StarBASIC::SetGlobalBreakHdl( Link() ); +// StarBASIC::setGlobalStarScriptListener( XEngineListenerRef() ); +} + +IMPL_STATIC_LINK(ExtraData, GlobalBasicBreakHdl, StarBASIC *, pBasic, BasicDebugFlags) +{ + BasicDebugFlags nRet = BasicDebugFlags::NONE; + if (Shell* pShell = GetShell()) + { + if (BasicManager* pBasMgr = FindBasicManager(pBasic)) + { + // I do get here twice if Step into protected Basic + // => bad, if password query twice, also you don't see + // the lib in the PasswordDlg... + // => start no password query at this point + ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) ); + OSL_ENSURE( aDocument.isValid(), "basctl::ExtraData::GlobalBasicBreakHdl: no document for the basic manager!" ); + if ( aDocument.isValid() ) + { + OUString aOULibName( pBasic->GetName() ); + Reference< script::XLibraryContainer > xModLibContainer = aDocument.getLibraryContainer( E_SCRIPTS ); + if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) ) + { + Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY ); + if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) ) + { + // a step-out should get me out of the protected area... + nRet = BasicDebugFlags::StepOut; + } + else + { + nRet = pShell->CallBasicBreakHdl( pBasic ); + } + } + } + } + } + + return nRet; +} + + +} // namespace basctl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3