Line data Source code
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 "oox/ole/vbaproject.hxx"
21 :
22 : #include <com/sun/star/document/XStorageBasedDocument.hpp>
23 : #include <com/sun/star/embed/ElementModes.hpp>
24 : #include <com/sun/star/embed/XTransactedObject.hpp>
25 : #include <com/sun/star/frame/XModel.hpp>
26 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 : #include <com/sun/star/script/ModuleType.hpp>
28 : #include <com/sun/star/script/XLibraryContainer.hpp>
29 : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
30 : #include <com/sun/star/script/vba/XVBAMacroResolver.hpp>
31 : #include <com/sun/star/uno/XComponentContext.hpp>
32 : #include <comphelper/configurationhelper.hxx>
33 : #include <comphelper/string.hxx>
34 : #include <osl/diagnose.h>
35 : #include <rtl/tencinfo.h>
36 : #include <rtl/ustrbuf.h>
37 : #include "oox/helper/binaryinputstream.hxx"
38 : #include "oox/helper/containerhelper.hxx"
39 : #include "oox/helper/propertyset.hxx"
40 : #include "oox/helper/textinputstream.hxx"
41 : #include "oox/ole/olestorage.hxx"
42 : #include "oox/ole/vbacontrol.hxx"
43 : #include "oox/ole/vbahelper.hxx"
44 : #include "oox/ole/vbainputstream.hxx"
45 : #include "oox/ole/vbamodule.hxx"
46 : #include "oox/token/properties.hxx"
47 :
48 : namespace oox {
49 : namespace ole {
50 :
51 : using namespace ::com::sun::star::container;
52 : using namespace ::com::sun::star::document;
53 : using namespace ::com::sun::star::embed;
54 : using namespace ::com::sun::star::frame;
55 : using namespace ::com::sun::star::io;
56 : using namespace ::com::sun::star::lang;
57 : using namespace ::com::sun::star::script;
58 : using namespace ::com::sun::star::script::vba;
59 : using namespace ::com::sun::star::uno;
60 :
61 : using ::comphelper::ConfigurationHelper;
62 :
63 : namespace {
64 :
65 126 : bool lclReadConfigItem( const Reference< XInterface >& rxConfigAccess, const OUString& rItemName )
66 : {
67 : // some applications do not support all configuration items, assume 'false' in this case
68 : try
69 : {
70 126 : Any aItem = ConfigurationHelper::readRelativeKey( rxConfigAccess, "Filter/Import/VBA", rItemName );
71 126 : return aItem.has< bool >() && aItem.get< bool >();
72 : }
73 0 : catch(const Exception& )
74 : {
75 : }
76 0 : return false;
77 : }
78 :
79 : } // namespace
80 :
81 32 : VbaFilterConfig::VbaFilterConfig( const Reference< XComponentContext >& rxContext, const OUString& rConfigCompName )
82 : {
83 : OSL_ENSURE( rxContext.is(), "VbaFilterConfig::VbaFilterConfig - missing component context" );
84 32 : if( rxContext.is() ) try
85 : {
86 : OSL_ENSURE( !rConfigCompName.isEmpty(), "VbaFilterConfig::VbaFilterConfig - invalid configuration component name" );
87 32 : OUString aConfigPackage = "org.openoffice.Office." + rConfigCompName;
88 32 : mxConfigAccess = ConfigurationHelper::openConfig( rxContext, aConfigPackage, ConfigurationHelper::E_READONLY );
89 : }
90 0 : catch(const Exception& )
91 : {
92 : }
93 : OSL_ENSURE( mxConfigAccess.is(), "VbaFilterConfig::VbaFilterConfig - cannot open configuration" );
94 32 : }
95 :
96 32 : VbaFilterConfig::~VbaFilterConfig()
97 : {
98 32 : }
99 :
100 31 : bool VbaFilterConfig::isImportVba() const
101 : {
102 31 : return lclReadConfigItem( mxConfigAccess, "Load" );
103 : }
104 :
105 64 : bool VbaFilterConfig::isImportVbaExecutable() const
106 : {
107 64 : return lclReadConfigItem( mxConfigAccess, "Executable" );
108 : }
109 :
110 31 : bool VbaFilterConfig::isExportVba() const
111 : {
112 31 : return lclReadConfigItem( mxConfigAccess, "Save" );
113 : }
114 :
115 0 : VbaMacroAttacherBase::VbaMacroAttacherBase( const OUString& rMacroName ) :
116 0 : maMacroName( rMacroName )
117 : {
118 : OSL_ENSURE( !maMacroName.isEmpty(), "VbaMacroAttacherBase::VbaMacroAttacherBase - empty macro name" );
119 0 : }
120 :
121 0 : VbaMacroAttacherBase::~VbaMacroAttacherBase()
122 : {
123 0 : }
124 :
125 0 : void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroResolver >& rxResolver )
126 : {
127 : try
128 : {
129 0 : attachMacro( rxResolver->resolveVBAMacroToScriptURL( maMacroName ) );
130 : }
131 0 : catch(const Exception& )
132 : {
133 : }
134 0 : }
135 :
136 32 : VbaProject::VbaProject( const Reference< XComponentContext >& rxContext,
137 : const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) :
138 : VbaFilterConfig( rxContext, rConfigCompName ),
139 : mxContext( rxContext ),
140 : mxDocModel( rxDocModel ),
141 32 : maPrjName( "Standard" )
142 : {
143 : OSL_ENSURE( mxContext.is(), "VbaProject::VbaProject - missing component context" );
144 : OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" );
145 32 : }
146 :
147 32 : VbaProject::~VbaProject()
148 : {
149 32 : }
150 :
151 31 : bool VbaProject::importVbaProject( StorageBase& rVbaPrjStrg )
152 : {
153 : // create GraphicHelper
154 31 : Reference< ::com::sun::star::frame::XFrame > xFrame;
155 31 : if ( mxDocModel.is() )
156 : {
157 31 : Reference< ::com::sun::star::frame::XController > xController = mxDocModel->getCurrentController();
158 31 : xFrame = xController.is() ? xController->getFrame() : NULL;
159 : }
160 62 : StorageRef noStorage;
161 : // if the GraphicHelper tries to use noStorage it will of course crash
162 : // but.. this shouldn't happen as there is no reason for GraphicHelper
163 : // to do that when importing VBA projects
164 62 : GraphicHelper grfHlp( mxContext, xFrame, noStorage );
165 31 : importVbaProject( rVbaPrjStrg, grfHlp );
166 : // return true if something has been imported
167 62 : return hasModules() || hasDialogs();
168 : }
169 :
170 31 : void VbaProject::importVbaProject( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr )
171 : {
172 31 : if( rVbaPrjStrg.isStorage() )
173 : {
174 : // load the code modules and forms
175 31 : if( isImportVba() )
176 31 : importVba( rVbaPrjStrg, rGraphicHelper, bDefaultColorBgr );
177 : // copy entire storage into model
178 31 : if( isExportVba() )
179 31 : copyStorage( rVbaPrjStrg );
180 : }
181 31 : }
182 :
183 0 : void VbaProject::registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher )
184 : {
185 : OSL_ENSURE( rxAttacher.get(), "VbaProject::registerMacroAttacher - unexpected empty reference" );
186 0 : maMacroAttachers.push_back( rxAttacher );
187 0 : }
188 :
189 31 : bool VbaProject::hasModules() const
190 : {
191 31 : return mxBasicLib.is() && mxBasicLib->hasElements();
192 : }
193 :
194 0 : bool VbaProject::hasDialogs() const
195 : {
196 0 : return mxDialogLib.is() && mxDialogLib->hasElements();
197 : }
198 :
199 : // protected ------------------------------------------------------------------
200 :
201 0 : void VbaProject::addDummyModule( const OUString& rName, sal_Int32 nType )
202 : {
203 : OSL_ENSURE( !rName.isEmpty(), "VbaProject::addDummyModule - missing module name" );
204 0 : maDummyModules[ rName ] = nType;
205 0 : }
206 :
207 31 : void VbaProject::prepareImport()
208 : {
209 31 : }
210 :
211 : // private --------------------------------------------------------------------
212 :
213 66 : Reference< XLibraryContainer > VbaProject::getLibraryContainer( sal_Int32 nPropId )
214 : {
215 66 : PropertySet aDocProp( mxDocModel );
216 66 : Reference< XLibraryContainer > xLibContainer( aDocProp.getAnyProperty( nPropId ), UNO_QUERY );
217 66 : return xLibContainer;
218 : }
219 :
220 34 : Reference< XNameContainer > VbaProject::openLibrary( sal_Int32 nPropId, bool bCreateMissing )
221 : {
222 34 : Reference< XNameContainer > xLibrary;
223 : try
224 : {
225 34 : Reference< XLibraryContainer > xLibContainer( getLibraryContainer( nPropId ), UNO_SET_THROW );
226 34 : if( bCreateMissing && !xLibContainer->hasByName( maPrjName ) )
227 34 : xLibContainer->createLibrary( maPrjName );
228 34 : xLibrary.set( xLibContainer->getByName( maPrjName ), UNO_QUERY_THROW );
229 : }
230 0 : catch(const Exception& )
231 : {
232 : }
233 : OSL_ENSURE( !bCreateMissing || xLibrary.is(), "VbaProject::openLibrary - cannot create library" );
234 34 : return xLibrary;
235 : }
236 :
237 32 : Reference< XNameContainer > VbaProject::createBasicLibrary()
238 : {
239 32 : if( !mxBasicLib.is() )
240 32 : mxBasicLib = openLibrary( PROP_BasicLibraries, true );
241 32 : return mxBasicLib;
242 : }
243 :
244 2 : Reference< XNameContainer > VbaProject::createDialogLibrary()
245 : {
246 2 : if( !mxDialogLib.is() )
247 2 : mxDialogLib = openLibrary( PROP_DialogLibraries, true );
248 2 : return mxDialogLib;
249 : }
250 :
251 31 : void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr )
252 : {
253 31 : readVbaModules( rVbaPrjStrg );
254 31 : importModulesAndForms(rVbaPrjStrg, rGraphicHelper, bDefaultColorBgr );
255 31 : }
256 :
257 32 : void VbaProject::readVbaModules( StorageBase& rVbaPrjStrg )
258 : {
259 32 : StorageRef xVbaStrg = rVbaPrjStrg.openSubStorage( "VBA", false );
260 : OSL_ENSURE( xVbaStrg.get(), "VbaProject::readVbaModules - cannot open 'VBA' substorage" );
261 32 : if( !xVbaStrg )
262 0 : return;
263 :
264 : /* Read the 'VBA/dir' stream which contains general settings of the VBA
265 : project such as the text encoding used throughout several streams, and
266 : a list of all code modules.
267 : */
268 64 : BinaryXInputStream aInStrm( xVbaStrg->openInputStream( "dir" ), true );
269 : // VbaInputStream implements decompression
270 64 : VbaInputStream aDirStrm( aInStrm );
271 : OSL_ENSURE( !aDirStrm.isEof(), "VbaProject::importVba - cannot open 'dir' stream" );
272 32 : if( aDirStrm.isEof() )
273 0 : return;
274 :
275 : // virtual call, derived classes may do some preparations
276 32 : prepareImport();
277 :
278 : // read all records of the directory
279 32 : rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252;
280 32 : sal_uInt16 nModuleCount = 0;
281 32 : bool bExecutable = isImportVbaExecutable();
282 :
283 32 : sal_uInt16 nRecId = 0;
284 64 : StreamDataSequence aRecData;
285 1098 : while( VbaHelper::readDirRecord( nRecId, aRecData, aDirStrm ) && (nRecId != VBA_ID_PROJECTEND) )
286 : {
287 : // create record stream object from imported record data
288 1034 : SequenceInputStream aRecStrm( aRecData );
289 1034 : sal_Int32 nRecSize = aRecData.getLength();
290 1034 : switch( nRecId )
291 : {
292 : case VBA_ID_PROJECTCODEPAGE:
293 : {
294 : OSL_ENSURE( nRecSize == 2, "VbaProject::importVba - invalid record size" );
295 : OSL_ENSURE( maModules.empty(), "VbaProject::importVba - unexpected PROJECTCODEPAGE record" );
296 32 : rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( aRecStrm.readuInt16() );
297 : OSL_ENSURE( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW, "VbaProject::importVba - unknown text encoding" );
298 32 : if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
299 32 : eTextEnc = eNewTextEnc;
300 : }
301 32 : break;
302 : case VBA_ID_PROJECTNAME:
303 : {
304 32 : OUString aPrjName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc );
305 : OSL_ENSURE( !aPrjName.isEmpty(), "VbaProject::importVba - invalid project name" );
306 32 : if( !aPrjName.isEmpty() )
307 32 : maPrjName = aPrjName;
308 : }
309 32 : break;
310 : case VBA_ID_PROJECTMODULES:
311 : OSL_ENSURE( nRecSize == 2, "VbaProject::importVba - invalid record size" );
312 : OSL_ENSURE( maModules.empty(), "VbaProject::importVba - unexpected PROJECTMODULES record" );
313 32 : nModuleCount = aRecStrm.readuInt16();
314 32 : break;
315 : case VBA_ID_MODULENAME:
316 : {
317 160 : OUString aName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc );
318 : OSL_ENSURE( !aName.isEmpty(), "VbaProject::importVba - invalid module name" );
319 : OSL_ENSURE( !maModules.has( aName ), "VbaProject::importVba - multiple modules with the same name" );
320 160 : VbaModuleMap::mapped_type& rxModule = maModules[ aName ];
321 160 : rxModule.reset( new VbaModule( mxContext, mxDocModel, aName, eTextEnc, bExecutable ) );
322 : // read all remaining records until the MODULEEND record
323 160 : rxModule->importDirRecords( aDirStrm );
324 : OSL_ENSURE( !maModulesByStrm.has( rxModule->getStreamName() ), "VbaProject::importVba - multiple modules with the same stream name" );
325 160 : maModulesByStrm[ rxModule->getStreamName() ] = rxModule;
326 : }
327 160 : break;
328 : }
329 1034 : }
330 : SAL_WARN_IF( nModuleCount != maModules.size(), "oox.ole", "VbaProject::importVba - invalid module count" );
331 :
332 : /* The directory does not contain the real type of the modules, it
333 : distinguishes only between 'procedural' and 'document' (the latter
334 : includes class and form modules). Now, the exact type of all modules
335 : will be read from the 'PROJECT' stream. It consists of text lines in
336 : 'key=value' format which list the code modules by type.
337 :
338 : - The line 'document=<modulename>/&HXXXXXXXX' declares document
339 : modules. These are attached to the Word document (usually called
340 : 'ThisDocument'), the Excel workbook (usually called
341 : 'ThisWorkbook'), or single Excel worksheets or chartsheets (usually
342 : called 'SheetX' or 'ChartX', X being a decimal number). Of course,
343 : users may rename all these modules. The slash character separates
344 : an automation server version number (hexadecimal 'XXXXXXXX') from
345 : the module name.
346 : - The line 'Module=<modulename>' declares common procedural code
347 : modules.
348 : - The line 'Class=<modulename>' declares a class module.
349 : - The line 'BaseClass=<modulename>' declares a code module attached
350 : to a user form with the same name.
351 : */
352 32 : BinaryXInputStream aPrjStrm( rVbaPrjStrg.openInputStream( "PROJECT" ), true );
353 : OSL_ENSURE( !aPrjStrm.isEof(), "VbaProject::importVba - cannot open 'PROJECT' stream" );
354 : // do not exit if this stream does not exist, but proceed to load the modules below
355 32 : if( !aPrjStrm.isEof() )
356 : {
357 32 : TextInputStream aPrjTextStrm( mxContext, aPrjStrm, eTextEnc );
358 64 : OUString aKey, aValue;
359 32 : bool bExitLoop = false;
360 518 : while( !bExitLoop && !aPrjTextStrm.isEof() )
361 : {
362 : // read a text line from the stream
363 454 : OUString aLine = aPrjTextStrm.readLine().trim();
364 454 : sal_Int32 nLineLen = aLine.getLength();
365 : // exit if a subsection starts (section name is given in brackets)
366 454 : bExitLoop = (nLineLen >= 2) && (aLine[ 0 ] == '[') && (aLine[ nLineLen - 1 ] == ']');
367 454 : if( !bExitLoop && VbaHelper::extractKeyValue( aKey, aValue, aLine ) )
368 : {
369 390 : sal_Int32 nType = ModuleType::UNKNOWN;
370 390 : if( aKey.equalsIgnoreAsciiCase( "Document" ) )
371 : {
372 128 : nType = ModuleType::DOCUMENT;
373 : // strip automation server version from module names
374 128 : sal_Int32 nSlashPos = aValue.indexOf( '/' );
375 128 : if( nSlashPos >= 0 )
376 128 : aValue = aValue.copy( 0, nSlashPos );
377 : }
378 262 : else if( aKey.equalsIgnoreAsciiCase( "Module" ) )
379 30 : nType = ModuleType::NORMAL;
380 232 : else if( aKey.equalsIgnoreAsciiCase( "Class" ) )
381 0 : nType = ModuleType::CLASS;
382 232 : else if( aKey.equalsIgnoreAsciiCase( "BaseClass" ) )
383 2 : nType = ModuleType::FORM;
384 :
385 390 : if( (nType != ModuleType::UNKNOWN) && !aValue.isEmpty() )
386 : {
387 : OSL_ENSURE( maModules.has( aValue ), "VbaProject::importVba - module not found" );
388 160 : if( VbaModule* pModule = maModules.get( aValue ).get() )
389 158 : pModule->setType( nType );
390 : }
391 : }
392 486 : }
393 : }
394 32 : if( !maModules.empty() ) try
395 : {
396 : /* Set library container to VBA compatibility mode. This will create
397 : the VBA Globals object and store it in the Basic manager of the
398 : document. */
399 : try
400 : {
401 32 : Reference< XVBACompatibility > xVBACompat( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW );
402 32 : xVBACompat->setVBACompatibilityMode( sal_True );
403 32 : xVBACompat->setProjectName( maPrjName );
404 :
405 : }
406 0 : catch(const Exception& )
407 : {
408 : }
409 : }
410 0 : catch(const Exception& )
411 : {
412 64 : }
413 : }
414 :
415 32 : void VbaProject::importModulesAndForms( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr )
416 : {
417 32 : StorageRef xVbaStrg = rVbaPrjStrg.openSubStorage( "VBA", false );
418 : OSL_ENSURE( xVbaStrg.get(), "VbaProject::importModulesAndForms - cannot open 'VBA' substorage" );
419 32 : if( !xVbaStrg )
420 32 : return;
421 32 : rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252;
422 32 : bool bExecutable = isImportVbaExecutable();
423 :
424 : // create empty dummy modules
425 64 : VbaModuleMap aDummyModules;
426 32 : for( DummyModuleMap::iterator aIt = maDummyModules.begin(), aEnd = maDummyModules.end(); aIt != aEnd; ++aIt )
427 : {
428 : OSL_ENSURE( !maModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" );
429 0 : VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
430 0 : rxModule.reset( new VbaModule( mxContext, mxDocModel, aIt->first, eTextEnc, bExecutable ) );
431 0 : rxModule->setType( aIt->second );
432 : }
433 :
434 : /* Now it is time to load the source code. All modules will be inserted
435 : into the Basic library of the document specified by the 'maPrjName'
436 : member. Do not create the Basic library, if there are no modules
437 : specified. */
438 32 : if( !maModules.empty() || !aDummyModules.empty() ) try
439 : {
440 : // get the model factory and the basic library
441 32 : Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
442 64 : Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW );
443 :
444 : // try to get access to document objects related to code modules
445 64 : Reference< XNameAccess > xDocObjectNA;
446 : try
447 : {
448 32 : xDocObjectNA.set( xModelFactory->createInstance( "ooo.vba.VBAObjectModuleObjectProvider" ), UNO_QUERY );
449 : }
450 5 : catch(const Exception& )
451 : {
452 : // not all documents support this
453 : }
454 :
455 32 : if( xBasicLib.is() )
456 : {
457 : // #TODO cater for mxOleOverridesSink, like I used to before
458 : // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
459 : maModules.forEachMem( &VbaModule::createAndImportModule,
460 32 : ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ),
461 64 : ::boost::cref( xDocObjectNA ) );
462 :
463 : // create empty dummy modules
464 : aDummyModules.forEachMem( &VbaModule::createEmptyModule,
465 32 : ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
466 32 : }
467 : }
468 0 : catch(const Exception& )
469 : {
470 : }
471 :
472 : /* Load the forms. The file format specification requires that a module
473 : must exist for every form. We are a bit more tolerant and scan the
474 : project storage for all form substorages. This may 'repair' broken VBA
475 : storages that misses to mention a module for an existing form. */
476 64 : ::std::vector< OUString > aElements;
477 32 : rVbaPrjStrg.getElementNames( aElements );
478 130 : for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
479 : {
480 : // try to open the element as storage
481 98 : if( *aIt != "VBA" )
482 : {
483 66 : StorageRef xSubStrg = rVbaPrjStrg.openSubStorage( *aIt, false );
484 66 : if( xSubStrg.get() ) try
485 : {
486 : // resolve module name from storage name (which equals the module stream name)
487 2 : VbaModule* pModule = maModulesByStrm.get( *aIt ).get();
488 : OSL_ENSURE( pModule && (pModule->getType() == ModuleType::FORM),
489 : "VbaProject::importVba - form substorage without form module" );
490 2 : OUString aModuleName;
491 2 : if( pModule )
492 2 : aModuleName = pModule->getName();
493 :
494 : // create and import the form
495 4 : Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW );
496 4 : VbaUserForm aForm( mxContext, mxDocModel, rGraphicHelper, bDefaultColorBgr );
497 4 : aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc );
498 : }
499 0 : catch(const Exception& )
500 : {
501 66 : }
502 : }
503 : }
504 :
505 : // attach macros to registered objects
506 64 : attachMacros();
507 : }
508 :
509 32 : void VbaProject::attachMacros()
510 : {
511 32 : if( !maMacroAttachers.empty() && mxContext.is() ) try
512 : {
513 0 : Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW );
514 0 : Sequence< Any > aArgs( 2 );
515 0 : aArgs[ 0 ] <<= mxDocModel;
516 0 : aArgs[ 1 ] <<= maPrjName;
517 0 : Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext(
518 0 : "com.sun.star.script.vba.VBAMacroResolver", aArgs, mxContext ), UNO_QUERY_THROW );
519 0 : maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) );
520 : }
521 0 : catch(const Exception& )
522 : {
523 : }
524 32 : }
525 :
526 31 : void VbaProject::copyStorage( StorageBase& rVbaPrjStrg )
527 : {
528 31 : if( mxContext.is() ) try
529 : {
530 31 : Reference< XStorageBasedDocument > xStorageBasedDoc( mxDocModel, UNO_QUERY_THROW );
531 62 : Reference< XStorage > xDocStorage( xStorageBasedDoc->getDocumentStorage(), UNO_QUERY_THROW );
532 : {
533 31 : const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE;
534 31 : Reference< XStream > xDocStream( xDocStorage->openStreamElement( "_MS_VBA_Macros", nOpenMode ), UNO_SET_THROW );
535 62 : OleStorage aDestStorage( mxContext, xDocStream, false );
536 31 : rVbaPrjStrg.copyStorageToStorage( aDestStorage );
537 62 : aDestStorage.commit();
538 : }
539 62 : Reference< XTransactedObject >( xDocStorage, UNO_QUERY_THROW )->commit();
540 : }
541 0 : catch(const Exception& )
542 : {
543 : }
544 31 : }
545 :
546 : } // namespace ole
547 246 : } // namespace oox
548 :
549 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|