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