Update ooo320-m1
[ooovba.git] / sc / source / ui / vba / vbaworkbooks.cxx
blob4764cfefaf463a603b37483ec731b69eb6171332
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbaworkbooks.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include <comphelper/processfactory.hxx>
32 #include <cppuhelper/implbase1.hxx>
33 #include <cppuhelper/implbase3.hxx>
35 #include <com/sun/star/frame/XDesktop.hpp>
36 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/frame/XComponentLoader.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/frame/XModel.hpp>
41 #include <com/sun/star/frame/XFrame.hpp>
42 #include <com/sun/star/frame/FrameSearchFlag.hpp>
43 #include <com/sun/star/util/XModifiable.hpp>
44 #include <com/sun/star/frame/XStorable.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #include <com/sun/star/beans/PropertyVetoException.hpp>
47 #include <com/sun/star/util/XCloseable.hpp>
48 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
49 #include <com/sun/star/document/XTypeDetection.hpp>
50 #include <com/sun/star/uri/XUriReference.hpp>
51 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
53 #include <sfx2/objsh.hxx>
54 #include <tools/urlobj.hxx>
56 #include "vbaglobals.hxx"
57 #include "vbaworkbook.hxx"
58 #include "vbaworkbooks.hxx"
59 #include <vbahelper/vbahelper.hxx>
61 #include <hash_map>
62 #include <osl/file.hxx>
63 using namespace ::ooo::vba;
64 using namespace ::com::sun::star;
66 const sal_Int16 CUSTOM_CHAR = 5;
68 static uno::Any
69 getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Any& aApplication )
71 // FIXME: fine as long as ScVbaWorkbook is stateless ...
72 uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
73 if( !xModel.is() )
74 return uno::Any();
76 ScVbaWorkbook *pWb = new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel );
77 return uno::Any( uno::Reference< excel::XWorkbook > (pWb) );
80 class WorkBookEnumImpl : public EnumerationHelperImpl
82 uno::Any m_aApplication;
83 public:
84 WorkBookEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_aApplication( aApplication ) {}
86 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
88 uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
89 return getWorkbook( m_xContext, xDoc, m_aApplication );
94 ScVbaWorkbooks::ScVbaWorkbooks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWorkbooks_BASE( xParent, xContext, VbaDocumentsBase::EXCEL_DOCUMENT )
97 //XEnumerationAccess
98 uno::Type
99 ScVbaWorkbooks::getElementType() throw (uno::RuntimeException)
101 return excel::XWorkbook::static_type(0);
103 uno::Reference< container::XEnumeration >
104 ScVbaWorkbooks::createEnumeration() throw (uno::RuntimeException)
106 // #FIXME its possible the WorkBookEnumImpl here doens't reflect
107 // the state of this object ( although it should ) would be
108 // safer to create an enumeration based on this objects state
109 // rather than one effectively based of the desktop component
110 uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
111 return new WorkBookEnumImpl( mxContext, xEnumerationAccess->createEnumeration(), Application() );
114 uno::Any
115 ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource )
117 uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW );
118 return getWorkbook( mxContext, xDoc, Application() );
122 uno::Any SAL_CALL
123 ScVbaWorkbooks::Add() throw (uno::RuntimeException)
125 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW );
127 if( xSpreadDoc.is() )
128 return getWorkbook( mxContext, xSpreadDoc, Application() );
129 return uno::Any();
132 void
133 ScVbaWorkbooks::Close() throw (uno::RuntimeException)
135 VbaDocumentsBase::Close();
138 bool
139 ScVbaWorkbooks::isTextFile( const rtl::OUString& sType )
141 // will return true if the file is
142 // a) a variant of a text file
143 // b) a csv file
144 // c) unknown
145 // returning true basically means treat this like a csv file
146 const static rtl::OUString txtType( RTL_CONSTASCII_USTRINGPARAM("writer_Text" ) );
147 const static rtl::OUString csvType( RTL_CONSTASCII_USTRINGPARAM("calc_Text_txt_csv_StarCalc" ) );
148 const static rtl::OUString encodedTxtType( RTL_CONSTASCII_USTRINGPARAM("writer_Text_encoded" ) );
149 return sType.equals( txtType ) || sType.equals( csvType ) || ( sType.getLength() == 0 ) || sType.equals( encodedTxtType );
152 bool
153 ScVbaWorkbooks::isSpreadSheetFile( const rtl::OUString& sType )
155 // include calc_QPro etc. ? ( not for the moment anyway )
156 if ( sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc_MS"))) == 0
157 || sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc8"))) == 0
158 || sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc_StarOffice"))) == 0 )
159 return true;
160 return false;
163 rtl::OUString
164 ScVbaWorkbooks::getFileFilterType( const rtl::OUString& rFileName )
166 uno::Reference< document::XTypeDetection > xTypeDetect( mxContext->getServiceManager()->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection"), mxContext), uno::UNO_QUERY_THROW );
167 uno::Sequence< beans::PropertyValue > aMediaDesc(1);
168 aMediaDesc[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("URL" ) );
169 aMediaDesc[ 0 ].Value <<= rFileName;
170 rtl::OUString sType = xTypeDetect->queryTypeByDescriptor( aMediaDesc, sal_True );
171 return sType;
174 // #TODO# #FIXME# can any of the unused params below be used?
175 uno::Any
176 ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLinks*/, const uno::Any& ReadOnly, const uno::Any& Format, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*IgnoreReadOnlyRecommended*/, const uno::Any& /*Origin*/, const uno::Any& Delimiter, const uno::Any& /*Editable*/, const uno::Any& /*Notify*/, const uno::Any& /*Converter*/, const uno::Any& /*AddToMru*/ ) throw (uno::RuntimeException)
178 // we need to detect if this is a URL, if not then assume its a file path
179 rtl::OUString aURL;
180 INetURLObject aObj;
181 aObj.SetURL( rFileName );
182 bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
183 if ( bIsURL )
184 aURL = rFileName;
185 else
186 osl::FileBase::getFileURLFromSystemPath( rFileName, aURL );
188 uno::Sequence< beans::PropertyValue > sProps(0);
189 sal_Int32 nIndex = 0;
191 rtl::OUString sType = getFileFilterType( aURL );
192 // A text file means it needs to be processed as a csv file
193 if ( isTextFile( sType ) )
195 // Values for format
196 // 1 Tabs
197 // 2 Commas
198 // 3 Spaces
199 // 4 Semicolons
200 // 5 Nothing
201 // 6 Custom character (see the Delimiter argument
202 // no format means use the current delimiter
203 sProps.realloc( 3 );
204 sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FilterOptions" ) );
205 sal_Int16 delims[] = { 0 /*default not used*/, 9/*tab*/, 44/*comma*/, 32/*space*/, 59/*semicolon*/ };
206 static rtl::OUString sRestOfFormat( RTL_CONSTASCII_USTRINGPARAM(",34,0,1" ) );
208 rtl::OUString sFormat;
209 sal_Int16 nFormat = 0; // default indicator
212 if ( Format.hasValue() )
214 Format >>= nFormat; // val of nFormat overwritten if extracted
215 // validate param
216 if ( nFormat < 1 || nFormat > 6 )
217 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal value for Format" ) ), uno::Reference< uno::XInterface >() );
220 sal_Int16 nDelim = getCurrentDelim();
222 if ( nFormat > 0 && nFormat < CUSTOM_CHAR )
224 nDelim = delims[ nFormat ];
226 else if ( nFormat > CUSTOM_CHAR )
228 // Need to check Delimiter param
229 if ( !Delimiter.hasValue() )
230 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expected value for Delimiter" ) ), uno::Reference< uno::XInterface >() );
231 rtl::OUString sStr;
232 Delimiter >>= sStr;
233 String aUniStr( sStr );
234 if ( aUniStr.Len() )
235 nDelim = aUniStr.GetChar(0);
236 else
237 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Incorrect value for Delimiter" ) ), uno::Reference< uno::XInterface >() );
240 getCurrentDelim() = nDelim; //set new current
242 sFormat = rtl::OUString::valueOf( (sal_Int32)nDelim ) + sRestOfFormat;
243 sProps[ nIndex++ ].Value <<= sFormat;
244 sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FilterName") );
245 sProps[ nIndex++ ].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Text - txt - csv (StarCalc)") );
246 // Ensure WORKAROUND_CSV_TXT_BUG_i60158 gets called in typedetection.cxx so
247 // csv is forced for deep detected 'writerxxx' types
248 sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentService") );
249 sProps[ nIndex ].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") );
251 else if ( !isSpreadSheetFile( sType ) )
252 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() );
254 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
255 uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, Application() );
256 uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
257 if ( xWBook.is() )
258 xWBook->Activate();
259 return aRet;
262 rtl::OUString&
263 ScVbaWorkbooks::getServiceImplName()
265 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbooks") );
266 return sImplName;
269 css::uno::Sequence<rtl::OUString>
270 ScVbaWorkbooks::getServiceNames()
272 static uno::Sequence< rtl::OUString > sNames;
273 if ( sNames.getLength() == 0 )
275 sNames.realloc( 1 );
276 sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbooks") );
278 return sNames;