1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbaworkbooks.cxx,v $
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>
62 #include <osl/file.hxx>
63 using namespace ::ooo::vba
;
64 using namespace ::com::sun::star
;
66 const sal_Int16 CUSTOM_CHAR
= 5;
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
);
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
;
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
)
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() );
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() );
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() );
133 ScVbaWorkbooks::Close() throw (uno::RuntimeException
)
135 VbaDocumentsBase::Close();
139 ScVbaWorkbooks::isTextFile( const rtl::OUString
& sType
)
141 // will return true if the file is
142 // a) a variant of a text file
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
);
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 )
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
);
174 // #TODO# #FIXME# can any of the unused params below be used?
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
181 aObj
.SetURL( rFileName
);
182 bool bIsURL
= aObj
.GetProtocol() != INET_PROT_NOT_VALID
;
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
) )
201 // 6 Custom character (see the Delimiter argument
202 // no format means use the current delimiter
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
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
>() );
233 String
aUniStr( sStr
);
235 nDelim
= aUniStr
.GetChar(0);
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
);
263 ScVbaWorkbooks::getServiceImplName()
265 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbooks") );
269 css::uno::Sequence
<rtl::OUString
>
270 ScVbaWorkbooks::getServiceNames()
272 static uno::Sequence
< rtl::OUString
> sNames
;
273 if ( sNames
.getLength() == 0 )
276 sNames
[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbooks") );