LibreOffice Module sc (master) 1
externallinkfragment.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
22#include <com/sun/star/sheet/XExternalSheetCache.hpp>
25#include <oox/token/namespaces.hxx>
26#include <oox/token/tokens.hxx>
27#include <osl/diagnose.h>
28#include <addressconverter.hxx>
29#include <unitconverter.hxx>
30#include <biffhelper.hxx>
31
32namespace oox::xls {
33
34using namespace ::com::sun::star::sheet;
35using namespace ::com::sun::star::uno;
36using namespace ::oox::core;
37
39 WorkbookFragmentBase& rFragment, const Reference< XExternalSheetCache >& rxSheetCache )
40 : WorkbookContextBase(rFragment)
41 , mxSheetCache(rxSheetCache)
42 , mnCurrType(XML_TOKEN_INVALID)
43{
44 OSL_ENSURE( mxSheetCache.is(), "ExternalSheetDataContext::ExternalSheetDataContext - missing sheet cache" );
45}
46
48{
49 switch( getCurrentElement() )
50 {
51 case XLS_TOKEN( sheetData ):
52 if( nElement == XLS_TOKEN( row ) ) return this;
53 break;
54 case XLS_TOKEN( row ):
55 if( nElement == XLS_TOKEN( cell ) ) { importCell( rAttribs ); return this; }
56 break;
57 case XLS_TOKEN( cell ):
58 if( nElement == XLS_TOKEN( v ) ) return this; // collect characters in onCharacters()
59 break;
60 }
61 return nullptr;
62}
63
64void ExternalSheetDataContext::onCharacters( const OUString& rChars )
65{
66 if( !isCurrentElement( XLS_TOKEN( v ) ) )
67 return;
68
69 switch( mnCurrType )
70 {
71 case XML_b:
72 case XML_n:
73 setCellValue( Any( rChars.toDouble() ) );
74 break;
75 case XML_e:
76 setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) );
77 break;
78 case XML_str:
79 setCellValue( Any( rChars ) );
80 break;
81 }
83}
84
86{
87 switch( getCurrentElement() )
88 {
90 if( nRecId == BIFF12_ID_EXTROW ) { maCurrPos.SetRow( rStrm.readInt32() ); return this; }
91 break;
93 switch( nRecId )
94 {
100 }
101 break;
102 }
103 return nullptr;
104}
105
106// private --------------------------------------------------------------------
107
109{
110 if( getAddressConverter().convertToCellAddress( maCurrPos, rAttribs.getString( XML_r, OUString() ), 0, false ) )
111 mnCurrType = rAttribs.getToken( XML_t, XML_n );
112 else
114}
115
117{
118 maCurrPos.SetCol( rStrm.readInt32() );
119 setCellValue( Any( OUString() ) );
120}
121
123{
124 maCurrPos.SetCol( rStrm.readInt32() );
125 double fValue = (rStrm.readuInt8() == 0) ? 0.0 : 1.0;
126 setCellValue( Any( fValue ) );
127}
128
130{
131 maCurrPos.SetCol( rStrm.readInt32() );
132 setCellValue( Any( rStrm.readDouble() ) );
133}
134
136{
137 maCurrPos.SetCol( rStrm.readInt32() );
139}
140
142{
143 maCurrPos.SetCol( rStrm.readInt32() );
145}
146
148{
149 if( mxSheetCache.is() && getAddressConverter().checkCellAddress( maCurrPos, false ) ) try
150 {
151 mxSheetCache->setCellValue( maCurrPos.Col(), maCurrPos.Row(), rValue );
152 }
153 catch( Exception& )
154 {
155 }
156}
157
159 const OUString& rFragmentPath, ExternalLink& rExtLink ) :
160 WorkbookFragmentBase( rHelper, rFragmentPath ),
161 mrExtLink( rExtLink ),
162 mnResultType( XML_TOKEN_INVALID )
163{
164}
165
167{
168 switch( getCurrentElement() )
169 {
170 case XML_ROOT_CONTEXT:
171 if( nElement == XLS_TOKEN( externalLink ) ) return this;
172 break;
173
174 case XLS_TOKEN( externalLink ):
175 switch( nElement )
176 {
177 case XLS_TOKEN( externalBook ): mrExtLink.importExternalBook( getRelations(), rAttribs ); return this;
178 case XLS_TOKEN( ddeLink ): mrExtLink.importDdeLink( rAttribs ); return this;
179 case XLS_TOKEN( oleLink ): mrExtLink.importOleLink( getRelations(), rAttribs ); return this;
180 }
181 break;
182
183 case XLS_TOKEN( externalBook ):
184 switch( nElement )
185 {
186 case XLS_TOKEN( sheetNames ):
187 case XLS_TOKEN( definedNames ):
188 case XLS_TOKEN( sheetDataSet ): return this;
189 }
190 break;
191
192 case XLS_TOKEN( sheetNames ):
193 if( nElement == XLS_TOKEN( sheetName ) ) mrExtLink.importSheetName( rAttribs );
194 break;
195 case XLS_TOKEN( definedNames ):
196 if( nElement == XLS_TOKEN( definedName ) ) mrExtLink.importDefinedName( rAttribs );
197 break;
198 case XLS_TOKEN( sheetDataSet ):
199 if( (nElement == XLS_TOKEN( sheetData )) && (mrExtLink.getLinkType() == ExternalLinkType::External) )
200 return createSheetDataContext( rAttribs.getInteger( XML_sheetId, -1 ) );
201 break;
202
203 case XLS_TOKEN( ddeLink ):
204 if( nElement == XLS_TOKEN( ddeItems ) ) return this;
205 break;
206 case XLS_TOKEN( ddeItems ):
207 if( nElement == XLS_TOKEN( ddeItem ) )
208 {
209 mxExtName = mrExtLink.importDdeItem( rAttribs );
210 return this;
211 }
212 break;
213 case XLS_TOKEN( ddeItem ):
214 if( nElement == XLS_TOKEN( values ) )
215 {
216 if( mxExtName ) mxExtName->importValues( rAttribs );
217 return this;
218 }
219 break;
220 case XLS_TOKEN( values ):
221 if( nElement == XLS_TOKEN( value ) )
222 {
223 mnResultType = rAttribs.getToken( XML_t, XML_n );
224 return this;
225 }
226 break;
227 case XLS_TOKEN( value ):
228 if( nElement == XLS_TOKEN( val ) ) return this; // collect value in onCharacters()
229 break;
230
231 case XLS_TOKEN( oleLink ):
232 if( nElement == XLS_TOKEN( oleItems ) ) return this;
233 break;
234 case XLS_TOKEN( oleItems ):
235 if( nElement == XLS_TOKEN( oleItem ) ) mxExtName = mrExtLink.importOleItem( rAttribs );
236 break;
237 }
238 return nullptr;
239}
240
241void ExternalLinkFragment::onCharacters( const OUString& rChars )
242{
243 if( isCurrentElement( XLS_TOKEN( val ) ) )
244 maResultValue = rChars;
245}
246
248{
249 if( !(isCurrentElement( XLS_TOKEN( value ) ) && mxExtName) )
250 return;
251
252 switch( mnResultType )
253 {
254 case XML_b:
255 mxExtName->appendResultValue( maResultValue.toDouble() );
256 break;
257 case XML_e:
258 mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( maResultValue ) ) );
259 break;
260 case XML_n:
261 mxExtName->appendResultValue( maResultValue.toDouble() );
262 break;
263 case XML_str:
264 mxExtName->appendResultValue( maResultValue );
265 break;
266 default:
268 }
269}
270
272{
273 switch( getCurrentElement() )
274 {
275 case XML_ROOT_CONTEXT:
276 if( nRecId == BIFF12_ID_EXTERNALBOOK )
277 {
278 mrExtLink.importExternalBook( getRelations(), rStrm );
279 return this;
280 }
281 break;
282
284 switch( nRecId )
285 {
288 return createSheetDataContext( rStrm.readInt32() );
289 break;
290
293 }
294 break;
295
297 switch( nRecId )
298 {
299 case BIFF12_ID_EXTERNALNAMEFLAGS: if( mxExtName ) mxExtName->importExternalNameFlags( rStrm ); break;
300 case BIFF12_ID_DDEITEMVALUES: if( mxExtName ) mxExtName->importDdeItemValues( rStrm ); return this;
301 }
302 break;
303
305 switch( nRecId )
306 {
307 case BIFF12_ID_DDEITEM_BOOL: if( mxExtName ) mxExtName->importDdeItemBool( rStrm ); break;
308 case BIFF12_ID_DDEITEM_DOUBLE: if( mxExtName ) mxExtName->importDdeItemDouble( rStrm ); break;
309 case BIFF12_ID_DDEITEM_ERROR: if( mxExtName ) mxExtName->importDdeItemError( rStrm ); break;
310 case BIFF12_ID_DDEITEM_STRING: if( mxExtName ) mxExtName->importDdeItemString( rStrm ); break;
311 }
312 break;
313 }
314 return nullptr;
315}
316
318{
319 return new ExternalSheetDataContext( *this, mrExtLink.getSheetCache( nSheetId ) );
320}
321
323{
324 static const RecordInfo spRecInfos[] =
325 {
329 { BIFF12_ID_EXTROW, -1 },
331 { -1, -1 }
332 };
333 return spRecInfos;
334}
335
336} // namespace oox::xls
337
338/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
std::optional< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
std::optional< OUString > getString(sal_Int32 nAttrToken) const
std::optional< sal_Int32 > getToken(sal_Int32 nAttrToken) const
bool isCurrentElement(sal_Int32 nElement) const
sal_Int32 getCurrentElement() const
static double calcDoubleFromError(sal_uInt8 nErrorCode)
Converts the passed BIFF error to a double containing the respective Calc error code.
Definition: biffhelper.cxx:57
static OUString readString(SequenceInputStream &rStrm, bool b32BitLen=true)
Reads a BIFF12 string with leading 16-bit or 32-bit length field.
Definition: biffhelper.cxx:79
virtual void onCharacters(const OUString &rChars) override
ExternalLinkFragment(const WorkbookHelper &rHelper, const OUString &rFragmentPath, ExternalLink &rExtLink)
virtual const ::oox::core::RecordInfo * getRecordInfos() const override
virtual void onEndElement() override
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
virtual ::oox::core::ContextHandlerRef onCreateRecordContext(sal_Int32 nRecId, SequenceInputStream &rStrm) override
::oox::core::ContextHandlerRef createSheetDataContext(sal_Int32 nSheetId)
This class implements importing the sheetData element in external sheets.
void setCellValue(const css::uno::Any &rValue)
Sets the passed cell value to the current position in the sheet cache.
void importExtCellBool(SequenceInputStream &rStrm)
Imports the EXTCELL_BOOL from the passed stream.
void importExtCellBlank(SequenceInputStream &rStrm)
Imports the EXTCELL_BLANK from the passed stream.
void importExtCellDouble(SequenceInputStream &rStrm)
Imports the EXTCELL_DOUBLE from the passed stream.
sal_Int32 mnCurrType
Position of current cell.
void importExtCellError(SequenceInputStream &rStrm)
Imports the EXTCELL_ERROR from the passed stream.
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
void importCell(const AttributeList &rAttribs)
Imports cell settings from a c element.
virtual void onCharacters(const OUString &rChars) override
css::uno::Reference< css::sheet::XExternalSheetCache > mxSheetCache
ExternalSheetDataContext(WorkbookFragmentBase &rFragment, const css::uno::Reference< css::sheet::XExternalSheetCache > &rxSheetCache)
virtual ::oox::core::ContextHandlerRef onCreateRecordContext(sal_Int32 nRecId, SequenceInputStream &rStrm) override
void importExtCellString(SequenceInputStream &rStrm)
Imports the EXTCELL_STRING from the passed stream.
ScAddress maCurrPos
The sheet cache used to store external cell values.
Context handler derived from the WorkbookHelper helper class.
Fragment handler derived from the WorkbookHelper helper class.
Helper class to provide access to global workbook data.
AddressConverter & getAddressConverter() const
Returns the converter for string to cell address/range conversion.
UnitConverter & getUnitConverter() const
Returns the measurement unit converter.
Any value
float v
@ Exception
void SvStream & rStrm
const sal_Int32 XML_ROOT_CONTEXT
const sal_Int32 BIFF12_ID_EXTCELL_BLANK
Definition: biffhelper.hxx:100
const sal_Int32 BIFF12_ID_EXTCELL_STRING
Definition: biffhelper.hxx:104
const sal_Int32 BIFF12_ID_DDEITEMVALUES
Definition: biffhelper.hxx:88
const sal_Int32 BIFF12_ID_DDEITEM_ERROR
Definition: biffhelper.hxx:91
const sal_Int32 BIFF12_ID_EXTSHEETDATA
Definition: biffhelper.hxx:114
const sal_Int32 BIFF12_ID_EXTERNALNAMEFLAGS
Definition: biffhelper.hxx:115
const sal_uInt8 BIFF_ERR_NA
Definition: biffhelper.hxx:566
const sal_Int32 BIFF12_ID_DDEITEM_BOOL
Definition: biffhelper.hxx:89
const sal_Int32 BIFF12_ID_EXTERNALBOOK
Definition: biffhelper.hxx:106
const sal_Int32 BIFF12_ID_EXTCELL_DOUBLE
Definition: biffhelper.hxx:102
@ External
Link refers to the current sheet.
const sal_Int32 BIFF12_ID_EXTERNALNAME
Definition: biffhelper.hxx:107
const sal_Int32 BIFF12_ID_EXTROW
Definition: biffhelper.hxx:113
const sal_Int32 BIFF12_ID_DDEITEM_STRING
Definition: biffhelper.hxx:92
const sal_Int32 BIFF12_ID_EXTCELL_ERROR
Definition: biffhelper.hxx:103
const sal_Int32 BIFF12_ID_DDEITEM_DOUBLE
Definition: biffhelper.hxx:90
const sal_Int32 BIFF12_ID_EXTSHEETNAMES
Definition: biffhelper.hxx:116
const sal_Int32 BIFF12_ID_EXTCELL_BOOL
Definition: biffhelper.hxx:101
XML_TOKEN_INVALID
std::vector< char * > values