xref: /AOO41X/main/vbahelper/source/vbahelper/vbadocumentbase.cxx (revision e6ed5fbc51cf474df369618b58e945b84a21a167)
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 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
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