xref: /trunk/main/sc/source/filter/rtf/eeimpars.cxx (revision b77af630)
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_scfilt.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