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
VbaDocumentBase(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext)47 VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) :VbaDocumentBase_BASE( xParent, xContext ), mxModel(NULL)
48 {
49 }
50
VbaDocumentBase(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,uno::Reference<frame::XModel> xModel)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
VbaDocumentBase(uno::Sequence<uno::Any> const & args,uno::Reference<uno::XComponentContext> const & xContext)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
getName()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
getPath()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
getFullName()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
Close(const uno::Any & rSaveArg,const uno::Any & rFileArg,const uno::Any & rRouteArg)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 disagrees with a reset request for the modify state
180 // we shouldn't do so. Otherwise 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
Protect(const uno::Any & aPassword)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
Unprotect(const uno::Any & aPassword)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
setSaved(sal_Bool bSave)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
getSaved()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
Save()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
Activate()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
getVBProject()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&
getServiceImplName()283 VbaDocumentBase::getServiceImplName()
284 {
285 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaDocumentBase") );
286 return sImplName;
287 }
288
289 uno::Sequence< rtl::OUString >
getServiceNames()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