Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "xistyle.hxx"
30 : : #include <sfx2/printer.hxx>
31 : : #include <sfx2/objsh.hxx>
32 : : #include <svtools/ctrltool.hxx>
33 : : #include <editeng/editobj.hxx>
34 : : #include "scitems.hxx"
35 : : #include <editeng/fontitem.hxx>
36 : : #include <editeng/fhgtitem.hxx>
37 : : #include <editeng/wghtitem.hxx>
38 : : #include <editeng/udlnitem.hxx>
39 : : #include <editeng/postitem.hxx>
40 : : #include <editeng/crsditem.hxx>
41 : : #include <editeng/cntritem.hxx>
42 : : #include <editeng/shdditem.hxx>
43 : : #include <editeng/escpitem.hxx>
44 : : #include <svx/algitem.hxx>
45 : : #include <editeng/boxitem.hxx>
46 : : #include <editeng/bolnitem.hxx>
47 : : #include <svx/rotmodit.hxx>
48 : : #include <editeng/colritem.hxx>
49 : : #include <editeng/brshitem.hxx>
50 : : #include <editeng/frmdiritem.hxx>
51 : : #include <editeng/eeitem.hxx>
52 : : #include <editeng/flstitem.hxx>
53 : : #include <editeng/justifyitem.hxx>
54 : : #include <sal/macros.h>
55 : : #include "document.hxx"
56 : : #include "docpool.hxx"
57 : : #include "attrib.hxx"
58 : : #include "stlpool.hxx"
59 : : #include "stlsheet.hxx"
60 : : #include "cell.hxx"
61 : : #include "globstr.hrc"
62 : : #include "attarray.hxx"
63 : : #include "xltracer.hxx"
64 : : #include "xistream.hxx"
65 : : #include "xicontent.hxx"
66 : :
67 : : #include "root.hxx"
68 : : #include "colrowst.hxx"
69 : : #include "svl/poolcach.hxx"
70 : :
71 : : #include <list>
72 : :
73 : : using ::std::list;
74 : :
75 : : #include <cppuhelper/implbase1.hxx>
76 : : #include <com/sun/star/container/XIndexAccess.hpp>
77 : : #include <com/sun/star/beans/XPropertySet.hpp>
78 : : using namespace ::com::sun::star;
79 : :
80 : : typedef ::cppu::WeakImplHelper1< container::XIndexAccess > XIndexAccess_BASE;
81 : : typedef ::std::vector< ColorData > ColorDataVec;
82 : :
83 [ - + ]: 12 : class PaletteIndex : public XIndexAccess_BASE
84 : : {
85 : : public:
86 [ + - ]: 6 : PaletteIndex( const ColorDataVec& rColorDataTable ) : maColorData( rColorDataTable ) {}
87 : :
88 : : // Methods XIndexAccess
89 : 0 : virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException)
90 : : {
91 : 0 : return maColorData.size();
92 : : }
93 : :
94 : 0 : virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
95 : : {
96 : : //--Index; // apparently the palette is already 1 based
97 [ # # ]: 0 : return uno::makeAny( sal_Int32( maColorData[ Index ] ) );
98 : : }
99 : :
100 : : // Methods XElementAcess
101 : 0 : virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
102 : : {
103 : 0 : return ::getCppuType( (sal_Int32*)0 );
104 : : }
105 : 0 : virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException)
106 : : {
107 : 0 : return (maColorData.size() > 0);
108 : : }
109 : :
110 : : private:
111 : : ColorDataVec maColorData;
112 : : };
113 : :
114 : : void
115 : 6 : XclImpPalette::ExportPalette()
116 : : {
117 [ + - ]: 6 : if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
118 : : {
119 : : // copy values in color palette
120 : 6 : sal_Int16 nColors = maColorTable.size();
121 [ + - ]: 6 : ColorDataVec aColors;
122 [ + - ]: 6 : aColors.resize( nColors );
123 [ + + ]: 1707 : for( sal_uInt16 nIndex = 0; nIndex < nColors; ++nIndex )
124 [ + - ][ + - ]: 1701 : aColors[ nIndex ] = GetColorData( nIndex );
125 : :
126 [ + - ][ + - ]: 6 : uno::Reference< beans::XPropertySet > xProps( pDocShell->GetModel(), uno::UNO_QUERY );
127 [ + - ]: 6 : if ( xProps.is() )
128 : : {
129 [ + - ][ + - ]: 6 : uno::Reference< container::XIndexAccess > xIndex( new PaletteIndex( aColors ) );
[ + - ]
130 [ + - ][ + - ]: 6 : xProps->setPropertyValue( CREATE_OUSTRING("ColorPalette"), uno::makeAny( xIndex ) );
[ + - ][ + - ]
131 : 6 : }
132 : : }
133 : :
134 : 6 : }
135 : : // PALETTE record - color information =========================================
136 : :
137 : 55 : XclImpPalette::XclImpPalette( const XclImpRoot& rRoot ) :
138 : 55 : XclDefaultPalette( rRoot ), mrRoot( rRoot )
139 : : {
140 : 55 : }
141 : :
142 : 0 : void XclImpPalette::Initialize()
143 : : {
144 : 0 : maColorTable.clear();
145 : 0 : }
146 : :
147 : 3804 : ColorData XclImpPalette::GetColorData( sal_uInt16 nXclIndex ) const
148 : : {
149 [ + + ]: 3804 : if( nXclIndex >= EXC_COLOR_USEROFFSET )
150 : : {
151 : 3756 : sal_uInt32 nIx = nXclIndex - EXC_COLOR_USEROFFSET;
152 [ + + ]: 3756 : if( nIx < maColorTable.size() )
153 : 1659 : return maColorTable[ nIx ];
154 : : }
155 : 3804 : return GetDefColorData( nXclIndex );
156 : : }
157 : :
158 : 6 : void XclImpPalette::ReadPalette( XclImpStream& rStrm )
159 : : {
160 : : sal_uInt16 nCount;
161 [ + - ]: 6 : rStrm >> nCount;
162 : : OSL_ENSURE( rStrm.GetRecLeft() == static_cast< sal_Size >( 4 * nCount ),
163 : : "XclImpPalette::ReadPalette - size mismatch" );
164 : :
165 [ + - ]: 6 : maColorTable.resize( nCount );
166 : 6 : Color aColor;
167 [ + + ]: 1707 : for( sal_uInt16 nIndex = 0; nIndex < nCount; ++nIndex )
168 : : {
169 [ + - ]: 1701 : rStrm >> aColor;
170 [ + - ]: 1701 : maColorTable[ nIndex ] = aColor.GetColor();
171 : : }
172 [ + - ]: 6 : ExportPalette();
173 : 6 : }
174 : :
175 : : // FONT record - font information =============================================
176 : :
177 : 761 : XclImpFont::XclImpFont( const XclImpRoot& rRoot ) :
178 : : XclImpRoot( rRoot ),
179 : : mbHasCharSet( false ),
180 : : mbHasWstrn( true ),
181 : : mbHasAsian( false ),
182 [ + - ]: 761 : mbHasCmplx( false )
183 : : {
184 : 761 : SetAllUsedFlags( false );
185 : 761 : }
186 : :
187 : 93 : XclImpFont::XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData ) :
188 [ + - ]: 93 : XclImpRoot( rRoot )
189 : : {
190 [ + - ]: 93 : SetFontData( rFontData, false );
191 : 93 : }
192 : :
193 : 1664 : void XclImpFont::SetAllUsedFlags( bool bUsed )
194 : : {
195 : : mbFontNameUsed = mbHeightUsed = mbColorUsed = mbWeightUsed = mbEscapemUsed =
196 : 1664 : mbUnderlUsed = mbItalicUsed = mbStrikeUsed = mbOutlineUsed = mbShadowUsed = bUsed;
197 : 1664 : }
198 : :
199 : 252 : void XclImpFont::SetFontData( const XclFontData& rFontData, bool bHasCharSet )
200 : : {
201 : 252 : maData = rFontData;
202 : 252 : mbHasCharSet = bHasCharSet;
203 [ + + ]: 252 : if( maData.maStyle.Len() )
204 : : {
205 [ + - ]: 6 : if( SfxObjectShell* pDocShell = GetDocShell() )
206 : : {
207 [ + - ]: 6 : if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
208 : 6 : pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
209 : : {
210 [ + - ]: 6 : if( const FontList* pFontList = pInfoItem->GetFontList() )
211 : : {
212 [ + - ]: 6 : FontInfo aFontInfo( pFontList->Get( maData.maName, maData.maStyle ) );
213 [ + - ][ + - ]: 6 : maData.SetScWeight( aFontInfo.GetWeight() );
214 [ + - ][ + - ]: 6 : maData.SetScPosture( aFontInfo.GetItalic() );
[ + - ]
215 : : }
216 : : }
217 : : }
218 : 6 : maData.maStyle.Erase();
219 : : }
220 : 252 : GuessScriptType();
221 : 252 : SetAllUsedFlags( true );
222 : 252 : }
223 : :
224 : 49 : rtl_TextEncoding XclImpFont::GetFontEncoding() const
225 : : {
226 : : // #i63105# use text encoding from FONT record
227 : : // #i67768# BIFF2-BIFF4 FONT records do not contain character set
228 [ + - ]: 49 : rtl_TextEncoding eFontEnc = mbHasCharSet ? maData.GetFontEncoding() : GetTextEncoding();
229 [ - + ]: 49 : return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? GetTextEncoding() : eFontEnc;
230 : : }
231 : :
232 : 651 : void XclImpFont::ReadFont( XclImpStream& rStrm )
233 : : {
234 [ - - - + : 651 : switch( GetBiff() )
- ]
235 : : {
236 : : case EXC_BIFF2:
237 : 0 : ReadFontData2( rStrm );
238 : 0 : ReadFontName2( rStrm );
239 : 0 : break;
240 : : case EXC_BIFF3:
241 : : case EXC_BIFF4:
242 : 0 : ReadFontData2( rStrm );
243 : 0 : ReadFontColor( rStrm );
244 : 0 : ReadFontName2( rStrm );
245 : 0 : break;
246 : : case EXC_BIFF5:
247 : 0 : ReadFontData5( rStrm );
248 : 0 : ReadFontName2( rStrm );
249 : 0 : break;
250 : : case EXC_BIFF8:
251 : 651 : ReadFontData5( rStrm );
252 : 651 : ReadFontName8( rStrm );
253 : 651 : break;
254 : : default:
255 : : DBG_ERROR_BIFF();
256 : 651 : return;
257 : : }
258 : 651 : GuessScriptType();
259 : 651 : SetAllUsedFlags( true );
260 : : }
261 : :
262 : 0 : void XclImpFont::ReadEfont( XclImpStream& rStrm )
263 : : {
264 : 0 : ReadFontColor( rStrm );
265 : 0 : }
266 : :
267 : 0 : void XclImpFont::ReadCFFontBlock( XclImpStream& rStrm )
268 : : {
269 : : OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8 );
270 [ # # ]: 0 : if( GetBiff() != EXC_BIFF8 )
271 : 0 : return;
272 : :
273 : : sal_uInt32 nHeight, nStyle, nColor, nFontFlags1, nFontFlags2, nFontFlags3;
274 : : sal_uInt16 nWeight, nEscapem;
275 : : sal_uInt8 nUnderl;
276 : :
277 [ # # ]: 0 : rStrm.Ignore( 64 );
278 [ # # ][ # # ]: 0 : rStrm >> nHeight >> nStyle >> nWeight >> nEscapem >> nUnderl;
[ # # ][ # # ]
[ # # ]
279 [ # # ]: 0 : rStrm.Ignore( 3 );
280 [ # # ]: 0 : rStrm >> nColor;
281 [ # # ]: 0 : rStrm.Ignore( 4 );
282 [ # # ][ # # ]: 0 : rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3;
[ # # ]
283 [ # # ]: 0 : rStrm.Ignore( 18 );
284 : :
285 [ # # ]: 0 : if( (mbHeightUsed = (nHeight <= 0x7FFF)) == true )
286 : 0 : maData.mnHeight = static_cast< sal_uInt16 >( nHeight );
287 [ # # ][ # # ]: 0 : if( (mbWeightUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE ) && (nWeight < 0x7FFF)) == true )
[ # # ]
288 : 0 : maData.mnWeight = static_cast< sal_uInt16 >( nWeight );
289 [ # # ]: 0 : if( (mbItalicUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE )) == true )
290 : 0 : maData.mbItalic = ::get_flag( nStyle, EXC_CF_FONT_STYLE );
291 [ # # ][ # # ]: 0 : if( (mbUnderlUsed = !::get_flag( nFontFlags3, EXC_CF_FONT_UNDERL ) && (nUnderl <= 0x7F)) == true )
[ # # ]
292 : 0 : maData.mnUnderline = nUnderl;
293 [ # # ]: 0 : if( (mbColorUsed = (nColor <= 0x7FFF)) == true )
294 [ # # ][ # # ]: 0 : maData.maColor = GetPalette().GetColor( static_cast< sal_uInt16 >( nColor ) );
295 [ # # ]: 0 : if( (mbStrikeUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT )) == true )
296 : 0 : maData.mbStrikeout = ::get_flag( nStyle, EXC_CF_FONT_STRIKEOUT );
297 : : }
298 : :
299 : 810 : void XclImpFont::FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType, bool bSkipPoolDefs ) const
300 : : {
301 : : // true = edit engine Which-IDs (EE_CHAR_*); false = Calc Which-IDs (ATTR_*)
302 : 810 : bool bEE = eType != EXC_FONTITEM_CELL;
303 : :
304 : : // item = the item to put into the item set
305 : : // sc_which = the Calc Which-ID of the item
306 : : // ee_which = the edit engine Which-ID of the item
307 : : #define PUTITEM( item, sc_which, ee_which ) \
308 : : ScfTools::PutItem( rItemSet, item, (bEE ? (ee_which) : (sc_which)), bSkipPoolDefs )
309 : :
310 : : // Font item
311 : : // #i36997# do not set default Tahoma font from notes
312 [ - + ][ # # ]: 810 : bool bDefNoteFont = (eType == EXC_FONTITEM_NOTE) && (maData.maName.EqualsIgnoreCaseAscii( "Tahoma" ));
313 [ + - ][ + - ]: 810 : if( mbFontNameUsed && !bDefNoteFont )
314 : : {
315 [ + - ]: 810 : rtl_TextEncoding eFontEnc = maData.GetFontEncoding();
316 : 351 : rtl_TextEncoding eTempTextEnc = (bEE && (eFontEnc == GetTextEncoding())) ?
317 [ + + + + ]: 1161 : ScfTools::GetSystemTextEncoding() : eFontEnc;
[ + - ]
318 : :
319 [ + - ]: 810 : SvxFontItem aFontItem( maData.GetScFamily( GetTextEncoding() ), maData.maName, EMPTY_STRING,
320 [ + - ][ + - ]: 810 : PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
321 : : // set only for valid script types
322 [ + - ]: 810 : if( mbHasWstrn )
323 [ + + ][ + - ]: 810 : PUTITEM( aFontItem, ATTR_FONT, EE_CHAR_FONTINFO );
324 [ - + ]: 810 : if( mbHasAsian )
325 [ # # ][ # # ]: 0 : PUTITEM( aFontItem, ATTR_CJK_FONT, EE_CHAR_FONTINFO_CJK );
326 [ + + ]: 810 : if( mbHasCmplx )
327 [ - + ][ + - ]: 810 : PUTITEM( aFontItem, ATTR_CTL_FONT, EE_CHAR_FONTINFO_CTL );
[ + - ]
328 : : }
329 : :
330 : : // Font height (for all script types)
331 [ + - ]: 810 : if( mbHeightUsed )
332 : : {
333 : 810 : sal_Int32 nHeight = maData.mnHeight;
334 [ + + ][ + + ]: 810 : if( bEE && (eType != EXC_FONTITEM_HF) ) // do not convert header/footer height
335 : 258 : nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH; // 1 in == 72 pt
336 : :
337 [ + - ]: 810 : SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
338 [ + + ][ + - ]: 810 : PUTITEM( aHeightItem, ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT );
339 [ + + ][ + - ]: 810 : PUTITEM( aHeightItem, ATTR_CJK_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CJK );
340 [ + + ][ + - ]: 810 : PUTITEM( aHeightItem, ATTR_CTL_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CTL );
[ + - ]
341 : : }
342 : :
343 : : // Font color - pass AUTO_COL to item
344 [ + - ]: 810 : if( mbColorUsed )
345 [ + + ][ + - ]: 810 : PUTITEM( SvxColorItem( maData.maColor, ATTR_FONT_COLOR ), ATTR_FONT_COLOR, EE_CHAR_COLOR );
346 : :
347 : : // Font weight (for all script types)
348 [ + - ]: 810 : if( mbWeightUsed )
349 : : {
350 [ + - ][ + - ]: 810 : SvxWeightItem aWeightItem( maData.GetScWeight(), ATTR_FONT_WEIGHT );
351 [ + + ][ + - ]: 810 : PUTITEM( aWeightItem, ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT );
352 [ + + ][ + - ]: 810 : PUTITEM( aWeightItem, ATTR_CJK_FONT_WEIGHT, EE_CHAR_WEIGHT_CJK );
353 [ + + ][ + - ]: 810 : PUTITEM( aWeightItem, ATTR_CTL_FONT_WEIGHT, EE_CHAR_WEIGHT_CTL );
[ + - ]
354 : : }
355 : :
356 : : // Font underline
357 [ + - ]: 810 : if( mbUnderlUsed )
358 : : {
359 [ + - ][ + - ]: 810 : SvxUnderlineItem aUnderlItem( maData.GetScUnderline(), ATTR_FONT_UNDERLINE );
360 [ + + ][ + - ]: 810 : PUTITEM( aUnderlItem, ATTR_FONT_UNDERLINE, EE_CHAR_UNDERLINE );
[ + - ]
361 : : }
362 : :
363 : : // Font posture (for all script types)
364 [ + - ]: 810 : if( mbItalicUsed )
365 : : {
366 [ + - ][ + - ]: 810 : SvxPostureItem aPostItem( maData.GetScPosture(), ATTR_FONT_POSTURE );
367 [ + + ][ + - ]: 810 : PUTITEM( aPostItem, ATTR_FONT_POSTURE, EE_CHAR_ITALIC );
368 [ + + ][ + - ]: 810 : PUTITEM( aPostItem, ATTR_CJK_FONT_POSTURE, EE_CHAR_ITALIC_CJK );
369 [ + + ][ + - ]: 810 : PUTITEM( aPostItem, ATTR_CTL_FONT_POSTURE, EE_CHAR_ITALIC_CTL );
[ + - ]
370 : : }
371 : :
372 : : // Boolean attributes crossed out, contoured, shadowed
373 [ + - ]: 810 : if( mbStrikeUsed )
374 [ + + ][ + - ]: 810 : PUTITEM( SvxCrossedOutItem( maData.GetScStrikeout(), ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, EE_CHAR_STRIKEOUT );
375 [ + - ]: 810 : if( mbOutlineUsed )
376 [ + + ][ + - ]: 810 : PUTITEM( SvxContourItem( maData.mbOutline, ATTR_FONT_CONTOUR ), ATTR_FONT_CONTOUR, EE_CHAR_OUTLINE );
377 [ + - ]: 810 : if( mbShadowUsed )
378 [ + + ][ + - ]: 810 : PUTITEM( SvxShadowedItem( maData.mbShadow, ATTR_FONT_SHADOWED ), ATTR_FONT_SHADOWED, EE_CHAR_SHADOW );
379 : :
380 : : // Super-/subscript: only on edit engine objects
381 [ + - ][ + + ]: 810 : if( mbEscapemUsed && bEE )
382 [ + - ]: 351 : rItemSet.Put( SvxEscapementItem( maData.GetScEscapement(), EE_CHAR_ESCAPEMENT ) );
383 : :
384 : : #undef PUTITEM
385 : 810 : }
386 : :
387 : 39 : void XclImpFont::WriteFontProperties( ScfPropertySet& rPropSet,
388 : : XclFontPropSetType eType, const Color* pFontColor ) const
389 : : {
390 : 39 : GetFontPropSetHelper().WriteFontProperties(
391 : 39 : rPropSet, eType, maData, mbHasWstrn, mbHasAsian, mbHasCmplx, pFontColor );
392 : 39 : }
393 : :
394 : 0 : void XclImpFont::ReadFontData2( XclImpStream& rStrm )
395 : : {
396 : : sal_uInt16 nFlags;
397 [ # # ][ # # ]: 0 : rStrm >> maData.mnHeight >> nFlags;
398 : :
399 [ # # ]: 0 : maData.mnWeight = ::get_flagvalue( nFlags, EXC_FONTATTR_BOLD, EXC_FONTWGHT_BOLD, EXC_FONTWGHT_NORMAL );
400 [ # # ]: 0 : maData.mnUnderline = ::get_flagvalue( nFlags, EXC_FONTATTR_UNDERLINE, EXC_FONTUNDERL_SINGLE, EXC_FONTUNDERL_NONE );
401 : 0 : maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
402 : 0 : maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
403 : 0 : maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
404 : 0 : maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
405 : 0 : mbHasCharSet = false;
406 : 0 : }
407 : :
408 : 651 : void XclImpFont::ReadFontData5( XclImpStream& rStrm )
409 : : {
410 : : sal_uInt16 nFlags;
411 : :
412 [ + - ][ + - ]: 651 : rStrm >> maData.mnHeight >> nFlags;
413 [ + - ]: 651 : ReadFontColor( rStrm );
414 [ + - ][ + - ]: 651 : rStrm >> maData.mnWeight >> maData.mnEscapem >> maData.mnUnderline >> maData.mnFamily >> maData.mnCharSet;
[ + - ][ + - ]
[ + - ]
415 [ + - ]: 651 : rStrm.Ignore( 1 );
416 : :
417 : 651 : maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
418 : 651 : maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
419 : 651 : maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
420 : 651 : maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
421 : 651 : mbHasCharSet = true;
422 : 651 : }
423 : :
424 : 651 : void XclImpFont::ReadFontColor( XclImpStream& rStrm )
425 : : {
426 : 651 : maData.maColor = GetPalette().GetColor( rStrm.ReaduInt16() );
427 : 651 : }
428 : :
429 : 0 : void XclImpFont::ReadFontName2( XclImpStream& rStrm )
430 : : {
431 [ # # ]: 0 : maData.maName = rStrm.ReadByteString( false );
432 : 0 : }
433 : :
434 : 651 : void XclImpFont::ReadFontName8( XclImpStream& rStrm )
435 : : {
436 [ + - ]: 651 : maData.maName = rStrm.ReadUniString( rStrm.ReaduInt8() );
437 : 651 : }
438 : :
439 : 903 : void XclImpFont::GuessScriptType()
440 : : {
441 : 903 : mbHasWstrn = true;
442 : 903 : mbHasAsian = mbHasCmplx = false;
443 : :
444 : : // find the script types for which the font contains characters
445 [ + - ]: 903 : if( OutputDevice* pPrinter = GetPrinter() )
446 : : {
447 [ + - ]: 903 : Font aFont( maData.maName, Size( 0, 10 ) );
448 [ + - ]: 903 : FontCharMap aCharMap;
449 : :
450 [ + - ]: 903 : pPrinter->SetFont( aFont );
451 [ + - ][ + - ]: 903 : if( pPrinter->GetFontCharMap( aCharMap ) )
452 : : {
453 : : // CJK fonts
454 : : mbHasAsian =
455 [ + - ]: 903 : aCharMap.HasChar( 0x3041 ) || // 3040-309F: Hiragana
456 [ + - ]: 903 : aCharMap.HasChar( 0x30A1 ) || // 30A0-30FF: Katakana
457 [ + - ]: 903 : aCharMap.HasChar( 0x3111 ) || // 3100-312F: Bopomofo
458 [ + - ]: 903 : aCharMap.HasChar( 0x3131 ) || // 3130-318F: Hangul Compatibility Jamo
459 [ + - ]: 903 : aCharMap.HasChar( 0x3301 ) || // 3300-33FF: CJK Compatibility
460 [ + - ]: 903 : aCharMap.HasChar( 0x3401 ) || // 3400-4DBF: CJK Unified Ideographs Extension A
461 [ + - ]: 903 : aCharMap.HasChar( 0x4E01 ) || // 4E00-9FAF: CJK Unified Ideographs
462 [ + - ]: 903 : aCharMap.HasChar( 0x7E01 ) || // 4E00-9FAF: CJK unified ideographs
463 [ + - ]: 903 : aCharMap.HasChar( 0xA001 ) || // A001-A48F: Yi Syllables
464 [ + - ]: 903 : aCharMap.HasChar( 0xAC01 ) || // AC00-D7AF: Hangul Syllables
465 [ + - ]: 903 : aCharMap.HasChar( 0xCC01 ) || // AC00-D7AF: Hangul Syllables
466 [ + - ]: 903 : aCharMap.HasChar( 0xF901 ) || // F900-FAFF: CJK Compatibility Ideographs
467 [ + - ][ + - ]: 10836 : aCharMap.HasChar( 0xFF71 ); // FF00-FFEF: Halfwidth/Fullwidth Forms
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
468 : : // CTL fonts
469 : : mbHasCmplx =
470 [ + - ]: 903 : aCharMap.HasChar( 0x05D1 ) || // 0590-05FF: Hebrew
471 [ + - ]: 498 : aCharMap.HasChar( 0x0631 ) || // 0600-06FF: Arabic
472 [ + - ]: 498 : aCharMap.HasChar( 0x0721 ) || // 0700-074F: Syriac
473 [ + - ]: 498 : aCharMap.HasChar( 0x0911 ) || // 0900-0DFF: Indic scripts
474 [ + - ]: 498 : aCharMap.HasChar( 0x0E01 ) || // 0E00-0E7F: Thai
475 [ + - ]: 498 : aCharMap.HasChar( 0xFB21 ) || // FB1D-FB4F: Hebrew Presentation Forms
476 [ + - ]: 498 : aCharMap.HasChar( 0xFB51 ) || // FB50-FDFF: Arabic Presentation Forms-A
477 [ + + ][ + - ]: 3891 : aCharMap.HasChar( 0xFE71 ); // FE70-FEFF: Arabic Presentation Forms-B
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
478 : : // Western fonts
479 [ + - ][ + + ]: 903 : mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || aCharMap.HasChar( 'A' );
[ + - ][ + - ]
480 [ + - ][ + - ]: 903 : }
481 : : }
482 : 903 : }
483 : :
484 : : // ----------------------------------------------------------------------------
485 : :
486 : 55 : XclImpFontBuffer::XclImpFontBuffer( const XclImpRoot& rRoot ) :
487 : : XclImpRoot( rRoot ),
488 : : maFont4( rRoot ),
489 [ + - ][ + - ]: 55 : maCtrlFont( rRoot )
[ + - ][ + - ]
490 : : {
491 [ + - ]: 55 : Initialize();
492 : :
493 : : // default font for form controls without own font information
494 [ + - ]: 55 : XclFontData aCtrlFontData;
495 [ - + - ]: 55 : switch( GetBiff() )
496 : : {
497 : : case EXC_BIFF2:
498 : : case EXC_BIFF3:
499 : : case EXC_BIFF4:
500 : : case EXC_BIFF5:
501 [ # # ]: 0 : aCtrlFontData.maName.AssignAscii( "Helv" );
502 : 0 : aCtrlFontData.mnHeight = 160;
503 : 0 : aCtrlFontData.mnWeight = EXC_FONTWGHT_BOLD;
504 : 0 : break;
505 : : case EXC_BIFF8:
506 [ + - ]: 55 : aCtrlFontData.maName.AssignAscii( "Tahoma" );
507 : 55 : aCtrlFontData.mnHeight = 160;
508 : 55 : aCtrlFontData.mnWeight = EXC_FONTWGHT_NORMAL;
509 : 55 : break;
510 : : default:
511 : : DBG_ERROR_BIFF();
512 : : }
513 [ + - ][ + - ]: 55 : maCtrlFont.SetFontData( aCtrlFontData, false );
514 : 55 : }
515 : :
516 : 55 : void XclImpFontBuffer::Initialize()
517 : : {
518 [ + - ]: 55 : maFontList.clear();
519 : :
520 : : // application font for column width calculation, later filled with first font from font list
521 [ + - ]: 55 : XclFontData aAppFontData;
522 [ + - ]: 55 : aAppFontData.maName.AssignAscii( "Arial" );
523 : 55 : aAppFontData.mnHeight = 200;
524 : 55 : aAppFontData.mnWeight = EXC_FONTWGHT_NORMAL;
525 [ + - ][ + - ]: 55 : UpdateAppFont( aAppFontData, false );
526 : 55 : }
527 : :
528 : 3174 : const XclImpFont* XclImpFontBuffer::GetFont( sal_uInt16 nFontIndex ) const
529 : : {
530 : : /* Font with index 4 is not stored in an Excel file, but used e.g. by
531 : : BIFF5 form pushbutton objects. It is the bold default font.
532 : : This also means that entries above 4 are out by one in the list. */
533 : :
534 [ - + ]: 3174 : if (nFontIndex == 4)
535 : 0 : return &maFont4;
536 : :
537 [ + + ]: 3174 : if (nFontIndex < 4)
538 : : {
539 : : // Font ID is zero-based when it's less than 4.
540 [ + - ]: 1765 : return nFontIndex >= maFontList.size() ? NULL : &maFontList[nFontIndex];
541 : : }
542 : :
543 : : // Font ID is greater than 4. It is now 1-based.
544 [ + - ]: 3174 : return nFontIndex > maFontList.size() ? NULL : &maFontList[nFontIndex-1];
545 : : }
546 : :
547 : 651 : void XclImpFontBuffer::ReadFont( XclImpStream& rStrm )
548 : : {
549 [ + - ]: 651 : XclImpFont* pFont = new XclImpFont( GetRoot() );
550 : 651 : pFont->ReadFont( rStrm );
551 : 651 : maFontList.push_back( pFont );
552 : :
553 [ + + ]: 651 : if( maFontList.size() == 1 )
554 : : {
555 : 49 : UpdateAppFont( pFont->GetFontData(), pFont->HasCharSet() );
556 : : // #i71033# set text encoding from application font, if CODEPAGE is missing
557 : 49 : SetAppFontEncoding( pFont->GetFontEncoding() );
558 : : }
559 : 651 : }
560 : :
561 : 0 : void XclImpFontBuffer::ReadEfont( XclImpStream& rStrm )
562 : : {
563 [ # # ]: 0 : if( !maFontList.empty() )
564 : 0 : maFontList.back().ReadEfont( rStrm );
565 : 0 : }
566 : :
567 : 717 : void XclImpFontBuffer::FillToItemSet(
568 : : SfxItemSet& rItemSet, XclFontItemType eType,
569 : : sal_uInt16 nFontIdx, bool bSkipPoolDefs ) const
570 : : {
571 [ + - ]: 717 : if( const XclImpFont* pFont = GetFont( nFontIdx ) )
572 : 717 : pFont->FillToItemSet( rItemSet, eType, bSkipPoolDefs );
573 : 717 : }
574 : :
575 : 39 : void XclImpFontBuffer::WriteFontProperties( ScfPropertySet& rPropSet,
576 : : XclFontPropSetType eType, sal_uInt16 nFontIdx, const Color* pFontColor ) const
577 : : {
578 [ + - ]: 39 : if( const XclImpFont* pFont = GetFont( nFontIdx ) )
579 : 39 : pFont->WriteFontProperties( rPropSet, eType, pFontColor );
580 : 39 : }
581 : :
582 : 0 : void XclImpFontBuffer::WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const
583 : : {
584 : 0 : maCtrlFont.WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL );
585 : 0 : }
586 : :
587 : 104 : void XclImpFontBuffer::UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet )
588 : : {
589 [ + - ]: 104 : maAppFont = rFontData;
590 : : // #i3006# Calculate the width of '0' from first font and current printer.
591 [ + - ]: 104 : SetCharWidth( maAppFont );
592 : :
593 : : // font 4 is bold font 0
594 [ + - ]: 104 : XclFontData aFont4Data( maAppFont );
595 : 104 : aFont4Data.mnWeight = EXC_FONTWGHT_BOLD;
596 [ + - ][ + - ]: 104 : maFont4.SetFontData( aFont4Data, bHasCharSet );
597 : 104 : }
598 : :
599 : : // FORMAT record - number formats =============================================
600 : :
601 : 55 : XclImpNumFmtBuffer::XclImpNumFmtBuffer( const XclImpRoot& rRoot ) :
602 : : XclNumFmtBuffer( rRoot ),
603 : : XclImpRoot( rRoot ),
604 [ + - ][ + - ]: 55 : mnNextXclIdx( 0 )
605 : : {
606 : 55 : }
607 : :
608 : 0 : void XclImpNumFmtBuffer::Initialize()
609 : : {
610 : 0 : maIndexMap.clear();
611 : 0 : mnNextXclIdx = 0;
612 : 0 : InitializeImport(); // base class
613 : 0 : }
614 : :
615 : 405 : void XclImpNumFmtBuffer::ReadFormat( XclImpStream& rStrm )
616 : : {
617 [ + - ]: 405 : String aFormat;
618 [ - - - + : 405 : switch( GetBiff() )
- ]
619 : : {
620 : : case EXC_BIFF2:
621 : : case EXC_BIFF3:
622 [ # # ][ # # ]: 0 : aFormat = rStrm.ReadByteString( false );
[ # # ]
623 : 0 : break;
624 : :
625 : : case EXC_BIFF4:
626 [ # # ]: 0 : rStrm.Ignore( 2 ); // in BIFF4 the index field exists, but is undefined
627 [ # # ][ # # ]: 0 : aFormat = rStrm.ReadByteString( false );
[ # # ]
628 : 0 : break;
629 : :
630 : : case EXC_BIFF5:
631 [ # # ]: 0 : rStrm >> mnNextXclIdx;
632 [ # # ][ # # ]: 0 : aFormat = rStrm.ReadByteString( false );
[ # # ]
633 : 0 : break;
634 : :
635 : : case EXC_BIFF8:
636 [ + - ]: 405 : rStrm >> mnNextXclIdx;
637 [ + - ][ + - ]: 405 : aFormat = rStrm.ReadUniString();
[ + - ]
638 : 405 : break;
639 : :
640 : : default:
641 : : DBG_ERROR_BIFF();
642 : 405 : return;
643 : : }
644 : :
645 [ + - ]: 405 : if( mnNextXclIdx < 0xFFFF )
646 : : {
647 [ + - ]: 405 : InsertFormat( mnNextXclIdx, aFormat );
648 : 405 : ++mnNextXclIdx;
649 [ + - ][ + - ]: 405 : }
650 : : }
651 : :
652 : 52 : void XclImpNumFmtBuffer::CreateScFormats()
653 : : {
654 : : OSL_ENSURE( maIndexMap.empty(), "XclImpNumFmtBuffer::CreateScFormats - already created" );
655 : :
656 : 52 : SvNumberFormatter& rFormatter = GetFormatter();
657 [ + + ]: 4293 : for( XclNumFmtMap::const_iterator aIt = GetFormatMap().begin(), aEnd = GetFormatMap().end(); aIt != aEnd; ++aIt )
658 : : {
659 : 4241 : const XclNumFmt& rNumFmt = aIt->second;
660 : :
661 : : // insert/convert the Excel number format
662 : : xub_StrLen nCheckPos;
663 : 4241 : short nType = NUMBERFORMAT_DEFINED;
664 : : sal_uInt32 nKey;
665 [ + + ]: 4241 : if( rNumFmt.maFormat.Len() )
666 : : {
667 [ + - ]: 3057 : String aFormat( rNumFmt.maFormat );
668 : : rFormatter.PutandConvertEntry( aFormat, nCheckPos,
669 [ + - ][ + - ]: 3057 : nType, nKey, LANGUAGE_ENGLISH_US, rNumFmt.meLanguage );
670 : : }
671 : : else
672 [ + - ]: 1184 : nKey = rFormatter.GetFormatIndex( rNumFmt.meOffset, rNumFmt.meLanguage );
673 : :
674 : : // insert the resulting format key into the Excel->Calc index map
675 [ + - ]: 4241 : maIndexMap[ aIt->first ] = nKey;
676 : : }
677 : 52 : }
678 : :
679 : 157 : sal_uLong XclImpNumFmtBuffer::GetScFormat( sal_uInt16 nXclNumFmt ) const
680 : : {
681 [ + - ]: 157 : XclImpIndexMap::const_iterator aIt = maIndexMap.find( nXclNumFmt );
682 [ + - ][ + + ]: 157 : return (aIt != maIndexMap.end()) ? aIt->second : NUMBERFORMAT_ENTRY_NOT_FOUND;
[ + - ]
683 : : }
684 : :
685 : 145 : void XclImpNumFmtBuffer::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt, bool bSkipPoolDefs ) const
686 : : {
687 : 145 : sal_uLong nScNumFmt = GetScFormat( nXclNumFmt );
688 [ - + ]: 145 : if( nScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND )
689 : 0 : nScNumFmt = GetStdScNumFmt();
690 : 145 : FillScFmtToItemSet( rItemSet, nScNumFmt, bSkipPoolDefs );
691 : 145 : }
692 : :
693 : 145 : void XclImpNumFmtBuffer::FillScFmtToItemSet( SfxItemSet& rItemSet, sal_uLong nScNumFmt, bool bSkipPoolDefs ) const
694 : : {
695 : : OSL_ENSURE( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND, "XclImpNumFmtBuffer::FillScFmtToItemSet - invalid number format" );
696 [ + - ]: 145 : ScfTools::PutItem( rItemSet, SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ), bSkipPoolDefs );
697 [ + + ]: 145 : if( rItemSet.GetItemState( ATTR_VALUE_FORMAT, false ) == SFX_ITEM_SET )
698 : 102 : ScGlobal::AddLanguage( rItemSet, GetFormatter() );
699 : 145 : }
700 : :
701 : : // XF, STYLE record - Cell formatting =========================================
702 : :
703 : 0 : void XclImpCellProt::FillFromXF2( sal_uInt8 nNumFmt )
704 : : {
705 : 0 : mbLocked = ::get_flag( nNumFmt, EXC_XF2_LOCKED );
706 : 0 : mbHidden = ::get_flag( nNumFmt, EXC_XF2_HIDDEN );
707 : 0 : }
708 : :
709 : 2017 : void XclImpCellProt::FillFromXF3( sal_uInt16 nProt )
710 : : {
711 : 2017 : mbLocked = ::get_flag( nProt, EXC_XF_LOCKED );
712 : 2017 : mbHidden = ::get_flag( nProt, EXC_XF_HIDDEN );
713 : 2017 : }
714 : :
715 : 106 : void XclImpCellProt::FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
716 : : {
717 [ + - ]: 106 : ScfTools::PutItem( rItemSet, ScProtectionAttr( mbLocked, mbHidden ), bSkipPoolDefs );
718 : 106 : }
719 : :
720 : :
721 : : // ----------------------------------------------------------------------------
722 : :
723 : 0 : void XclImpCellAlign::FillFromXF2( sal_uInt8 nFlags )
724 : : {
725 : 0 : mnHorAlign = ::extract_value< sal_uInt8 >( nFlags, 0, 3 );
726 : 0 : }
727 : :
728 : 0 : void XclImpCellAlign::FillFromXF3( sal_uInt16 nAlign )
729 : : {
730 : 0 : mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
731 : 0 : mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK ); // new in BIFF3
732 : 0 : }
733 : :
734 : 0 : void XclImpCellAlign::FillFromXF4( sal_uInt16 nAlign )
735 : : {
736 : 0 : FillFromXF3( nAlign );
737 : 0 : mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 2 ); // new in BIFF4
738 : 0 : mnOrient = ::extract_value< sal_uInt8 >( nAlign, 6, 2 ); // new in BIFF4
739 : 0 : }
740 : :
741 : 0 : void XclImpCellAlign::FillFromXF5( sal_uInt16 nAlign )
742 : : {
743 : 0 : mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
744 : 0 : mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
745 : 0 : mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
746 : 0 : mnOrient = ::extract_value< sal_uInt8 >( nAlign, 8, 2 );
747 : 0 : }
748 : :
749 : 2017 : void XclImpCellAlign::FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
750 : : {
751 : 2017 : mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
752 : 2017 : mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
753 : 2017 : mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
754 : 2017 : mnRotation = ::extract_value< sal_uInt8 >( nAlign, 8, 8 ); // new in BIFF8
755 : 2017 : mnIndent = ::extract_value< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8
756 : 2017 : mbShrink = ::get_flag( nMiscAttrib, EXC_XF8_SHRINK ); // new in BIFF8
757 : 2017 : mnTextDir = ::extract_value< sal_uInt8 >( nMiscAttrib, 6, 2 ); // new in BIFF8
758 : 2017 : }
759 : :
760 : 186 : void XclImpCellAlign::FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs ) const
761 : : {
762 : : // horizontal alignment
763 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
764 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScHorJustifyMethod(), ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
765 : :
766 : : // text wrap (#i74508# always if vertical alignment is justified or distributed)
767 [ + - ][ - + ]: 186 : bool bLineBreak = mbLineBreak || (mnVerAlign == EXC_XF_VER_JUSTIFY) || (mnVerAlign == EXC_XF_VER_DISTRIB);
[ + + ]
768 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, bLineBreak ), bSkipPoolDefs );
769 : :
770 : : // vertical alignment
771 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
772 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScVerJustifyMethod(), ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
773 : :
774 : : // indent
775 : 186 : sal_uInt16 nScIndent = mnIndent * 200; // 1 Excel unit == 10 pt == 200 twips
776 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, nScIndent ), bSkipPoolDefs );
777 : :
778 : : // shrink to fit
779 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, mbShrink ), bSkipPoolDefs );
780 : :
781 : : // text orientation/rotation (BIFF2-BIFF7 sets mnOrient)
782 [ + - ]: 186 : sal_uInt8 nXclRot = (mnOrient == EXC_ORIENT_NONE) ? mnRotation : XclTools::GetXclRotFromOrient( mnOrient );
783 : 186 : bool bStacked = (nXclRot == EXC_ROT_STACKED);
784 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, bStacked ), bSkipPoolDefs );
785 : : // set an angle in the range from -90 to 90 degrees
786 : 186 : sal_Int32 nAngle = XclTools::GetScRotation( nXclRot, 0 );
787 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, nAngle ), bSkipPoolDefs );
788 : : // set "Use asian vertical layout", if cell is stacked and font contains CKJ characters
789 [ # # ][ # # ]: 186 : bool bAsianVert = bStacked && pFont && pFont->HasAsianChars();
[ - + ]
790 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_VERTICAL_ASIAN, bAsianVert ), bSkipPoolDefs );
791 : :
792 : : // CTL text direction
793 [ + - ]: 186 : ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
794 : 186 : }
795 : :
796 : : // ----------------------------------------------------------------------------
797 : :
798 : 2017 : XclImpCellBorder::XclImpCellBorder()
799 : : {
800 : 2017 : SetUsedFlags( false, false );
801 : 2017 : }
802 : :
803 : 4034 : void XclImpCellBorder::SetUsedFlags( bool bOuterUsed, bool bDiagUsed )
804 : : {
805 : 4034 : mbLeftUsed = mbRightUsed = mbTopUsed = mbBottomUsed = bOuterUsed;
806 : 4034 : mbDiagUsed = bDiagUsed;
807 : 4034 : }
808 : :
809 : 0 : void XclImpCellBorder::FillFromXF2( sal_uInt8 nFlags )
810 : : {
811 : 0 : mnLeftLine = ::get_flagvalue( nFlags, EXC_XF2_LEFTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
812 : 0 : mnRightLine = ::get_flagvalue( nFlags, EXC_XF2_RIGHTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
813 : 0 : mnTopLine = ::get_flagvalue( nFlags, EXC_XF2_TOPLINE, EXC_LINE_THIN, EXC_LINE_NONE );
814 : 0 : mnBottomLine = ::get_flagvalue( nFlags, EXC_XF2_BOTTOMLINE, EXC_LINE_THIN, EXC_LINE_NONE );
815 : 0 : mnLeftColor = mnRightColor = mnTopColor = mnBottomColor = EXC_COLOR_BIFF2_BLACK;
816 : 0 : SetUsedFlags( true, false );
817 : 0 : }
818 : :
819 : 0 : void XclImpCellBorder::FillFromXF3( sal_uInt32 nBorder )
820 : : {
821 : 0 : mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
822 : 0 : mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 8, 3 );
823 : 0 : mnBottomLine = ::extract_value< sal_uInt8 >( nBorder, 16, 3 );
824 : 0 : mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 24, 3 );
825 : 0 : mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 3, 5 );
826 : 0 : mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 11, 5 );
827 : 0 : mnBottomColor = ::extract_value< sal_uInt16 >( nBorder, 19, 5 );
828 : 0 : mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 27, 5 );
829 : 0 : SetUsedFlags( true, false );
830 : 0 : }
831 : :
832 : 0 : void XclImpCellBorder::FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea )
833 : : {
834 : 0 : mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
835 : 0 : mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 3, 3 );
836 : 0 : mnBottomLine = ::extract_value< sal_uInt8 >( nArea, 22, 3 );
837 : 0 : mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 6, 3 );
838 : 0 : mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 9, 7 );
839 : 0 : mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 16, 7 );
840 : 0 : mnBottomColor = ::extract_value< sal_uInt16 >( nArea, 25, 7 );
841 : 0 : mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 23, 7 );
842 : 0 : SetUsedFlags( true, false );
843 : 0 : }
844 : :
845 : 2017 : void XclImpCellBorder::FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
846 : : {
847 : 2017 : mnLeftLine = ::extract_value< sal_uInt8 >( nBorder1, 0, 4 );
848 : 2017 : mnRightLine = ::extract_value< sal_uInt8 >( nBorder1, 4, 4 );
849 : 2017 : mnTopLine = ::extract_value< sal_uInt8 >( nBorder1, 8, 4 );
850 : 2017 : mnBottomLine = ::extract_value< sal_uInt8 >( nBorder1, 12, 4 );
851 : 2017 : mnLeftColor = ::extract_value< sal_uInt16 >( nBorder1, 16, 7 );
852 : 2017 : mnRightColor = ::extract_value< sal_uInt16 >( nBorder1, 23, 7 );
853 : 2017 : mnTopColor = ::extract_value< sal_uInt16 >( nBorder2, 0, 7 );
854 : 2017 : mnBottomColor = ::extract_value< sal_uInt16 >( nBorder2, 7, 7 );
855 : 2017 : mbDiagTLtoBR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_TL_TO_BR );
856 : 2017 : mbDiagBLtoTR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_BL_TO_TR );
857 [ - + ][ + - ]: 2017 : if( mbDiagTLtoBR || mbDiagBLtoTR )
858 : : {
859 : 0 : mnDiagLine = ::extract_value< sal_uInt8 >( nBorder2, 21, 4 );
860 : 0 : mnDiagColor = ::extract_value< sal_uInt16 >( nBorder2, 14, 7 );
861 : : }
862 : 2017 : SetUsedFlags( true, true );
863 : 2017 : }
864 : :
865 : 0 : void XclImpCellBorder::FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags )
866 : : {
867 : 0 : mnLeftLine = ::extract_value< sal_uInt8 >( nLineStyle, 0, 4 );
868 : 0 : mnRightLine = ::extract_value< sal_uInt8 >( nLineStyle, 4, 4 );
869 : 0 : mnTopLine = ::extract_value< sal_uInt8 >( nLineStyle, 8, 4 );
870 : 0 : mnBottomLine = ::extract_value< sal_uInt8 >( nLineStyle, 12, 4 );
871 : 0 : mnLeftColor = ::extract_value< sal_uInt16 >( nLineColor, 0, 7 );
872 : 0 : mnRightColor = ::extract_value< sal_uInt16 >( nLineColor, 7, 7 );
873 : 0 : mnTopColor = ::extract_value< sal_uInt16 >( nLineColor, 16, 7 );
874 : 0 : mnBottomColor = ::extract_value< sal_uInt16 >( nLineColor, 23, 7 );
875 : 0 : mbLeftUsed = !::get_flag( nFlags, EXC_CF_BORDER_LEFT );
876 : 0 : mbRightUsed = !::get_flag( nFlags, EXC_CF_BORDER_RIGHT );
877 : 0 : mbTopUsed = !::get_flag( nFlags, EXC_CF_BORDER_TOP );
878 : 0 : mbBottomUsed = !::get_flag( nFlags, EXC_CF_BORDER_BOTTOM );
879 : 0 : mbDiagUsed = false;
880 : 0 : }
881 : :
882 : 0 : bool XclImpCellBorder::HasAnyOuterBorder() const
883 : : {
884 : : return
885 : : (mbLeftUsed && (mnLeftLine != EXC_LINE_NONE)) ||
886 : : (mbRightUsed && (mnRightLine != EXC_LINE_NONE)) ||
887 : : (mbTopUsed && (mnTopLine != EXC_LINE_NONE)) ||
888 [ # # ][ # # ]: 0 : (mbBottomUsed && (mnBottomLine != EXC_LINE_NONE));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
889 : : }
890 : :
891 : : namespace {
892 : :
893 : : /** Converts the passed line style to a ::editeng::SvxBorderLine, or returns false, if style is "no line". */
894 : 1440 : bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette& rPalette, sal_uInt8 nXclLine, sal_uInt16 nXclColor )
895 : : {
896 : : static const sal_uInt16 ppnLineParam[][ 4 ] =
897 : : {
898 : : // outer width, type
899 : : { 0, table::BorderLineStyle::SOLID }, // 0 = none
900 : : { EXC_BORDER_THIN, table::BorderLineStyle::SOLID }, // 1 = thin
901 : : { EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID }, // 2 = medium
902 : : { EXC_BORDER_THIN, table::BorderLineStyle::DASHED }, // 3 = dashed
903 : : { EXC_BORDER_THIN, table::BorderLineStyle::DOTTED }, // 4 = dotted
904 : : { EXC_BORDER_THICK, table::BorderLineStyle::SOLID }, // 5 = thick
905 : : { EXC_BORDER_THIN, table::BorderLineStyle::DOUBLE }, // 6 = double
906 : : { EXC_BORDER_HAIR, table::BorderLineStyle::SOLID }, // 7 = hair
907 : : { EXC_BORDER_MEDIUM, table::BorderLineStyle::DASHED }, // 8 = med dash
908 : : { EXC_BORDER_THIN, table::BorderLineStyle::SOLID }, // 9 = thin dashdot
909 : : { EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID }, // A = med dashdot
910 : : { EXC_BORDER_THIN, table::BorderLineStyle::SOLID }, // B = thin dashdotdot
911 : : { EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID }, // C = med dashdotdot
912 : : { EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID } // D = med slant dashdot
913 : : };
914 : :
915 [ + + ]: 1440 : if( nXclLine == EXC_LINE_NONE )
916 : 800 : return false;
917 [ - + ]: 640 : if( nXclLine >= SAL_N_ELEMENTS( ppnLineParam ) )
918 : 0 : nXclLine = EXC_LINE_THIN;
919 : :
920 : 640 : rLine.SetColor( rPalette.GetColor( nXclColor ) );
921 : 640 : rLine.SetWidth( ppnLineParam[ nXclLine ][ 0 ] );
922 : : rLine.SetBorderLineStyle( static_cast< ::editeng::SvxBorderStyle>(
923 : 640 : ppnLineParam[ nXclLine ][ 1 ]) );
924 : 1440 : return true;
925 : : }
926 : :
927 : : } // namespace
928 : :
929 : 288 : void XclImpCellBorder::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
930 : : {
931 [ - + ][ # # ]: 288 : if( mbLeftUsed || mbRightUsed || mbTopUsed || mbBottomUsed )
[ # # ][ # # ]
932 : : {
933 [ + - ]: 288 : SvxBoxItem aBoxItem( ATTR_BORDER );
934 [ + - ]: 288 : ::editeng::SvxBorderLine aLine;
935 [ + - ][ + - ]: 288 : if( mbLeftUsed && lclConvertBorderLine( aLine, rPalette, mnLeftLine, mnLeftColor ) )
[ + + ][ + + ]
936 [ + - ]: 151 : aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
937 [ + - ][ + - ]: 288 : if( mbRightUsed && lclConvertBorderLine( aLine, rPalette, mnRightLine, mnRightColor ) )
[ + + ][ + + ]
938 [ + - ]: 151 : aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
939 [ + - ][ + - ]: 288 : if( mbTopUsed && lclConvertBorderLine( aLine, rPalette, mnTopLine, mnTopColor ) )
[ + + ][ + + ]
940 [ + - ]: 165 : aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
941 [ + - ][ + - ]: 288 : if( mbBottomUsed && lclConvertBorderLine( aLine, rPalette, mnBottomLine, mnBottomColor ) )
[ + + ][ + + ]
942 [ + - ]: 173 : aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
943 [ + - ][ + - ]: 288 : ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
944 : : }
945 [ + - ]: 288 : if( mbDiagUsed )
946 : : {
947 [ + - ]: 288 : SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
948 [ + - ]: 288 : SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
949 [ + - ]: 288 : ::editeng::SvxBorderLine aLine;
950 [ + - ][ - + ]: 288 : if( lclConvertBorderLine( aLine, rPalette, mnDiagLine, mnDiagColor ) )
951 : : {
952 [ # # ]: 0 : if( mbDiagTLtoBR )
953 [ # # ]: 0 : aTLBRItem.SetLine( &aLine );
954 [ # # ]: 0 : if( mbDiagBLtoTR )
955 [ # # ]: 0 : aBLTRItem.SetLine( &aLine );
956 : : }
957 [ + - ]: 288 : ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
958 [ + - ][ + - ]: 288 : ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
[ + - ]
959 : : }
960 : 288 : }
961 : :
962 : : // ----------------------------------------------------------------------------
963 : :
964 : 2017 : XclImpCellArea::XclImpCellArea()
965 : : {
966 : 2017 : SetUsedFlags( false );
967 : 2017 : }
968 : :
969 : 4034 : void XclImpCellArea::SetUsedFlags( bool bUsed )
970 : : {
971 : 4034 : mbForeUsed = mbBackUsed = mbPattUsed = bUsed;
972 : 4034 : }
973 : :
974 : 0 : void XclImpCellArea::FillFromXF2( sal_uInt8 nFlags )
975 : : {
976 : 0 : mnPattern = ::get_flagvalue( nFlags, EXC_XF2_BACKGROUND, EXC_PATT_12_5_PERC, EXC_PATT_NONE );
977 : 0 : mnForeColor = EXC_COLOR_BIFF2_BLACK;
978 : 0 : mnBackColor = EXC_COLOR_BIFF2_WHITE;
979 : 0 : SetUsedFlags( true );
980 : 0 : }
981 : :
982 : 0 : void XclImpCellArea::FillFromXF3( sal_uInt16 nArea )
983 : : {
984 : 0 : mnPattern = ::extract_value< sal_uInt8 >( nArea, 0, 6 );
985 : 0 : mnForeColor = ::extract_value< sal_uInt16 >( nArea, 6, 5 );
986 : 0 : mnBackColor = ::extract_value< sal_uInt16 >( nArea, 11, 5 );
987 : 0 : SetUsedFlags( true );
988 : 0 : }
989 : :
990 : 0 : void XclImpCellArea::FillFromXF5( sal_uInt32 nArea )
991 : : {
992 : 0 : mnPattern = ::extract_value< sal_uInt8 >( nArea, 16, 6 );
993 : 0 : mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
994 : 0 : mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
995 : 0 : SetUsedFlags( true );
996 : 0 : }
997 : :
998 : 2017 : void XclImpCellArea::FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea )
999 : : {
1000 : 2017 : mnPattern = ::extract_value< sal_uInt8 >( nBorder2, 26, 6 );
1001 : 2017 : mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
1002 : 2017 : mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
1003 : 2017 : SetUsedFlags( true );
1004 : 2017 : }
1005 : :
1006 : 0 : void XclImpCellArea::FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags )
1007 : : {
1008 : 0 : mnForeColor = ::extract_value< sal_uInt16 >( nColor, 0, 7 );
1009 : 0 : mnBackColor = ::extract_value< sal_uInt16 >( nColor, 7, 7 );
1010 : 0 : mnPattern = ::extract_value< sal_uInt8 >( nPattern, 10, 6 );
1011 : 0 : mbForeUsed = !::get_flag( nFlags, EXC_CF_AREA_FGCOLOR );
1012 : 0 : mbBackUsed = !::get_flag( nFlags, EXC_CF_AREA_BGCOLOR );
1013 : 0 : mbPattUsed = !::get_flag( nFlags, EXC_CF_AREA_PATTERN );
1014 : :
1015 [ # # ][ # # ]: 0 : if( mbBackUsed && (!mbPattUsed || (mnPattern == EXC_PATT_SOLID)) )
[ # # ]
1016 : : {
1017 : 0 : mnForeColor = mnBackColor;
1018 : 0 : mnPattern = EXC_PATT_SOLID;
1019 : 0 : mbForeUsed = mbPattUsed = true;
1020 : : }
1021 [ # # ][ # # ]: 0 : else if( !mbBackUsed && mbPattUsed && (mnPattern == EXC_PATT_SOLID) )
[ # # ]
1022 : : {
1023 : 0 : mbPattUsed = false;
1024 : : }
1025 : 0 : }
1026 : :
1027 : 332 : void XclImpCellArea::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
1028 : : {
1029 [ + - ]: 332 : if( mbPattUsed ) // colors may be both unused in cond. formats
1030 : : {
1031 [ + - ]: 332 : SvxBrushItem aBrushItem( ATTR_BACKGROUND );
1032 : :
1033 : : // do not use IsTransparent() - old Calc filter writes tranparency with different color indexes
1034 [ + + ]: 332 : if( mnPattern == EXC_PATT_NONE )
1035 : : {
1036 : 55 : aBrushItem.SetColor( Color( COL_TRANSPARENT ) );
1037 : : }
1038 : : else
1039 : : {
1040 [ + - ][ + - ]: 277 : Color aFore( rPalette.GetColor( mbForeUsed ? mnForeColor : EXC_COLOR_WINDOWTEXT ) );
1041 [ + - ][ + - ]: 277 : Color aBack( rPalette.GetColor( mbBackUsed ? mnBackColor : EXC_COLOR_WINDOWBACK ) );
1042 [ + - ]: 277 : aBrushItem.SetColor( XclTools::GetPatternColor( aFore, aBack, mnPattern ) );
1043 : : }
1044 : :
1045 [ + - ][ + - ]: 332 : ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
1046 : : }
1047 : 332 : }
1048 : :
1049 : :
1050 : : // ----------------------------------------------------------------------------
1051 : :
1052 : 2017 : XclImpXF::XclImpXF( const XclImpRoot& rRoot ) :
1053 : : XclXFBase( true ), // default is cell XF
1054 : : XclImpRoot( rRoot ),
1055 : : mpStyleSheet( 0 ),
1056 : : mnXclNumFmt( 0 ),
1057 [ + - ][ + - ]: 2017 : mnXclFont( 0 )
[ + - ][ + - ]
[ + - ]
1058 : : {
1059 : 2017 : }
1060 : :
1061 [ + - ][ + - ]: 2017 : XclImpXF::~XclImpXF()
1062 : : {
1063 [ - + ]: 4034 : }
1064 : :
1065 : 0 : void XclImpXF::ReadXF2( XclImpStream& rStrm )
1066 : : {
1067 : : sal_uInt8 nReadFont, nReadNumFmt, nFlags;
1068 [ # # ]: 0 : rStrm >> nReadFont;
1069 [ # # ]: 0 : rStrm.Ignore( 1 );
1070 [ # # ][ # # ]: 0 : rStrm >> nReadNumFmt >> nFlags;
1071 : :
1072 : : // XF type always cell, no parent, used flags always true
1073 [ # # ]: 0 : SetAllUsedFlags( true );
1074 : :
1075 : : // attributes
1076 [ # # ]: 0 : maProtection.FillFromXF2( nReadNumFmt );
1077 : 0 : mnXclFont = nReadFont;
1078 : 0 : mnXclNumFmt = nReadNumFmt & EXC_XF2_VALFMT_MASK;
1079 [ # # ]: 0 : maAlignment.FillFromXF2( nFlags );
1080 [ # # ]: 0 : maBorder.FillFromXF2( nFlags );
1081 [ # # ]: 0 : maArea.FillFromXF2( nFlags );
1082 : 0 : }
1083 : :
1084 : 0 : void XclImpXF::ReadXF3( XclImpStream& rStrm )
1085 : : {
1086 : : sal_uInt32 nBorder;
1087 : : sal_uInt16 nTypeProt, nAlign, nArea;
1088 : : sal_uInt8 nReadFont, nReadNumFmt;
1089 [ # # ][ # # ]: 0 : rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
[ # # ][ # # ]
[ # # ][ # # ]
1090 : :
1091 : : // XF type/parent, attribute used flags
1092 : 0 : mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE ); // new in BIFF3
1093 : 0 : mnParent = ::extract_value< sal_uInt16 >( nAlign, 4, 12 ); // new in BIFF3
1094 [ # # ]: 0 : SetUsedFlags( ::extract_value< sal_uInt8 >( nTypeProt, 10, 6 ) );
1095 : :
1096 : : // attributes
1097 [ # # ]: 0 : maProtection.FillFromXF3( nTypeProt );
1098 : 0 : mnXclFont = nReadFont;
1099 : 0 : mnXclNumFmt = nReadNumFmt;
1100 [ # # ]: 0 : maAlignment.FillFromXF3( nAlign );
1101 [ # # ]: 0 : maBorder.FillFromXF3( nBorder );
1102 [ # # ]: 0 : maArea.FillFromXF3( nArea ); // new in BIFF3
1103 : 0 : }
1104 : :
1105 : 0 : void XclImpXF::ReadXF4( XclImpStream& rStrm )
1106 : : {
1107 : : sal_uInt32 nBorder;
1108 : : sal_uInt16 nTypeProt, nAlign, nArea;
1109 : : sal_uInt8 nReadFont, nReadNumFmt;
1110 [ # # ][ # # ]: 0 : rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
[ # # ][ # # ]
[ # # ][ # # ]
1111 : :
1112 : : // XF type/parent, attribute used flags
1113 : 0 : mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
1114 : 0 : mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
1115 [ # # ]: 0 : SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
1116 : :
1117 : : // attributes
1118 [ # # ]: 0 : maProtection.FillFromXF3( nTypeProt );
1119 : 0 : mnXclFont = nReadFont;
1120 : 0 : mnXclNumFmt = nReadNumFmt;
1121 [ # # ]: 0 : maAlignment.FillFromXF4( nAlign );
1122 [ # # ]: 0 : maBorder.FillFromXF3( nBorder );
1123 [ # # ]: 0 : maArea.FillFromXF3( nArea );
1124 : 0 : }
1125 : :
1126 : 0 : void XclImpXF::ReadXF5( XclImpStream& rStrm )
1127 : : {
1128 : : sal_uInt32 nArea, nBorder;
1129 : : sal_uInt16 nTypeProt, nAlign;
1130 [ # # ][ # # ]: 0 : rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
[ # # ][ # # ]
[ # # ][ # # ]
1131 : :
1132 : : // XF type/parent, attribute used flags
1133 : 0 : mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
1134 : 0 : mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
1135 [ # # ]: 0 : SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
1136 : :
1137 : : // attributes
1138 [ # # ]: 0 : maProtection.FillFromXF3( nTypeProt );
1139 [ # # ]: 0 : maAlignment.FillFromXF5( nAlign );
1140 [ # # ]: 0 : maBorder.FillFromXF5( nBorder, nArea );
1141 [ # # ]: 0 : maArea.FillFromXF5( nArea );
1142 : 0 : }
1143 : :
1144 : 2017 : void XclImpXF::ReadXF8( XclImpStream& rStrm )
1145 : : {
1146 : : sal_uInt32 nBorder1, nBorder2;
1147 : : sal_uInt16 nTypeProt, nAlign, nMiscAttrib, nArea;
1148 [ + - ][ + - ]: 2017 : rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
1149 : :
1150 : : // XF type/parent, attribute used flags
1151 : 2017 : mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
1152 : 2017 : mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
1153 [ + - ]: 2017 : SetUsedFlags( ::extract_value< sal_uInt8 >( nMiscAttrib, 10, 6 ) );
1154 : :
1155 : : // attributes
1156 [ + - ]: 2017 : maProtection.FillFromXF3( nTypeProt );
1157 [ + - ]: 2017 : maAlignment.FillFromXF8( nAlign, nMiscAttrib );
1158 [ + - ]: 2017 : maBorder.FillFromXF8( nBorder1, nBorder2 );
1159 [ + - ]: 2017 : maArea.FillFromXF8( nBorder2, nArea );
1160 : 2017 : }
1161 : :
1162 : 2017 : void XclImpXF::ReadXF( XclImpStream& rStrm )
1163 : : {
1164 [ - - - - : 2017 : switch( GetBiff() )
+ - ]
1165 : : {
1166 : 0 : case EXC_BIFF2: ReadXF2( rStrm ); break;
1167 : 0 : case EXC_BIFF3: ReadXF3( rStrm ); break;
1168 : 0 : case EXC_BIFF4: ReadXF4( rStrm ); break;
1169 : 0 : case EXC_BIFF5: ReadXF5( rStrm ); break;
1170 : 2017 : case EXC_BIFF8: ReadXF8( rStrm ); break;
1171 : : default: DBG_ERROR_BIFF();
1172 : : }
1173 : 2017 : }
1174 : :
1175 : 27597 : const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs )
1176 : : {
1177 [ + + ]: 27597 : if( mpPattern.get() )
1178 : 26913 : return *mpPattern;
1179 : :
1180 : : // create new pattern attribute set
1181 [ + - ][ + - ]: 684 : mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) );
[ + - ]
1182 : 684 : SfxItemSet& rItemSet = mpPattern->GetItemSet();
1183 [ + - ][ + - ]: 684 : XclImpXF* pParentXF = IsCellXF() ? GetXFBuffer().GetXF( mnParent ) : 0;
[ + + ]
1184 : :
1185 : : // parent cell style
1186 [ + + ][ + - ]: 684 : if( IsCellXF() && !mpStyleSheet )
[ + + ]
1187 : : {
1188 [ + - ][ + - ]: 403 : mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent );
1189 : :
1190 : : /* Enables mb***Used flags, if the formatting attributes differ from
1191 : : the passed XF record. In cell XFs Excel uses the cell attributes,
1192 : : if they differ from the parent style XF.
1193 : : ...or if the respective flag is not set in parent style XF. */
1194 [ + - ]: 403 : if( pParentXF )
1195 : : {
1196 [ + + ]: 403 : if( !mbProtUsed )
1197 [ + - ][ + - ]: 343 : mbProtUsed = !pParentXF->mbProtUsed || !(maProtection == pParentXF->maProtection);
[ - + ]
1198 [ + + ]: 403 : if( !mbFontUsed )
1199 [ + - ][ - + ]: 220 : mbFontUsed = !pParentXF->mbFontUsed || (mnXclFont != pParentXF->mnXclFont);
1200 [ + + ]: 403 : if( !mbFmtUsed )
1201 [ + + ][ - + ]: 334 : mbFmtUsed = !pParentXF->mbFmtUsed || (mnXclNumFmt != pParentXF->mnXclNumFmt);
1202 [ + + ]: 403 : if( !mbAlignUsed )
1203 [ + - ][ + - ]: 263 : mbAlignUsed = !pParentXF->mbAlignUsed || !(maAlignment == pParentXF->maAlignment);
[ - + ]
1204 [ + + ]: 403 : if( !mbBorderUsed )
1205 [ + + ][ + - ]: 214 : mbBorderUsed = !pParentXF->mbBorderUsed || !(maBorder == pParentXF->maBorder);
[ - + ]
1206 [ + + ]: 403 : if( !mbAreaUsed )
1207 [ + + ][ + - ]: 283 : mbAreaUsed = !pParentXF->mbAreaUsed || !(maArea == pParentXF->maArea);
[ + + ]
1208 : : }
1209 : : }
1210 : :
1211 : : // cell protection
1212 [ + + ]: 684 : if( mbProtUsed )
1213 [ + - ]: 106 : maProtection.FillToItemSet( rItemSet, bSkipPoolDefs );
1214 : :
1215 : : // font
1216 [ + + ]: 684 : if( mbFontUsed )
1217 [ + - ][ + - ]: 459 : GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs );
1218 : :
1219 : : // value format
1220 [ + + ]: 684 : if( mbFmtUsed )
1221 : : {
1222 [ + - ][ + - ]: 145 : GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs );
1223 : : // Trace occurrences of Windows date formats
1224 [ + - ][ + - ]: 145 : GetTracer().TraceDates( mnXclNumFmt );
1225 : : }
1226 : :
1227 : : // alignment
1228 [ + + ]: 684 : if( mbAlignUsed )
1229 [ + - ][ + - ]: 186 : maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs );
[ + - ]
1230 : :
1231 : : // border
1232 [ + + ]: 684 : if( mbBorderUsed )
1233 : : {
1234 [ + - ][ + - ]: 288 : maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
1235 [ + - ]: 288 : GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR ||
1236 : : maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR ||
1237 [ + - ][ + - ]: 576 : maBorder.mnBottomLine > EXC_LINE_HAIR );
[ + - ][ - + ]
[ + - ]
1238 : : }
1239 : :
1240 : : // area
1241 [ + + ]: 684 : if( mbAreaUsed )
1242 : : {
1243 [ + - ][ + - ]: 332 : maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
1244 [ + - ]: 332 : GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE &&
1245 [ + + ][ - + ]: 664 : maArea.mnPattern != EXC_PATT_SOLID);
[ + - ]
1246 : : }
1247 : :
1248 : : /* #i38709# Decide which rotation reference mode to use. If any outer
1249 : : border line of the cell is set (either explicitly or via cell style),
1250 : : and the cell contents are rotated, set rotation reference to bottom of
1251 : : cell. This causes the borders to be painted rotated with the text. */
1252 [ + + ][ + + ]: 684 : if( mbAlignUsed || mbBorderUsed )
1253 : : {
1254 : 353 : SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
1255 [ + + ][ + + ]: 353 : const XclImpCellAlign* pAlign = mbAlignUsed ? &maAlignment : (pParentXF ? &pParentXF->maAlignment : 0);
1256 [ + + ][ + - ]: 353 : const XclImpCellBorder* pBorder = mbBorderUsed ? &maBorder : (pParentXF ? &pParentXF->maBorder : 0);
1257 [ + + ][ + - ]: 353 : if( pAlign && pBorder && (0 < pAlign->mnRotation) && (pAlign->mnRotation <= 180) && pBorder->HasAnyOuterBorder() )
[ - + ][ # # ]
[ # # ][ - + ]
1258 : 0 : eRotateMode = SVX_ROTATE_MODE_BOTTOM;
1259 [ + - ][ + - ]: 353 : ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
[ + - ]
1260 : : }
1261 : :
1262 : : // Excel's cell margins are different from Calc's default margins.
1263 [ + - ]: 684 : SvxMarginItem aItem(40, 40, 40, 40, ATTR_MARGIN);
1264 [ + - ]: 684 : ScfTools::PutItem(rItemSet, aItem, bSkipPoolDefs);
1265 : :
1266 [ + - ]: 27597 : return *mpPattern;
1267 : : }
1268 : :
1269 : 27316 : void XclImpXF::ApplyPatternToAttrList(
1270 : : list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, sal_uInt32 nForceScNumFmt)
1271 : : {
1272 : : // force creation of cell style and hard formatting, do it here to have mpStyleSheet
1273 : 27316 : CreatePattern();
1274 : 27316 : ScPatternAttr& rPat = *mpPattern;
1275 : :
1276 : : // insert into document
1277 : 27316 : ScDocument& rDoc = GetDoc();
1278 : :
1279 [ + - ]: 27316 : if (IsCellXF())
1280 : : {
1281 [ + - ]: 27316 : if (mpStyleSheet)
1282 : : {
1283 : : // Apply style sheet. Don't clear the direct formats.
1284 : 27316 : rPat.SetStyleSheet(mpStyleSheet, false);
1285 : : }
1286 : : else
1287 : : {
1288 : : // When the cell format is not associated with any style, use the
1289 : : // 'Default' style. Some buggy XLS docs generated by apps other
1290 : : // than Excel (such as 1C) may not have any built-in styles at
1291 : : // all.
1292 : 0 : ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
1293 [ # # ]: 0 : if (pStylePool)
1294 : : {
1295 : : ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
1296 : : pStylePool->Find(
1297 : 0 : ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA));
1298 : :
1299 [ # # ]: 0 : if (pStyleSheet)
1300 : 0 : rPat.SetStyleSheet(pStyleSheet, false);
1301 : : }
1302 : :
1303 : : }
1304 : : }
1305 : :
1306 [ - + ]: 27316 : if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
1307 : : {
1308 [ # # ][ # # ]: 0 : ScPatternAttr aNumPat(rDoc.GetPool());
1309 [ # # ][ # # ]: 0 : GetNumFmtBuffer().FillScFmtToItemSet(aNumPat.GetItemSet(), nForceScNumFmt);
1310 [ # # ][ # # ]: 0 : rPat.GetItemSet().Put(aNumPat.GetItemSet());
1311 : : }
1312 : :
1313 : : // Make sure we skip unnamed styles.
1314 [ + - ]: 27316 : if (rPat.GetStyleName())
1315 : : {
1316 : : // Check for a gap between the last entry and this one.
1317 : 27316 : bool bHasGap = false;
1318 [ + + ][ + + ]: 27316 : if (rAttrs.empty() && nRow1 > 0)
[ + + ]
1319 : : // First attribute range doesn't start at row 0.
1320 : 181 : bHasGap = true;
1321 : :
1322 [ + + ][ + - ]: 27316 : if (!rAttrs.empty() && rAttrs.back().nRow + 1 < nRow1)
[ + + ][ + + ]
1323 : 180 : bHasGap = true;
1324 : :
1325 [ + + ]: 27316 : if (bHasGap)
1326 : : {
1327 : : // Fill this gap with the default pattern.
1328 : : ScAttrEntry aEntry;
1329 : 361 : aEntry.nRow = nRow1 - 1;
1330 [ + - ]: 361 : aEntry.pPattern = rDoc.GetDefPattern();
1331 [ + - ]: 361 : rAttrs.push_back(aEntry);
1332 : : }
1333 : :
1334 : : ScAttrEntry aEntry;
1335 : 27316 : aEntry.nRow = nRow2;
1336 [ + - ][ + - ]: 27316 : aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat));
1337 [ + - ]: 27316 : rAttrs.push_back(aEntry);
1338 : : }
1339 : 27316 : }
1340 : :
1341 : 2017 : void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags )
1342 : : {
1343 : : /* Notes about finding the mb***Used flags:
1344 : : - In cell XFs a *set* bit means a used attribute.
1345 : : - In style XFs a *cleared* bit means a used attribute.
1346 : : The mb***Used members always store true, if the attribute is used.
1347 : : The "mbCellXF == ::get_flag(...)" construct evaluates to true in
1348 : : both mentioned cases: cell XF and set bit; or style XF and cleared bit.
1349 : : */
1350 : 2017 : mbProtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_PROT ));
1351 : 2017 : mbFontUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_FONT ));
1352 : 2017 : mbFmtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_VALFMT ));
1353 : 2017 : mbAlignUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_ALIGN ));
1354 : 2017 : mbBorderUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_BORDER ));
1355 : 2017 : mbAreaUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_AREA ));
1356 : 2017 : }
1357 : :
1358 : : // ----------------------------------------------------------------------------
1359 : :
1360 : 908 : XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) :
1361 : : XclImpRoot( rRoot ),
1362 : : mnXfId( EXC_XF_NOTFOUND ),
1363 : : mnBuiltinId( EXC_STYLE_USERDEF ),
1364 : : mnLevel( EXC_STYLE_NOLEVEL ),
1365 : : mbBuiltin( false ),
1366 : : mbCustom( false ),
1367 : : mbHidden( false ),
1368 [ + - ][ + - ]: 908 : mpStyleSheet( 0 )
1369 : : {
1370 : 908 : }
1371 : :
1372 : 908 : void XclImpStyle::ReadStyle( XclImpStream& rStrm )
1373 : : {
1374 : : OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF3 );
1375 : :
1376 : : sal_uInt16 nXFIndex;
1377 [ + - ]: 908 : rStrm >> nXFIndex;
1378 : 908 : mnXfId = nXFIndex & EXC_STYLE_XFMASK;
1379 : 908 : mbBuiltin = ::get_flag( nXFIndex, EXC_STYLE_BUILTIN );
1380 : :
1381 [ + + ]: 908 : if( mbBuiltin )
1382 : : {
1383 [ + - ][ + - ]: 301 : rStrm >> mnBuiltinId >> mnLevel;
1384 : : }
1385 : : else
1386 : : {
1387 [ - + ][ # # ]: 607 : maName = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
[ + - ][ + - ]
[ + - ]
1388 : : // #i103281# check if this is a new built-in style introduced in XL2007
1389 [ + - ][ + - ]: 607 : if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() )
[ + + ][ + - ]
[ + - ][ + + ]
1390 : : {
1391 : : sal_uInt8 nExtFlags;
1392 [ + - ]: 375 : rStrm.Ignore( 12 );
1393 [ + - ]: 375 : rStrm >> nExtFlags;
1394 : 375 : mbBuiltin = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN );
1395 : 375 : mbCustom = ::get_flag( nExtFlags, EXC_STYLEEXT_CUSTOM );
1396 : 375 : mbHidden = ::get_flag( nExtFlags, EXC_STYLEEXT_HIDDEN );
1397 [ + + ]: 375 : if( mbBuiltin )
1398 : : {
1399 [ + - ]: 369 : rStrm.Ignore( 1 ); // category
1400 [ + - ][ + - ]: 375 : rStrm >> mnBuiltinId >> mnLevel;
1401 : : }
1402 : : }
1403 : : }
1404 : 908 : }
1405 : :
1406 : 641 : ScStyleSheet* XclImpStyle::CreateStyleSheet()
1407 : : {
1408 : : // #i1624# #i1768# ignore unnamed user styles
1409 [ + + ][ + - ]: 641 : if( !mpStyleSheet && (maFinalName.Len() > 0) )
[ + + ]
1410 : : {
1411 : 281 : bool bCreatePattern = false;
1412 : 281 : XclImpXF* pXF = GetXFBuffer().GetXF( mnXfId );
1413 : :
1414 [ + - ][ + + ]: 281 : bool bDefStyle = mbBuiltin && (mnBuiltinId == EXC_STYLE_NORMAL);
1415 [ + + ]: 281 : if( bDefStyle )
1416 : : {
1417 : : // set all flags to true to get all items in XclImpXF::CreatePattern()
1418 [ + - ]: 43 : if( pXF ) pXF->SetAllUsedFlags( true );
1419 : : // use existing "Default" style sheet
1420 : 43 : mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find(
1421 : 43 : ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) );
1422 : : OSL_ENSURE( mpStyleSheet, "XclImpStyle::CreateStyleSheet - Default style not found" );
1423 : 43 : bCreatePattern = true;
1424 : : }
1425 : : else
1426 : : {
1427 : : /* #i103281# do not create another style sheet of the same name,
1428 : : if it exists already. This is needed to prevent that styles
1429 : : pasted from clipboard get duplicated over and over. */
1430 : 238 : mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
1431 [ + - ]: 238 : if( !mpStyleSheet )
1432 : : {
1433 : 238 : mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
1434 : 238 : bCreatePattern = true;
1435 : : }
1436 : : }
1437 : :
1438 : : // bDefStyle==true omits default pool items in CreatePattern()
1439 [ + - ][ + - ]: 281 : if( bCreatePattern && mpStyleSheet && pXF )
[ + - ]
1440 : 281 : mpStyleSheet->GetItemSet().Put( pXF->CreatePattern( bDefStyle ).GetItemSet() );
1441 : : }
1442 : 641 : return mpStyleSheet;
1443 : : }
1444 : :
1445 : 908 : void XclImpStyle::CreateUserStyle( const String& rFinalName )
1446 : : {
1447 : 908 : maFinalName = rFinalName;
1448 [ - + ][ + + ]: 908 : if( !IsBuiltin() || mbCustom )
[ + + ]
1449 : 238 : CreateStyleSheet();
1450 : 908 : }
1451 : :
1452 : : // ----------------------------------------------------------------------------
1453 : :
1454 : 55 : XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) :
1455 [ + - ][ + - ]: 55 : XclImpRoot( rRoot )
[ + - ][ + - ]
1456 : : {
1457 : 55 : }
1458 : :
1459 : 0 : void XclImpXFBuffer::Initialize()
1460 : : {
1461 : 0 : maXFList.clear();
1462 : 0 : maBuiltinStyles.clear();
1463 : 0 : maUserStyles.clear();
1464 : 0 : maStylesByXf.clear();
1465 : 0 : }
1466 : :
1467 : 2017 : void XclImpXFBuffer::ReadXF( XclImpStream& rStrm )
1468 : : {
1469 [ + - ]: 2017 : XclImpXF* pXF = new XclImpXF( GetRoot() );
1470 : 2017 : pXF->ReadXF( rStrm );
1471 : 2017 : maXFList.push_back( pXF );
1472 : 2017 : }
1473 : :
1474 : 908 : void XclImpXFBuffer::ReadStyle( XclImpStream& rStrm )
1475 : : {
1476 [ + - ]: 908 : XclImpStyle* pStyle = new XclImpStyle( GetRoot() );
1477 : 908 : pStyle->ReadStyle( rStrm );
1478 [ + + ]: 908 : (pStyle->IsBuiltin() ? maBuiltinStyles : maUserStyles).push_back( pStyle );
1479 : : OSL_ENSURE( maStylesByXf.count( pStyle->GetXfId() ) == 0, "XclImpXFBuffer::ReadStyle - multiple styles with equal XF identifier" );
1480 [ + - ]: 908 : maStylesByXf[ pStyle->GetXfId() ] = pStyle;
1481 : 908 : }
1482 : :
1483 : 2133 : sal_uInt16 XclImpXFBuffer::GetFontIndex( sal_uInt16 nXFIndex ) const
1484 : : {
1485 : 2133 : const XclImpXF* pXF = GetXF( nXFIndex );
1486 [ + - ]: 2133 : return pXF ? pXF->GetFontIndex() : EXC_FONT_NOTFOUND;
1487 : : }
1488 : :
1489 : 2133 : const XclImpFont* XclImpXFBuffer::GetFont( sal_uInt16 nXFIndex ) const
1490 : : {
1491 : 2133 : return GetFontBuffer().GetFont( GetFontIndex( nXFIndex ) );
1492 : : }
1493 : :
1494 : : namespace {
1495 : :
1496 : : /** Functor for case-insensitive string comparison, usable in maps etc. */
1497 : : struct IgnoreCaseCompare
1498 : : {
1499 : 15404 : inline bool operator()( const String& rName1, const String& rName2 ) const
1500 : 15404 : { return rName1.CompareIgnoreCaseToAscii( rName2 ) == COMPARE_LESS; }
1501 : : };
1502 : :
1503 : : } // namespace
1504 : :
1505 : 52 : void XclImpXFBuffer::CreateUserStyles()
1506 : : {
1507 : : // calculate final names of all styles
1508 : : typedef ::std::map< String, XclImpStyle*, IgnoreCaseCompare > CellStyleNameMap;
1509 : : typedef ::std::vector< XclImpStyle* > XclImpStyleVector;
1510 : :
1511 [ + - ]: 52 : CellStyleNameMap aCellStyles;
1512 [ + - ]: 52 : XclImpStyleVector aConflictNameStyles;
1513 : :
1514 : : /* First, reserve style names that are built-in in Calc. This causes that
1515 : : imported cell styles get different unused names and thus do not try to
1516 : : overwrite these built-in styles. For BIFF4 workbooks (which contain a
1517 : : separate list of cell styles per sheet), reserve all existing styles if
1518 : : current sheet is not the first sheet (this styles buffer will be
1519 : : initialized again for every new sheet). This will create unique names
1520 : : for styles in different sheets with the same name. Assuming that the
1521 : : BIFF4W import filter is never used to import from clipboard... */
1522 [ - + ][ # # ]: 52 : bool bReserveAll = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0);
1523 [ + - ][ + - ]: 52 : SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
1524 [ + - ][ + - ]: 52 : String aStandardName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
1525 [ + - ][ + - ]: 312 : for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
[ + + ]
1526 [ + - ][ + - ]: 260 : if( (pStyleSheet->GetName() != aStandardName) && (bReserveAll || !pStyleSheet->IsUserDefined()) )
[ + + ][ + - ]
[ + - ][ + + ]
1527 [ + - ][ + - ]: 208 : if( aCellStyles.count( pStyleSheet->GetName() ) == 0 )
[ + - ]
1528 [ + - ][ + - ]: 208 : aCellStyles[ pStyleSheet->GetName() ] = 0;
1529 : :
1530 : : /* Calculate names of built-in styles. Store styles with reserved names
1531 : : in the aConflictNameStyles list. */
1532 [ + - ][ + - ]: 722 : for( XclImpStyleList::iterator itStyle = maBuiltinStyles.begin(); itStyle != maBuiltinStyles.end(); ++itStyle )
[ + - ][ + - ]
[ + + ]
1533 : : {
1534 [ + - ][ + - ]: 670 : String aStyleName = XclTools::GetBuiltInStyleName( itStyle->GetBuiltinId(), itStyle->GetName(), itStyle->GetLevel() );
[ + - ][ + - ]
[ + - ][ + - ]
1535 : : OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
1536 : : "XclImpXFBuffer::CreateUserStyles - multiple styles with equal built-in identifier" );
1537 [ - + ][ + - ]: 670 : if( aCellStyles.count( aStyleName ) > 0 )
1538 [ # # ][ # # ]: 0 : aConflictNameStyles.push_back( &(*itStyle) );
1539 : : else
1540 [ + - ][ + - ]: 670 : aCellStyles[ aStyleName ] = &(*itStyle);
1541 [ + - ]: 670 : }
1542 : :
1543 : : /* Calculate names of user defined styles. Store styles with reserved
1544 : : names in the aConflictNameStyles list. */
1545 [ + - ][ + - ]: 290 : for( XclImpStyleList::iterator itStyle = maUserStyles.begin(); itStyle != maUserStyles.end(); ++itStyle )
[ + - ][ + - ]
[ + + ]
1546 : : {
1547 : : // #i1624# #i1768# ignore unnamed user styles
1548 [ + - ][ + - ]: 238 : if( itStyle->GetName().Len() > 0 )
1549 : : {
1550 [ + - ][ + - ]: 238 : if( aCellStyles.count( itStyle->GetName() ) > 0 )
[ - + ]
1551 [ # # ][ # # ]: 0 : aConflictNameStyles.push_back( &(*itStyle) );
1552 : : else
1553 [ + - ][ + - ]: 238 : aCellStyles[ itStyle->GetName() ] = &(*itStyle);
[ + - ]
1554 : : }
1555 : : }
1556 : :
1557 : : // find unused names for all styles with conflicting names
1558 [ + - ][ - + ]: 52 : for( XclImpStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
1559 : : {
1560 : 0 : XclImpStyle* pStyle = *aIt;
1561 [ # # ]: 0 : String aUnusedName;
1562 : 0 : sal_Int32 nIndex = 0;
1563 [ # # ]: 0 : do
1564 : : {
1565 [ # # ][ # # ]: 0 : aUnusedName.Assign( pStyle->GetName() ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) );
[ # # ][ # # ]
[ # # ]
1566 : : }
1567 [ # # ]: 0 : while( aCellStyles.count( aUnusedName ) > 0 );
1568 [ # # ]: 0 : aCellStyles[ aUnusedName ] = pStyle;
1569 [ # # ]: 0 : }
1570 : :
1571 : : // set final names and create user-defined and modified built-in cell styles
1572 [ + + ]: 1168 : for( CellStyleNameMap::iterator aIt = aCellStyles.begin(), aEnd = aCellStyles.end(); aIt != aEnd; ++aIt )
1573 [ + + ]: 1116 : if( aIt->second )
1574 [ + - ][ + - ]: 960 : aIt->second->CreateUserStyle( aIt->first );
[ + - ]
1575 : 52 : }
1576 : :
1577 : 403 : ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex )
1578 : : {
1579 [ + - ]: 403 : XclImpStyleMap::iterator aIt = maStylesByXf.find( nXFIndex );
1580 [ - + ][ + - ]: 403 : return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet();
1581 : : }
1582 : :
1583 : : // Buffer for XF indexes in cells =============================================
1584 : :
1585 : 8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange )
1586 : :
1587 : 6267 : bool XclImpXFRange::Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex )
1588 : : {
1589 [ + + ]: 6267 : if( maXFIndex != rXFIndex )
1590 : 873 : return false;
1591 : :
1592 [ + + ]: 5394 : if( mnScRow2 + 1 == nScRow )
1593 : : {
1594 : 5286 : ++mnScRow2;
1595 : 5286 : return true;
1596 : : }
1597 [ + - ][ - + ]: 108 : if( mnScRow1 > 0 && (mnScRow1 - 1 == nScRow) )
1598 : : {
1599 : 0 : --mnScRow1;
1600 : 0 : return true;
1601 : : }
1602 : :
1603 : 6267 : return false;
1604 : : }
1605 : :
1606 : 0 : bool XclImpXFRange::Expand( const XclImpXFRange& rNextRange )
1607 : : {
1608 : : OSL_ENSURE( mnScRow2 < rNextRange.mnScRow1, "XclImpXFRange::Expand - rows out of order" );
1609 [ # # ][ # # ]: 0 : if( (maXFIndex == rNextRange.maXFIndex) && (mnScRow2 + 1 == rNextRange.mnScRow1) )
[ # # ]
1610 : : {
1611 : 0 : mnScRow2 = rNextRange.mnScRow2;
1612 : 0 : return true;
1613 : : }
1614 : 0 : return false;
1615 : : }
1616 : :
1617 : : // ----------------------------------------------------------------------------
1618 : :
1619 : 24750 : void XclImpXFRangeColumn::SetDefaultXF( const XclImpXFIndex& rXFIndex )
1620 : : {
1621 : : // List should be empty when inserting the default column format.
1622 : : // Later explicit SetXF() calls will break up this range.
1623 : : OSL_ENSURE( maIndexList.empty(), "XclImpXFRangeColumn::SetDefaultXF - Setting Default Column XF is not empty" );
1624 : :
1625 : : // insert a complete row range with one insert.
1626 : 24750 : maIndexList.push_back( new XclImpXFRange( 0, MAXROW, rXFIndex ) );
1627 : 24750 : }
1628 : :
1629 : : // ----------------------------------------------------------------------------
1630 : :
1631 : 10212 : void XclImpXFRangeColumn::SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex )
1632 : : {
1633 : : XclImpXFRange* pPrevRange;
1634 : : XclImpXFRange* pNextRange;
1635 : : sal_uLong nNextIndex;
1636 : :
1637 [ + - ]: 10212 : Find( pPrevRange, pNextRange, nNextIndex, nScRow );
1638 : :
1639 : : // previous range:
1640 : : // try to overwrite XF (if row is contained in) or try to expand range
1641 [ + + ]: 10212 : if( pPrevRange )
1642 : : {
1643 [ + + ]: 10022 : if( pPrevRange->Contains( nScRow ) ) // overwrite old XF
1644 : : {
1645 [ + + ]: 9008 : if( rXFIndex == pPrevRange->maXFIndex )
1646 : : return;
1647 : :
1648 : 6210 : SCROW nFirstScRow = pPrevRange->mnScRow1;
1649 : 6210 : SCROW nLastScRow = pPrevRange->mnScRow2;
1650 : 6210 : sal_uLong nIndex = nNextIndex - 1;
1651 : 6210 : XclImpXFRange* pThisRange = pPrevRange;
1652 [ + + ][ + - ]: 6210 : pPrevRange = (nIndex > 0 && nIndex <= maIndexList.size()) ? &(maIndexList[ nIndex - 1 ]) : 0;
[ + - ]
1653 : :
1654 [ - + ]: 6210 : if( nFirstScRow == nLastScRow ) // replace solely XF
1655 : : {
1656 : 0 : pThisRange->maXFIndex = rXFIndex;
1657 [ # # ]: 0 : TryConcatPrev( nNextIndex ); // try to concat. next with this
1658 [ # # ]: 0 : TryConcatPrev( nIndex ); // try to concat. this with previous
1659 : : }
1660 [ + + ]: 6210 : else if( nFirstScRow == nScRow ) // replace first XF
1661 : : {
1662 : 5769 : ++(pThisRange->mnScRow1);
1663 : : // try to concatenate with previous of this
1664 [ + + ][ + + ]: 5769 : if( !pPrevRange || !pPrevRange->Expand( nScRow, rXFIndex ) )
[ + + ]
1665 [ + - ][ + - ]: 1275 : Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
1666 : : }
1667 [ - + ]: 441 : else if( nLastScRow == nScRow ) // replace last XF
1668 : : {
1669 : 0 : --(pThisRange->mnScRow2);
1670 [ # # ][ # # ]: 0 : if( !pNextRange || !pNextRange->Expand( nScRow, rXFIndex ) )
[ # # ]
1671 [ # # ][ # # ]: 0 : Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
1672 : : }
1673 : : else // insert in the middle of the range
1674 : : {
1675 : 441 : pThisRange->mnScRow1 = nScRow + 1;
1676 : : // List::Insert() moves entries towards end of list, so insert twice at nIndex
1677 [ + - ][ + - ]: 441 : Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
1678 [ + - ][ + - ]: 441 : Insert( new XclImpXFRange( nFirstScRow, nScRow - 1, pThisRange->maXFIndex ), nIndex );
1679 : : }
1680 : : return;
1681 : : }
1682 [ + + ]: 1014 : else if( pPrevRange->Expand( nScRow, rXFIndex ) ) // try to expand
1683 : : {
1684 [ + - ]: 792 : TryConcatPrev( nNextIndex ); // try to concatenate next with expanded
1685 : : return;
1686 : : }
1687 : : }
1688 : :
1689 : : // try to expand next range
1690 [ - + ][ # # ]: 412 : if( pNextRange && pNextRange->Expand( nScRow, rXFIndex ) )
[ + - ]
1691 : : return;
1692 : :
1693 : : // create new range
1694 [ + - ][ + - ]: 10212 : Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
1695 : : }
1696 : :
1697 : 2569 : void XclImpXFRangeColumn::Insert(XclImpXFRange* pXFRange, sal_uLong nIndex)
1698 : : {
1699 : 2569 : maIndexList.insert( maIndexList.begin() + nIndex, pXFRange );
1700 : 2569 : }
1701 : :
1702 : 10212 : void XclImpXFRangeColumn::Find(
1703 : : XclImpXFRange*& rpPrevRange, XclImpXFRange*& rpNextRange,
1704 : : sal_uLong& rnNextIndex, SCROW nScRow )
1705 : : {
1706 : :
1707 : : // test whether list is empty
1708 [ + + ]: 10212 : if( maIndexList.empty() )
1709 : : {
1710 : 190 : rpPrevRange = rpNextRange = 0;
1711 : 190 : rnNextIndex = 0;
1712 : 190 : return;
1713 : : }
1714 : :
1715 : 10022 : rpPrevRange = &maIndexList.front();
1716 : 10022 : rpNextRange = &maIndexList.back();
1717 : :
1718 : : // test whether row is at end of list (contained in or behind last range)
1719 : : // rpPrevRange will contain a possible existing row
1720 [ + - ]: 10022 : if( rpNextRange->mnScRow1 <= nScRow )
1721 : : {
1722 : 10022 : rpPrevRange = rpNextRange;
1723 : 10022 : rpNextRange = 0;
1724 : 10022 : rnNextIndex = maIndexList.size();
1725 : 10022 : return;
1726 : : }
1727 : :
1728 : : // test whether row is at beginning of list (really before first range)
1729 [ # # ]: 0 : if( nScRow < rpPrevRange->mnScRow1 )
1730 : : {
1731 : 0 : rpNextRange = rpPrevRange;
1732 : 0 : rpPrevRange = 0;
1733 : 0 : rnNextIndex = 0;
1734 : 0 : return;
1735 : : }
1736 : :
1737 : : // loop: find range entries before and after new row
1738 : : // break the loop if there is no more range between first and last -or-
1739 : : // if rpPrevRange contains nScRow (rpNextRange will never contain nScRow)
1740 : 0 : sal_uLong nPrevIndex = 0;
1741 : : sal_uLong nMidIndex;
1742 : 0 : rnNextIndex = maIndexList.size() - 1;
1743 : : XclImpXFRange* pMidRange;
1744 [ # # ][ # # ]: 0 : while( ((rnNextIndex - nPrevIndex) > 1) && (rpPrevRange->mnScRow2 < nScRow) )
[ # # ]
1745 : : {
1746 : 0 : nMidIndex = (nPrevIndex + rnNextIndex) / 2;
1747 : 0 : pMidRange = &maIndexList[nMidIndex];
1748 : : OSL_ENSURE( pMidRange, "XclImpXFRangeColumn::Find - missing XF index range" );
1749 [ # # ]: 0 : if( nScRow < pMidRange->mnScRow1 ) // row is really before pMidRange
1750 : : {
1751 : 0 : rpNextRange = pMidRange;
1752 : 0 : rnNextIndex = nMidIndex;
1753 : : }
1754 : : else // row is in or after pMidRange
1755 : : {
1756 : 0 : rpPrevRange = pMidRange;
1757 : 0 : nPrevIndex = nMidIndex;
1758 : : }
1759 : : }
1760 : :
1761 : : // find next rpNextRange if rpPrevRange contains nScRow
1762 [ # # ]: 0 : if( nScRow <= rpPrevRange->mnScRow2 )
1763 : : {
1764 : 0 : rnNextIndex = nPrevIndex + 1;
1765 : 10212 : rpNextRange = &maIndexList[rnNextIndex];
1766 : : }
1767 : : }
1768 : :
1769 : 792 : void XclImpXFRangeColumn::TryConcatPrev( sal_uLong nIndex )
1770 : : {
1771 [ + - ][ + - ]: 792 : if( !nIndex || nIndex >= maIndexList.size() )
[ + - ]
1772 : 792 : return;
1773 : :
1774 : 0 : XclImpXFRange& prevRange = maIndexList[ nIndex - 1 ];
1775 : 0 : XclImpXFRange& nextRange = maIndexList[ nIndex ];
1776 : :
1777 [ # # ]: 0 : if( prevRange.Expand( nextRange ) )
1778 : 0 : maIndexList.erase( maIndexList.begin() + nIndex );
1779 : : }
1780 : :
1781 : : // ----------------------------------------------------------------------------
1782 : :
1783 : 55 : XclImpXFRangeBuffer::XclImpXFRangeBuffer( const XclImpRoot& rRoot ) :
1784 [ + - ][ + - ]: 55 : XclImpRoot( rRoot )
[ + - ]
1785 : : {
1786 : 55 : }
1787 : :
1788 [ + - ]: 55 : XclImpXFRangeBuffer::~XclImpXFRangeBuffer()
1789 : : {
1790 [ - + ]: 110 : }
1791 : :
1792 : 165 : void XclImpXFRangeBuffer::Initialize()
1793 : : {
1794 : 165 : maColumns.clear();
1795 : 165 : maHyperlinks.clear();
1796 : 165 : maMergeList.RemoveAll();
1797 : 165 : }
1798 : :
1799 : 10212 : void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode )
1800 : : {
1801 : 10212 : SCCOL nScCol = rScPos.Col();
1802 : 10212 : SCROW nScRow = rScPos.Row();
1803 : :
1804 : : // set cell XF's
1805 : 10212 : size_t nIndex = static_cast< size_t >( nScCol );
1806 [ + + ]: 10212 : if( maColumns.size() <= nIndex )
1807 : 142 : maColumns.resize( nIndex + 1 );
1808 [ + + ]: 10212 : if( !maColumns[ nIndex ] )
1809 [ + - ]: 190 : maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
1810 : : // remember all Boolean cells, they will get 'Standard' number format
1811 [ + - ]: 10212 : maColumns[ nIndex ]->SetXF( nScRow, XclImpXFIndex( nXFIndex, eMode == xlXFModeBoolCell ) );
1812 : :
1813 : : // set "center across selection" and "fill" attribute for all following empty cells
1814 : : // ignore it on row default XFs
1815 [ + - ]: 10212 : if( eMode != xlXFModeRow )
1816 : : {
1817 : 10212 : const XclImpXF* pXF = GetXFBuffer().GetXF( nXFIndex );
1818 [ + - ][ - + ]: 10212 : if( pXF && ((pXF->GetHorAlign() == EXC_XF_HOR_CENTER_AS) || (pXF->GetHorAlign() == EXC_XF_HOR_FILL)) )
[ - + ][ + + ]
1819 : : {
1820 : : // expand last merged range if this attribute is set repeatedly
1821 [ # # ]: 0 : ScRange* pRange = maMergeList.empty() ? NULL : maMergeList.back();
1822 [ # # ][ # # ]: 0 : if (pRange && (pRange->aEnd.Row() == nScRow) && (pRange->aEnd.Col() + 1 == nScCol) && (eMode == xlXFModeBlank))
[ # # ][ # # ]
[ # # ]
1823 : 0 : pRange->aEnd.IncCol();
1824 [ # # ]: 0 : else if( eMode != xlXFModeBlank ) // do not merge empty cells
1825 : 0 : SetMerge( nScCol, nScRow );
1826 : : }
1827 : : }
1828 : 10212 : }
1829 : :
1830 : 7718 : void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
1831 : : {
1832 : 7718 : SetXF( rScPos, nXFIndex, xlXFModeCell );
1833 : 7718 : }
1834 : :
1835 : 2494 : void XclImpXFRangeBuffer::SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
1836 : : {
1837 : 2494 : SetXF( rScPos, nXFIndex, xlXFModeBlank );
1838 : 2494 : }
1839 : :
1840 : 0 : void XclImpXFRangeBuffer::SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
1841 : : {
1842 : 0 : SetXF( rScPos, nXFIndex, xlXFModeBoolCell );
1843 : 0 : }
1844 : :
1845 : 0 : void XclImpXFRangeBuffer::SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex )
1846 : : {
1847 [ # # ]: 0 : for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
1848 [ # # ]: 0 : SetXF( ScAddress( nScCol, nScRow, 0 ), nXFIndex, xlXFModeRow );
1849 : 0 : }
1850 : :
1851 : 24750 : void XclImpXFRangeBuffer::SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex )
1852 : : {
1853 : : // our array should not have values when creating the default column format.
1854 : 24750 : size_t nIndex = static_cast< size_t >( nScCol );
1855 [ + - ]: 24750 : if( maColumns.size() <= nIndex )
1856 : 24750 : maColumns.resize( nIndex + 1 );
1857 : : OSL_ENSURE( !maColumns[ nIndex ], "XclImpXFRangeBuffer::SetColumnDefXF - default column of XFs already has values" );
1858 [ + - ]: 24750 : maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
1859 [ + - ]: 24750 : maColumns[ nIndex ]->SetDefaultXF( XclImpXFIndex( nXFIndex ) );
1860 : 24750 : }
1861 : :
1862 : 48 : void XclImpXFRangeBuffer::SetBorderLine( const ScRange& rRange, SCTAB nScTab, sal_uInt16 nLine )
1863 : : {
1864 [ + + ]: 48 : SCCOL nFromScCol = (nLine == BOX_LINE_RIGHT) ? rRange.aEnd.Col() : rRange.aStart.Col();
1865 [ + + ]: 48 : SCROW nFromScRow = (nLine == BOX_LINE_BOTTOM) ? rRange.aEnd.Row() : rRange.aStart.Row();
1866 : 48 : ScDocument& rDoc = GetDoc();
1867 : :
1868 : : const SvxBoxItem* pFromItem = static_cast< const SvxBoxItem* >(
1869 [ + - ]: 48 : rDoc.GetAttr( nFromScCol, nFromScRow, nScTab, ATTR_BORDER ) );
1870 : : const SvxBoxItem* pToItem = static_cast< const SvxBoxItem* >(
1871 [ + - ]: 48 : rDoc.GetAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, ATTR_BORDER ) );
1872 : :
1873 [ + - ]: 48 : SvxBoxItem aNewItem( *pToItem );
1874 [ + - ][ + - ]: 48 : aNewItem.SetLine( pFromItem->GetLine( nLine ), nLine );
1875 [ + - ][ + - ]: 48 : rDoc.ApplyAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, aNewItem );
1876 : 48 : }
1877 : :
1878 : 24 : void XclImpXFRangeBuffer::SetHyperlink( const XclRange& rXclRange, const String& rUrl )
1879 : : {
1880 [ + - ]: 24 : maHyperlinks.push_back( XclImpHyperlinkRange( rXclRange, rUrl ) );
1881 : 24 : }
1882 : :
1883 : 0 : void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol, SCROW nScRow )
1884 : : {
1885 [ # # ]: 0 : maMergeList.Append( ScRange( nScCol, nScRow, 0 ) );
1886 : 0 : }
1887 : :
1888 : 45 : void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 )
1889 : : {
1890 [ - + ][ # # ]: 45 : if( (nScCol1 < nScCol2) || (nScRow1 < nScRow2) )
1891 [ + - ]: 45 : maMergeList.Append( ScRange( nScCol1, nScRow1, 0, nScCol2, nScRow2, 0 ) );
1892 : 45 : }
1893 : :
1894 : 165 : void XclImpXFRangeBuffer::Finalize()
1895 : : {
1896 : 165 : ScDocument& rDoc = GetDoc();
1897 : 165 : SCTAB nScTab = GetCurrScTab();
1898 : :
1899 : : // apply patterns
1900 : 165 : XclImpXFBuffer& rXFBuffer = GetXFBuffer();
1901 [ + - ][ + - ]: 25162 : for( XclImpXFRangeColumnVec::const_iterator aVBeg = maColumns.begin(), aVEnd = maColumns.end(), aVIt = aVBeg; aVIt != aVEnd; ++aVIt )
[ + + ][ + - ]
1902 : : {
1903 : : // apply all cell styles of an existing column
1904 [ + + ]: 24997 : if( aVIt->get() )
1905 : : {
1906 : 24940 : XclImpXFRangeColumn& rColumn = **aVIt;
1907 [ + - ]: 24940 : SCCOL nScCol = static_cast< SCCOL >( aVIt - aVBeg );
1908 [ + - ]: 24940 : list<ScAttrEntry> aAttrs;
1909 : :
1910 [ + - ][ + - ]: 52259 : for (XclImpXFRangeColumn::IndexList::iterator itr = rColumn.begin(), itrEnd = rColumn.end();
[ + - ][ + - ]
[ + + ]
1911 : : itr != itrEnd; ++itr)
1912 : : {
1913 [ + - ]: 27319 : XclImpXFRange& rStyle = *itr;
1914 : 27319 : const XclImpXFIndex& rXFIndex = rStyle.maXFIndex;
1915 [ + - ]: 27319 : XclImpXF* pXF = rXFBuffer.GetXF( rXFIndex.GetXFIndex() );
1916 [ + + ]: 27319 : if (!pXF)
1917 : 3 : continue;
1918 : :
1919 : 27316 : sal_uInt32 nForceScNumFmt = rXFIndex.IsBoolCell() ?
1920 [ # # ][ - + ]: 27316 : GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
1921 : :
1922 [ + - ]: 27316 : pXF->ApplyPatternToAttrList(aAttrs, rStyle.mnScRow1, rStyle.mnScRow2, nForceScNumFmt);
1923 : : }
1924 : :
1925 [ + - ][ + - ]: 24940 : if (aAttrs.empty() || aAttrs.back().nRow != MAXROW)
[ + + ][ + + ]
1926 : : {
1927 : : ScAttrEntry aEntry;
1928 : 190 : aEntry.nRow = MAXROW;
1929 [ + - ]: 190 : aEntry.pPattern = rDoc.GetDefPattern();
1930 [ + - ]: 190 : aAttrs.push_back(aEntry);
1931 : : }
1932 : :
1933 : 24940 : size_t nAttrSize = aAttrs.size();
1934 [ + - ]: 24940 : ScAttrEntry* pData = new ScAttrEntry[nAttrSize];
1935 : 24940 : list<ScAttrEntry>::const_iterator itr = aAttrs.begin(), itrEnd = aAttrs.end();
1936 [ + + ]: 52807 : for (size_t i = 0; itr != itrEnd; ++itr, ++i)
1937 : 27867 : pData[i] = *itr;
1938 : :
1939 [ + - ]: 24940 : rDoc.SetAttrEntries(nScCol, nScTab, pData, static_cast<SCSIZE>(nAttrSize));
1940 : : }
1941 : : }
1942 : :
1943 : : // insert hyperlink cells
1944 [ + + ]: 189 : for( XclImpHyperlinkList::const_iterator aLIt = maHyperlinks.begin(), aLEnd = maHyperlinks.end(); aLIt != aLEnd; ++aLIt )
1945 [ + - ]: 24 : XclImpHyperlink::InsertUrl( GetRoot(), aLIt->first, aLIt->second );
1946 : :
1947 : : // apply cell merging
1948 [ + + ]: 210 : for ( size_t i = 0, nRange = maMergeList.size(); i < nRange; ++i )
1949 : : {
1950 : 45 : const ScRange* pRange = maMergeList[ i ];
1951 : 45 : const ScAddress& rStart = pRange->aStart;
1952 : 45 : const ScAddress& rEnd = pRange->aEnd;
1953 : 45 : bool bMultiCol = rStart.Col() != rEnd.Col();
1954 : 45 : bool bMultiRow = rStart.Row() != rEnd.Row();
1955 : : // set correct right border
1956 [ + - ]: 45 : if( bMultiCol )
1957 : 45 : SetBorderLine( *pRange, nScTab, BOX_LINE_RIGHT );
1958 : : // set correct lower border
1959 [ + + ]: 45 : if( bMultiRow )
1960 : 3 : SetBorderLine( *pRange, nScTab, BOX_LINE_BOTTOM );
1961 : : // do merge
1962 [ - + ][ # # ]: 45 : if( bMultiCol || bMultiRow )
1963 : 45 : rDoc.DoMerge( nScTab, rStart.Col(), rStart.Row(), rEnd.Col(), rEnd.Row() );
1964 : : // #i93609# merged range in a single row: test if manual row height is needed
1965 [ + + ]: 45 : if( !bMultiRow )
1966 : : {
1967 : 42 : bool bTextWrap = static_cast< const SfxBoolItem* >( rDoc.GetAttr( rStart.Col(), rStart.Row(), rStart.Tab(), ATTR_LINEBREAK ) )->GetValue();
1968 [ - + ][ - + ]: 42 : if( !bTextWrap && (rDoc.GetCellType( rStart ) == CELLTYPE_EDIT) )
[ + + ]
1969 [ # # ]: 0 : if( const EditTextObject* pEditObj = static_cast< const ScEditCell* >( rDoc.GetCell( rStart ) )->GetData() )
1970 : 0 : bTextWrap = pEditObj->GetParagraphCount() > 1;
1971 [ + + ]: 42 : if( bTextWrap )
1972 : 15 : GetOldRoot().pColRowBuff->SetManualRowHeight( rStart.Row() );
1973 : : }
1974 : : }
1975 [ + - ][ + - ]: 189 : }
1976 : :
1977 : : // ============================================================================
1978 : :
1979 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|