forked from amazingfate/loongoffice
(make from 5 existing only one) Much of what makes up this patch is adapted from existing code that is used to organize and select macros and to assign macros to shortcut keys. Comments in the patch say where code is borrowed from. Known issues: + Scripting framework library rename for BeanShell, Java, and JavaScript always returns fail when there are no macro entries in the library even though it actually succeeds. The same thing happens using SvxScriptOrgDialog::renameEntry. + Deleting Basic macros from the Macro Manager dialog is not implemented yet. Change-Id: If4da04549f8b39675910cbbd1f94dd9a6b73c31a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176254 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
1506 lines
51 KiB
C++
1506 lines
51 KiB
C++
/* -*- 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 <memory>
|
|
#include <basctl/scriptdocument.hxx>
|
|
#include <basobj.hxx>
|
|
#include <strings.hrc>
|
|
#include <iderid.hxx>
|
|
#include <dlgeddef.hxx>
|
|
#include <doceventnotifier.hxx>
|
|
#include "documentenumeration.hxx"
|
|
|
|
#include <com/sun/star/ucb/ContentCreationException.hpp>
|
|
#include <com/sun/star/uri/UriReferenceFactory.hpp>
|
|
#include <com/sun/star/util/theMacroExpander.hpp>
|
|
#include <com/sun/star/frame/XStorable.hpp>
|
|
#include <com/sun/star/frame/FrameSearchFlag.hpp>
|
|
#include <com/sun/star/frame/XDispatchProvider.hpp>
|
|
#include <com/sun/star/awt/XWindow2.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/document/XEmbeddedScripts.hpp>
|
|
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
|
|
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
|
|
#include <com/sun/star/script/ModuleInfo.hpp>
|
|
#include <com/sun/star/script/ModuleType.hpp>
|
|
|
|
#include <sfx2/app.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
#include <sfx2/bindings.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
|
|
#include <basic/basicmanagerrepository.hxx>
|
|
|
|
#include <xmlscript/xmldlg_imexp.hxx>
|
|
|
|
#include <i18nlangtag/languagetag.hxx>
|
|
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <config_folders.h>
|
|
#include <tools/debug.hxx>
|
|
|
|
#include <comphelper/documentinfo.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <comphelper/string.hxx>
|
|
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/settings.hxx>
|
|
|
|
#include <osl/file.hxx>
|
|
#include <rtl/uri.hxx>
|
|
#include <set>
|
|
|
|
|
|
namespace basctl
|
|
{
|
|
using ::com::sun::star::uno::Sequence;
|
|
using ::com::sun::star::uno::Reference;
|
|
using ::com::sun::star::frame::XModel;
|
|
using ::com::sun::star::beans::XPropertySet;
|
|
using ::com::sun::star::script::XLibraryContainer;
|
|
using ::com::sun::star::uno::UNO_QUERY_THROW;
|
|
using ::com::sun::star::uno::UNO_SET_THROW;
|
|
using ::com::sun::star::uno::Exception;
|
|
using ::com::sun::star::container::XNameContainer;
|
|
using ::com::sun::star::container::NoSuchElementException;
|
|
using ::com::sun::star::uno::UNO_QUERY;
|
|
using ::com::sun::star::task::XStatusIndicator;
|
|
using ::com::sun::star::uno::Any;
|
|
using ::com::sun::star::script::XLibraryContainer2;
|
|
using ::com::sun::star::uri::UriReferenceFactory;
|
|
using ::com::sun::star::uri::XUriReferenceFactory;
|
|
using ::com::sun::star::uri::XUriReference;
|
|
using ::com::sun::star::uno::XComponentContext;
|
|
using ::com::sun::star::util::XMacroExpander;
|
|
using ::com::sun::star::util::theMacroExpander;
|
|
using ::com::sun::star::io::XInputStreamProvider;
|
|
using ::com::sun::star::uno::Any;
|
|
using ::com::sun::star::io::XInputStream;
|
|
using ::com::sun::star::frame::XStorable;
|
|
using ::com::sun::star::util::XModifiable;
|
|
using ::com::sun::star::frame::XController;
|
|
using ::com::sun::star::frame::XFrame;
|
|
using ::com::sun::star::util::URL;
|
|
using ::com::sun::star::frame::XDispatchProvider;
|
|
using ::com::sun::star::frame::XDispatch;
|
|
using ::com::sun::star::beans::PropertyValue;
|
|
using ::com::sun::star::awt::XWindow2;
|
|
using ::com::sun::star::document::XEmbeddedScripts;
|
|
using ::com::sun::star::script::ModuleInfo;
|
|
using ::com::sun::star::script::vba::XVBACompatibility;
|
|
using ::com::sun::star::script::vba::XVBAModuleInfo;
|
|
|
|
namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag;
|
|
|
|
|
|
namespace
|
|
{
|
|
class FilterDocuments : public docs::IDocumentDescriptorFilter
|
|
{
|
|
public:
|
|
explicit FilterDocuments(bool _bFilterInvisible)
|
|
: m_bFilterInvisible(_bFilterInvisible)
|
|
{
|
|
}
|
|
|
|
virtual ~FilterDocuments() {}
|
|
|
|
virtual bool includeDocument( const docs::DocumentDescriptor& _rDocument ) const override;
|
|
|
|
private:
|
|
static bool impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument );
|
|
|
|
private:
|
|
bool m_bFilterInvisible;
|
|
};
|
|
|
|
bool FilterDocuments::impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument )
|
|
{
|
|
try
|
|
{
|
|
for (auto const& controller : _rDocument.aControllers)
|
|
{
|
|
Reference< XFrame > xFrame( controller->getFrame(), UNO_SET_THROW );
|
|
Reference< XWindow2 > xContainer( xFrame->getContainerWindow(), UNO_QUERY_THROW );
|
|
if ( xContainer->isVisible() )
|
|
return true;
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool FilterDocuments::includeDocument( const docs::DocumentDescriptor& _rDocument ) const
|
|
{
|
|
Reference< XEmbeddedScripts > xScripts( _rDocument.xModel, UNO_QUERY );
|
|
if ( !xScripts.is() )
|
|
return false;
|
|
return !m_bFilterInvisible || impl_isDocumentVisible_nothrow( _rDocument );
|
|
}
|
|
|
|
void lcl_getAllModels_throw( docs::Documents& _out_rModels, bool _bVisibleOnly )
|
|
{
|
|
_out_rModels.clear();
|
|
|
|
FilterDocuments aFilter( _bVisibleOnly );
|
|
docs::DocumentEnumeration aEnum(
|
|
comphelper::getProcessComponentContext(), &aFilter );
|
|
|
|
aEnum.getDocuments( _out_rModels );
|
|
}
|
|
}
|
|
|
|
class ScriptDocument::Impl : public DocumentEventListener
|
|
{
|
|
private:
|
|
bool m_bIsApplication;
|
|
bool m_bValid;
|
|
bool m_bDocumentClosed;
|
|
Reference< XModel > m_xDocument;
|
|
Reference< XModifiable > m_xDocModify;
|
|
Reference< XEmbeddedScripts > m_xScriptAccess;
|
|
std::unique_ptr< DocumentEventNotifier > m_pDocListener;
|
|
|
|
public:
|
|
Impl ();
|
|
explicit Impl(Reference<XModel> const& rxDocument);
|
|
virtual ~Impl() override;
|
|
|
|
/** determines whether the instance refers to a valid "document" with script and
|
|
dialog libraries
|
|
*/
|
|
bool isValid() const { return m_bValid; }
|
|
/** determines whether the instance refers to a non-closed document
|
|
*/
|
|
bool isAlive() const { return m_bValid && ( m_bIsApplication || !m_bDocumentClosed ); }
|
|
/// determines whether the "document" refers to the application in real
|
|
bool isApplication() const { return m_bValid && m_bIsApplication; }
|
|
/// determines whether the document refers to a real document (instead of the application)
|
|
bool isDocument() const { return m_bValid && !m_bIsApplication; }
|
|
|
|
/** invalidates the instance
|
|
*/
|
|
void invalidate();
|
|
|
|
const Reference< XModel >&
|
|
getDocumentRef() const { return m_xDocument; }
|
|
|
|
/// returns a library container belonging to the document
|
|
Reference< XLibraryContainer >
|
|
getLibraryContainer( LibraryContainerType _eType ) const;
|
|
|
|
/// determines whether a given library is part of the shared installation
|
|
bool isLibraryShared( const OUString& _rLibName, LibraryContainerType _eType );
|
|
|
|
/** returns the current frame of the document
|
|
|
|
To be called for documents only, not for the application.
|
|
|
|
If <FALSE/> is returned, an assertion will be raised in non-product builds.
|
|
*/
|
|
bool getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const;
|
|
|
|
// versions with the same signature/semantics as in ScriptDocument itself
|
|
bool isReadOnly() const;
|
|
bool isInVBAMode() const;
|
|
BasicManager*
|
|
getBasicManager() const;
|
|
Reference< XModel >
|
|
getDocument() const;
|
|
void setDocumentModified() const;
|
|
bool isDocumentModified() const;
|
|
void saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const;
|
|
|
|
OUString getTitle() const;
|
|
OUString getURL() const;
|
|
|
|
bool allowMacros() const;
|
|
|
|
Reference< XNameContainer >
|
|
getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const;
|
|
bool hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const;
|
|
Reference< XNameContainer >
|
|
getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const;
|
|
|
|
void loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary );
|
|
|
|
bool removeModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModuleName );
|
|
bool hasModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModName ) const;
|
|
bool getModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, Any& _out_rModuleOrDialog );
|
|
bool renameModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel );
|
|
bool createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const;
|
|
bool insertModuleOrDialog( LibraryContainerType _eType, const OUString& _rObjectName, const OUString& _rModName, const Any& _rElement ) const;
|
|
bool updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const;
|
|
bool createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const;
|
|
|
|
protected:
|
|
// DocumentEventListener
|
|
virtual void onDocumentCreated( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentOpened( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentSave( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentSaveDone( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentSaveAs( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentClosed( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument ) override;
|
|
virtual void onDocumentModeChanged( const ScriptDocument& _rDocument ) override;
|
|
|
|
private:
|
|
bool impl_initDocument_nothrow( const Reference< XModel >& _rxModel );
|
|
};
|
|
|
|
|
|
ScriptDocument::Impl::Impl()
|
|
:m_bIsApplication( true )
|
|
,m_bValid( true )
|
|
,m_bDocumentClosed( false )
|
|
{
|
|
}
|
|
|
|
ScriptDocument::Impl::Impl( const Reference< XModel >& _rxDocument )
|
|
:m_bIsApplication( false )
|
|
,m_bValid( false )
|
|
,m_bDocumentClosed( false )
|
|
{
|
|
if ( _rxDocument.is() )
|
|
impl_initDocument_nothrow( _rxDocument );
|
|
}
|
|
|
|
ScriptDocument::Impl::~Impl()
|
|
{
|
|
invalidate();
|
|
}
|
|
|
|
void ScriptDocument::Impl::invalidate()
|
|
{
|
|
m_bIsApplication = false;
|
|
m_bValid = false;
|
|
m_bDocumentClosed = false;
|
|
|
|
m_xDocument.clear();
|
|
m_xDocModify.clear();
|
|
m_xScriptAccess.clear();
|
|
|
|
if (m_pDocListener)
|
|
m_pDocListener->dispose();
|
|
}
|
|
|
|
bool ScriptDocument::Impl::impl_initDocument_nothrow( const Reference< XModel >& _rxModel )
|
|
{
|
|
try
|
|
{
|
|
m_xDocument.set ( _rxModel, UNO_SET_THROW );
|
|
m_xDocModify.set ( _rxModel, UNO_QUERY_THROW );
|
|
m_xScriptAccess.set ( _rxModel, UNO_QUERY );
|
|
|
|
m_bValid = m_xScriptAccess.is();
|
|
|
|
if ( m_bValid )
|
|
m_pDocListener.reset( new DocumentEventNotifier( *this, _rxModel ) );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
m_bValid = false;
|
|
}
|
|
|
|
if ( !m_bValid )
|
|
{
|
|
invalidate();
|
|
}
|
|
|
|
return m_bValid;
|
|
}
|
|
|
|
Reference< XLibraryContainer > ScriptDocument::Impl::getLibraryContainer( LibraryContainerType _eType ) const
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::getLibraryContainer: invalid!" );
|
|
|
|
Reference< XLibraryContainer > xContainer;
|
|
if ( !isValid() )
|
|
return xContainer;
|
|
|
|
try
|
|
{
|
|
if ( isApplication() )
|
|
xContainer.set( _eType == E_SCRIPTS ? SfxGetpApp()->GetBasicContainer() : SfxGetpApp()->GetDialogContainer(), UNO_QUERY_THROW );
|
|
else
|
|
{
|
|
xContainer.set(
|
|
_eType == E_SCRIPTS ? m_xScriptAccess->getBasicLibraries() : m_xScriptAccess->getDialogLibraries(),
|
|
UNO_QUERY_THROW );
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return xContainer;
|
|
}
|
|
|
|
bool ScriptDocument::Impl::isReadOnly() const
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::isReadOnly: invalid state!" );
|
|
OSL_ENSURE( !isApplication(), "ScriptDocument::Impl::isReadOnly: not allowed to be called for the application!" );
|
|
|
|
bool bIsReadOnly = true;
|
|
if ( isValid() && !isApplication() )
|
|
{
|
|
try
|
|
{
|
|
// note that XStorable is required by the OfficeDocument service
|
|
Reference< XStorable > xDocStorable( m_xDocument, UNO_QUERY_THROW );
|
|
bIsReadOnly = xDocStorable->isReadonly();
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
return bIsReadOnly;
|
|
}
|
|
|
|
bool ScriptDocument::Impl::isInVBAMode() const
|
|
{
|
|
bool bResult = false;
|
|
if ( !isApplication() )
|
|
{
|
|
Reference< XVBACompatibility > xVBACompat( getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
|
|
if ( xVBACompat.is() )
|
|
bResult = xVBACompat->getVBACompatibilityMode();
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BasicManager* ScriptDocument::Impl::getBasicManager() const
|
|
{
|
|
try
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::getBasicManager: invalid state!" );
|
|
if ( !isValid() )
|
|
return nullptr;
|
|
|
|
if ( isApplication() )
|
|
return SfxApplication::GetBasicManager();
|
|
|
|
return ::basic::BasicManagerRepository::getDocumentBasicManager( m_xDocument );
|
|
}
|
|
catch (const css::ucb::ContentCreationException&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "basctl.basicide", "ScriptDocument::getBasicManager" );
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
Reference< XModel > ScriptDocument::Impl::getDocument() const
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::getDocument: invalid state!" );
|
|
OSL_ENSURE( isDocument(), "ScriptDocument::Impl::getDocument: for documents only!" );
|
|
if ( !isValid() || !isDocument() )
|
|
return nullptr;
|
|
|
|
return m_xDocument;
|
|
}
|
|
|
|
|
|
Reference< XNameContainer > ScriptDocument::Impl::getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::getLibrary: invalid state!" );
|
|
|
|
Reference< XNameContainer > xContainer;
|
|
try
|
|
{
|
|
Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType );
|
|
if ( isValid() && xLibContainer.is() )
|
|
xContainer.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW );
|
|
|
|
if ( !xContainer.is() )
|
|
throw NoSuchElementException();
|
|
|
|
// load library
|
|
if ( _bLoadLibrary && !xLibContainer->isLibraryLoaded( _rLibName ) )
|
|
xLibContainer->loadLibrary( _rLibName );
|
|
}
|
|
catch( const NoSuchElementException& )
|
|
{
|
|
throw; // allowed to leave
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
return xContainer;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
bool bHas = false;
|
|
try
|
|
{
|
|
Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType );
|
|
bHas = xLibContainer.is() && xLibContainer->hasByName( _rLibName );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return bHas;
|
|
}
|
|
|
|
|
|
Reference< XNameContainer > ScriptDocument::Impl::getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
Reference< XNameContainer > xLibrary;
|
|
try
|
|
{
|
|
Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ), UNO_SET_THROW );
|
|
if ( xLibContainer->hasByName( _rLibName ) )
|
|
xLibrary.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW );
|
|
else
|
|
xLibrary.set( xLibContainer->createLibrary( _rLibName ), UNO_SET_THROW );
|
|
|
|
if ( !xLibContainer->isLibraryLoaded( _rLibName ) )
|
|
xLibContainer->loadLibrary( _rLibName );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return xLibrary;
|
|
}
|
|
|
|
|
|
void ScriptDocument::Impl::loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary )
|
|
{
|
|
try
|
|
{
|
|
Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ) );
|
|
if ( xLibContainer.is() && xLibContainer->hasByName( _rLibrary ) && !xLibContainer->isLibraryLoaded( _rLibrary ) )
|
|
xLibContainer->loadLibrary( _rLibrary );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::removeModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModuleName )
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::removeModuleOrDialog: invalid!" );
|
|
if ( !isValid() )
|
|
return false;
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ) );
|
|
if ( xLib.is() )
|
|
{
|
|
xLib->removeByName( _rModuleName );
|
|
Reference< XVBAModuleInfo > xVBAModuleInfo(xLib, UNO_QUERY);
|
|
if(xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo(_rModuleName))
|
|
xVBAModuleInfo->removeModuleInfo(_rModuleName);
|
|
return true;
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::hasModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModName ) const
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::hasModuleOrDialog: invalid!" );
|
|
if ( !isValid() )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ) );
|
|
if ( xLib.is() )
|
|
return xLib->hasByName( _rModName );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::getModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, Any& _out_rModuleOrDialog )
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::getModuleOrDialog: invalid!" );
|
|
if ( !isValid() )
|
|
return false;
|
|
|
|
_out_rModuleOrDialog.clear();
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ), UNO_SET_THROW );
|
|
if ( xLib->hasByName( _rObjectName ) )
|
|
{
|
|
_out_rModuleOrDialog = xLib->getByName( _rObjectName );
|
|
return true;
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::renameModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName,
|
|
const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel )
|
|
{
|
|
OSL_ENSURE( isValid(), "ScriptDocument::Impl::renameModuleOrDialog: invalid!" );
|
|
if ( !isValid() )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ), UNO_SET_THROW );
|
|
|
|
// get element
|
|
Any aElement( xLib->getByName( _rOldName ) );
|
|
|
|
// remove element from container
|
|
xLib->removeByName( _rOldName );
|
|
|
|
// if it's a dialog, import and export, to reflect the new name
|
|
if ( _eType == E_DIALOGS )
|
|
{
|
|
// create dialog model
|
|
const Reference< XComponentContext >& aContext(
|
|
comphelper::getProcessComponentContext() );
|
|
Reference< XNameContainer > xDialogModel;
|
|
if ( _rxExistingDialogModel.is() )
|
|
xDialogModel = _rxExistingDialogModel;
|
|
else
|
|
xDialogModel.set(
|
|
( aContext->getServiceManager()->
|
|
createInstanceWithContext(
|
|
u"com.sun.star.awt.UnoControlDialogModel"_ustr,
|
|
aContext ) ),
|
|
UNO_QUERY_THROW );
|
|
|
|
// import dialog model
|
|
Reference< XInputStreamProvider > xISP( aElement, UNO_QUERY_THROW );
|
|
if ( !_rxExistingDialogModel.is() )
|
|
{
|
|
Reference< XInputStream > xInput( xISP->createInputStream(), UNO_SET_THROW );
|
|
::xmlscript::importDialogModel( xInput, xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() );
|
|
}
|
|
|
|
// set new name as property
|
|
Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW );
|
|
xDlgPSet->setPropertyValue( DLGED_PROP_NAME, Any( _rNewName ) );
|
|
|
|
// export dialog model
|
|
xISP = ::xmlscript::exportDialogModel( xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() );
|
|
aElement <<= xISP;
|
|
}
|
|
|
|
// insert element by new name in container
|
|
if ( _eType == E_SCRIPTS )
|
|
{
|
|
Reference< XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
|
|
if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( _rOldName ) )
|
|
{
|
|
ModuleInfo sModuleInfo = xVBAModuleInfo->getModuleInfo( _rOldName );
|
|
xVBAModuleInfo->removeModuleInfo( _rOldName );
|
|
xVBAModuleInfo->insertModuleInfo( _rNewName, sModuleInfo );
|
|
}
|
|
}
|
|
xLib->insertByName( _rNewName, aElement );
|
|
return true;
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const
|
|
{
|
|
_out_rNewModuleCode.clear();
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( E_SCRIPTS, _rLibName, true ) );
|
|
if ( !xLib.is() || xLib->hasByName( _rModName ) )
|
|
return false;
|
|
|
|
// create new module
|
|
_out_rNewModuleCode = "REM ***** BASIC *****\n\n" ;
|
|
if ( _bCreateMain )
|
|
_out_rNewModuleCode += "Sub Main\n\nEnd Sub\n" ;
|
|
|
|
Reference< XVBAModuleInfo > xVBAModuleInfo(xLib, UNO_QUERY);
|
|
if (xVBAModuleInfo.is())
|
|
{
|
|
css::script::ModuleInfo aModuleInfo;
|
|
aModuleInfo.ModuleType = css::script::ModuleType::NORMAL;
|
|
xVBAModuleInfo->insertModuleInfo(_rModName, aModuleInfo);
|
|
}
|
|
|
|
// insert module into library
|
|
xLib->insertByName( _rModName, Any( _out_rNewModuleCode ) );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::insertModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, const Any& _rElement ) const
|
|
{
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getOrCreateLibrary( _eType, _rLibName ), UNO_SET_THROW );
|
|
if ( xLib->hasByName( _rObjectName ) )
|
|
return false;
|
|
|
|
xLib->insertByName( _rObjectName, _rElement );
|
|
return true;
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const
|
|
{
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getOrCreateLibrary( E_SCRIPTS, _rLibName ), UNO_SET_THROW );
|
|
if ( !xLib->hasByName( _rModName ) )
|
|
return false;
|
|
xLib->replaceByName( _rModName, Any( _rModuleCode ) );
|
|
return true;
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
|
|
{
|
|
try
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( E_DIALOGS, _rLibName, true ), UNO_SET_THROW );
|
|
|
|
// create dialog
|
|
_out_rDialogProvider.clear();
|
|
if ( xLib->hasByName( _rDialogName ) )
|
|
return false;
|
|
|
|
// create new dialog model
|
|
const Reference< XComponentContext >& aContext(
|
|
comphelper::getProcessComponentContext() );
|
|
Reference< XNameContainer > xDialogModel(
|
|
aContext->getServiceManager()->createInstanceWithContext(
|
|
u"com.sun.star.awt.UnoControlDialogModel"_ustr, aContext ),
|
|
UNO_QUERY_THROW );
|
|
|
|
// set name property
|
|
Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW );
|
|
xDlgPSet->setPropertyValue( DLGED_PROP_NAME, Any( _rDialogName ) );
|
|
|
|
// export dialog model
|
|
_out_rDialogProvider = ::xmlscript::exportDialogModel( xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() );
|
|
|
|
// insert dialog into library
|
|
xLib->insertByName( _rDialogName, Any( _out_rDialogProvider ) );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
return _out_rDialogProvider.is();
|
|
}
|
|
|
|
|
|
void ScriptDocument::Impl::setDocumentModified() const
|
|
{
|
|
OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::setDocumentModified: only to be called for real documents!" );
|
|
if ( isValid() && isDocument() )
|
|
{
|
|
try
|
|
{
|
|
m_xDocModify->setModified( true );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::isDocumentModified() const
|
|
{
|
|
OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::isDocumentModified: only to be called for real documents!" );
|
|
bool bIsModified = false;
|
|
if ( isValid() && isDocument() )
|
|
{
|
|
try
|
|
{
|
|
bIsModified = m_xDocModify->isModified();
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
return bIsModified;
|
|
}
|
|
|
|
|
|
void ScriptDocument::Impl::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const
|
|
{
|
|
Reference< XFrame > xFrame;
|
|
if ( !getCurrentFrame( xFrame ) )
|
|
return;
|
|
|
|
Sequence< PropertyValue > aArgs;
|
|
if ( _rxStatusIndicator.is() )
|
|
{
|
|
aArgs = ::comphelper::InitPropertySequence({
|
|
{ "StatusIndicator", Any(_rxStatusIndicator) }
|
|
});
|
|
}
|
|
|
|
try
|
|
{
|
|
URL aURL;
|
|
aURL.Complete = ".uno:Save" ;
|
|
aURL.Main = aURL.Complete;
|
|
aURL.Protocol = ".uno:" ;
|
|
aURL.Path = "Save" ;
|
|
|
|
Reference< XDispatchProvider > xDispProv( xFrame, UNO_QUERY_THROW );
|
|
Reference< XDispatch > xDispatch(
|
|
xDispProv->queryDispatch( aURL, u"_self"_ustr, FrameSearchFlag::AUTO ),
|
|
UNO_SET_THROW );
|
|
|
|
xDispatch->dispatch( aURL, aArgs );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
|
|
|
|
OUString ScriptDocument::Impl::getTitle() const
|
|
{
|
|
OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getTitle: for documents only!" );
|
|
|
|
OUString sTitle;
|
|
if ( isValid() && isDocument() )
|
|
{
|
|
sTitle = ::comphelper::DocumentInfo::getDocumentTitle( m_xDocument );
|
|
}
|
|
return sTitle;
|
|
}
|
|
|
|
|
|
OUString ScriptDocument::Impl::getURL() const
|
|
{
|
|
OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getURL: for documents only!" );
|
|
|
|
OUString sURL;
|
|
if ( isValid() && isDocument() )
|
|
{
|
|
try
|
|
{
|
|
sURL = m_xDocument->getURL();
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
return sURL;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::allowMacros() const
|
|
{
|
|
OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::allowMacros: for documents only!" );
|
|
bool bAllow = false;
|
|
if ( isValid() && isDocument() )
|
|
{
|
|
try
|
|
{
|
|
bAllow = m_xScriptAccess->getAllowMacroExecution();
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
return bAllow;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const
|
|
{
|
|
_out_rxFrame.clear();
|
|
OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getCurrentFrame: documents only!" );
|
|
if ( !isValid() || !isDocument() )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
Reference< XModel > xDocument( m_xDocument, UNO_SET_THROW );
|
|
Reference< XController > xController( xDocument->getCurrentController(), UNO_SET_THROW );
|
|
_out_rxFrame.set( xController->getFrame(), UNO_SET_THROW );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
return _out_rxFrame.is();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::Impl::isLibraryShared( const OUString& _rLibName, LibraryContainerType _eType )
|
|
{
|
|
bool bIsShared = false;
|
|
try
|
|
{
|
|
Reference< XLibraryContainer2 > xLibContainer( getLibraryContainer( _eType ), UNO_QUERY_THROW );
|
|
|
|
if ( !xLibContainer->hasByName( _rLibName ) || !xLibContainer->isLibraryLink( _rLibName ) )
|
|
return false;
|
|
OUString aFileURL;
|
|
const Reference< XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
|
|
Reference< XUriReferenceFactory > xUriFac = UriReferenceFactory::create(xContext);
|
|
|
|
OUString aLinkURL( xLibContainer->getLibraryLinkURL( _rLibName ) );
|
|
Reference< XUriReference > xUriRef( xUriFac->parse( aLinkURL ), UNO_SET_THROW );
|
|
|
|
OUString aScheme = xUriRef->getScheme();
|
|
if ( aScheme.equalsIgnoreAsciiCase("file") )
|
|
{
|
|
aFileURL = aLinkURL;
|
|
}
|
|
else if ( aScheme.equalsIgnoreAsciiCase("vnd.sun.star.pkg") )
|
|
{
|
|
OUString aDecodedURL = xUriRef->getAuthority();
|
|
if (aDecodedURL.startsWithIgnoreAsciiCase("vnd.sun.star.expand:", &aDecodedURL))
|
|
{
|
|
aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
|
|
Reference< XMacroExpander > xMacroExpander = theMacroExpander::get(xContext);
|
|
aFileURL = xMacroExpander->expandMacros( aDecodedURL );
|
|
}
|
|
}
|
|
|
|
if ( !aFileURL.isEmpty() )
|
|
{
|
|
::osl::DirectoryItem aFileItem;
|
|
::osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileURL );
|
|
OSL_VERIFY( ::osl::DirectoryItem::get( aFileURL, aFileItem ) == ::osl::FileBase::E_None );
|
|
OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None );
|
|
OUString aCanonicalFileURL( aFileStatus.getFileURL() );
|
|
|
|
if( aCanonicalFileURL.indexOf( LIBO_SHARE_FOLDER "/basic" ) >= 0 ||
|
|
aCanonicalFileURL.indexOf( LIBO_SHARE_FOLDER "/uno_packages" ) >= 0 ||
|
|
aCanonicalFileURL.indexOf( LIBO_SHARE_FOLDER "/extensions" ) >= 0 )
|
|
bIsShared = true;
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
return bIsShared;
|
|
}
|
|
|
|
|
|
void ScriptDocument::Impl::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentClosed( const ScriptDocument& _rDocument )
|
|
{
|
|
DBG_TESTSOLARMUTEX();
|
|
OSL_PRECOND( isValid(), "ScriptDocument::Impl::onDocumentClosed: should not be listening if I'm not valid!" );
|
|
|
|
bool bMyDocument = m_xDocument == _rDocument.getDocument();
|
|
OSL_PRECOND( bMyDocument, "ScriptDocument::Impl::onDocumentClosed: didn't want to know *this*!" );
|
|
if ( bMyDocument )
|
|
{
|
|
m_bDocumentClosed = true;
|
|
}
|
|
}
|
|
|
|
|
|
void ScriptDocument::Impl::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
void ScriptDocument::Impl::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
|
|
{
|
|
// not interested in
|
|
}
|
|
|
|
|
|
ScriptDocument::ScriptDocument()
|
|
:m_pImpl(std::make_shared<Impl>())
|
|
{ }
|
|
|
|
|
|
ScriptDocument::ScriptDocument( ScriptDocument::SpecialDocument _eType )
|
|
:m_pImpl( std::make_shared<Impl>( Reference< XModel >() ) )
|
|
{
|
|
OSL_ENSURE( _eType == NoDocument, "ScriptDocument::ScriptDocument: unknown SpecialDocument type!" );
|
|
}
|
|
|
|
|
|
ScriptDocument::ScriptDocument( const Reference< XModel >& _rxDocument )
|
|
:m_pImpl( std::make_shared<Impl>( _rxDocument ) )
|
|
{
|
|
OSL_ENSURE( _rxDocument.is(), "ScriptDocument::ScriptDocument: document must not be NULL!" );
|
|
// a NULL document results in an uninitialized instance, and for this
|
|
// purpose, there is a dedicated constructor
|
|
}
|
|
|
|
|
|
const ScriptDocument& ScriptDocument::getApplicationScriptDocument()
|
|
{
|
|
static ScriptDocument s_aApplicationScripts;
|
|
return s_aApplicationScripts;
|
|
}
|
|
|
|
|
|
ScriptDocument ScriptDocument::getDocumentForBasicManager( const BasicManager* _pManager )
|
|
{
|
|
if ( _pManager == SfxApplication::GetBasicManager() )
|
|
return getApplicationScriptDocument();
|
|
|
|
docs::Documents aDocuments;
|
|
lcl_getAllModels_throw( aDocuments, false );
|
|
|
|
for (auto const& doc : aDocuments)
|
|
{
|
|
const BasicManager* pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( doc.xModel );
|
|
if ( ( pDocBasicManager != SfxApplication::GetBasicManager() )
|
|
&& ( pDocBasicManager == _pManager )
|
|
)
|
|
{
|
|
return ScriptDocument( doc.xModel );
|
|
}
|
|
}
|
|
|
|
OSL_FAIL( "ScriptDocument::getDocumentForBasicManager: did not find a document for this manager!" );
|
|
return ScriptDocument( NoDocument );
|
|
}
|
|
|
|
|
|
ScriptDocument ScriptDocument::getDocumentWithURLOrCaption( std::u16string_view _rUrlOrCaption )
|
|
{
|
|
ScriptDocument aDocument( getApplicationScriptDocument() );
|
|
if ( _rUrlOrCaption.empty() )
|
|
return aDocument;
|
|
|
|
docs::Documents aDocuments;
|
|
lcl_getAllModels_throw( aDocuments, false );
|
|
|
|
for (auto const& doc : aDocuments)
|
|
{
|
|
const ScriptDocument aCheck( doc.xModel );
|
|
if ( _rUrlOrCaption == aCheck.getTitle()
|
|
|| _rUrlOrCaption == aCheck.m_pImpl->getURL()
|
|
)
|
|
{
|
|
aDocument = aCheck;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return aDocument;
|
|
}
|
|
|
|
ScriptDocuments ScriptDocument::getAllScriptDocuments( ScriptDocument::ScriptDocumentList _eListType )
|
|
{
|
|
ScriptDocuments aScriptDocs;
|
|
|
|
// include application?
|
|
if ( _eListType == AllWithApplication )
|
|
aScriptDocs.push_back( getApplicationScriptDocument() );
|
|
|
|
// obtain documents
|
|
try
|
|
{
|
|
docs::Documents aDocuments;
|
|
lcl_getAllModels_throw( aDocuments, true /* exclude invisible */ );
|
|
|
|
for (auto const& doc : aDocuments)
|
|
{
|
|
// exclude documents without script/library containers
|
|
ScriptDocument aDoc( doc.xModel );
|
|
if ( !aDoc.isValid() )
|
|
continue;
|
|
|
|
aScriptDocs.push_back( aDoc );
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
// sort document list by doc title?
|
|
if ( _eListType == DocumentsSorted )
|
|
{
|
|
auto const sort = comphelper::string::NaturalStringSorter(
|
|
comphelper::getProcessComponentContext(),
|
|
Application::GetSettings().GetUILanguageTag().getLocale());
|
|
std::sort(aScriptDocs.begin(), aScriptDocs.end(),
|
|
[&sort](const ScriptDocument& rLHS, const ScriptDocument& rRHS) {
|
|
return sort.compare(rLHS.getTitle(), rRHS.getTitle()) < 0;
|
|
});
|
|
}
|
|
|
|
return aScriptDocs;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::operator==( const ScriptDocument& _rhs ) const
|
|
{
|
|
return m_pImpl->getDocumentRef() == _rhs.m_pImpl->getDocumentRef();
|
|
}
|
|
|
|
|
|
sal_Int32 ScriptDocument::hashCode() const
|
|
{
|
|
return sal::static_int_cast<sal_Int32>(reinterpret_cast< sal_IntPtr >( m_pImpl->getDocumentRef().get() ));
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isValid() const
|
|
{
|
|
return m_pImpl->isValid();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isAlive() const
|
|
{
|
|
return m_pImpl->isAlive();
|
|
}
|
|
|
|
|
|
Reference< XLibraryContainer > ScriptDocument::getLibraryContainer( LibraryContainerType _eType ) const
|
|
{
|
|
return m_pImpl->getLibraryContainer( _eType );
|
|
}
|
|
|
|
|
|
Reference< XNameContainer > ScriptDocument::getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const
|
|
{
|
|
return m_pImpl->getLibrary( _eType, _rLibName, _bLoadLibrary );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
return m_pImpl->hasLibrary( _eType, _rLibName );
|
|
}
|
|
|
|
|
|
Reference< XNameContainer > ScriptDocument::getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
return m_pImpl->getOrCreateLibrary( _eType, _rLibName );
|
|
}
|
|
|
|
|
|
void ScriptDocument::loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary )
|
|
{
|
|
m_pImpl->loadLibraryIfExists( _eType, _rLibrary );
|
|
}
|
|
|
|
|
|
Sequence< OUString > ScriptDocument::getObjectNames( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
Sequence< OUString > aModuleNames;
|
|
|
|
try
|
|
{
|
|
if ( hasLibrary( _eType, _rLibName ) )
|
|
{
|
|
Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, false ) );
|
|
if ( xLib.is() )
|
|
aModuleNames = xLib->getElementNames();
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
|
|
// sort
|
|
auto const sort = comphelper::string::NaturalStringSorter(
|
|
comphelper::getProcessComponentContext(),
|
|
Application::GetSettings().GetUILanguageTag().getLocale());
|
|
auto [begin, end] = asNonConstRange(aModuleNames);
|
|
std::sort(begin, end,
|
|
[&sort](const OUString& rLHS, const OUString& rRHS) {
|
|
return sort.compare(rLHS, rRHS) < 0;
|
|
});
|
|
return aModuleNames;
|
|
}
|
|
|
|
|
|
OUString ScriptDocument::createObjectName( LibraryContainerType _eType, const OUString& _rLibName ) const
|
|
{
|
|
OUString aObjectName;
|
|
|
|
OUString aBaseName = _eType == E_SCRIPTS ? u"Module"_ustr : u"Dialog"_ustr;
|
|
|
|
const Sequence< OUString > aUsedNames( getObjectNames( _eType, _rLibName ) );
|
|
std::set< OUString > aUsedNamesCheck( aUsedNames.begin(), aUsedNames.end() );
|
|
|
|
bool bValid = false;
|
|
sal_Int32 i = 1;
|
|
while ( !bValid )
|
|
{
|
|
aObjectName = aBaseName
|
|
+ OUString::number( i );
|
|
|
|
if ( aUsedNamesCheck.find( aObjectName ) == aUsedNamesCheck.end() )
|
|
bValid = true;
|
|
|
|
++i;
|
|
}
|
|
|
|
return aObjectName;
|
|
}
|
|
|
|
|
|
Sequence< OUString > ScriptDocument::getLibraryNames() const
|
|
{
|
|
return GetMergedLibraryNames( getLibraryContainer( E_SCRIPTS ), getLibraryContainer( E_DIALOGS ) );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isReadOnly() const
|
|
{
|
|
return m_pImpl->isReadOnly();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isApplication() const
|
|
{
|
|
return m_pImpl->isApplication();
|
|
}
|
|
|
|
bool ScriptDocument::isInVBAMode() const
|
|
{
|
|
return m_pImpl->isInVBAMode();
|
|
}
|
|
|
|
|
|
BasicManager* ScriptDocument::getBasicManager() const
|
|
{
|
|
return m_pImpl->getBasicManager();
|
|
}
|
|
|
|
|
|
Reference< XModel > ScriptDocument::getDocument() const
|
|
{
|
|
return m_pImpl->getDocument();
|
|
}
|
|
|
|
|
|
Reference< XModel > ScriptDocument::getDocumentOrNull() const
|
|
{
|
|
if ( isDocument() )
|
|
return m_pImpl->getDocument();
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::removeModule( const OUString& _rLibName, const OUString& _rModuleName ) const
|
|
{
|
|
return m_pImpl->removeModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::hasModule( const OUString& _rLibName, const OUString& _rModuleName ) const
|
|
{
|
|
return m_pImpl->hasModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::getModule( const OUString& _rLibName, const OUString& _rModName, OUString& _out_rModuleSource ) const
|
|
{
|
|
Any aCode;
|
|
if ( !m_pImpl->getModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, aCode ) )
|
|
return false;
|
|
OSL_VERIFY( aCode >>= _out_rModuleSource );
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::renameModule( const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName ) const
|
|
{
|
|
return m_pImpl->renameModuleOrDialog( E_SCRIPTS, _rLibName, _rOldName, _rNewName, nullptr );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const
|
|
{
|
|
if ( !m_pImpl->createModule( _rLibName, _rModName, _bCreateMain, _out_rNewModuleCode ) )
|
|
return false;
|
|
|
|
// doc shell modified
|
|
MarkDocumentModified( *const_cast< ScriptDocument* >( this ) ); // here?
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::insertModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const
|
|
{
|
|
return m_pImpl->insertModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, Any( _rModuleCode ) );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const
|
|
{
|
|
return m_pImpl->updateModule( _rLibName, _rModName, _rModuleCode );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::removeDialog( const OUString& _rLibName, const OUString& _rDialogName ) const
|
|
{
|
|
return m_pImpl->removeModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::hasDialog( const OUString& _rLibName, const OUString& _rDialogName ) const
|
|
{
|
|
return m_pImpl->hasModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::getDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
|
|
{
|
|
Any aCode;
|
|
if ( !m_pImpl->getModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, aCode ) )
|
|
return false;
|
|
OSL_VERIFY( aCode >>= _out_rDialogProvider );
|
|
return _out_rDialogProvider.is();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::renameDialog( const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel ) const
|
|
{
|
|
return m_pImpl->renameModuleOrDialog( E_DIALOGS, _rLibName, _rOldName, _rNewName, _rxExistingDialogModel );
|
|
}
|
|
|
|
|
|
bool ScriptDocument::createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
|
|
{
|
|
if ( !m_pImpl->createDialog( _rLibName, _rDialogName, _out_rDialogProvider ) )
|
|
return false;
|
|
|
|
MarkDocumentModified( *const_cast< ScriptDocument* >( this ) ); // here?
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::insertDialog( const OUString& _rLibName, const OUString& _rDialogName, const Reference< XInputStreamProvider >& _rxDialogProvider ) const
|
|
{
|
|
return m_pImpl->insertModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, Any( _rxDialogProvider ) );
|
|
}
|
|
|
|
|
|
void ScriptDocument::setDocumentModified() const
|
|
{
|
|
m_pImpl->setDocumentModified();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isDocumentModified() const
|
|
{
|
|
return m_pImpl->isDocumentModified();
|
|
}
|
|
|
|
|
|
void ScriptDocument::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const
|
|
{
|
|
m_pImpl->saveDocument( _rxStatusIndicator );
|
|
}
|
|
|
|
|
|
LibraryLocation ScriptDocument::getLibraryLocation( const OUString& _rLibName ) const
|
|
{
|
|
LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN;
|
|
if ( !_rLibName.isEmpty() )
|
|
{
|
|
if ( isDocument() )
|
|
{
|
|
eLocation = LIBRARY_LOCATION_DOCUMENT;
|
|
}
|
|
else
|
|
{
|
|
if ( ( hasLibrary( E_SCRIPTS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_SCRIPTS ) )
|
|
|| ( hasLibrary( E_DIALOGS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_DIALOGS ) )
|
|
)
|
|
{
|
|
eLocation = LIBRARY_LOCATION_USER;
|
|
}
|
|
else
|
|
{
|
|
eLocation = LIBRARY_LOCATION_SHARE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return eLocation;
|
|
}
|
|
|
|
|
|
OUString ScriptDocument::getTitle( LibraryLocation _eLocation, LibraryType _eType ) const
|
|
{
|
|
OUString aTitle;
|
|
|
|
switch ( _eLocation )
|
|
{
|
|
case LIBRARY_LOCATION_USER:
|
|
{
|
|
switch ( _eType )
|
|
{
|
|
case LibraryType::Module: aTitle = IDEResId(RID_STR_USERMACROS); break;
|
|
case LibraryType::Dialog: aTitle = IDEResId(RID_STR_USERDIALOGS); break;
|
|
case LibraryType::All: aTitle = IDEResId(RID_STR_USERMACROSDIALOGS); break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case LIBRARY_LOCATION_SHARE:
|
|
{
|
|
switch ( _eType )
|
|
{
|
|
case LibraryType::Module: aTitle = IDEResId(RID_STR_SHAREMACROS); break;
|
|
case LibraryType::Dialog: aTitle = IDEResId(RID_STR_SHAREDIALOGS); break;
|
|
case LibraryType::All: aTitle = IDEResId(RID_STR_SHAREMACROSDIALOGS); break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case LIBRARY_LOCATION_DOCUMENT:
|
|
aTitle = getTitle();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return aTitle;
|
|
}
|
|
|
|
|
|
OUString ScriptDocument::getTitle() const
|
|
{
|
|
return m_pImpl->getTitle();
|
|
}
|
|
|
|
|
|
bool ScriptDocument::isActive() const
|
|
{
|
|
bool bIsActive( false );
|
|
try
|
|
{
|
|
Reference< XFrame > xFrame;
|
|
if ( m_pImpl->getCurrentFrame( xFrame ) )
|
|
bIsActive = xFrame->isActive();
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
return bIsActive;
|
|
}
|
|
|
|
|
|
bool ScriptDocument::allowMacros() const
|
|
{
|
|
return m_pImpl->allowMacros();
|
|
}
|
|
|
|
} // namespace basctl
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|