1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "vbahelper/vbadocumentbase.hxx" 29 #include "vbahelper/helperdecl.hxx" 30 31 #include <com/sun/star/lang/DisposedException.hpp> 32 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 33 #include <com/sun/star/util/XModifiable.hpp> 34 #include <com/sun/star/util/XProtectable.hpp> 35 #include <com/sun/star/util/XCloseable.hpp> 36 #include <com/sun/star/util/XURLTransformer.hpp> 37 #include <com/sun/star/frame/XStorable.hpp> 38 #include <com/sun/star/frame/XFrame.hpp> 39 #include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn 40 #include <com/sun/star/beans/XPropertySet.hpp> 41 #include <ooo/vba/XApplicationBase.hpp> 42 43 #include <cppuhelper/exc_hlp.hxx> 44 #include <comphelper/unwrapargs.hxx> 45 #include <tools/urlobj.hxx> 46 #include <osl/file.hxx> 47 48 using namespace ::com::sun::star; 49 using namespace ::ooo::vba; 50 51 VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) :VbaDocumentBase_BASE( xParent, xContext ), mxModel(NULL) 52 { 53 } 54 55 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 ) 56 { 57 } 58 59 VbaDocumentBase::VbaDocumentBase( uno::Sequence< uno::Any> const & args, 60 uno::Reference< uno::XComponentContext> const & xContext ) : VbaDocumentBase_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ) 61 { 62 } 63 64 ::rtl::OUString 65 VbaDocumentBase::getName() throw (uno::RuntimeException) 66 { 67 rtl::OUString sName = getModel()->getURL(); 68 if ( sName.getLength() ) 69 { 70 71 INetURLObject aURL( getModel()->getURL() ); 72 ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName ); 73 } 74 else 75 { 76 const static rtl::OUString sTitle( RTL_CONSTASCII_USTRINGPARAM("Title" ) ); 77 // process "UntitledX - $(PRODUCTNAME)" 78 uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW ); 79 uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW ); 80 xProps->getPropertyValue(sTitle ) >>= sName; 81 sal_Int32 pos = 0; 82 sName = sName.getToken(0,'-',pos); 83 sName = sName.trim(); 84 } 85 return sName; 86 } 87 ::rtl::OUString 88 VbaDocumentBase::getPath() throw (uno::RuntimeException) 89 { 90 INetURLObject aURL( getModel()->getURL() ); 91 rtl::OUString sURL = aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); 92 rtl::OUString sPath; 93 if( sURL.getLength() > 0 ) 94 { 95 sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 ); 96 ::osl::File::getSystemPathFromFileURL( sURL, sPath ); 97 } 98 return sPath; 99 } 100 101 ::rtl::OUString 102 VbaDocumentBase::getFullName() throw (uno::RuntimeException) 103 { 104 rtl::OUString sPath = getName(); 105 //::osl::File::getSystemPathFromFileURL( getModel()->getURL(), sPath ); 106 return sPath; 107 } 108 109 void 110 VbaDocumentBase::Close( const uno::Any &rSaveArg, const uno::Any &rFileArg, 111 const uno::Any &rRouteArg ) throw (uno::RuntimeException) 112 { 113 sal_Bool bSaveChanges = sal_False; 114 rtl::OUString aFileName; 115 sal_Bool bRouteWorkbook = sal_True; 116 117 rSaveArg >>= bSaveChanges; 118 sal_Bool bFileName = ( rFileArg >>= aFileName ); 119 rRouteArg >>= bRouteWorkbook; 120 uno::Reference< frame::XStorable > xStorable( getModel(), uno::UNO_QUERY_THROW ); 121 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); 122 123 if( bSaveChanges ) 124 { 125 if( xStorable->isReadonly() ) 126 { 127 throw uno::RuntimeException(::rtl::OUString( 128 RTL_CONSTASCII_USTRINGPARAM( "Unable to save to a read only file ") ), 129 uno::Reference< XInterface >() ); 130 } 131 if( bFileName ) 132 xStorable->storeAsURL( aFileName, uno::Sequence< beans::PropertyValue >(0) ); 133 else 134 xStorable->store(); 135 } 136 else 137 xModifiable->setModified( false ); 138 139 // first try to close the document using UI dispatch functionality 140 sal_Bool bUIClose = sal_False; 141 try 142 { 143 uno::Reference< frame::XController > xController( getModel()->getCurrentController(), uno::UNO_SET_THROW ); 144 uno::Reference< frame::XDispatchProvider > xDispatchProvider( xController->getFrame(), uno::UNO_QUERY_THROW ); 145 146 uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); 147 uno::Reference< util::XURLTransformer > xURLTransformer( 148 xServiceManager->createInstanceWithContext( 149 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ), 150 mxContext ), 151 uno::UNO_QUERY_THROW ); 152 153 util::URL aURL; 154 aURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CloseDoc" ) ); 155 xURLTransformer->parseStrict( aURL ); 156 157 uno::Reference< css::frame::XDispatch > xDispatch( 158 xDispatchProvider->queryDispatch( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), 0 ), 159 uno::UNO_SET_THROW ); 160 xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() ); 161 bUIClose = sal_True; 162 } 163 catch( uno::Exception& ) 164 { 165 } 166 167 if ( !bUIClose ) 168 { 169 // if it is not possible to use UI dispatch, try to close the model directly 170 uno::Reference< util::XCloseable > xCloseable( getModel(), uno::UNO_QUERY ); 171 if( xCloseable.is() ) 172 { 173 // use close(boolean DeliverOwnership) 174 175 // The boolean parameter DeliverOwnership tells objects vetoing the close process that they may 176 // assume ownership if they object the closure by throwing a CloseVetoException 177 // Here we give up ownership. To be on the safe side, catch possible veto exception anyway. 178 xCloseable->close(sal_True); 179 } 180 else 181 { 182 // If close is not supported by this model - try to dispose it. 183 // But if the model disagree with a reset request for the modify state 184 // we shouldn't do so. Otherwhise some strange things can happen. 185 uno::Reference< lang::XComponent > xDisposable ( getModel(), uno::UNO_QUERY ); 186 if ( xDisposable.is() ) 187 xDisposable->dispose(); 188 } 189 } 190 } 191 192 void 193 VbaDocumentBase::Protect( const uno::Any &aPassword ) throw (uno::RuntimeException) 194 { 195 rtl::OUString rPassword; 196 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); 197 SC_VBA_FIXME(("Workbook::Protect stub")); 198 if( aPassword >>= rPassword ) 199 xProt->protect( rPassword ); 200 else 201 xProt->protect( rtl::OUString() ); 202 } 203 204 void 205 VbaDocumentBase::Unprotect( const uno::Any &aPassword ) throw (uno::RuntimeException) 206 { 207 rtl::OUString rPassword; 208 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); 209 if( !xProt->isProtected() ) 210 throw uno::RuntimeException(::rtl::OUString( 211 RTL_CONSTASCII_USTRINGPARAM( "File is already unprotected" ) ), 212 uno::Reference< XInterface >() ); 213 else 214 { 215 if( aPassword >>= rPassword ) 216 xProt->unprotect( rPassword ); 217 else 218 xProt->unprotect( rtl::OUString() ); 219 } 220 } 221 222 void 223 VbaDocumentBase::setSaved( sal_Bool bSave ) throw (uno::RuntimeException) 224 { 225 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); 226 try 227 { 228 xModifiable->setModified( !bSave ); 229 } 230 catch ( lang::DisposedException& ) 231 { 232 // impossibility to set the modified state on disposed document should not trigger an error 233 } 234 catch ( beans::PropertyVetoException& ) 235 { 236 uno::Any aCaught( ::cppu::getCaughtException() ); 237 throw lang::WrappedTargetRuntimeException( 238 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't change modified state of model!" ) ), 239 uno::Reference< uno::XInterface >(), 240 aCaught ); 241 } 242 } 243 244 sal_Bool 245 VbaDocumentBase::getSaved() throw (uno::RuntimeException) 246 { 247 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); 248 return !xModifiable->isModified(); 249 } 250 251 void 252 VbaDocumentBase::Save() throw (uno::RuntimeException) 253 { 254 rtl::OUString url = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".uno:Save")); 255 uno::Reference< frame::XModel > xModel = getModel(); 256 dispatchRequests(xModel,url); 257 } 258 259 void 260 VbaDocumentBase::Activate() throw (uno::RuntimeException) 261 { 262 uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW ); 263 xFrame->activate(); 264 } 265 266 uno::Any SAL_CALL 267 VbaDocumentBase::getVBProject() throw (uno::RuntimeException) 268 { 269 if( !mxVBProject.is() ) try 270 { 271 uno::Reference< XApplicationBase > xApp( Application(), uno::UNO_QUERY_THROW ); 272 uno::Reference< XInterface > xVBE( xApp->getVBE(), uno::UNO_QUERY_THROW ); 273 uno::Sequence< uno::Any > aArgs( 2 ); 274 aArgs[ 0 ] <<= xVBE; // the VBE 275 aArgs[ 1 ] <<= getModel(); // document model for script container access 276 uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); 277 mxVBProject = xServiceManager->createInstanceWithArgumentsAndContext( 278 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.vbide.VBProject" ) ), aArgs, mxContext ); 279 } 280 catch( uno::Exception& ) 281 { 282 } 283 return uno::Any( mxVBProject ); 284 } 285 286 rtl::OUString& 287 VbaDocumentBase::getServiceImplName() 288 { 289 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaDocumentBase") ); 290 return sImplName; 291 } 292 293 uno::Sequence< rtl::OUString > 294 VbaDocumentBase::getServiceNames() 295 { 296 static uno::Sequence< rtl::OUString > aServiceNames; 297 if ( aServiceNames.getLength() == 0 ) 298 { 299 aServiceNames.realloc( 1 ); 300 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.VbaDocumentBase" ) ); 301 } 302 return aServiceNames; 303 } 304 305