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 "scitems.hxx"
30 : : #include <editeng/eeitem.hxx>
31 : :
32 : :
33 : : #include <editeng/adjitem.hxx>
34 : : #include <editeng/editobj.hxx>
35 : : #include <editeng/editview.hxx>
36 : : #include <editeng/escpitem.hxx>
37 : : #include <editeng/langitem.hxx>
38 : : #include <svx/svdograf.hxx>
39 : : #include <svx/svdpage.hxx>
40 : : #include <editeng/scripttypeitem.hxx>
41 : : #include <svtools/htmlcfg.hxx>
42 : : #include <sfx2/sfxhtml.hxx>
43 : : #include <svtools/parhtml.hxx>
44 : : #include <svl/zforlist.hxx>
45 : : #include <vcl/virdev.hxx>
46 : : #include <vcl/svapp.hxx>
47 : : #include <unotools/syslocale.hxx>
48 : : #include <unotools/charclass.hxx>
49 : : #include <comphelper/string.hxx>
50 : :
51 : : #include "eeimport.hxx"
52 : : #include "global.hxx"
53 : : #include "document.hxx"
54 : : #include "editutil.hxx"
55 : : #include "stlsheet.hxx"
56 : : #include "docpool.hxx"
57 : : #include "attrib.hxx"
58 : : #include "patattr.hxx"
59 : : #include "cell.hxx"
60 : : #include "eeparser.hxx"
61 : : #include "drwlayer.hxx"
62 : : #include "rangenam.hxx"
63 : : #include "progress.hxx"
64 : : #include "stringutil.hxx"
65 : :
66 : : #include "globstr.hrc"
67 : :
68 : : // in fuins1.cxx
69 : : extern void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage );
70 : :
71 : : //------------------------------------------------------------------------
72 : :
73 : 3 : ScEEImport::ScEEImport( ScDocument* pDocP, const ScRange& rRange ) :
74 : : maRange( rRange ),
75 : : mpDoc( pDocP ),
76 [ + - ]: 3 : mpParser( NULL )
77 : : {
78 : : const ScPatternAttr* pPattern = mpDoc->GetPattern(
79 [ + - ]: 3 : maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
80 [ + - ][ + - ]: 3 : mpEngine = new ScTabEditEngine( *pPattern, mpDoc->GetEditPool() );
[ + - ]
81 [ + - ]: 3 : mpEngine->SetUpdateMode( false );
82 [ + - ]: 3 : mpEngine->EnableUndo( false );
83 : 3 : }
84 : :
85 : :
86 : 3 : ScEEImport::~ScEEImport()
87 : : {
88 : : // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
89 : : // Ist gewaehrleistet, da ScEEImport Basisklasse ist
90 [ + - ][ + - ]: 3 : delete mpEngine; // nach Parser!
91 [ - + ]: 3 : }
92 : :
93 : :
94 : 3 : sal_uLong ScEEImport::Read( SvStream& rStream, const String& rBaseURL )
95 : : {
96 [ + - ]: 3 : sal_uLong nErr = mpParser->Read( rStream, rBaseURL );
97 : :
98 : : SCCOL nEndCol;
99 : : SCROW nEndRow;
100 : 3 : mpParser->GetDimensions( nEndCol, nEndRow );
101 [ + - ]: 3 : if ( nEndCol != 0 )
102 : : {
103 : 3 : nEndCol += maRange.aStart.Col() - 1;
104 [ - + ]: 3 : if ( nEndCol > MAXCOL )
105 : 0 : nEndCol = MAXCOL;
106 : : }
107 : : else
108 : 0 : nEndCol = maRange.aStart.Col();
109 [ + - ]: 3 : if ( nEndRow != 0 )
110 : : {
111 : 3 : nEndRow += maRange.aStart.Row() - 1;
112 [ - + ]: 3 : if ( nEndRow > MAXROW )
113 : 0 : nEndRow = MAXROW;
114 : : }
115 : : else
116 : 0 : nEndRow = maRange.aStart.Row();
117 : 3 : maRange.aEnd.Set( nEndCol, nEndRow, maRange.aStart.Tab() );
118 : :
119 : 3 : return nErr;
120 : : }
121 : :
122 : :
123 : 3 : void ScEEImport::WriteToDocument( bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
124 : : {
125 : 3 : ScProgress* pProgress = new ScProgress( mpDoc->GetDocumentShell(),
126 [ + - ]: 3 : ScGlobal::GetRscString( STR_LOAD_DOC ), mpParser->ListSize() );
127 : 3 : sal_uLong nProgress = 0;
128 : :
129 : : SCCOL nStartCol, nEndCol;
130 : : SCROW nStartRow, nEndRow;
131 : : SCTAB nTab;
132 : : SCROW nOverlapRowMax, nLastMergedRow;
133 : : SCCOL nMergeColAdd;
134 : 3 : nStartCol = maRange.aStart.Col();
135 : 3 : nStartRow = maRange.aStart.Row();
136 : 3 : nTab = maRange.aStart.Tab();
137 : 3 : nEndCol = maRange.aEnd.Col();
138 : 3 : nEndRow = maRange.aEnd.Row();
139 : 3 : nOverlapRowMax = 0;
140 : 3 : nMergeColAdd = 0;
141 : 3 : nLastMergedRow = SCROW_MAX;
142 : 3 : sal_Bool bHasGraphics = false;
143 : : ScEEParseEntry* pE;
144 [ - + ]: 3 : if (!pFormatter)
145 : 0 : pFormatter = mpDoc->GetFormatTable();
146 : 3 : bool bNumbersEnglishUS = false;
147 [ + - ]: 3 : if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM)
148 : : {
149 : : // Automatic language option selected. Check for the global 'use US English' option.
150 [ + - ]: 3 : SvxHtmlOptions aOpt;
151 [ + - ][ + - ]: 3 : bNumbersEnglishUS = aOpt.IsNumbersEnglishUS();
152 : : }
153 : 3 : ScDocumentPool* pDocPool = mpDoc->GetPool();
154 : 3 : ScRangeName* pRangeNames = mpDoc->GetRangeName();
155 [ + + ]: 24 : for ( size_t i = 0, n = mpParser->ListSize(); i < n; ++i )
156 : : {
157 : 21 : pE = mpParser->ListEntry( i );
158 : 21 : SCROW nRow = nStartRow + pE->nRow;
159 [ + + ]: 21 : if ( nRow != nLastMergedRow )
160 : 15 : nMergeColAdd = 0;
161 : 21 : SCCOL nCol = nStartCol + pE->nCol + nMergeColAdd;
162 : : // RowMerge feststellen, pures ColMerge und ColMerge der ersten
163 : : // MergeRow bereits beim parsen
164 [ + + ]: 21 : if ( nRow <= nOverlapRowMax )
165 : : {
166 [ + - - + ]: 18 : while ( nCol <= MAXCOL && mpDoc->HasAttrib( nCol, nRow, nTab,
[ - + ]
167 : 9 : nCol, nRow, nTab, HASATTR_OVERLAPPED ) )
168 : : {
169 : 0 : nCol++;
170 : 0 : nMergeColAdd++;
171 : : }
172 : 9 : nLastMergedRow = nRow;
173 : : }
174 : : // fuer zweiten Durchlauf eintragen
175 : 21 : pE->nCol = nCol;
176 : 21 : pE->nRow = nRow;
177 [ + + ][ + - ]: 21 : if ( ValidCol(nCol) && ValidRow(nRow) )
[ + + ]
178 : : {
179 [ + - ]: 18 : SfxItemSet aSet = mpEngine->GetAttribs( pE->aSel );
180 : : // Default raus, wir setzen selber links/rechts je nachdem ob Text
181 : : // oder Zahl; EditView.GetAttribs liefert immer kompletten Set
182 : : // mit Defaults aufgefuellt
183 [ + - ]: 18 : const SfxPoolItem& rItem = aSet.Get( EE_PARA_JUST );
184 [ + - ]: 18 : if ( ((const SvxAdjustItem&)rItem).GetAdjust() == SVX_ADJUST_LEFT )
185 [ + - ]: 18 : aSet.ClearItem( EE_PARA_JUST );
186 : :
187 : : // Testen, ob einfacher String ohne gemischte Attribute
188 : 18 : sal_Bool bSimple = ( pE->aSel.nStartPara == pE->aSel.nEndPara );
189 [ + + ][ + - ]: 558 : for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && bSimple; nId++)
[ + + ]
190 : : {
191 : 540 : const SfxPoolItem* pItem = 0;
192 [ + - ]: 540 : SfxItemState eState = aSet.GetItemState( nId, sal_True, &pItem );
193 [ - + ]: 540 : if (eState == SFX_ITEM_DONTCARE)
194 : 0 : bSimple = false;
195 [ + + ]: 540 : else if (eState == SFX_ITEM_SET)
196 : : {
197 [ + + ]: 522 : if ( nId == EE_CHAR_ESCAPEMENT ) // Hoch-/Tiefstellen immer ueber EE
198 : : {
199 [ + - ][ - + ]: 18 : if ( (SvxEscapement)((const SvxEscapementItem*)pItem)->GetEnumValue()
200 : : != SVX_ESCAPEMENT_OFF )
201 : 0 : bSimple = false;
202 : : }
203 : : }
204 : : }
205 [ + - ]: 18 : if ( bSimple )
206 : : { // Feldbefehle enthalten?
207 [ + - ]: 18 : SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, false );
208 [ + - ][ - + ]: 18 : if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
209 : 0 : bSimple = false;
210 : : }
211 : :
212 : : // HTML
213 : 18 : rtl::OUString aValStr, aNumStr;
214 : : double fVal;
215 : 18 : sal_uInt32 nNumForm = 0;
216 : 18 : LanguageType eNumLang = LANGUAGE_NONE;
217 [ - + ]: 18 : if ( pE->pNumStr )
218 : : { // SDNUM muss sein wenn SDVAL
219 : 0 : aNumStr = *pE->pNumStr;
220 [ # # ]: 0 : if ( pE->pValStr )
221 : 0 : aValStr = *pE->pValStr;
222 : : fVal = SfxHTMLParser::GetTableDataOptionsValNum(
223 [ # # ][ # # ]: 0 : nNumForm, eNumLang, aValStr, aNumStr, *pFormatter );
[ # # ][ # # ]
[ # # ]
224 : : }
225 : :
226 : : // Attribute setzen
227 [ + - ]: 18 : ScPatternAttr aAttr( pDocPool );
228 [ + - ]: 18 : aAttr.GetFromEditItemSet( &aSet );
229 : 18 : SfxItemSet& rSet = aAttr.GetItemSet();
230 [ - + ]: 18 : if (!aNumStr.isEmpty())
231 : : {
232 [ # # ][ # # ]: 0 : rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumForm ) );
[ # # ]
233 [ # # ][ # # ]: 0 : rSet.Put( SvxLanguageItem( eNumLang, ATTR_LANGUAGE_FORMAT ) );
[ # # ]
234 : : }
235 : 18 : const SfxItemSet& rESet = pE->aItemSet;
236 [ - + ]: 18 : if ( rESet.Count() )
237 : : {
238 : : const SfxPoolItem* pItem;
239 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_BACKGROUND, false, &pItem) == SFX_ITEM_SET )
240 [ # # ]: 0 : rSet.Put( *pItem );
241 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_BORDER, false, &pItem) == SFX_ITEM_SET )
242 [ # # ]: 0 : rSet.Put( *pItem );
243 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_SHADOW, false, &pItem) == SFX_ITEM_SET )
244 [ # # ]: 0 : rSet.Put( *pItem );
245 : : // HTML
246 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_HOR_JUSTIFY, false, &pItem) == SFX_ITEM_SET )
247 [ # # ]: 0 : rSet.Put( *pItem );
248 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_VER_JUSTIFY, false, &pItem) == SFX_ITEM_SET )
249 [ # # ]: 0 : rSet.Put( *pItem );
250 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_LINEBREAK, false, &pItem) == SFX_ITEM_SET )
251 [ # # ]: 0 : rSet.Put( *pItem );
252 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT_COLOR, false, &pItem) == SFX_ITEM_SET )
253 [ # # ]: 0 : rSet.Put( *pItem );
254 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT_UNDERLINE, false, &pItem) == SFX_ITEM_SET )
255 [ # # ]: 0 : rSet.Put( *pItem );
256 : : // HTML LATIN/CJK/CTL script type dependent
257 : : const SfxPoolItem* pFont;
258 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT, false, &pFont) != SFX_ITEM_SET )
259 : 0 : pFont = 0;
260 : : const SfxPoolItem* pHeight;
261 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT_HEIGHT, false, &pHeight) != SFX_ITEM_SET )
262 : 0 : pHeight = 0;
263 : : const SfxPoolItem* pWeight;
264 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT_WEIGHT, false, &pWeight) != SFX_ITEM_SET )
265 : 0 : pWeight = 0;
266 : : const SfxPoolItem* pPosture;
267 [ # # ][ # # ]: 0 : if ( rESet.GetItemState( ATTR_FONT_POSTURE, false, &pPosture) != SFX_ITEM_SET )
268 : 0 : pPosture = 0;
269 : : // Number format
270 : 0 : const SfxPoolItem* pNumFmt = NULL;
271 [ # # ][ # # ]: 0 : if ( rESet.GetItemState(ATTR_VALUE_FORMAT, false, &pNumFmt) == SFX_ITEM_SET )
272 [ # # ]: 0 : rSet.Put(*pNumFmt);
273 [ # # ][ # # ]: 0 : if ( pFont || pHeight || pWeight || pPosture )
[ # # ][ # # ]
274 : : {
275 [ # # ]: 0 : String aStr( mpEngine->GetText( pE->aSel ) );
276 [ # # ][ # # ]: 0 : sal_uInt8 nScriptType = mpDoc->GetStringScriptType( aStr );
277 : : const sal_uInt8 nScripts[3] = { SCRIPTTYPE_LATIN,
278 : 0 : SCRIPTTYPE_ASIAN, SCRIPTTYPE_COMPLEX };
279 [ # # ]: 0 : for ( sal_uInt8 j=0; j<3; ++j )
280 : : {
281 [ # # ]: 0 : if ( nScriptType & nScripts[j] )
282 : : {
283 [ # # ]: 0 : if ( pFont )
284 : : rSet.Put( *pFont, ScGlobal::GetScriptedWhichID(
285 [ # # ][ # # ]: 0 : nScripts[j], ATTR_FONT ));
286 [ # # ]: 0 : if ( pHeight )
287 : : rSet.Put( *pHeight, ScGlobal::GetScriptedWhichID(
288 [ # # ][ # # ]: 0 : nScripts[j], ATTR_FONT_HEIGHT ));
289 [ # # ]: 0 : if ( pWeight )
290 : : rSet.Put( *pWeight, ScGlobal::GetScriptedWhichID(
291 [ # # ][ # # ]: 0 : nScripts[j], ATTR_FONT_WEIGHT ));
292 [ # # ]: 0 : if ( pPosture )
293 : : rSet.Put( *pPosture, ScGlobal::GetScriptedWhichID(
294 [ # # ][ # # ]: 0 : nScripts[j], ATTR_FONT_POSTURE ));
295 : : }
296 [ # # ]: 0 : }
297 : : }
298 : : }
299 [ + - ][ - + ]: 18 : if ( pE->nColOverlap > 1 || pE->nRowOverlap > 1 )
300 : : { // merged cells, mit SfxItemSet Put schneller als mit
301 : : // nachtraeglichem ScDocument DoMerge
302 [ # # ]: 0 : ScMergeAttr aMerge( pE->nColOverlap, pE->nRowOverlap );
303 [ # # ]: 0 : rSet.Put( aMerge );
304 : 0 : SCROW nRO = 0;
305 [ # # ]: 0 : if ( pE->nColOverlap > 1 )
306 : : mpDoc->ApplyFlagsTab( nCol+1, nRow,
307 : : nCol + pE->nColOverlap - 1, nRow, nTab,
308 [ # # ]: 0 : SC_MF_HOR );
309 [ # # ]: 0 : if ( pE->nRowOverlap > 1 )
310 : : {
311 : 0 : nRO = nRow + pE->nRowOverlap - 1;
312 : : mpDoc->ApplyFlagsTab( nCol, nRow+1,
313 : : nCol, nRO , nTab,
314 [ # # ]: 0 : SC_MF_VER );
315 [ # # ]: 0 : if ( nRO > nOverlapRowMax )
316 : 0 : nOverlapRowMax = nRO;
317 : : }
318 [ # # ][ # # ]: 0 : if ( pE->nColOverlap > 1 && pE->nRowOverlap > 1 )
319 : : mpDoc->ApplyFlagsTab( nCol+1, nRow+1,
320 : : nCol + pE->nColOverlap - 1, nRO, nTab,
321 [ # # ][ # # ]: 0 : SC_MF_HOR | SC_MF_VER );
322 : : }
323 : : const ScStyleSheet* pStyleSheet =
324 [ + - ]: 18 : mpDoc->GetPattern( nCol, nRow, nTab )->GetStyleSheet();
325 [ + - ]: 18 : aAttr.SetStyleSheet( (ScStyleSheet*)pStyleSheet );
326 [ + - ]: 18 : mpDoc->SetPattern( nCol, nRow, nTab, aAttr, sal_True );
327 : :
328 : : // Daten eintragen
329 [ + - ]: 18 : if (bSimple)
330 : : {
331 [ + - ]: 18 : ScSetStringParam aParam;
332 : 18 : aParam.mpNumFormatter = pFormatter;
333 : 18 : aParam.mbDetectNumberFormat = true;
334 : 18 : aParam.meSetTextNumFormat = ScSetStringParam::SpecialNumberOnly;
335 : 18 : aParam.mbHandleApostrophe = false;
336 : :
337 [ - + ]: 18 : if (!aValStr.isEmpty())
338 [ # # ]: 0 : mpDoc->SetValue( nCol, nRow, nTab, fVal );
339 [ - + ]: 18 : else if ( !pE->aSel.HasRange() )
340 : : {
341 : : // maybe ALT text of IMG or similar
342 [ # # ]: 0 : mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, &aParam );
343 : : // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen!
344 : : }
345 : : else
346 : : {
347 [ + - ]: 18 : String aStr;
348 [ - + ]: 18 : if( pE->bEntirePara )
349 : : {
350 [ # # ][ # # ]: 0 : aStr = mpEngine->GetText( pE->aSel.nStartPara );
[ # # ]
351 : : }
352 : : else
353 : : {
354 [ + - ][ + - ]: 18 : aStr = comphelper::string::strip(mpEngine->GetText(pE->aSel), ' ');
[ + - ][ + - ]
[ + - ]
355 : : }
356 : :
357 : 18 : bool bTextFormat = false;
358 : :
359 : 18 : const SfxPoolItem* pNumFmt = NULL;
360 [ + - ][ - + ]: 18 : if (rSet.GetItemState(ATTR_VALUE_FORMAT, false, &pNumFmt) == SFX_ITEM_SET)
361 : : {
362 : 0 : sal_uInt32 nNumFmt = static_cast<const SfxUInt32Item*>(pNumFmt)->GetValue();
363 [ # # ]: 0 : sal_uInt16 nType = pFormatter->GetType(nNumFmt);
364 [ # # ]: 0 : if (nType == NUMBERFORMAT_TEXT)
365 : : // Format is set to Text.
366 : 0 : bTextFormat = true;
367 : : }
368 : :
369 : : // TODO: RTF import should follow the language tag,
370 : : // currently this follows the HTML options for both, HTML
371 : : // and RTF.
372 [ - + ]: 18 : if (bNumbersEnglishUS)
373 : : {
374 [ # # ]: 0 : pFormatter->ChangeIntl( LANGUAGE_ENGLISH_US);
375 [ # # ]: 0 : sal_uInt32 nIndex = pFormatter->GetStandardIndex( LANGUAGE_ENGLISH_US);
376 : 0 : double fEnVal = 0.0;
377 [ # # ][ # # ]: 0 : if (pFormatter->IsNumberFormat( aStr, nIndex, fEnVal))
378 : : {
379 : : sal_uInt32 nNewIndex =
380 : : pFormatter->GetFormatForLanguageIfBuiltIn(
381 [ # # ]: 0 : nIndex, LANGUAGE_SYSTEM);
382 : : OSL_ENSURE( nNewIndex != nIndex, "ScEEImport::WriteToDocument: NumbersEnglishUS not a built-in format?");
383 [ # # ]: 0 : pFormatter->GetInputLineString( fEnVal, nNewIndex, aStr);
384 : : }
385 : : else
386 : 0 : bTextFormat = true;
387 [ # # ]: 0 : pFormatter->ChangeIntl( LANGUAGE_SYSTEM);
388 : : }
389 : :
390 : : // #105460#, #i4180# String cells can't contain tabs or linebreaks
391 : : // -> replace with spaces
392 [ + - ]: 18 : aStr.SearchAndReplaceAll( (sal_Unicode)'\t', (sal_Unicode)' ' );
393 [ + - ]: 18 : aStr.SearchAndReplaceAll( (sal_Unicode)'\n', (sal_Unicode)' ' );
394 : :
395 [ - + ]: 18 : if (bTextFormat)
396 [ # # ][ # # ]: 0 : mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr));
[ # # ][ # # ]
397 : : else
398 : : {
399 : 18 : aParam.mbDetectNumberFormat = bConvertDate;
400 [ + - ][ + - ]: 18 : mpDoc->SetString( nCol, nRow, nTab, aStr, &aParam );
401 [ + - ]: 18 : }
402 : : }
403 : : }
404 : : else
405 : : {
406 [ # # ]: 0 : EditTextObject* pObject = mpEngine->CreateTextObject( pE->aSel );
407 : : mpDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pObject,
408 [ # # ][ # # ]: 0 : mpDoc, mpEngine->GetEditTextObjectPool() ) );
[ # # ][ # # ]
409 [ # # ][ # # ]: 0 : delete pObject;
410 : : }
411 [ - + ]: 18 : if ( pE->maImageList.size() )
412 [ # # ]: 0 : bHasGraphics |= GraphicSize( nCol, nRow, nTab, pE );
413 [ - + ]: 18 : if ( pE->pName )
414 : : { // Anchor Name => RangeName
415 [ # # ][ # # ]: 0 : if (!pRangeNames->findByUpperName(ScGlobal::pCharClass->uppercase(*pE->pName)))
[ # # ]
416 : : {
417 : : ScRangeData* pData = new ScRangeData( mpDoc, *pE->pName,
418 [ # # ][ # # ]: 0 : ScAddress( nCol, nRow, nTab ) );
419 [ # # ]: 0 : pRangeNames->insert( pData );
420 : : }
421 [ + - ][ + - ]: 18 : }
422 : : }
423 : 21 : pProgress->SetStateOnPercent( ++nProgress );
424 : : }
425 [ + - ]: 3 : if ( bSizeColsRows )
426 : : {
427 : : // Spaltenbreiten
428 : 3 : ColWidthsMap& rColWidths = mpParser->GetColWidths();
429 [ - + ]: 3 : if ( !rColWidths.empty() )
430 : : {
431 : 0 : nProgress = 0;
432 [ # # ]: 0 : pProgress->SetState( nProgress, nEndCol - nStartCol + 1 );
433 [ # # ]: 0 : for ( SCCOL nCol = nStartCol; nCol <= nEndCol; nCol++ )
434 : : {
435 : 0 : sal_uInt16 nWidth = 0;
436 [ # # ][ # # ]: 0 : ColWidthsMap::const_iterator it = rColWidths.find( nCol );
437 [ # # ][ # # ]: 0 : if ( it != rColWidths.end() )
[ # # ]
438 [ # # ]: 0 : nWidth = it->second;
439 [ # # ]: 0 : if ( nWidth )
440 [ # # ]: 0 : mpDoc->SetColWidth( nCol, nTab, nWidth );
441 [ # # ]: 0 : pProgress->SetState( ++nProgress );
442 : : }
443 : : }
444 [ + - ][ + - ]: 3 : DELETEZ( pProgress ); // SetOptimalHeight hat seinen eigenen ProgressBar
445 : : // Zeilenhoehen anpassen, Basis 100% Zoom
446 [ + - ]: 3 : Fraction aZoom( 1, 1 );
447 [ + - ]: 3 : double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
448 : 3 : / nOutputFactor; // Faktor ist Drucker zu Bildschirm
449 [ + - ]: 3 : double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
450 [ + - ]: 3 : VirtualDevice aVirtDev;
451 : : mpDoc->SetOptimalHeight( 0, nEndRow, 0,
452 : : static_cast< sal_uInt16 >( ScGlobal::nLastRowHeightExtra ), &aVirtDev,
453 [ + - ]: 3 : nPPTX, nPPTY, aZoom, aZoom, false );
454 [ - + ]: 3 : if ( !maRowHeights.empty() )
455 : : {
456 [ # # ]: 0 : for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow++ )
457 : : {
458 [ # # ][ # # ]: 0 : RowHeightMap::const_iterator it = maRowHeights.find( nRow );
459 [ # # ][ # # ]: 0 : sal_uInt16 nHeight = it == maRowHeights.end() ? 0 : it->second;
[ # # ][ # # ]
460 [ # # ][ # # ]: 0 : if ( nHeight > mpDoc->GetRowHeight( nRow, nTab ) )
461 [ # # ]: 0 : mpDoc->SetRowHeight( nRow, nTab, nHeight );
462 : : }
463 [ + - ]: 3 : }
464 : : }
465 [ - + ]: 3 : if ( bHasGraphics )
466 : : {
467 : : // Grafiken einfuegen
468 [ # # ]: 0 : for ( size_t i = 0, nListSize = mpParser->ListSize(); i < nListSize; ++i )
469 : : {
470 : 0 : pE = mpParser->ListEntry( i );
471 [ # # ]: 0 : if ( !pE->maImageList.empty() )
472 : : {
473 : 0 : SCCOL nCol = pE->nCol;
474 : 0 : SCROW nRow = pE->nRow;
475 [ # # ][ # # ]: 0 : if ( ValidCol(nCol) && ValidRow(nRow) )
[ # # ]
476 : 0 : InsertGraphic( nCol, nRow, nTab, pE );
477 : : }
478 : : }
479 : : }
480 [ - + ]: 3 : if ( pProgress )
481 [ # # ]: 0 : delete pProgress;
482 : 3 : }
483 : :
484 : :
485 : 0 : sal_Bool ScEEImport::GraphicSize( SCCOL nCol, SCROW nRow, SCTAB /*nTab*/, ScEEParseEntry* pE )
486 : : {
487 [ # # ]: 0 : if ( !pE->maImageList.size() )
488 : 0 : return false;
489 : 0 : sal_Bool bHasGraphics = false;
490 [ # # ]: 0 : OutputDevice* pDefaultDev = Application::GetDefaultDevice();
491 : : long nWidth, nHeight;
492 : 0 : nWidth = nHeight = 0;
493 : 0 : sal_Char nDir = nHorizontal;
494 [ # # ]: 0 : for ( sal_uInt32 i = 0; i < pE->maImageList.size() ; ++i )
495 : : {
496 [ # # ]: 0 : ScHTMLImage* pI = &pE->maImageList[ i ];
497 [ # # ]: 0 : if ( pI->pGraphic )
498 : 0 : bHasGraphics = sal_True;
499 : 0 : Size aSizePix = pI->aSize;
500 : 0 : aSizePix.Width() += 2 * pI->aSpace.X();
501 : 0 : aSizePix.Height() += 2 * pI->aSpace.Y();
502 [ # # ][ # # ]: 0 : Size aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_TWIP ) );
[ # # ]
503 [ # # ]: 0 : if ( nDir & nHorizontal )
504 : 0 : nWidth += aLogicSize.Width();
505 [ # # ]: 0 : else if ( nWidth < aLogicSize.Width() )
506 : 0 : nWidth = aLogicSize.Width();
507 [ # # ]: 0 : if ( nDir & nVertical )
508 : 0 : nHeight += aLogicSize.Height();
509 [ # # ]: 0 : else if ( nHeight < aLogicSize.Height() )
510 : 0 : nHeight = aLogicSize.Height();
511 : 0 : nDir = pI->nDir;
512 : : }
513 : : // Spaltenbreiten
514 : 0 : ColWidthsMap& rColWidths = mpParser->GetColWidths();
515 : 0 : long nThisWidth = 0;
516 [ # # ][ # # ]: 0 : ColWidthsMap::const_iterator it = rColWidths.find( nCol );
517 [ # # ][ # # ]: 0 : if ( it != rColWidths.end() )
[ # # ]
518 [ # # ]: 0 : nThisWidth = it->second;
519 : 0 : long nColWidths = nThisWidth;
520 : 0 : SCCOL nColSpanCol = nCol + pE->nColOverlap;
521 [ # # ]: 0 : for ( SCCOL nC = nCol + 1; nC < nColSpanCol; nC++ )
522 : : {
523 [ # # ][ # # ]: 0 : ColWidthsMap::const_iterator it2 = rColWidths.find( nC );
524 [ # # ][ # # ]: 0 : if ( it2 != rColWidths.end() )
[ # # ]
525 [ # # ]: 0 : nColWidths += it2->second;
526 : : }
527 [ # # ]: 0 : if ( nWidth > nColWidths )
528 : : { // Differenz nur in der ersten Spalte eintragen
529 [ # # ]: 0 : rColWidths[ nCol ] = nWidth - nColWidths + nThisWidth;
530 : : }
531 : : // Zeilenhoehen, Differenz auf alle betroffenen Zeilen verteilen
532 : 0 : SCROW nRowSpan = pE->nRowOverlap;
533 : 0 : nHeight /= nRowSpan;
534 [ # # ]: 0 : if ( nHeight == 0 )
535 : 0 : nHeight = 1; // fuer eindeutigen Vergleich
536 [ # # ]: 0 : for ( SCROW nR = nRow; nR < nRow + nRowSpan; nR++ )
537 : : {
538 [ # # ][ # # ]: 0 : RowHeightMap::const_iterator it2 = maRowHeights.find( nR );
539 [ # # ][ # # ]: 0 : long nRowHeight = it2 == maRowHeights.end() ? 0 : it2->second;
[ # # ][ # # ]
540 [ # # ]: 0 : if ( nHeight > nRowHeight )
541 : : {
542 [ # # ]: 0 : maRowHeights[ nR ] = nHeight;
543 : : }
544 : : }
545 : 0 : return bHasGraphics;
546 : : }
547 : :
548 : :
549 : 0 : void ScEEImport::InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab,
550 : : ScEEParseEntry* pE )
551 : : {
552 [ # # ]: 0 : if ( !pE->maImageList.size() )
553 : 0 : return ;
554 [ # # ]: 0 : ScDrawLayer* pModel = mpDoc->GetDrawLayer();
555 [ # # ]: 0 : if (!pModel)
556 : : {
557 [ # # ]: 0 : mpDoc->InitDrawLayer();
558 [ # # ]: 0 : pModel = mpDoc->GetDrawLayer();
559 : : }
560 [ # # ]: 0 : SdrPage* pPage = pModel->GetPage( static_cast<sal_uInt16>(nTab) );
561 [ # # ]: 0 : OutputDevice* pDefaultDev = Application::GetDefaultDevice();
562 : :
563 : : Point aCellInsertPos(
564 [ # # ]: 0 : (long)((double) mpDoc->GetColOffset( nCol, nTab ) * HMM_PER_TWIPS),
565 [ # # ]: 0 : (long)((double) mpDoc->GetRowOffset( nRow, nTab ) * HMM_PER_TWIPS) );
566 : :
567 : 0 : Point aInsertPos( aCellInsertPos );
568 : 0 : Point aSpace;
569 : 0 : Size aLogicSize;
570 : 0 : sal_Char nDir = nHorizontal;
571 [ # # ]: 0 : for ( sal_uInt32 i = 0; i < pE->maImageList.size(); ++i )
572 : : {
573 [ # # ]: 0 : ScHTMLImage* pI = &pE->maImageList[ i ];
574 [ # # ]: 0 : if ( nDir & nHorizontal )
575 : : { // horizontal
576 : 0 : aInsertPos.X() += aLogicSize.Width();
577 : 0 : aInsertPos.X() += aSpace.X();
578 : 0 : aInsertPos.Y() = aCellInsertPos.Y();
579 : : }
580 : : else
581 : : { // vertikal
582 : 0 : aInsertPos.X() = aCellInsertPos.X();
583 : 0 : aInsertPos.Y() += aLogicSize.Height();
584 : 0 : aInsertPos.Y() += aSpace.Y();
585 : : }
586 : : // Offset des Spacings drauf
587 [ # # ][ # # ]: 0 : aSpace = pDefaultDev->PixelToLogic( pI->aSpace, MapMode( MAP_100TH_MM ) );
[ # # ]
588 : 0 : aInsertPos += aSpace;
589 : :
590 : 0 : Size aSizePix = pI->aSize;
591 [ # # ][ # # ]: 0 : aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_100TH_MM ) );
[ # # ]
592 : : // Groesse begrenzen
593 [ # # ][ # # ]: 0 : ::ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
594 : :
595 [ # # ]: 0 : if ( pI->pGraphic )
596 : : {
597 [ # # ]: 0 : Rectangle aRect ( aInsertPos, aLogicSize );
598 [ # # ][ # # ]: 0 : SdrGrafObj* pObj = new SdrGrafObj( *pI->pGraphic, aRect );
599 : : // calling SetGraphicLink here doesn't work
600 [ # # ]: 0 : pObj->SetName( pI->aURL );
601 : :
602 [ # # ]: 0 : pPage->InsertObject( pObj );
603 : :
604 : : // SetGraphicLink has to be used after inserting the object,
605 : : // otherwise an empty graphic is swapped in and the contact stuff crashes.
606 : : // See #i37444#.
607 [ # # ][ # # ]: 0 : pObj->SetGraphicLink( pI->aURL, pI->aFilterName );
[ # # ]
608 : :
609 [ # # ]: 0 : pObj->SetLogicRect( aRect ); // erst nach InsertObject !!!
610 : : }
611 : 0 : nDir = pI->nDir;
612 : : }
613 : : }
614 : :
615 : :
616 : 3 : ScEEParser::ScEEParser( EditEngine* pEditP ) :
617 : : pEdit( pEditP ),
618 : 3 : pPool( EditEngine::CreatePool() ),
619 [ + - ]: 3 : pDocPool( new ScDocumentPool ),
620 : : nLastToken(0),
621 : : nColCnt(0),
622 : : nRowCnt(0),
623 : : nColMax(0),
624 [ + - ]: 6 : nRowMax(0)
625 : : {
626 : : // pPool wird spaeter bei RTFIMP_START dem SvxRTFParser untergejubelt
627 [ + - ]: 3 : pPool->SetSecondaryPool( pDocPool );
628 [ + - ]: 3 : pPool->FreezeIdRanges();
629 [ + - ]: 3 : NewActEntry( NULL );
630 : 3 : }
631 : :
632 : :
633 : 3 : ScEEParser::~ScEEParser()
634 : : {
635 [ + - ][ + - ]: 3 : delete pActEntry;
636 [ + - ]: 3 : if ( !maList.empty() ) maList.clear();
637 : :
638 : : // Pool erst loeschen nachdem die Listen geloescht wurden
639 [ + - ]: 3 : pPool->SetSecondaryPool( NULL );
640 [ + - ]: 3 : SfxItemPool::Free(pDocPool);
641 [ + - ]: 3 : SfxItemPool::Free(pPool);
642 [ - + ]: 3 : }
643 : :
644 : :
645 : 3 : void ScEEParser::NewActEntry( ScEEParseEntry* pE )
646 : : { // neuer freifliegender pActEntry
647 [ + - ]: 3 : pActEntry = new ScEEParseEntry( pPool );
648 [ - + ]: 3 : pActEntry->aSel.nStartPara = (pE ? pE->aSel.nEndPara + 1 : 0);
649 : 3 : pActEntry->aSel.nStartPos = 0;
650 : 3 : }
651 : :
652 : :
653 : :
654 : :
655 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|