1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "xihelper.hxx"
21 #include <svl/itemset.hxx>
22 #include <editeng/editobj.hxx>
23 #include <tools/urlobj.hxx>
24 #include "scitems.hxx"
25 #include <editeng/eeitem.hxx>
26 #include <editeng/flditem.hxx>
27 #include "document.hxx"
29 #include "rangelst.hxx"
30 #include "editutil.hxx"
32 #include "xltracer.hxx"
33 #include "xistream.hxx"
34 #include "xistyle.hxx"
36 #include "excform.hxx"
38 // Excel->Calc cell address/range conversion ==================================
42 /** Fills the passed Calc address with the passed Excel cell coordinates without checking any limits. */
43 inline void lclFillAddress( ScAddress
& rScPos
, sal_uInt16 nXclCol
, sal_uInt32 nXclRow
, SCTAB nScTab
)
45 rScPos
.SetCol( static_cast< SCCOL
>( nXclCol
) );
46 rScPos
.SetRow( static_cast< SCROW
>( nXclRow
) );
47 rScPos
.SetTab( nScTab
);
52 // ----------------------------------------------------------------------------
54 XclImpAddressConverter::XclImpAddressConverter( const XclImpRoot
& rRoot
) :
55 XclAddressConverterBase( rRoot
.GetTracer(), rRoot
.GetScMaxPos() )
59 // cell address ---------------------------------------------------------------
61 bool XclImpAddressConverter::CheckAddress( const XclAddress
& rXclPos
, bool bWarn
)
63 bool bValidCol
= rXclPos
.mnCol
<= mnMaxCol
;
64 bool bValidRow
= rXclPos
.mnRow
<= mnMaxRow
;
65 bool bValid
= bValidCol
&& bValidRow
;
66 if( !bValid
&& bWarn
)
68 mbColTrunc
|= !bValidCol
;
69 mbRowTrunc
|= !bValidRow
;
70 mrTracer
.TraceInvalidAddress( ScAddress(
71 static_cast< SCCOL
>( rXclPos
.mnCol
), static_cast< SCROW
>( rXclPos
.mnRow
), 0 ), maMaxPos
);
76 bool XclImpAddressConverter::ConvertAddress( ScAddress
& rScPos
,
77 const XclAddress
& rXclPos
, SCTAB nScTab
, bool bWarn
)
79 bool bValid
= CheckAddress( rXclPos
, bWarn
);
81 lclFillAddress( rScPos
, rXclPos
.mnCol
, rXclPos
.mnRow
, nScTab
);
85 ScAddress
XclImpAddressConverter::CreateValidAddress(
86 const XclAddress
& rXclPos
, SCTAB nScTab
, bool bWarn
)
88 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
89 if( !ConvertAddress( aScPos
, rXclPos
, nScTab
, bWarn
) )
91 aScPos
.SetCol( static_cast< SCCOL
>( ::std::min( rXclPos
.mnCol
, mnMaxCol
) ) );
92 aScPos
.SetRow( static_cast< SCROW
>( ::std::min( rXclPos
.mnRow
, mnMaxRow
) ) );
93 aScPos
.SetTab( limit_cast
< SCTAB
>( nScTab
, 0, maMaxPos
.Tab() ) );
98 // cell range -----------------------------------------------------------------
100 bool XclImpAddressConverter::ConvertRange( ScRange
& rScRange
,
101 const XclRange
& rXclRange
, SCTAB nScTab1
, SCTAB nScTab2
, bool bWarn
)
103 // check start position
104 bool bValidStart
= CheckAddress( rXclRange
.maFirst
, bWarn
);
107 lclFillAddress( rScRange
.aStart
, rXclRange
.maFirst
.mnCol
, rXclRange
.maFirst
.mnRow
, nScTab1
);
109 // check & correct end position
110 sal_uInt16 nXclCol2
= rXclRange
.maLast
.mnCol
;
111 sal_uInt32 nXclRow2
= rXclRange
.maLast
.mnRow
;
112 if( !CheckAddress( rXclRange
.maLast
, bWarn
) )
114 nXclCol2
= ::std::min( nXclCol2
, mnMaxCol
);
115 nXclRow2
= ::std::min( nXclRow2
, mnMaxRow
);
117 lclFillAddress( rScRange
.aEnd
, nXclCol2
, nXclRow2
, nScTab2
);
122 // cell range list ------------------------------------------------------------
124 void XclImpAddressConverter::ConvertRangeList( ScRangeList
& rScRanges
,
125 const XclRangeList
& rXclRanges
, SCTAB nScTab
, bool bWarn
)
127 rScRanges
.RemoveAll();
128 for( XclRangeList::const_iterator aIt
= rXclRanges
.begin(), aEnd
= rXclRanges
.end(); aIt
!= aEnd
; ++aIt
)
130 ScRange
aScRange( ScAddress::UNINITIALIZED
);
131 if( ConvertRange( aScRange
, *aIt
, nScTab
, nScTab
, bWarn
) )
132 rScRanges
.Append( aScRange
);
136 // String->EditEngine conversion ==============================================
140 EditTextObject
* lclCreateTextObject( const XclImpRoot
& rRoot
,
141 const XclImpString
& rString
, XclFontItemType eType
, sal_uInt16 nXFIndex
)
143 EditTextObject
* pTextObj
= 0;
145 const XclImpXFBuffer
& rXFBuffer
= rRoot
.GetXFBuffer();
146 const XclImpFont
* pFirstFont
= rXFBuffer
.GetFont( nXFIndex
);
147 bool bFirstEscaped
= pFirstFont
&& pFirstFont
->HasEscapement();
149 if( rString
.IsRich() || bFirstEscaped
)
151 const XclImpFontBuffer
& rFontBuffer
= rRoot
.GetFontBuffer();
152 const XclFormatRunVec
& rFormats
= rString
.GetFormats();
154 ScEditEngineDefaulter
& rEE
= (eType
== EXC_FONTITEM_NOTE
) ?
155 static_cast< ScEditEngineDefaulter
& >( rRoot
.GetDoc().GetNoteEngine() ) : rRoot
.GetEditEngine();
156 rEE
.SetText( rString
.GetText() );
158 SfxItemSet
aItemSet( rEE
.GetEmptyItemSet() );
160 rFontBuffer
.FillToItemSet( aItemSet
, eType
, rXFBuffer
.GetFontIndex( nXFIndex
) );
161 ESelection aSelection
;
163 XclFormatRun aNextRun
;
164 XclFormatRunVec::const_iterator aIt
= rFormats
.begin();
165 XclFormatRunVec::const_iterator aEnd
= rFormats
.end();
170 aNextRun
.mnChar
= 0xFFFF;
172 xub_StrLen nLen
= rString
.GetText().Len();
173 for( sal_uInt16 nChar
= 0; nChar
< nLen
; ++nChar
)
175 // reached new different formatted text portion
176 if( nChar
>= aNextRun
.mnChar
)
178 // send items to edit engine
179 rEE
.QuickSetAttribs( aItemSet
, aSelection
);
181 // start new item set
182 aItemSet
.ClearItem();
183 rFontBuffer
.FillToItemSet( aItemSet
, eType
, aNextRun
.mnFontIdx
);
185 // read new formatting information
189 aNextRun
.mnChar
= 0xFFFF;
191 // reset selection start to current position
192 aSelection
.nStartPara
= aSelection
.nEndPara
;
193 aSelection
.nStartPos
= aSelection
.nEndPos
;
196 // set end of selection to current position
197 if( rString
.GetText().GetChar( nChar
) == '\n' )
199 ++aSelection
.nEndPara
;
200 aSelection
.nEndPos
= 0;
203 ++aSelection
.nEndPos
;
206 // send items of last text portion to edit engine
207 rEE
.QuickSetAttribs( aItemSet
, aSelection
);
209 pTextObj
= rEE
.CreateTextObject();
217 EditTextObject
* XclImpStringHelper::CreateTextObject(
218 const XclImpRoot
& rRoot
, const XclImpString
& rString
)
220 return lclCreateTextObject( rRoot
, rString
, EXC_FONTITEM_EDITENG
, 0 );
223 ScBaseCell
* XclImpStringHelper::CreateCell(
224 const XclImpRoot
& rRoot
, const XclImpString
& rString
, sal_uInt16 nXFIndex
)
226 ScBaseCell
* pCell
= 0;
228 if( rString
.GetText().Len() )
230 ::std::auto_ptr
< EditTextObject
> pTextObj( lclCreateTextObject( rRoot
, rString
, EXC_FONTITEM_EDITENG
, nXFIndex
) );
231 ScDocument
& rDoc
= rRoot
.GetDoc();
234 // ScEditCell creates own copy of text object
235 pCell
= new ScEditCell( pTextObj
.get(), &rDoc
, rRoot
.GetEditEngine().GetEditTextObjectPool() );
237 pCell
= ScBaseCell::CreateTextCell( rString
.GetText(), &rDoc
);
243 // Header/footer conversion ===================================================
245 XclImpHFConverter::XclImpHFPortionInfo::XclImpHFPortionInfo() :
249 maSel
.nStartPara
= maSel
.nEndPara
= 0;
250 maSel
.nStartPos
= maSel
.nEndPos
= 0;
253 // ----------------------------------------------------------------------------
255 XclImpHFConverter::XclImpHFConverter( const XclImpRoot
& rRoot
) :
257 mrEE( rRoot
.GetHFEditEngine() ),
258 mxFontData( new XclFontData
),
259 meCurrObj( EXC_HF_CENTER
)
263 XclImpHFConverter::~XclImpHFConverter()
267 void XclImpHFConverter::ParseString( const String
& rHFString
)
269 // edit engine objects
270 mrEE
.SetText( EMPTY_STRING
);
272 maInfos
.resize( EXC_HF_PORTION_COUNT
);
273 meCurrObj
= EXC_HF_CENTER
;
275 // parser temporaries
277 String aReadFont
; // current font name
278 String aReadStyle
; // current font style
279 sal_uInt16 nReadHeight
= 0; // current font height
282 /** State of the parser. */
283 enum XclHFParserState
285 xlPSText
, /// Read text, search for functions.
286 xlPSFunc
, /// Read function (token following a '&').
287 xlPSFont
, /// Read font name ('&' is followed by '"', reads until next '"' or ',').
288 xlPSFontStyle
, /// Read font style name (font part after ',', reads until next '"').
289 xlPSHeight
/// Read font height ('&' is followed by num. digits, reads until non-digit).
292 const sal_Unicode
* pChar
= rHFString
.GetBuffer();
293 const sal_Unicode
* pNull
= pChar
+ rHFString
.Len(); // pointer to teminating null char
299 // --- read text character ---
305 case '&': // new command
309 case '\n': // line break
314 maCurrText
+= *pChar
;
319 // --- read control sequence ---
326 case '&': maCurrText
+= '&'; break; // the '&' character
328 case 'L': SetNewPortion( EXC_HF_LEFT
); break; // Left portion
329 case 'C': SetNewPortion( EXC_HF_CENTER
); break; // Center portion
330 case 'R': SetNewPortion( EXC_HF_RIGHT
); break; // Right portion
332 case 'P': InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD
) ); break; // page
333 case 'N': InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD
) ); break; // page count
334 case 'D': InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD
) ); break; // date
335 case 'T': InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD
) ); break; // time
336 case 'A': InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD
) ); break; // table name
338 case 'Z': // file path
339 InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD
) ); // convert to full name
340 if( (pNull
- pChar
>= 2) && (*(pChar
+ 1) == '&') && (*(pChar
+ 2) == 'F') )
342 // &Z&F found - ignore the &F part
346 case 'F': // file name
347 InsertField( SvxFieldItem( SvxExtFileField( EMPTY_STRING
, SVXFILETYPE_VAR
, SVXFILEFORMAT_NAME_EXT
), EE_FEATURE_FIELD
) );
350 case 'U': // underline
352 mxFontData
->mnUnderline
= (mxFontData
->mnUnderline
== EXC_FONTUNDERL_SINGLE
) ?
353 EXC_FONTUNDERL_NONE
: EXC_FONTUNDERL_SINGLE
;
355 case 'E': // double underline
357 mxFontData
->mnUnderline
= (mxFontData
->mnUnderline
== EXC_FONTUNDERL_DOUBLE
) ?
358 EXC_FONTUNDERL_NONE
: EXC_FONTUNDERL_DOUBLE
;
360 case 'S': // strikeout
362 mxFontData
->mbStrikeout
= !mxFontData
->mbStrikeout
;
364 case 'X': // superscript
366 mxFontData
->mnEscapem
= (mxFontData
->mnEscapem
== EXC_FONTESC_SUPER
) ?
367 EXC_FONTESC_NONE
: EXC_FONTESC_SUPER
;
369 case 'Y': // subsrcipt
371 mxFontData
->mnEscapem
= (mxFontData
->mnEscapem
== EXC_FONTESC_SUB
) ?
372 EXC_FONTESC_NONE
: EXC_FONTESC_SUB
;
375 case '\"': // font name
381 if( ('0' <= *pChar
) && (*pChar
<= '9') ) // font size
383 nReadHeight
= *pChar
- '0';
390 // --- read font name ---
400 eState
= xlPSFontStyle
;
408 // --- read font style ---
416 if( aReadFont
.Len() )
417 mxFontData
->maName
= aReadFont
;
418 mxFontData
->maStyle
= aReadStyle
;
422 aReadStyle
+= *pChar
;
427 // --- read font height ---
431 if( ('0' <= *pChar
) && (*pChar
<= '9') )
433 if( nReadHeight
!= 0xFFFF )
436 nReadHeight
+= (*pChar
- '0');
437 if( nReadHeight
> 1600 ) // max 1600pt = 32000twips
438 nReadHeight
= 0xFFFF;
443 if( (nReadHeight
!= 0) && (nReadHeight
!= 0xFFFF) )
446 mxFontData
->mnHeight
= nReadHeight
* 20;
459 maInfos
[ EXC_HF_LEFT
].mnHeight
+= GetMaxLineHeight( EXC_HF_LEFT
);
460 maInfos
[ EXC_HF_CENTER
].mnHeight
+= GetMaxLineHeight( EXC_HF_CENTER
);
461 maInfos
[ EXC_HF_RIGHT
].mnHeight
+= GetMaxLineHeight( EXC_HF_RIGHT
);
464 void XclImpHFConverter::FillToItemSet( SfxItemSet
& rItemSet
, sal_uInt16 nWhichId
) const
466 ScPageHFItem
aHFItem( nWhichId
);
467 if( maInfos
[ EXC_HF_LEFT
].mxObj
.get() )
468 aHFItem
.SetLeftArea( *maInfos
[ EXC_HF_LEFT
].mxObj
);
469 if( maInfos
[ EXC_HF_CENTER
].mxObj
.get() )
470 aHFItem
.SetCenterArea( *maInfos
[ EXC_HF_CENTER
].mxObj
);
471 if( maInfos
[ EXC_HF_RIGHT
].mxObj
.get() )
472 aHFItem
.SetRightArea( *maInfos
[ EXC_HF_RIGHT
].mxObj
);
473 rItemSet
.Put( aHFItem
);
476 sal_Int32
XclImpHFConverter::GetTotalHeight() const
478 return ::std::max( maInfos
[ EXC_HF_LEFT
].mnHeight
,
479 ::std::max( maInfos
[ EXC_HF_CENTER
].mnHeight
, maInfos
[ EXC_HF_RIGHT
].mnHeight
) );
482 // private --------------------------------------------------------------------
484 sal_uInt16
XclImpHFConverter::GetMaxLineHeight( XclImpHFPortion ePortion
) const
486 sal_uInt16 nMaxHt
= maInfos
[ ePortion
].mnMaxLineHt
;
487 return (nMaxHt
== 0) ? mxFontData
->mnHeight
: nMaxHt
;
490 sal_uInt16
XclImpHFConverter::GetCurrMaxLineHeight() const
492 return GetMaxLineHeight( meCurrObj
);
495 void XclImpHFConverter::UpdateMaxLineHeight( XclImpHFPortion ePortion
)
497 sal_uInt16
& rnMaxHt
= maInfos
[ ePortion
].mnMaxLineHt
;
498 rnMaxHt
= ::std::max( rnMaxHt
, mxFontData
->mnHeight
);
501 void XclImpHFConverter::UpdateCurrMaxLineHeight()
503 UpdateMaxLineHeight( meCurrObj
);
506 void XclImpHFConverter::SetAttribs()
508 ESelection
& rSel
= GetCurrSel();
509 if( (rSel
.nStartPara
!= rSel
.nEndPara
) || (rSel
.nStartPos
!= rSel
.nEndPos
) )
511 SfxItemSet
aItemSet( mrEE
.GetEmptyItemSet() );
512 XclImpFont
aFont( GetRoot(), *mxFontData
);
513 aFont
.FillToItemSet( aItemSet
, EXC_FONTITEM_HF
);
514 mrEE
.QuickSetAttribs( aItemSet
, rSel
);
515 rSel
.nStartPara
= rSel
.nEndPara
;
516 rSel
.nStartPos
= rSel
.nEndPos
;
520 void XclImpHFConverter::ResetFontData()
522 if( const XclImpFont
* pFirstFont
= GetFontBuffer().GetFont( EXC_FONT_APP
) )
523 *mxFontData
= pFirstFont
->GetFontData();
527 mxFontData
->mnHeight
= 200;
531 void XclImpHFConverter::InsertText()
533 if( maCurrText
.Len() )
535 ESelection
& rSel
= GetCurrSel();
536 mrEE
.QuickInsertText( maCurrText
, ESelection( rSel
.nEndPara
, rSel
.nEndPos
, rSel
.nEndPara
, rSel
.nEndPos
) );
537 rSel
.nEndPos
= rSel
.nEndPos
+ maCurrText
.Len();
539 UpdateCurrMaxLineHeight();
543 void XclImpHFConverter::InsertField( const SvxFieldItem
& rFieldItem
)
545 ESelection
& rSel
= GetCurrSel();
546 mrEE
.QuickInsertField( rFieldItem
, ESelection( rSel
.nEndPara
, rSel
.nEndPos
, rSel
.nEndPara
, rSel
.nEndPos
) );
548 UpdateCurrMaxLineHeight();
551 void XclImpHFConverter::InsertLineBreak()
553 ESelection
& rSel
= GetCurrSel();
554 mrEE
.QuickInsertText( rtl::OUString('\n'), ESelection( rSel
.nEndPara
, rSel
.nEndPos
, rSel
.nEndPara
, rSel
.nEndPos
) );
557 GetCurrInfo().mnHeight
+= GetCurrMaxLineHeight();
558 GetCurrInfo().mnMaxLineHt
= 0;
561 void XclImpHFConverter::CreateCurrObject()
565 GetCurrObj().reset( mrEE
.CreateTextObject() );
568 void XclImpHFConverter::SetNewPortion( XclImpHFPortion eNew
)
570 if( eNew
!= meCurrObj
)
574 if( GetCurrObj().get() )
575 mrEE
.SetText( *GetCurrObj() );
577 mrEE
.SetText( EMPTY_STRING
);
582 // URL conversion =============================================================
586 void lclAppendUrlChar( String
& rUrl
, sal_Unicode cChar
)
588 // encode special characters
591 case '#': rUrl
.AppendAscii( "%23" ); break;
592 case '%': rUrl
.AppendAscii( "%25" ); break;
593 default: rUrl
.Append( cChar
);
599 void XclImpUrlHelper::DecodeUrl(
600 String
& rUrl
, String
& rTabName
, bool& rbSameWb
,
601 const XclImpRoot
& rRoot
, const String
& rEncodedUrl
)
605 xlUrlInit
, /// Initial state, read string mode character.
606 xlUrlPath
, /// Read URL path.
607 xlUrlFileName
, /// Read file name.
608 xlUrlSheetName
, /// Read sheet name.
609 xlUrlRaw
/// Raw mode. No control characters will occur.
610 } eState
= xlUrlInit
;
612 bool bEncoded
= true;
615 sal_Unicode cCurrDrive
= 0;
616 String
aDosBase( INetURLObject( rRoot
.GetBasePath() ).getFSysPath( INetURLObject::FSYS_DOS
) );
617 if( (aDosBase
.Len() > 2) && aDosBase
.EqualsAscii( ":\\", 1, 2 ) )
618 cCurrDrive
= aDosBase
.GetChar( 0 );
620 const sal_Unicode
* pChar
= rEncodedUrl
.GetBuffer();
626 // --- first character ---
632 case EXC_URLSTART_ENCODED
:
635 case EXC_URLSTART_SELF
:
636 case EXC_URLSTART_SELFENCODED
:
638 eState
= xlUrlSheetName
;
642 eState
= xlUrlFileName
;
646 lclAppendUrlChar( rUrl
, *pChar
);
658 case EXC_URL_DOSDRIVE
:
664 rUrl
.AppendAscii( "\\\\" );
667 lclAppendUrlChar( rUrl
, *pChar
);
668 rUrl
.AppendAscii( ":\\" );
672 rUrl
.AppendAscii( "<NULL-DRIVE!>" );
675 case EXC_URL_DRIVEROOT
:
678 lclAppendUrlChar( rUrl
, cCurrDrive
);
685 else // control character in raw name -> DDE link
687 rUrl
.Append( EXC_DDE_DELIM
);
691 case EXC_URL_PARENTDIR
:
692 rUrl
.AppendAscii( "..\\" );
698 xub_StrLen nLen
= *++pChar
;
699 for( xub_StrLen nChar
= 0; (nChar
< nLen
) && *(pChar
+ 1); ++nChar
)
700 lclAppendUrlChar( rUrl
, *++pChar
);
701 // rUrl.Append( ':' );
706 eState
= xlUrlFileName
;
709 lclAppendUrlChar( rUrl
, *pChar
);
720 case ']': eState
= xlUrlSheetName
; break;
721 default: lclAppendUrlChar( rUrl
, *pChar
);
726 // --- sheet name ---
729 rTabName
.Append( *pChar
);
732 // --- raw read mode ---
735 lclAppendUrlChar( rUrl
, *pChar
);
743 void XclImpUrlHelper::DecodeUrl(
744 String
& rUrl
, bool& rbSameWb
, const XclImpRoot
& rRoot
, const String
& rEncodedUrl
)
747 DecodeUrl( rUrl
, aTabName
, rbSameWb
, rRoot
, rEncodedUrl
);
748 OSL_ENSURE( !aTabName
.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
751 void XclImpUrlHelper::DecodeUrl(
752 ::rtl::OUString
& rUrl
, bool& rbSameWb
, const XclImpRoot
& rRoot
, const ::rtl::OUString
& rEncodedUrl
)
756 DecodeUrl( aUrl
, aTabName
, rbSameWb
, rRoot
, rEncodedUrl
);
758 OSL_ENSURE( !aTabName
.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
761 bool XclImpUrlHelper::DecodeLink( String
& rApplic
, String
& rTopic
, const String rEncUrl
)
763 xub_StrLen nPos
= rEncUrl
.Search( EXC_DDE_DELIM
);
764 if( (nPos
!= STRING_NOTFOUND
) && (0 < nPos
) && (nPos
+ 1 < rEncUrl
.Len()) )
766 rApplic
= rEncUrl
.Copy( 0, nPos
);
767 rTopic
= rEncUrl
.Copy( nPos
+ 1 );
773 // Cached Values ==============================================================
775 XclImpCachedValue::XclImpCachedValue( XclImpStream
& rStrm
) :
782 case EXC_CACHEDVAL_EMPTY
:
785 case EXC_CACHEDVAL_DOUBLE
:
788 case EXC_CACHEDVAL_STRING
:
789 mxStr
.reset( new String( rStrm
.ReadUniString() ) );
791 case EXC_CACHEDVAL_BOOL
:
792 case EXC_CACHEDVAL_ERROR
:
798 const ScTokenArray
* pScTokArr
= rStrm
.GetRoot().GetOldFmlaConverter().GetBoolErr(
799 XclTools::ErrorToEnum( fVal
, mnType
== EXC_CACHEDVAL_ERROR
, mnBoolErr
) );
801 mxTokArr
.reset( pScTokArr
->Clone() );
805 OSL_FAIL( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
809 XclImpCachedValue::~XclImpCachedValue()
813 sal_uInt16
XclImpCachedValue::GetScError() const
815 return (mnType
== EXC_CACHEDVAL_ERROR
) ? XclTools::GetScErrorCode( mnBoolErr
) : 0;
818 // Matrix Cached Values ==============================================================
820 XclImpCachedMatrix::XclImpCachedMatrix( XclImpStream
& rStrm
) :
824 mnScCols
= rStrm
.ReaduInt8();
825 mnScRows
= rStrm
.ReaduInt16();
827 if( rStrm
.GetRoot().GetBiff() <= EXC_BIFF5
)
829 // in BIFF2-BIFF7: 256 columns represented by 0 columns
835 // in BIFF8: columns and rows decreaed by 1
840 for( SCSIZE nScRow
= 0; nScRow
< mnScRows
; ++nScRow
)
841 for( SCSIZE nScCol
= 0; nScCol
< mnScCols
; ++nScCol
)
842 maValueList
.push_back( new XclImpCachedValue( rStrm
) );
845 XclImpCachedMatrix::~XclImpCachedMatrix()
849 ScMatrixRef
XclImpCachedMatrix::CreateScMatrix() const
851 ScMatrixRef xScMatrix
;
852 OSL_ENSURE( mnScCols
* mnScRows
== maValueList
.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
853 if( mnScCols
&& mnScRows
&& static_cast< sal_uLong
>( mnScCols
* mnScRows
) <= maValueList
.size() )
855 xScMatrix
= new ScMatrix(mnScCols
, mnScRows
, 0.0);
856 XclImpValueList::const_iterator itValue
= maValueList
.begin();
857 for( SCSIZE nScRow
= 0; nScRow
< mnScRows
; ++nScRow
)
859 for( SCSIZE nScCol
= 0; nScCol
< mnScCols
; ++nScCol
)
861 switch( itValue
->GetType() )
863 case EXC_CACHEDVAL_EMPTY
:
864 // Excel shows 0.0 here, not an empty cell
865 xScMatrix
->PutEmpty( nScCol
, nScRow
);
867 case EXC_CACHEDVAL_DOUBLE
:
868 xScMatrix
->PutDouble( itValue
->GetValue(), nScCol
, nScRow
);
870 case EXC_CACHEDVAL_STRING
:
871 xScMatrix
->PutString( itValue
->GetString(), nScCol
, nScRow
);
873 case EXC_CACHEDVAL_BOOL
:
874 xScMatrix
->PutBoolean( itValue
->GetBool(), nScCol
, nScRow
);
876 case EXC_CACHEDVAL_ERROR
:
877 xScMatrix
->PutError( itValue
->GetScError(), nScCol
, nScRow
);
880 OSL_FAIL( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
881 xScMatrix
->PutEmpty( nScCol
, nScRow
);
890 // ============================================================================
892 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */