xref: /trunk/main/oox/source/xls/excelvbaproject.cxx (revision cdf0e10c)
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