LibreOffice Module vbahelper (master) 1
vbadocumentbase.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <utility>
22
23#include <com/sun/star/beans/PropertyVetoException.hpp>
24#include <com/sun/star/lang/DisposedException.hpp>
25#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
26#include <com/sun/star/util/XModifiable.hpp>
27#include <com/sun/star/util/XProtectable.hpp>
28#include <com/sun/star/util/XCloseable.hpp>
29#include <com/sun/star/util/URLTransformer.hpp>
30#include <com/sun/star/util/XURLTransformer.hpp>
31#include <com/sun/star/frame/XDispatchProvider.hpp>
32#include <com/sun/star/frame/XStorable.hpp>
33#include <com/sun/star/frame/XFrame.hpp>
34#include <com/sun/star/frame/XTitle.hpp>
35#include <ooo/vba/XApplicationBase.hpp>
36
39#include <tools/urlobj.hxx>
40#include <osl/file.hxx>
41#include <sal/log.hxx>
42
43using namespace ::com::sun::star;
44using namespace ::ooo::vba;
45
46VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > xModel ) : VbaDocumentBase_BASE( xParent, xContext ), mxModel(std::move( xModel ))
47{
48}
49
50VbaDocumentBase::VbaDocumentBase( uno::Sequence< uno::Any> const & args,
51 uno::Reference< uno::XComponentContext> const & xContext ) : VbaDocumentBase_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) )
52{
53}
54
55OUString
57{
59 SAL_INFO("vbahelper", "VbaDocumentBase::getName: '" << sName << "'");
60
61 return sName;
62}
63
64OUString VbaDocumentBase::getNameFromModel( const uno::Reference< frame::XModel >& xModel )
65{
66 OUString sName = xModel.is() ? xModel->getURL() : OUString();
67 if ( !sName.isEmpty() )
68 {
69
70 INetURLObject aURL( xModel->getURL() );
71 ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName );
72 }
73 else
74 {
75 uno::Reference< frame::XTitle > xTitle( xModel, uno::UNO_QUERY_THROW );
76 sName = xTitle->getTitle();
77 sName = sName.trim();
78 }
79 return sName;
80}
81OUString
83{
84 INetURLObject aURL( getModel()->getURL() );
85 OUString sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
86 OUString sPath;
87 if( !sURL.isEmpty() )
88 {
89 sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 );
90 ::osl::File::getSystemPathFromFileURL( sURL, sPath );
91 }
92 SAL_INFO("vbahelper", "VbaDocumentBase::getPath: '" << sPath << "'");
93
94 return sPath;
95}
96
97OUString
99{
100 // In the Automation case, follow the specs.
102 {
103 // We know that Automation is relevant only on Windows, so hardcode "\\".
104 OUString sPath = getPath() + "\\" + getName();
105 SAL_INFO("vbahelper", "VbaDocumentBase::getFullName: '" << sPath << "'");
106 return sPath;
107 }
108
109 OUString sPath = getName();
110 //::osl::File::getSystemPathFromFileURL( getModel()->getURL(), sPath );
111 SAL_INFO("vbahelper", "VbaDocumentBase::getFullName: '" << sPath << "'");
112 return sPath;
113}
114
115void
116VbaDocumentBase::Close( const uno::Any &rSaveArg, const uno::Any &rFileArg,
117 const uno::Any &rRouteArg )
118{
119 bool bSaveChanges = false;
120 OUString aFileName;
121 bool bRouteWorkbook = true;
122
123 rSaveArg >>= bSaveChanges;
124 bool bFileName = ( rFileArg >>= aFileName );
125 rRouteArg >>= bRouteWorkbook;
126 uno::Reference< frame::XStorable > xStorable( getModel(), uno::UNO_QUERY_THROW );
127 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
128
129 if( bSaveChanges )
130 {
131 if( xStorable->isReadonly() )
132 {
133 throw uno::RuntimeException("Unable to save to a read only file " );
134 }
135 if( bFileName )
136 xStorable->storeAsURL( aFileName, uno::Sequence< beans::PropertyValue >(0) );
137 else
138 xStorable->store();
139 }
140 else
141 xModifiable->setModified( false );
142
143 // first try to close the document using UI dispatch functionality
144 bool bUIClose = false;
145 try
146 {
147 uno::Reference< frame::XController > xController( getModel()->getCurrentController(), uno::UNO_SET_THROW );
148 uno::Reference< frame::XDispatchProvider > xDispatchProvider( xController->getFrame(), uno::UNO_QUERY_THROW );
149
150 uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
151 uno::Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create(mxContext) );
152
153 util::URL aURL;
154 aURL.Complete = ".uno:CloseDoc";
155 xURLTransformer->parseStrict( aURL );
156
157 uno::Reference< css::frame::XDispatch > xDispatch(
158 xDispatchProvider->queryDispatch( aURL, "_self" , 0 ),
159 uno::UNO_SET_THROW );
160 xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() );
161 bUIClose = true;
162 }
163 catch(const uno::Exception&)
164 {
165 }
166
167 if ( bUIClose )
168 return;
169
170 // if it is not possible to use UI dispatch, try to close the model directly
171 bool bCloseable = false;
172 uno::Reference< frame::XModel > xModel = getModel();
173 try
174 {
175 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
176
177 // use close(boolean DeliverOwnership)
178 // The boolean parameter DeliverOwnership tells objects vetoing the close
179 // process that they may assume ownership if they object the closure by
180 // throwing a CloseVetoException. Here we give up ownership. To be on the
181 // safe side, catch possible veto exception anyway.
182 if ( xCloseable.is() )
183 {
184 bCloseable = true;
185 xCloseable->close(true);
186 }
187 }
188 catch (const uno::Exception &)
189 {
190 // vetoed
191 }
192 if (bCloseable)
193 return;
194
195 try {
196 // If close is not supported by this model - try to dispose it.
197 // But if the model disagree with a reset request for the modify state
198 // we shouldn't do so. Otherwise some strange things can happen.
199 uno::Reference< lang::XComponent > xDisposable ( xModel, uno::UNO_QUERY_THROW );
200 xDisposable->dispose();
201 }
202 catch(const uno::Exception&)
203 {
204 }
205}
206
207void
209{
210 OUString rPassword;
211 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
212 SAL_INFO("vbahelper", "Workbook::Protect stub");
213 if( aPassword >>= rPassword )
214 xProt->protect( rPassword );
215 else
216 xProt->protect( OUString() );
217}
218
219void
221{
222 OUString rPassword;
223 uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
224 if( !xProt->isProtected() )
225 throw uno::RuntimeException("File is already unprotected" );
226 if( aPassword >>= rPassword )
227 xProt->unprotect( rPassword );
228 else
229 xProt->unprotect( OUString() );
230}
231
232void
234{
235 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
236 try
237 {
238 xModifiable->setModified( !bSave );
239 }
240 catch (const lang::DisposedException&)
241 {
242 // impossibility to set the modified state on disposed document should not trigger an error
243 }
244 catch (const beans::PropertyVetoException&)
245 {
246 uno::Any aCaught( ::cppu::getCaughtException() );
247 throw lang::WrappedTargetRuntimeException(
248 "Can't change modified state of model!",
249 uno::Reference< uno::XInterface >(),
250 aCaught );
251 }
252}
253
256{
257 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW );
258 return !xModifiable->isModified();
259}
260
261void
263{
264 uno::Reference< frame::XModel > xModel = getModel();
265 dispatchRequests(xModel,".uno:Save");
266}
267
268void
270{
271 uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_SET_THROW );
272 xFrame->activate();
273}
274
275uno::Any SAL_CALL
277{
278 if( !mxVBProject.is() ) try
279 {
280 uno::Reference< XApplicationBase > xApp( Application(), uno::UNO_QUERY_THROW );
281 uno::Reference< XInterface > xVBE( xApp->getVBE(), uno::UNO_QUERY_THROW );
282 uno::Sequence< uno::Any > aArgs{ uno::Any(xVBE), // the VBE
283 uno::Any(getModel()) }; // document model for script container access
284 uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
285 mxVBProject = xServiceManager->createInstanceWithArgumentsAndContext(
286 "ooo.vba.vbide.VBProject", aArgs, mxContext );
287 }
288 catch(const uno::Exception&)
289 {
290 }
291 return uno::Any( mxVBProject );
292}
293
294OUString
296{
297 return "VbaDocumentBase";
298}
299
300uno::Sequence< OUString >
302{
303 static uno::Sequence< OUString > const aServiceNames
304 {
305 "ooo.vba.VbaDocumentBase"
306 };
307 return aServiceNames;
308}
309
310/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::frame::XModel2 > mxModel
css::uno::Reference< css::uno::XComponentContext > mxContext
virtual void SAL_CALL Unprotect(const css::uno::Any &aPassword) override
virtual OUString SAL_CALL getPath() override
virtual OUString SAL_CALL getFullName() override
virtual css::uno::Sequence< OUString > getServiceNames() override
virtual void SAL_CALL Activate() override
virtual void SAL_CALL Save() override
css::uno::Reference< css::uno::XInterface > mxVBProject
virtual OUString getServiceImplName() override
virtual sal_Bool SAL_CALL getSaved() override
static OUString getNameFromModel(const css::uno::Reference< css::frame::XModel > &xModel)
virtual void SAL_CALL setSaved(sal_Bool bSave) override
virtual OUString SAL_CALL getName() override
virtual void SAL_CALL Close(const css::uno::Any &bSaveChanges, const css::uno::Any &aFileName, const css::uno::Any &bRouteWorkbook) override
virtual css::uno::Any SAL_CALL getVBProject() override
virtual void SAL_CALL Protect(const css::uno::Any &aPassword)
const css::uno::Reference< css::frame::XModel > & getModel() const
VbaDocumentBase(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, css::uno::Reference< css::frame::XModel > xModel)
Reference< XDispatch > xDispatch
URL aURL
Sequence< OUString > aServiceNames
OUString sName
#define SAL_INFO(area, stream)
css::uno::Reference< T > getXSomethingFromArgs(css::uno::Sequence< css::uno::Any > const &args, sal_Int32 nPos, bool bCanBeNull=true)
Definition: vbahelper.hxx:60
void dispatchRequests(const uno::Reference< frame::XModel > &xModel, const OUString &aUrl, const uno::Sequence< beans::PropertyValue > &sProps)
Definition: vbahelper.cxx:136
args
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
unsigned char sal_Bool