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