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