blob: d9fb9a86e003b4c964abc8794e24309b9c823e35 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "vbahelper/vbadocumentbase.hxx"
#include "vbahelper/helperdecl.hxx"
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/util/XProtectable.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn
#include <com/sun/star/beans/XPropertySet.hpp>
#include <ooo/vba/XApplicationBase.hpp>
#include <cppuhelper/exc_hlp.hxx>
#include <comphelper/unwrapargs.hxx>
#include <tools/urlobj.hxx>
#include <osl/file.hxx>
using namespace ::com::sun::star;
using namespace ::ooo::vba;
VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) :VbaDocumentBase_BASE( xParent, xContext ), mxModel(NULL)
{
}
VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > xModel ) : VbaDocumentBase_BASE( xParent, xContext ), mxModel( xModel )
{
}
VbaDocumentBase::VbaDocumentBase( uno::Sequence< uno::Any> const & args,
uno::Reference< uno::XComponentContext> const & xContext ) : VbaDocumentBase_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) )
{
}
::rtl::OUString
VbaDocumentBase::getName() throw (uno::RuntimeException)
{
rtl::OUString sName = getModel()->getURL();
if ( sName.getLength() )
{
INetURLObject aURL( getModel()->getURL() );
::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName );
}
else
{
const static rtl::OUString sTitle( RTL_CONSTASCII_USTRINGPARAM("Title" ) );
// process "UntitledX - $(PRODUCTNAME)"
uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW );
uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW );
xProps->getPropertyValue(sTitle ) >>= sName;
sal_Int32 pos = 0;
sName = sName.getToken(0,'-',pos);
sName = sName.trim();
}
return sName;
}
::rtl::OUString
VbaDocumentBase::getPath() throw (uno::RuntimeException)
{
INetURLObject aURL( getModel()->getURL() );
rtl::OUString sURL = aURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
rtl::OUString sPath;
if( sURL.getLength() > 0 )
{
sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 );
::osl::File::getSystemPathFromFileURL( sURL, sPath );
}
return sPath;
}
::rtl::OUString
VbaDocumentBase::getFullName() throw (uno::RuntimeException)
{
rtl::OUString sPath = getName();
//::osl::File::getSystemPathFromFileURL( getModel()->getURL(), sPath );
return sPath;
}
void
VbaDocumentBase::Close( const uno::Any &rSaveArg, const uno::Any &rFileArg,
const uno::Any &rRouteArg ) throw (uno::RuntimeException)
{
sal_Bool bSaveChanges = sal_False;
rtl::OUString aFileName;
sal_Bool bRouteWorkbook = sal_True;
rSaveArg >>= bSaveChanges;
sal_Bool bFileName = ( rFileArg >>= aFileName );
rRouteArg >>= bRouteWorkbook;
uno::Reference< frame::XStorable > xStorable( getModel(), uno::UNO_QUERY_THROW );
uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
if( bSaveChanges )
{
if( xStorable->isReadonly() )
{
throw uno::RuntimeException(::rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "Unable to save to a read only file ") ),
uno::Reference< XInterface >() );
}
if( bFileName )
xStorable->storeAsURL( aFileName, uno::Sequence< beans::PropertyValue >(0) );
else
xStorable->store();
}
else
xModifiable->setModified( false );
// first try to close the document using UI dispatch functionality
sal_Bool bUIClose = sal_False;
try
{
uno::Reference< frame::XController > xController( getModel()->getCurrentController(), uno::UNO_SET_THROW );
uno::Reference< frame::XDispatchProvider > xDispatchProvider( xController->getFrame(), uno::UNO_QUERY_THROW );
uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
uno::Reference< util::XURLTransformer > xURLTransformer(
xServiceManager->createInstanceWithContext(
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ),
mxContext ),
uno::UNO_QUERY_THROW );
util::URL aURL;
aURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CloseDoc" ) );
xURLTransformer->parseStrict( aURL );
uno::Reference< css::frame::XDispatch > xDispatch(
xDispatchProvider->queryDispatch( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), 0 ),
uno::UNO_SET_THROW );
xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() );
bUIClose = sal_True;
}
catch( uno::Exception& )
{
}
if ( !bUIClose )
{
// if it is not possible to use UI dispatch, try to close the model directly
uno::Reference< util::XCloseable > xCloseable( getModel(), uno::UNO_QUERY );
if( xCloseable.is() )
{
// use close(boolean DeliverOwnership)
// The boolean parameter DeliverOwnership tells objects vetoing the close process that they may
// assume ownership if they object the closure by throwing a CloseVetoException
// Here we give up ownership. To be on the safe side, catch possible veto exception anyway.
xCloseable->close(sal_True);
}
else
{
// If close is not supported by this model - try to dispose it.
// But if the model disagree with a reset request for the modify state
// we shouldn't do so. Otherwhise some strange things can happen.
uno::Reference< lang::XComponent > xDisposable ( getModel(), uno::UNO_QUERY );
if ( xDisposable.is() )
xDisposable->dispose();
}
}
}
void
VbaDocumentBase::Protect( const uno::Any &aPassword ) throw (uno::RuntimeException)
{
rtl::OUString rPassword;
uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
SC_VBA_FIXME(("Workbook::Protect stub"));
if( aPassword >>= rPassword )
xProt->protect( rPassword );
else
xProt->protect( rtl::OUString() );
}
void
VbaDocumentBase::Unprotect( const uno::Any &aPassword ) throw (uno::RuntimeException)
{
rtl::OUString rPassword;
uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
if( !xProt->isProtected() )
throw uno::RuntimeException(::rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "File is already unprotected" ) ),
uno::Reference< XInterface >() );
else
{
if( aPassword >>= rPassword )
xProt->unprotect( rPassword );
else
xProt->unprotect( rtl::OUString() );
}
}
void
VbaDocumentBase::setSaved( sal_Bool bSave ) throw (uno::RuntimeException)
{
uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
try
{
xModifiable->setModified( !bSave );
}
catch ( lang::DisposedException& )
{
// impossibility to set the modified state on disposed document should not trigger an error
}
catch ( beans::PropertyVetoException& )
{
uno::Any aCaught( ::cppu::getCaughtException() );
throw lang::WrappedTargetRuntimeException(
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't change modified state of model!" ) ),
uno::Reference< uno::XInterface >(),
aCaught );
}
}
sal_Bool
VbaDocumentBase::getSaved() throw (uno::RuntimeException)
{
uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
return !xModifiable->isModified();
}
void
VbaDocumentBase::Save() throw (uno::RuntimeException)
{
rtl::OUString url = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
uno::Reference< frame::XModel > xModel = getModel();
dispatchRequests(xModel,url);
}
void
VbaDocumentBase::Activate() throw (uno::RuntimeException)
{
uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW );
xFrame->activate();
}
uno::Any SAL_CALL
VbaDocumentBase::getVBProject() throw (uno::RuntimeException)
{
if( !mxVBProject.is() ) try
{
uno::Reference< XApplicationBase > xApp( Application(), uno::UNO_QUERY_THROW );
uno::Reference< XInterface > xVBE( xApp->getVBE(), uno::UNO_QUERY_THROW );
uno::Sequence< uno::Any > aArgs( 2 );
aArgs[ 0 ] <<= xVBE; // the VBE
aArgs[ 1 ] <<= getModel(); // document model for script container access
uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
mxVBProject = xServiceManager->createInstanceWithArgumentsAndContext(
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.vbide.VBProject" ) ), aArgs, mxContext );
}
catch( uno::Exception& )
{
}
return uno::Any( mxVBProject );
}
rtl::OUString&
VbaDocumentBase::getServiceImplName()
{
static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaDocumentBase") );
return sImplName;
}
uno::Sequence< rtl::OUString >
VbaDocumentBase::getServiceNames()
{
static uno::Sequence< rtl::OUString > aServiceNames;
if ( aServiceNames.getLength() == 0 )
{
aServiceNames.realloc( 1 );
aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.VbaDocumentBase" ) );
}
return aServiceNames;
}