update ooo310-m15
[ooovba.git] / applied_patches / 0453-vba-fix-missing-codename.diff
blob4d38930d23f05328f9d0bd137c27e7594fce31cf
1 diff --git sc/source/filter/excel/excimp8.cxx sc/source/filter/excel/excimp8.cxx
2 index 4d1db8b..d4953f8 100644
3 --- sc/source/filter/excel/excimp8.cxx
4 +++ sc/source/filter/excel/excimp8.cxx
5 @@ -249,7 +249,7 @@ void ImportExcel8::Codename( BOOL bWorkbookGlobals )
6 else
8 GetExtDocOptions().AppendCodeName( aName );
9 - GetDoc().SetCodeName( mnTab++, aName );
10 + GetDoc().SetCodeName( GetCurrScTab(), aName );
14 @@ -280,7 +280,7 @@ void ImportExcel8::ReadBasic( void )
15 pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
16 SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg );
17 bool bAsComment = !bLoadExecutable || !aGlobs.hasValue();
18 - aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, bAsComment );
19 + aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, AutoGeneratedCodeNames, bAsComment );
20 if ( !bAsComment )
22 GetObjectManager().SetOleNameOverrideInfo( aBasicImport.ControlNameForObjectId() );
23 diff --git sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
24 index aa2b377..3ceabf1 100644
25 --- sc/source/filter/excel/read.cxx
26 +++ sc/source/filter/excel/read.cxx
27 @@ -809,6 +809,12 @@ FltError ImportExcel8::Read( void )
28 ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
29 aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
31 + bool bSheetHasCodeName = false;
33 + std::vector< String > CodeNames;
35 + std::vector < SCTAB > nTabsWithNoCodeName;
37 while( eAkt != EXC_STATE_END )
39 aIn.StartNextRecord();
40 @@ -876,6 +882,7 @@ FltError ImportExcel8::Read( void )
41 // #i62752# possible to have BIFF8 sheet without globals
42 NeueTabelle();
43 eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
44 + bSheetHasCodeName = false; // reset
45 aIn.StoreGlobalPosition();
48 @@ -1047,9 +1054,30 @@ FltError ImportExcel8::Read( void )
49 case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
51 case 0x0A: // EOF [ 2345 ]
52 + {
53 eAkt = EXC_STATE_SHEET;
54 + String sName;
55 + GetDoc().GetName( GetCurrScTab(), sName );
56 + if ( !bSheetHasCodeName )
57 + {
58 + nTabsWithNoCodeName.push_back( GetCurrScTab() );
59 + OSL_TRACE("No Codename for %d", GetCurrScTab() );
60 + }
61 + else
62 + {
63 + String sCodeName;
64 + GetDoc().GetCodeName( GetCurrScTab(), sCodeName );
65 + OSL_TRACE("Have CodeName %s for SheetName %s",
66 + rtl::OUStringToOString( sCodeName, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() );
67 + CodeNames.push_back( sCodeName );
68 + }
70 + bSheetHasCodeName = false; // reset
73 aIn.SeekGlobalPosition(); // und zurueck an alte Position
74 break;
75 + }
76 case 0x12: SheetProtect(); break;
77 case 0x13: SheetPassword(); break;
78 case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
79 @@ -1061,7 +1089,7 @@ FltError ImportExcel8::Read( void )
80 case 0x9B: FilterMode(); break; // FILTERMODE
81 case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO
82 case 0x9E: AutoFilter(); break; // AUTOFILTER
83 - case 0x01BA: Codename( FALSE ); break;
84 + case 0x01BA: Codename( FALSE ); bSheetHasCodeName = true; break;
85 case 0x0208: Row34(); break; // ROW [ 34 ]
86 case 0x0021:
87 case 0x0221: Array34(); break; // ARRAY [ 34 ]
88 @@ -1171,6 +1199,42 @@ FltError ImportExcel8::Read( void )
90 if( eLastErr == eERR_OK )
92 + // In some strange circumstances a the codename might be missing
93 + // # Create any missing Sheet CodeNames
94 + std::vector < SCTAB >::iterator it_end = nTabsWithNoCodeName.end();
95 + for ( std::vector < SCTAB >::iterator it = nTabsWithNoCodeName.begin(); it != it_end; ++it )
96 + {
97 + bool bGotCodeName = false;
98 + SCTAB nTab = 1;
99 + OSL_TRACE("Trying to find suitable codename for %d", *it );
100 + while ( true )
102 + String sTmpName( RTL_CONSTASCII_USTRINGPARAM("Sheet" ) );
103 + sTmpName += String::CreateFromInt32( sal_Int32(nTab++) );
104 + std::vector< String >::iterator codeName_It = CodeNames.begin();
105 + std::vector< String >::iterator codeName_It_end = CodeNames.end();
106 + // search for codename
107 + for ( ; codeName_It != codeName_It_end; ++codeName_It )
109 + if ( *codeName_It == sTmpName )
110 + break;
113 + if ( codeName_It == codeName_It_end ) // generated codename not found
115 + OSL_TRACE("Using generated codename %s", rtl::OUStringToOString( sTmpName, RTL_TEXTENCODING_UTF8 ).getStr() );
116 + // Set new codename
117 + GetDoc().SetCodeName( *it, sTmpName );
118 + // Record newly used codename
119 + CodeNames.push_back( sTmpName );
120 + // Record those we have created so they can be created in
121 + // basic
122 + AutoGeneratedCodeNames.push_back( sTmpName );
123 + break;
128 // #i45843# Convert pivot tables before calculation, so they are available
129 // for the GETPIVOTDATA function.
130 if( GetBiff() == EXC_BIFF8 )
131 diff --git sc/source/filter/inc/excimp8.hxx sc/source/filter/inc/excimp8.hxx
132 index f35faef..226ec6b 100644
133 --- sc/source/filter/inc/excimp8.hxx
134 +++ sc/source/filter/inc/excimp8.hxx
135 @@ -54,6 +54,9 @@ class ImportExcel8 : public ImportExcel
137 SCTAB mnTab;
138 protected:
139 + // represents codename ( and associated modules )
140 + // not speficied directly in the binary format
141 + std::vector< String > AutoGeneratedCodeNames;
142 ExcScenarioList aScenList;
144 BOOL bHasBasic;
145 diff --git svx/inc/svxmsbas.hxx svx/inc/svxmsbas.hxx
146 index fab5faf..f1a4c44 100644
147 --- svx/inc/svxmsbas.hxx
148 +++ svx/inc/svxmsbas.hxx
149 @@ -76,8 +76,10 @@ public:
150 // 0 - nothing has done
151 // bit 0 = 1 -> any code is imported to the SO-Basic
152 // bit 1 = 1 -> the VBA - storage is copy to the ObjectShell storage
153 - int Import( const String& rStorageName, const String &rSubStorageName,
154 + int Import( const String& rStorageName, const String &rSubStorageName,
155 BOOL bAsComment=TRUE, BOOL bStripped=TRUE );
156 + int Import( const String& rStorageName, const String &rSubStorageName,
157 + const std::vector< String >& codeNames, BOOL bAsComment=TRUE, BOOL bStripped=TRUE );
159 // only for the export - copy or delete the saved VBA-macro-storage
160 // form the ObjectShell
161 @@ -98,15 +100,16 @@ private:
162 BOOL bImport;
163 BOOL bCopy;
165 - SVX_DLLPRIVATE BOOL ImportCode_Impl( const String& rStorageName,
166 - const String &rSubStorageName,
167 - BOOL bAsComment, BOOL bStripped );
168 + SVX_DLLPRIVATE BOOL ImportCode_Impl( const String& rStorageName,
169 + const String &rSubStorageName,
170 + const std::vector< String >&,
171 + BOOL bAsComment, BOOL bStripped );
172 SVX_DLLPRIVATE bool ImportForms_Impl(const String& rStorageName,
173 const String &rSubStorageName, BOOL bVBAMode );
174 SVX_DLLPRIVATE BOOL CopyStorage_Impl( const String& rStorageName,
175 const String &rSubStorageName);
176 rtl::OUString msProjectName;
177 - SVX_DLLPRIVATE BOOL ImportCode_Impl( VBA_Impl&, BOOL, BOOL );
178 + SVX_DLLPRIVATE BOOL ImportCode_Impl( VBA_Impl&, const std::vector< String >&, BOOL, BOOL );
179 SVX_DLLPRIVATE bool ImportForms_Impl( VBA_Impl&, const String&, const String&, BOOL);
182 diff --git svx/source/msfilter/svxmsbas.cxx svx/source/msfilter/svxmsbas.cxx
183 index d4d6838..0ebc074 100644
184 --- svx/source/msfilter/svxmsbas.cxx
185 +++ svx/source/msfilter/svxmsbas.cxx
186 @@ -62,6 +62,8 @@ using namespace com::sun::star;
188 using rtl::OUString;
190 +static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) );
192 void SvxImportMSVBasic::extractAttribute( const String& rAttribute, const String& rModName )
194 // format of the attribute we are interested in is
195 @@ -83,9 +85,17 @@ int SvxImportMSVBasic::Import( const String& rStorageName,
196 const String &rSubStorageName,
197 BOOL bAsComment, BOOL bStripped )
199 + std::vector< String > codeNames;
200 + return Import( rStorageName, rSubStorageName, codeNames, bAsComment, bStripped );
202 +int SvxImportMSVBasic::Import( const String& rStorageName,
203 + const String &rSubStorageName,
204 + const std::vector< String >& codeNames,
205 + BOOL bAsComment, BOOL bStripped )
207 msProjectName = rtl::OUString();
208 int nRet = 0;
209 - if( bImport && ImportCode_Impl( rStorageName, rSubStorageName,
210 + if( bImport && ImportCode_Impl( rStorageName, rSubStorageName, codeNames,
211 bAsComment, bStripped ))
212 nRet |= 1;
214 @@ -296,6 +306,7 @@ BOOL SvxImportMSVBasic::CopyStorage_Impl( const String& rStorageName,
216 BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
217 const String &rSubStorageName,
218 + const std::vector< String >& codeNames,
219 BOOL bAsComment, BOOL bStripped )
221 BOOL bRet = FALSE;
222 @@ -308,31 +319,24 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
223 if ( msProjectName.getLength() )
224 rDocSh.GetBasicManager()->SetName( msProjectName ); // set name of Project
226 - bRet = ImportCode_Impl( aVBA, bAsComment, bStripped );
227 + bRet = ImportCode_Impl( aVBA, codeNames, bAsComment, bStripped );
228 std::vector<rtl::OUString> sProjectRefs = aVBA.ProjectReferences();
230 for ( std::vector<rtl::OUString>::iterator it = sProjectRefs.begin(); it != sProjectRefs.end(); ++it )
232 rtl::OUString sFileName = *it;
233 -#ifndef WIN
234 -#ifdef DEBUG
235 - // hacky test code to read referenced projects on linux
236 - sal_Int32 nPos = (*it).lastIndexOf('\\');
237 - sFileName = (*it).copy( nPos + 1 );
238 - sFileName = rtl::OUString::createFromAscii("~/Documents/") + sFileName;
239 -#endif
240 -#endif
241 OSL_TRACE("referenced project %s ", rtl::OUStringToOString( sFileName, RTL_TEXTENCODING_UTF8 ).getStr() );
242 SotStorageRef rRoot = new SotStorage( sFileName, STREAM_STD_READWRITE, STORAGE_TRANSACTED );
243 VBA_Impl refVBA( *rRoot, bAsComment );
244 - if( refVBA.Open(rStorageName,rSubStorageName) && ImportCode_Impl( refVBA, bAsComment, bStripped ) )
245 + std::vector< String > codeNamesNone;
246 + if( refVBA.Open(rStorageName,rSubStorageName) && ImportCode_Impl( refVBA, codeNamesNone, bAsComment, bStripped ) )
247 bRet = TRUE; // mark that some code was imported
250 return bRet;
253 -BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, BOOL bAsComment, BOOL bStripped )
254 +BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, const std::vector< String >& codeNames, BOOL bAsComment, BOOL bStripped )
256 BOOL bRet = FALSE;
257 SFX_APP()->EnterBasicCall();
258 @@ -357,7 +361,7 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, BOOL bAsComment, BOOL b
260 if( xLib.is() )
262 - Reference< container::XNameAccess > xVBAObjectForCodeName;
263 + Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
264 if ( !bAsComment )
266 rDocSh.GetBasicManager()->GetLib( aLibName )->SetVBAEnabled( true );
267 @@ -366,11 +370,16 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, BOOL bAsComment, BOOL b
271 - xVBAObjectForCodeName.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), UNO_QUERY );
272 + xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), UNO_QUERY );
274 catch( Exception& ) { }
277 + typedef std::hash_map< rtl::OUString, uno::Any, ::rtl::OUStringHash,
278 +::std::equal_to< ::rtl::OUString > > NameModuleDataHash;
280 + NameModuleDataHash moduleData;
282 for( UINT16 i=0; i<nStreamCount;i++)
284 StringArray aDecompressed = aVBA.Decompress(i);
285 @@ -436,7 +445,6 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, BOOL bAsComment, BOOL b
286 DBG_ERRORFILE( "SvxImportMSVBasic::ImportCode_Impl - unknown module type" );
287 break;
289 - static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) );
290 static ::rtl::OUString sClassOption( RTL_CONSTASCII_USTRINGPARAM( "Option ClassModule\n" ) );
291 if ( !bAsComment /*&& !rDocSh.GetBasic()->isVBAEnabled() */)
293 @@ -508,60 +516,79 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, BOOL bAsComment, BOOL b
294 aSource += rtl::OUString::createFromAscii("\nEnd Sub");
296 ::rtl::OUString aModName( sModule );
298 - aSource = modeTypeComment + aSource;
299 + aSource = modeTypeComment + aSource;
301 - Any aSourceAny;
302 - OSL_TRACE("erm %d", mType );
303 - if ( !bAsComment )
305 - OSL_TRACE("vba processing %d", mType );
306 - script::ModuleInfo sModuleInfo;
307 - sModuleInfo.ModuleName = aModName;
308 - sModuleInfo.ModuleSource = aSource;
309 - sModuleInfo.ModuleType = mType;
310 - if ( mType == ModuleType::Form )
311 - // hack, the module ( imo document basic should...
312 - // know the XModel... ) but it doesn't
313 - sModuleInfo.ModuleObject.set( rDocSh.GetModel(), UNO_QUERY );
314 - // document modules, we should be able to access
315 - // the api objects at this time
316 - else if ( mType == ModuleType::Document )
318 - uno::Reference< lang::XMultiServiceFactory> xSF( rDocSh.GetModel(), uno::UNO_QUERY);
319 - uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
320 - if ( xSF.is() )
321 - xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY );
322 - // get the api object for the codename
323 - if ( xVBACodeNamedObjectAccess.is() )
325 - try
327 - sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( sModuleInfo.ModuleName ), uno::UNO_QUERY );
328 - OSL_TRACE("** Straight up creation of Module");
330 - catch(uno::Exception& e)
332 - OSL_TRACE("Failed to get documument object for %s", rtl::OUStringToOString( sModuleInfo.ModuleName, RTL_TEXTENCODING_UTF8 ).getStr() );
336 - aSourceAny <<= sModuleInfo;
338 - else
339 - aSourceAny <<= aSource;
340 - if( xLib->hasByName( aModName ) )
341 - xLib->replaceByName( aModName, aSourceAny );
342 - else
343 - xLib->insertByName( aModName, aSourceAny );
344 - }
346 - bRet = true;
349 + Any aSourceAny;
350 + OSL_TRACE("erm %d", mType );
351 + if ( !bAsComment )
353 + OSL_TRACE("vba processing %d", mType );
354 + script::ModuleInfo sModuleInfo;
355 + sModuleInfo.ModuleName = aModName;
356 + sModuleInfo.ModuleSource = aSource;
357 + sModuleInfo.ModuleType = mType;
358 + aSourceAny <<= sModuleInfo;
360 + else
361 + aSourceAny <<= aSource;
362 + moduleData[ aModName ] = aSourceAny;
365 + // Hack for missing codenames ( only know to happen in excel but... )
366 + // only makes sense to do this if we are importing non-commented basic
367 + if ( !bAsComment )
369 + for ( std::vector< String >::const_iterator it = codeNames.begin(); it != codeNames.end(); ++it )
371 + script::ModuleInfo sModuleInfo;
372 + sModuleInfo.ModuleName = *it;
373 + sModuleInfo.ModuleType = ModuleType::Document ;
374 + sModuleInfo.ModuleSource = sVBAOption;
375 + moduleData[ *it ] = uno::makeAny( sModuleInfo );
378 + NameModuleDataHash::iterator it_end = moduleData.end();
379 + for ( NameModuleDataHash::iterator it = moduleData.begin(); it != it_end; ++it )
381 + script::ModuleInfo sModuleInfo;
382 + if ( it->second >>=sModuleInfo )
385 + if ( sModuleInfo.ModuleType == ModuleType::Form )
386 + // hack, the module ( imo document basic should...
387 + // know the XModel... ) but it doesn't
388 + sModuleInfo.ModuleObject.set( rDocSh.GetModel(), UNO_QUERY );
389 + // document modules, we should be able to access
390 + // the api objects at this time
391 + else if ( sModuleInfo.ModuleType == ModuleType::Document )
393 + if ( xVBACodeNamedObjectAccess.is() )
395 + try
397 + sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( sModuleInfo.ModuleName ), uno::UNO_QUERY );
398 + OSL_TRACE("** Straight up creation of Module");
400 + catch(uno::Exception& e)
402 + OSL_TRACE("Failed to get documument object for %s", rtl::OUStringToOString( sModuleInfo.ModuleName, RTL_TEXTENCODING_UTF8 ).getStr() );
406 + it->second = uno::makeAny( sModuleInfo );
409 + if( xLib->hasByName( it->first ) )
410 + xLib->replaceByName( it->first, it->second );
411 + else
412 + xLib->insertByName( it->first, it->second );
413 + bRet = true;
414 + }
417 if( bRet )
418 - SFX_APP()->LeaveBasicCall();
419 - return bRet;
420 + SFX_APP()->LeaveBasicCall();
421 + return bRet;
424 /* vi:set tabstop=4 shiftwidth=4 expandtab: */