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 "xihelper.hxx"
30 : : #include <svl/itemset.hxx>
31 : : #include <editeng/editobj.hxx>
32 : : #include <tools/urlobj.hxx>
33 : : #include "scitems.hxx"
34 : : #include <editeng/eeitem.hxx>
35 : : #include <editeng/flditem.hxx>
36 : : #include "document.hxx"
37 : : #include "cell.hxx"
38 : : #include "rangelst.hxx"
39 : : #include "editutil.hxx"
40 : : #include "attrib.hxx"
41 : : #include "xltracer.hxx"
42 : : #include "xistream.hxx"
43 : : #include "xistyle.hxx"
44 : :
45 : : #include "excform.hxx"
46 : :
47 : : // Excel->Calc cell address/range conversion ==================================
48 : :
49 : : namespace {
50 : :
51 : : /** Fills the passed Calc address with the passed Excel cell coordinates without checking any limits. */
52 : 11581 : inline void lclFillAddress( ScAddress& rScPos, sal_uInt16 nXclCol, sal_uInt32 nXclRow, SCTAB nScTab )
53 : : {
54 : 11581 : rScPos.SetCol( static_cast< SCCOL >( nXclCol ) );
55 : 11581 : rScPos.SetRow( static_cast< SCROW >( nXclRow ) );
56 : 11581 : rScPos.SetTab( nScTab );
57 : 11581 : }
58 : :
59 : : } // namespace
60 : :
61 : : // ----------------------------------------------------------------------------
62 : :
63 : 55 : XclImpAddressConverter::XclImpAddressConverter( const XclImpRoot& rRoot ) :
64 : 55 : XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetScMaxPos() )
65 : : {
66 : 55 : }
67 : :
68 : : // cell address ---------------------------------------------------------------
69 : :
70 : 11581 : bool XclImpAddressConverter::CheckAddress( const XclAddress& rXclPos, bool bWarn )
71 : : {
72 : 11581 : bool bValidCol = rXclPos.mnCol <= mnMaxCol;
73 : 11581 : bool bValidRow = rXclPos.mnRow <= mnMaxRow;
74 [ + - ][ + - ]: 11581 : bool bValid = bValidCol && bValidRow;
75 [ - + ][ # # ]: 11581 : if( !bValid && bWarn )
76 : : {
77 : 0 : mbColTrunc |= !bValidCol;
78 : 0 : mbRowTrunc |= !bValidRow;
79 : : mrTracer.TraceInvalidAddress( ScAddress(
80 [ # # ]: 0 : static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), 0 ), maMaxPos );
81 : : }
82 : 11581 : return bValid;
83 : : }
84 : :
85 : 10707 : bool XclImpAddressConverter::ConvertAddress( ScAddress& rScPos,
86 : : const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
87 : : {
88 : 10707 : bool bValid = CheckAddress( rXclPos, bWarn );
89 [ + - ]: 10707 : if( bValid )
90 : 10707 : lclFillAddress( rScPos, rXclPos.mnCol, rXclPos.mnRow, nScTab );
91 : 10707 : return bValid;
92 : : }
93 : :
94 : 492 : ScAddress XclImpAddressConverter::CreateValidAddress(
95 : : const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
96 : : {
97 : 492 : ScAddress aScPos( ScAddress::UNINITIALIZED );
98 [ - + ]: 492 : if( !ConvertAddress( aScPos, rXclPos, nScTab, bWarn ) )
99 : : {
100 : 0 : aScPos.SetCol( static_cast< SCCOL >( ::std::min( rXclPos.mnCol, mnMaxCol ) ) );
101 : 0 : aScPos.SetRow( static_cast< SCROW >( ::std::min( rXclPos.mnRow, mnMaxRow ) ) );
102 : 0 : aScPos.SetTab( limit_cast< SCTAB >( nScTab, 0, maMaxPos.Tab() ) );
103 : : }
104 : 492 : return aScPos;
105 : : }
106 : :
107 : : // cell range -----------------------------------------------------------------
108 : :
109 : 437 : bool XclImpAddressConverter::ConvertRange( ScRange& rScRange,
110 : : const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
111 : : {
112 : : // check start position
113 : 437 : bool bValidStart = CheckAddress( rXclRange.maFirst, bWarn );
114 [ + - ]: 437 : if( bValidStart )
115 : : {
116 : 437 : lclFillAddress( rScRange.aStart, rXclRange.maFirst.mnCol, rXclRange.maFirst.mnRow, nScTab1 );
117 : :
118 : : // check & correct end position
119 : 437 : sal_uInt16 nXclCol2 = rXclRange.maLast.mnCol;
120 : 437 : sal_uInt32 nXclRow2 = rXclRange.maLast.mnRow;
121 [ - + ][ + - ]: 437 : if( !CheckAddress( rXclRange.maLast, bWarn ) )
122 : : {
123 [ # # ]: 0 : nXclCol2 = ::std::min( nXclCol2, mnMaxCol );
124 [ # # ]: 0 : nXclRow2 = ::std::min( nXclRow2, mnMaxRow );
125 : : }
126 : 437 : lclFillAddress( rScRange.aEnd, nXclCol2, nXclRow2, nScTab2 );
127 : : }
128 : 437 : return bValidStart;
129 : : }
130 : :
131 : : // cell range list ------------------------------------------------------------
132 : :
133 : 165 : void XclImpAddressConverter::ConvertRangeList( ScRangeList& rScRanges,
134 : : const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn )
135 : : {
136 : 165 : rScRanges.RemoveAll();
137 [ + - ][ + + ]: 330 : for( XclRangeList::const_iterator aIt = rXclRanges.begin(), aEnd = rXclRanges.end(); aIt != aEnd; ++aIt )
138 : : {
139 : 165 : ScRange aScRange( ScAddress::UNINITIALIZED );
140 [ + - ][ + - ]: 165 : if( ConvertRange( aScRange, *aIt, nScTab, nScTab, bWarn ) )
141 [ + - ]: 165 : rScRanges.Append( aScRange );
142 : : }
143 : 165 : }
144 : :
145 : : // String->EditEngine conversion ==============================================
146 : :
147 : : namespace {
148 : :
149 : 2133 : EditTextObject* lclCreateTextObject( const XclImpRoot& rRoot,
150 : : const XclImpString& rString, XclFontItemType eType, sal_uInt16 nXFIndex )
151 : : {
152 : 2133 : EditTextObject* pTextObj = 0;
153 : :
154 : 2133 : const XclImpXFBuffer& rXFBuffer = rRoot.GetXFBuffer();
155 : 2133 : const XclImpFont* pFirstFont = rXFBuffer.GetFont( nXFIndex );
156 [ - + ][ + - ]: 2133 : bool bFirstEscaped = pFirstFont && pFirstFont->HasEscapement();
157 : :
158 [ + + ][ - + ]: 2133 : if( rString.IsRich() || bFirstEscaped )
[ + + ]
159 : : {
160 [ + - ]: 141 : const XclImpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
161 : 141 : const XclFormatRunVec& rFormats = rString.GetFormats();
162 : :
163 : : ScEditEngineDefaulter& rEE = (eType == EXC_FONTITEM_NOTE) ?
164 [ # # ][ + - ]: 141 : static_cast< ScEditEngineDefaulter& >( rRoot.GetDoc().GetNoteEngine() ) : rRoot.GetEditEngine();
[ - + ]
165 [ + - ]: 141 : rEE.SetText( rString.GetText() );
166 : :
167 [ + - ][ + - ]: 141 : SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
168 [ - + ]: 141 : if( bFirstEscaped )
169 [ # # ][ # # ]: 0 : rFontBuffer.FillToItemSet( aItemSet, eType, rXFBuffer.GetFontIndex( nXFIndex ) );
170 : 141 : ESelection aSelection;
171 : :
172 : 141 : XclFormatRun aNextRun;
173 : 141 : XclFormatRunVec::const_iterator aIt = rFormats.begin();
174 : 141 : XclFormatRunVec::const_iterator aEnd = rFormats.end();
175 : :
176 [ + - ][ + - ]: 141 : if( aIt != aEnd )
177 [ + - ]: 141 : aNextRun = *aIt++;
178 : : else
179 : 0 : aNextRun.mnChar = 0xFFFF;
180 : :
181 : 141 : xub_StrLen nLen = rString.GetText().Len();
182 [ + + ]: 8127 : for( sal_uInt16 nChar = 0; nChar < nLen; ++nChar )
183 : : {
184 : : // reached new different formatted text portion
185 [ + + ]: 7986 : if( nChar >= aNextRun.mnChar )
186 : : {
187 : : // send items to edit engine
188 [ + - ]: 258 : rEE.QuickSetAttribs( aItemSet, aSelection );
189 : :
190 : : // start new item set
191 [ + - ]: 258 : aItemSet.ClearItem();
192 [ + - ]: 258 : rFontBuffer.FillToItemSet( aItemSet, eType, aNextRun.mnFontIdx );
193 : :
194 : : // read new formatting information
195 [ + - ][ + + ]: 258 : if( aIt != aEnd )
196 [ + - ]: 150 : aNextRun = *aIt++;
197 : : else
198 : 108 : aNextRun.mnChar = 0xFFFF;
199 : :
200 : : // reset selection start to current position
201 : 258 : aSelection.nStartPara = aSelection.nEndPara;
202 : 258 : aSelection.nStartPos = aSelection.nEndPos;
203 : : }
204 : :
205 : : // set end of selection to current position
206 [ + + ]: 7986 : if( rString.GetText().GetChar( nChar ) == '\n' )
207 : : {
208 : 3 : ++aSelection.nEndPara;
209 : 3 : aSelection.nEndPos = 0;
210 : : }
211 : : else
212 : 7983 : ++aSelection.nEndPos;
213 : : }
214 : :
215 : : // send items of last text portion to edit engine
216 [ + - ]: 141 : rEE.QuickSetAttribs( aItemSet, aSelection );
217 : :
218 [ + - ][ + - ]: 141 : pTextObj = rEE.CreateTextObject();
219 : : }
220 : :
221 : 2133 : return pTextObj;
222 : : }
223 : :
224 : : } // namespace
225 : :
226 : 33 : EditTextObject* XclImpStringHelper::CreateTextObject(
227 : : const XclImpRoot& rRoot, const XclImpString& rString )
228 : : {
229 : 33 : return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, 0 );
230 : : }
231 : :
232 : 2100 : ScBaseCell* XclImpStringHelper::CreateCell(
233 : : const XclImpRoot& rRoot, const XclImpString& rString, sal_uInt16 nXFIndex )
234 : : {
235 : 2100 : ScBaseCell* pCell = 0;
236 : :
237 [ + - ]: 2100 : if( rString.GetText().Len() )
238 : : {
239 [ + - ]: 2100 : ::std::auto_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
240 : 2100 : ScDocument& rDoc = rRoot.GetDoc();
241 : :
242 [ + + ]: 2100 : if( pTextObj.get() )
243 : : // ScEditCell creates own copy of text object
244 [ + - ][ + - ]: 108 : pCell = new ScEditCell( pTextObj.get(), &rDoc, rRoot.GetEditEngine().GetEditTextObjectPool() );
[ + - ][ + - ]
245 : : else
246 [ + - ][ + - ]: 2100 : pCell = ScBaseCell::CreateTextCell( rString.GetText(), &rDoc );
[ + - ]
247 : : }
248 : :
249 : 2100 : return pCell;
250 : : }
251 : :
252 : : // Header/footer conversion ===================================================
253 : :
254 : 270 : XclImpHFConverter::XclImpHFPortionInfo::XclImpHFPortionInfo() :
255 : : mnHeight( 0 ),
256 : 270 : mnMaxLineHt( 0 )
257 : : {
258 : 270 : maSel.nStartPara = maSel.nEndPara = 0;
259 : 270 : maSel.nStartPos = maSel.nEndPos = 0;
260 : 270 : }
261 : :
262 : : // ----------------------------------------------------------------------------
263 : :
264 : 165 : XclImpHFConverter::XclImpHFConverter( const XclImpRoot& rRoot ) :
265 : : XclImpRoot( rRoot ),
266 [ + - ]: 165 : mrEE( rRoot.GetHFEditEngine() ),
267 [ + - ]: 165 : mxFontData( new XclFontData ),
268 [ + - ][ + - ]: 495 : meCurrObj( EXC_HF_CENTER )
[ + - ]
269 : : {
270 : 165 : }
271 : :
272 [ + - ][ + - ]: 165 : XclImpHFConverter::~XclImpHFConverter()
273 : : {
274 [ - + ]: 165 : }
275 : :
276 : 90 : void XclImpHFConverter::ParseString( const String& rHFString )
277 : : {
278 : : // edit engine objects
279 [ + - ][ + - ]: 90 : mrEE.SetText( EMPTY_STRING );
280 : 90 : maInfos.clear();
281 [ + - ]: 90 : maInfos.resize( EXC_HF_PORTION_COUNT );
282 : 90 : meCurrObj = EXC_HF_CENTER;
283 : :
284 : : // parser temporaries
285 [ + - ]: 90 : maCurrText.Erase();
286 [ + - ]: 90 : String aReadFont; // current font name
287 [ + - ]: 90 : String aReadStyle; // current font style
288 : 90 : sal_uInt16 nReadHeight = 0; // current font height
289 [ + - ]: 90 : ResetFontData();
290 : :
291 : : /** State of the parser. */
292 : : enum XclHFParserState
293 : : {
294 : : xlPSText, /// Read text, search for functions.
295 : : xlPSFunc, /// Read function (token following a '&').
296 : : xlPSFont, /// Read font name ('&' is followed by '"', reads until next '"' or ',').
297 : : xlPSFontStyle, /// Read font style name (font part after ',', reads until next '"').
298 : : xlPSHeight /// Read font height ('&' is followed by num. digits, reads until non-digit).
299 : 90 : } eState = xlPSText;
300 : :
301 : 90 : const sal_Unicode* pChar = rHFString.GetBuffer();
302 : 90 : const sal_Unicode* pNull = pChar + rHFString.Len(); // pointer to teminating null char
303 [ + + ]: 990 : while( *pChar )
304 : : {
305 [ + + + + : 900 : switch( eState )
+ - ]
306 : : {
307 : :
308 : : // --- read text character ---
309 : :
310 : : case xlPSText:
311 : : {
312 [ + - + ]: 558 : switch( *pChar )
313 : : {
314 : : case '&': // new command
315 [ + - ]: 186 : InsertText();
316 : 186 : eState = xlPSFunc;
317 : 186 : break;
318 : : case '\n': // line break
319 [ # # ]: 0 : InsertText();
320 [ # # ]: 0 : InsertLineBreak();
321 : 0 : break;
322 : : default:
323 [ + - ]: 372 : maCurrText += *pChar;
324 : : }
325 : : }
326 : 558 : break;
327 : :
328 : : // --- read control sequence ---
329 : :
330 : : case xlPSFunc:
331 : : {
332 : 186 : eState = xlPSText;
333 [ - + + + : 186 : switch( *pChar )
+ - + - +
- + - - -
- - + + ]
334 : : {
335 [ # # ]: 0 : case '&': maCurrText += '&'; break; // the '&' character
336 : :
337 [ + - ]: 6 : case 'L': SetNewPortion( EXC_HF_LEFT ); break; // Left portion
338 [ + - ]: 78 : case 'C': SetNewPortion( EXC_HF_CENTER ); break; // Center portion
339 [ + - ]: 3 : case 'R': SetNewPortion( EXC_HF_RIGHT ); break; // Right portion
340 : :
341 [ + - ][ + - ]: 42 : case 'P': InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD ) ); break; // page
[ + - ][ + - ]
[ + - ]
342 [ # # ][ # # ]: 0 : case 'N': InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD ) ); break; // page count
[ # # ][ # # ]
[ # # ]
343 [ + - ][ + - ]: 3 : case 'D': InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD ) ); break; // date
[ + - ][ + - ]
[ + - ]
344 [ # # ][ # # ]: 0 : case 'T': InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD ) ); break; // time
[ # # ][ # # ]
[ # # ]
345 [ + - ][ + - ]: 39 : case 'A': InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD ) ); break; // table name
[ + - ][ + - ]
[ + - ]
346 : :
347 : : case 'Z': // file path
348 [ # # ][ # # ]: 0 : InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD ) ); // convert to full name
[ # # ][ # # ]
[ # # ]
349 [ # # ][ # # ]: 0 : if( (pNull - pChar >= 2) && (*(pChar + 1) == '&') && (*(pChar + 2) == 'F') )
[ # # ]
350 : : {
351 : : // &Z&F found - ignore the &F part
352 : 0 : pChar += 2;
353 : : }
354 : 0 : break;
355 : : case 'F': // file name
356 [ + - ][ + - ]: 3 : InsertField( SvxFieldItem( SvxExtFileField( EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ), EE_FEATURE_FIELD ) );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
357 : 3 : break;
358 : :
359 : : case 'U': // underline
360 [ # # ]: 0 : SetAttribs();
361 : 0 : mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_SINGLE) ?
362 [ # # ]: 0 : EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_SINGLE;
363 : 0 : break;
364 : : case 'E': // double underline
365 [ # # ]: 0 : SetAttribs();
366 : 0 : mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_DOUBLE) ?
367 [ # # ]: 0 : EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_DOUBLE;
368 : 0 : break;
369 : : case 'S': // strikeout
370 [ # # ]: 0 : SetAttribs();
371 : 0 : mxFontData->mbStrikeout = !mxFontData->mbStrikeout;
372 : 0 : break;
373 : : case 'X': // superscript
374 [ # # ]: 0 : SetAttribs();
375 : 0 : mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUPER) ?
376 [ # # ]: 0 : EXC_FONTESC_NONE : EXC_FONTESC_SUPER;
377 : 0 : break;
378 : : case 'Y': // subsrcipt
379 [ # # ]: 0 : SetAttribs();
380 : 0 : mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUB) ?
381 [ # # ]: 0 : EXC_FONTESC_NONE : EXC_FONTESC_SUB;
382 : 0 : break;
383 : :
384 : : case '\"': // font name
385 [ + - ]: 6 : aReadFont.Erase();
386 [ + - ]: 6 : aReadStyle.Erase();
387 : 6 : eState = xlPSFont;
388 : 6 : break;
389 : : default:
390 [ + - ][ + - ]: 6 : if( ('0' <= *pChar) && (*pChar <= '9') ) // font size
391 : : {
392 : 6 : nReadHeight = *pChar - '0';
393 : 6 : eState = xlPSHeight;
394 : : }
395 : : }
396 : : }
397 : 186 : break;
398 : :
399 : : // --- read font name ---
400 : :
401 : : case xlPSFont:
402 : : {
403 [ - + + ]: 96 : switch( *pChar )
404 : : {
405 : : case '\"':
406 : 0 : --pChar;
407 : : // run through
408 : : case ',':
409 : 6 : eState = xlPSFontStyle;
410 : 6 : break;
411 : : default:
412 [ + - ]: 90 : aReadFont += *pChar;
413 : : }
414 : : }
415 : 96 : break;
416 : :
417 : : // --- read font style ---
418 : :
419 : : case xlPSFontStyle:
420 : : {
421 [ + + ]: 48 : switch( *pChar )
422 : : {
423 : : case '\"':
424 [ + - ]: 6 : SetAttribs();
425 [ + - ]: 6 : if( aReadFont.Len() )
426 [ + - ]: 6 : mxFontData->maName = aReadFont;
427 [ + - ]: 6 : mxFontData->maStyle = aReadStyle;
428 : 6 : eState = xlPSText;
429 : 6 : break;
430 : : default:
431 [ + - ]: 42 : aReadStyle += *pChar;
432 : : }
433 : : }
434 : 48 : break;
435 : :
436 : : // --- read font height ---
437 : :
438 : : case xlPSHeight:
439 : : {
440 [ + + ][ + + ]: 12 : if( ('0' <= *pChar) && (*pChar <= '9') )
441 : : {
442 [ + - ]: 12 : if( nReadHeight != 0xFFFF )
443 : : {
444 : 6 : nReadHeight *= 10;
445 : 6 : nReadHeight += (*pChar - '0');
446 [ - + ]: 6 : if( nReadHeight > 1600 ) // max 1600pt = 32000twips
447 : 0 : nReadHeight = 0xFFFF;
448 : : }
449 : : }
450 : : else
451 : : {
452 [ + - ][ + - ]: 6 : if( (nReadHeight != 0) && (nReadHeight != 0xFFFF) )
453 : : {
454 [ + - ]: 6 : SetAttribs();
455 : 6 : mxFontData->mnHeight = nReadHeight * 20;
456 : : }
457 : 6 : --pChar;
458 : 6 : eState = xlPSText;
459 : : }
460 : : }
461 : 12 : break;
462 : : }
463 : 900 : ++pChar;
464 : : }
465 : :
466 : : // finalize
467 [ + - ]: 90 : CreateCurrObject();
468 [ + - ]: 90 : maInfos[ EXC_HF_LEFT ].mnHeight += GetMaxLineHeight( EXC_HF_LEFT );
469 [ + - ]: 90 : maInfos[ EXC_HF_CENTER ].mnHeight += GetMaxLineHeight( EXC_HF_CENTER );
470 [ + - ][ + - ]: 90 : maInfos[ EXC_HF_RIGHT ].mnHeight += GetMaxLineHeight( EXC_HF_RIGHT );
[ + - ]
471 : 90 : }
472 : :
473 : 180 : void XclImpHFConverter::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const
474 : : {
475 [ + - ]: 180 : ScPageHFItem aHFItem( nWhichId );
476 [ + + ]: 180 : if( maInfos[ EXC_HF_LEFT ].mxObj.get() )
477 [ + - ]: 12 : aHFItem.SetLeftArea( *maInfos[ EXC_HF_LEFT ].mxObj );
478 [ + - ]: 180 : if( maInfos[ EXC_HF_CENTER ].mxObj.get() )
479 [ + - ]: 180 : aHFItem.SetCenterArea( *maInfos[ EXC_HF_CENTER ].mxObj );
480 [ + + ]: 180 : if( maInfos[ EXC_HF_RIGHT ].mxObj.get() )
481 [ + - ]: 6 : aHFItem.SetRightArea( *maInfos[ EXC_HF_RIGHT ].mxObj );
482 [ + - ][ + - ]: 180 : rItemSet.Put( aHFItem );
483 : 180 : }
484 : :
485 : 90 : sal_Int32 XclImpHFConverter::GetTotalHeight() const
486 : : {
487 : 90 : return ::std::max( maInfos[ EXC_HF_LEFT ].mnHeight,
488 : 180 : ::std::max( maInfos[ EXC_HF_CENTER ].mnHeight, maInfos[ EXC_HF_RIGHT ].mnHeight ) );
489 : : }
490 : :
491 : : // private --------------------------------------------------------------------
492 : :
493 : 270 : sal_uInt16 XclImpHFConverter::GetMaxLineHeight( XclImpHFPortion ePortion ) const
494 : : {
495 : 270 : sal_uInt16 nMaxHt = maInfos[ ePortion ].mnMaxLineHt;
496 [ + + ]: 270 : return (nMaxHt == 0) ? mxFontData->mnHeight : nMaxHt;
497 : : }
498 : :
499 : 0 : sal_uInt16 XclImpHFConverter::GetCurrMaxLineHeight() const
500 : : {
501 : 0 : return GetMaxLineHeight( meCurrObj );
502 : : }
503 : :
504 : 132 : void XclImpHFConverter::UpdateMaxLineHeight( XclImpHFPortion ePortion )
505 : : {
506 : 132 : sal_uInt16& rnMaxHt = maInfos[ ePortion ].mnMaxLineHt;
507 : 132 : rnMaxHt = ::std::max( rnMaxHt, mxFontData->mnHeight );
508 : 132 : }
509 : :
510 : 132 : void XclImpHFConverter::UpdateCurrMaxLineHeight()
511 : : {
512 : 132 : UpdateMaxLineHeight( meCurrObj );
513 : 132 : }
514 : :
515 : 111 : void XclImpHFConverter::SetAttribs()
516 : : {
517 : 111 : ESelection& rSel = GetCurrSel();
518 [ + + ][ + - ]: 111 : if( (rSel.nStartPara != rSel.nEndPara) || (rSel.nStartPos != rSel.nEndPos) )
519 : : {
520 [ + - ][ + - ]: 93 : SfxItemSet aItemSet( mrEE.GetEmptyItemSet() );
521 [ + - ]: 93 : XclImpFont aFont( GetRoot(), *mxFontData );
522 [ + - ]: 93 : aFont.FillToItemSet( aItemSet, EXC_FONTITEM_HF );
523 [ + - ]: 93 : mrEE.QuickSetAttribs( aItemSet, rSel );
524 : 93 : rSel.nStartPara = rSel.nEndPara;
525 [ + - ][ + - ]: 93 : rSel.nStartPos = rSel.nEndPos;
526 : : }
527 : 111 : }
528 : :
529 : 99 : void XclImpHFConverter::ResetFontData()
530 : : {
531 [ + - ]: 99 : if( const XclImpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
532 : 99 : *mxFontData = pFirstFont->GetFontData();
533 : : else
534 : : {
535 : 0 : mxFontData->Clear();
536 : 0 : mxFontData->mnHeight = 200;
537 : : }
538 : 99 : }
539 : :
540 : 285 : void XclImpHFConverter::InsertText()
541 : : {
542 [ + + ]: 285 : if( maCurrText.Len() )
543 : : {
544 : 45 : ESelection& rSel = GetCurrSel();
545 [ + - ]: 45 : mrEE.QuickInsertText( maCurrText, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
546 : 45 : rSel.nEndPos = rSel.nEndPos + maCurrText.Len();
547 : 45 : maCurrText.Erase();
548 : 45 : UpdateCurrMaxLineHeight();
549 : : }
550 : 285 : }
551 : :
552 : 87 : void XclImpHFConverter::InsertField( const SvxFieldItem& rFieldItem )
553 : : {
554 : 87 : ESelection& rSel = GetCurrSel();
555 [ + - ]: 87 : mrEE.QuickInsertField( rFieldItem, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
556 : 87 : ++rSel.nEndPos;
557 : 87 : UpdateCurrMaxLineHeight();
558 : 87 : }
559 : :
560 : 0 : void XclImpHFConverter::InsertLineBreak()
561 : : {
562 : 0 : ESelection& rSel = GetCurrSel();
563 [ # # ][ # # ]: 0 : mrEE.QuickInsertText( rtl::OUString('\n'), ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
[ # # ]
564 : 0 : ++rSel.nEndPara;
565 : 0 : rSel.nEndPos = 0;
566 : 0 : GetCurrInfo().mnHeight += GetCurrMaxLineHeight();
567 : 0 : GetCurrInfo().mnMaxLineHt = 0;
568 : 0 : }
569 : :
570 : 99 : void XclImpHFConverter::CreateCurrObject()
571 : : {
572 : 99 : InsertText();
573 : 99 : SetAttribs();
574 : 99 : GetCurrObj().reset( mrEE.CreateTextObject() );
575 : 99 : }
576 : :
577 : 87 : void XclImpHFConverter::SetNewPortion( XclImpHFPortion eNew )
578 : : {
579 [ + + ]: 87 : if( eNew != meCurrObj )
580 : : {
581 : 9 : CreateCurrObject();
582 : 9 : meCurrObj = eNew;
583 [ - + ]: 9 : if( GetCurrObj().get() )
584 : 0 : mrEE.SetText( *GetCurrObj() );
585 : : else
586 : 9 : mrEE.SetText( EMPTY_STRING );
587 : 9 : ResetFontData();
588 : : }
589 : 87 : }
590 : :
591 : : // URL conversion =============================================================
592 : :
593 : : namespace {
594 : :
595 : 0 : void lclAppendUrlChar( String& rUrl, sal_Unicode cChar )
596 : : {
597 : : // encode special characters
598 [ # # # ]: 0 : switch( cChar )
599 : : {
600 : 0 : case '#': rUrl.AppendAscii( "%23" ); break;
601 : 0 : case '%': rUrl.AppendAscii( "%25" ); break;
602 : 0 : default: rUrl.Append( cChar );
603 : : }
604 : 0 : }
605 : :
606 : : } // namespace
607 : :
608 : 3 : void XclImpUrlHelper::DecodeUrl(
609 : : String& rUrl, String& rTabName, bool& rbSameWb,
610 : : const XclImpRoot& rRoot, const String& rEncodedUrl )
611 : : {
612 : : enum
613 : : {
614 : : xlUrlInit, /// Initial state, read string mode character.
615 : : xlUrlPath, /// Read URL path.
616 : : xlUrlFileName, /// Read file name.
617 : : xlUrlSheetName, /// Read sheet name.
618 : : xlUrlRaw /// Raw mode. No control characters will occur.
619 : 3 : } eState = xlUrlInit;
620 : :
621 : 3 : bool bEncoded = true;
622 : 3 : rbSameWb = false;
623 : :
624 : 3 : sal_Unicode cCurrDrive = 0;
625 [ + - ][ + - ]: 3 : String aDosBase( INetURLObject( rRoot.GetBasePath() ).getFSysPath( INetURLObject::FSYS_DOS ) );
[ + - ][ + - ]
[ + - ]
626 [ + - ][ - + ]: 3 : if( (aDosBase.Len() > 2) && aDosBase.EqualsAscii( ":\\", 1, 2 ) )
[ - + ][ + - ]
627 : 0 : cCurrDrive = aDosBase.GetChar( 0 );
628 : :
629 : 3 : const sal_Unicode* pChar = rEncodedUrl.GetBuffer();
630 [ + + ]: 24 : while( *pChar )
631 : : {
632 [ + - - + : 21 : switch( eState )
- - ]
633 : : {
634 : :
635 : : // --- first character ---
636 : :
637 : : case xlUrlInit:
638 : : {
639 [ - + - - ]: 3 : switch( *pChar )
640 : : {
641 : : case EXC_URLSTART_ENCODED:
642 : 0 : eState = xlUrlPath;
643 : 0 : break;
644 : : case EXC_URLSTART_SELF:
645 : : case EXC_URLSTART_SELFENCODED:
646 : 3 : rbSameWb = true;
647 : 3 : eState = xlUrlSheetName;
648 : 3 : break;
649 : : case '[':
650 : 0 : bEncoded = false;
651 : 0 : eState = xlUrlFileName;
652 : 0 : break;
653 : : default:
654 : 0 : bEncoded = false;
655 [ # # ]: 0 : lclAppendUrlChar( rUrl, *pChar );
656 : 0 : eState = xlUrlPath;
657 : : }
658 : : }
659 : 3 : break;
660 : :
661 : : // --- URL path ---
662 : :
663 : : case xlUrlPath:
664 : : {
665 [ # # # # : 0 : switch( *pChar )
# # # ]
666 : : {
667 : : case EXC_URL_DOSDRIVE:
668 : : {
669 [ # # ]: 0 : if( *(pChar + 1) )
670 : : {
671 : 0 : ++pChar;
672 [ # # ]: 0 : if( *pChar == '@' )
673 [ # # ]: 0 : rUrl.AppendAscii( "\\\\" );
674 : : else
675 : : {
676 [ # # ]: 0 : lclAppendUrlChar( rUrl, *pChar );
677 [ # # ]: 0 : rUrl.AppendAscii( ":\\" );
678 : : }
679 : : }
680 : : else
681 [ # # ]: 0 : rUrl.AppendAscii( "<NULL-DRIVE!>" );
682 : : }
683 : 0 : break;
684 : : case EXC_URL_DRIVEROOT:
685 [ # # ]: 0 : if( cCurrDrive )
686 : : {
687 [ # # ]: 0 : lclAppendUrlChar( rUrl, cCurrDrive );
688 [ # # ]: 0 : rUrl.Append( ':' );
689 : : }
690 : : // run through
691 : : case EXC_URL_SUBDIR:
692 [ # # ]: 0 : if( bEncoded )
693 [ # # ]: 0 : rUrl.Append( '\\' );
694 : : else // control character in raw name -> DDE link
695 : : {
696 [ # # ]: 0 : rUrl.Append( EXC_DDE_DELIM );
697 : 0 : eState = xlUrlRaw;
698 : : }
699 : 0 : break;
700 : : case EXC_URL_PARENTDIR:
701 [ # # ]: 0 : rUrl.AppendAscii( "..\\" );
702 : 0 : break;
703 : : case EXC_URL_RAW:
704 : : {
705 [ # # ]: 0 : if( *(pChar + 1) )
706 : : {
707 : 0 : xub_StrLen nLen = *++pChar;
708 [ # # ][ # # ]: 0 : for( xub_StrLen nChar = 0; (nChar < nLen) && *(pChar + 1); ++nChar )
[ # # ]
709 [ # # ]: 0 : lclAppendUrlChar( rUrl, *++pChar );
710 : : // rUrl.Append( ':' );
711 : : }
712 : : }
713 : 0 : break;
714 : : case '[':
715 : 0 : eState = xlUrlFileName;
716 : 0 : break;
717 : : default:
718 [ # # ]: 0 : lclAppendUrlChar( rUrl, *pChar );
719 : : }
720 : : }
721 : 0 : break;
722 : :
723 : : // --- file name ---
724 : :
725 : : case xlUrlFileName:
726 : : {
727 [ # # ]: 0 : switch( *pChar )
728 : : {
729 : 0 : case ']': eState = xlUrlSheetName; break;
730 [ # # ]: 0 : default: lclAppendUrlChar( rUrl, *pChar );
731 : : }
732 : : }
733 : 0 : break;
734 : :
735 : : // --- sheet name ---
736 : :
737 : : case xlUrlSheetName:
738 [ + - ]: 18 : rTabName.Append( *pChar );
739 : 18 : break;
740 : :
741 : : // --- raw read mode ---
742 : :
743 : : case xlUrlRaw:
744 [ # # ]: 0 : lclAppendUrlChar( rUrl, *pChar );
745 : 0 : break;
746 : : }
747 : :
748 : 21 : ++pChar;
749 [ + - ]: 3 : }
750 : 3 : }
751 : :
752 : 0 : void XclImpUrlHelper::DecodeUrl(
753 : : String& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const String& rEncodedUrl )
754 : : {
755 [ # # ]: 0 : String aTabName;
756 [ # # ]: 0 : DecodeUrl( rUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
757 [ # # ]: 0 : OSL_ENSURE( !aTabName.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
758 : 0 : }
759 : :
760 : 0 : void XclImpUrlHelper::DecodeUrl(
761 : : ::rtl::OUString& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const ::rtl::OUString& rEncodedUrl )
762 : : {
763 [ # # ]: 0 : String aTabName;
764 [ # # ]: 0 : String aUrl;
765 [ # # ][ # # ]: 0 : DecodeUrl( aUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
[ # # ]
766 [ # # ]: 0 : rUrl = aUrl;
767 [ # # ][ # # ]: 0 : OSL_ENSURE( !aTabName.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
768 : 0 : }
769 : :
770 : 0 : bool XclImpUrlHelper::DecodeLink( String& rApplic, String& rTopic, const String rEncUrl )
771 : : {
772 : 0 : xub_StrLen nPos = rEncUrl.Search( EXC_DDE_DELIM );
773 [ # # ][ # # ]: 0 : if( (nPos != STRING_NOTFOUND) && (0 < nPos) && (nPos + 1 < rEncUrl.Len()) )
[ # # ][ # # ]
774 : : {
775 [ # # ]: 0 : rApplic = rEncUrl.Copy( 0, nPos );
776 [ # # ]: 0 : rTopic = rEncUrl.Copy( nPos + 1 );
777 : 0 : return true;
778 : : }
779 : 0 : return false;
780 : : }
781 : :
782 : : // Cached Values ==============================================================
783 : :
784 : 0 : XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm ) :
785 : : mfValue( 0.0 ),
786 : 0 : mnBoolErr( 0 )
787 : : {
788 [ # # ]: 0 : rStrm >> mnType;
789 [ # # # # : 0 : switch( mnType )
# ]
790 : : {
791 : : case EXC_CACHEDVAL_EMPTY:
792 [ # # ]: 0 : rStrm.Ignore( 8 );
793 : 0 : break;
794 : : case EXC_CACHEDVAL_DOUBLE:
795 [ # # ]: 0 : rStrm >> mfValue;
796 : 0 : break;
797 : : case EXC_CACHEDVAL_STRING:
798 [ # # ][ # # ]: 0 : mxStr.reset( new String( rStrm.ReadUniString() ) );
799 : 0 : break;
800 : : case EXC_CACHEDVAL_BOOL:
801 : : case EXC_CACHEDVAL_ERROR:
802 : : {
803 : : double fVal;
804 [ # # ]: 0 : rStrm >> mnBoolErr;
805 [ # # ]: 0 : rStrm.Ignore( 7 );
806 : :
807 [ # # ]: 0 : const ScTokenArray* pScTokArr = rStrm.GetRoot().GetOldFmlaConverter().GetBoolErr(
808 [ # # ][ # # ]: 0 : XclTools::ErrorToEnum( fVal, mnType == EXC_CACHEDVAL_ERROR, mnBoolErr ) );
809 [ # # ]: 0 : if( pScTokArr )
810 [ # # ]: 0 : mxTokArr.reset( pScTokArr->Clone() );
811 : : }
812 : 0 : break;
813 : : default:
814 : : OSL_FAIL( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
815 : : }
816 : 0 : }
817 : :
818 [ # # ][ # # ]: 0 : XclImpCachedValue::~XclImpCachedValue()
819 : : {
820 [ # # ]: 0 : }
821 : :
822 : 0 : sal_uInt16 XclImpCachedValue::GetScError() const
823 : : {
824 [ # # ]: 0 : return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : 0;
825 : : }
826 : :
827 : : // Matrix Cached Values ==============================================================
828 : :
829 : 0 : XclImpCachedMatrix::XclImpCachedMatrix( XclImpStream& rStrm ) :
830 : : mnScCols( 0 ),
831 : 0 : mnScRows( 0 )
832 : : {
833 [ # # ]: 0 : mnScCols = rStrm.ReaduInt8();
834 [ # # ]: 0 : mnScRows = rStrm.ReaduInt16();
835 : :
836 [ # # ]: 0 : if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
837 : : {
838 : : // in BIFF2-BIFF7: 256 columns represented by 0 columns
839 [ # # ]: 0 : if( mnScCols == 0 )
840 : 0 : mnScCols = 256;
841 : : }
842 : : else
843 : : {
844 : : // in BIFF8: columns and rows decreaed by 1
845 : 0 : ++mnScCols;
846 : 0 : ++mnScRows;
847 : : }
848 : :
849 [ # # ]: 0 : for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
850 [ # # ]: 0 : for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
851 [ # # ][ # # ]: 0 : maValueList.push_back( new XclImpCachedValue( rStrm ) );
[ # # ]
852 : 0 : }
853 : :
854 : 0 : XclImpCachedMatrix::~XclImpCachedMatrix()
855 : : {
856 : 0 : }
857 : :
858 : 0 : ScMatrixRef XclImpCachedMatrix::CreateScMatrix() const
859 : : {
860 : 0 : ScMatrixRef xScMatrix;
861 : : OSL_ENSURE( mnScCols * mnScRows == maValueList.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
862 [ # # ][ # # ]: 0 : if( mnScCols && mnScRows && static_cast< sal_uLong >( mnScCols * mnScRows ) <= maValueList.size() )
[ # # ][ # # ]
863 : : {
864 [ # # ][ # # ]: 0 : xScMatrix = new ScMatrix(mnScCols, mnScRows, 0.0);
[ # # ]
865 [ # # ]: 0 : XclImpValueList::const_iterator itValue = maValueList.begin();
866 [ # # ]: 0 : for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
867 : : {
868 [ # # ]: 0 : for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
869 : : {
870 [ # # ][ # # : 0 : switch( itValue->GetType() )
# # # # ]
871 : : {
872 : : case EXC_CACHEDVAL_EMPTY:
873 : : // Excel shows 0.0 here, not an empty cell
874 [ # # ]: 0 : xScMatrix->PutEmpty( nScCol, nScRow );
875 : 0 : break;
876 : : case EXC_CACHEDVAL_DOUBLE:
877 [ # # ][ # # ]: 0 : xScMatrix->PutDouble( itValue->GetValue(), nScCol, nScRow );
878 : 0 : break;
879 : : case EXC_CACHEDVAL_STRING:
880 [ # # ][ # # ]: 0 : xScMatrix->PutString( itValue->GetString(), nScCol, nScRow );
[ # # ][ # # ]
881 : 0 : break;
882 : : case EXC_CACHEDVAL_BOOL:
883 [ # # ][ # # ]: 0 : xScMatrix->PutBoolean( itValue->GetBool(), nScCol, nScRow );
884 : 0 : break;
885 : : case EXC_CACHEDVAL_ERROR:
886 [ # # ][ # # ]: 0 : xScMatrix->PutError( itValue->GetScError(), nScCol, nScRow );
[ # # ]
887 : 0 : break;
888 : : default:
889 : : OSL_FAIL( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
890 [ # # ]: 0 : xScMatrix->PutEmpty( nScCol, nScRow );
891 : : }
892 [ # # ]: 0 : ++itValue;
893 : : }
894 : : }
895 : : }
896 : 0 : return xScMatrix;
897 : : }
898 : :
899 : : // ============================================================================
900 : :
901 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|