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