1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "oox/xls/excelvbaproject.hxx" 29 30 #include <list> 31 #include <set> 32 #include <com/sun/star/container/XEnumeration.hpp> 33 #include <com/sun/star/container/XEnumerationAccess.hpp> 34 #include <com/sun/star/document/XEventsSupplier.hpp> 35 #include <com/sun/star/frame/XModel.hpp> 36 #include <com/sun/star/script/ModuleType.hpp> 37 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 38 #include <rtl/ustrbuf.hxx> 39 #include "oox/helper/helper.hxx" 40 #include "oox/helper/propertyset.hxx" 41 42 namespace oox { 43 namespace xls { 44 45 // ============================================================================ 46 47 using namespace ::com::sun::star::container; 48 using namespace ::com::sun::star::document; 49 using namespace ::com::sun::star::frame; 50 using namespace ::com::sun::star::lang; 51 using namespace ::com::sun::star::script; 52 using namespace ::com::sun::star::sheet; 53 using namespace ::com::sun::star::uno; 54 55 using ::rtl::OUString; 56 using ::rtl::OUStringBuffer; 57 58 // ============================================================================ 59 60 ExcelVbaProject::ExcelVbaProject( const Reference< XComponentContext >& rxContext, const Reference< XSpreadsheetDocument >& rxDocument ) : 61 ::oox::ole::VbaProject( rxContext, Reference< XModel >( rxDocument, UNO_QUERY ), CREATE_OUSTRING( "Calc" ) ), 62 mxDocument( rxDocument ) 63 { 64 } 65 66 // protected ------------------------------------------------------------------ 67 68 namespace { 69 70 struct SheetCodeNameInfo 71 { 72 PropertySet maSheetProps; /// Property set of the sheet without codename. 73 OUString maPrefix; /// Prefix for the codename to be generated. 74 75 inline explicit SheetCodeNameInfo( PropertySet& rSheetProps, const OUString& rPrefix ) : 76 maSheetProps( rSheetProps ), maPrefix( rPrefix ) {} 77 }; 78 79 typedef ::std::set< OUString > CodeNameSet; 80 typedef ::std::list< SheetCodeNameInfo > SheetCodeNameInfoList; 81 82 } // namespace 83 84 void ExcelVbaProject::prepareImport() 85 { 86 /* Check if the sheets have imported codenames. Generate new unused 87 codenames if not. */ 88 if( mxDocument.is() ) try 89 { 90 // collect existing codenames (do not use them when creating new codenames) 91 CodeNameSet aUsedCodeNames; 92 93 // collect sheets without codenames 94 SheetCodeNameInfoList aCodeNameInfos; 95 96 // iterate over all imported sheets 97 Reference< XEnumerationAccess > xSheetsEA( mxDocument->getSheets(), UNO_QUERY_THROW ); 98 Reference< XEnumeration > xSheetsEnum( xSheetsEA->createEnumeration(), UNO_SET_THROW ); 99 // own try/catch for every sheet 100 while( xSheetsEnum->hasMoreElements() ) try 101 { 102 PropertySet aSheetProp( xSheetsEnum->nextElement() ); 103 OUString aCodeName; 104 aSheetProp.getProperty( aCodeName, PROP_CodeName ); 105 if( aCodeName.getLength() > 0 ) 106 { 107 aUsedCodeNames.insert( aCodeName ); 108 } 109 else 110 { 111 // TODO: once we have chart sheets we need a switch/case on sheet type ('SheetNNN' vs. 'ChartNNN') 112 aCodeNameInfos.push_back( SheetCodeNameInfo( aSheetProp, CREATE_OUSTRING( "Sheet" ) ) ); 113 } 114 } 115 catch( Exception& ) 116 { 117 } 118 119 // create new codenames if sheets do not have one 120 for( SheetCodeNameInfoList::iterator aIt = aCodeNameInfos.begin(), aEnd = aCodeNameInfos.end(); aIt != aEnd; ++aIt ) 121 { 122 // search for an unused codename 123 sal_Int32 nCounter = 1; 124 OUString aCodeName; 125 do 126 { 127 aCodeName = OUStringBuffer( aIt->maPrefix ).append( nCounter++ ).makeStringAndClear(); 128 } 129 while( aUsedCodeNames.count( aCodeName ) > 0 ); 130 aUsedCodeNames.insert( aCodeName ); 131 132 // set codename at sheet 133 aIt->maSheetProps.setProperty( PROP_CodeName, aCodeName ); 134 135 // tell base class to create a dummy module 136 addDummyModule( aCodeName, ModuleType::DOCUMENT ); 137 } 138 } 139 catch( Exception& ) 140 { 141 } 142 } 143 144 // ============================================================================ 145 146 } // namespace xls 147 } // namespace oox 148