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