merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / html / htmlgrin.cxx
blob688ed149a5868dcfa5c9bf3ac1500c105b93209f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlgrin.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include "hintids.hxx"
35 #include <vcl/svapp.hxx>
36 #ifndef _WRKWIN_HXX //autogen
37 #include <vcl/wrkwin.hxx>
38 #endif
39 #include <i18npool/mslangid.hxx>
40 #include <svtools/stritem.hxx>
41 #include <svtools/urihelper.hxx>
42 #include <svx/fhgtitem.hxx>
43 #include <svx/lrspitem.hxx>
44 #include <svx/adjitem.hxx>
45 #include <svx/fhgtitem.hxx>
46 #include <svx/brshitem.hxx>
47 #include <svx/colritem.hxx>
48 #include <svx/boxitem.hxx>
49 #include <svx/ulspitem.hxx>
50 #include <svx/langitem.hxx>
51 #include <svx/scripttypeitem.hxx>
52 #include <sfx2/docfile.hxx>
53 #include <svtools/imap.hxx>
54 #include <svtools/htmltokn.h>
55 #include <svtools/htmlkywd.hxx>
56 #include <svtools/eventcfg.hxx>
58 #include <fmtornt.hxx>
59 #include <fmturl.hxx>
60 #include <fmtanchr.hxx>
61 #include <fmtsrnd.hxx>
62 #include <fmtinfmt.hxx>
63 #include <fmtcntnt.hxx>
64 #include <fmtanchr.hxx>
65 #include <fmtfsize.hxx>
66 #include <fmtinfmt.hxx>
67 #include "frmatr.hxx"
68 #include "charatr.hxx"
69 #include <frmfmt.hxx>
70 #include <charfmt.hxx>
71 #include <docary.hxx>
72 #include <docsh.hxx>
73 #include <pam.hxx>
74 #include <doc.hxx>
75 #include <ndtxt.hxx>
76 #include <shellio.hxx>
77 #include <poolfmt.hxx>
78 #include <IMark.hxx>
79 #include <ndgrf.hxx>
80 #include <htmlnum.hxx>
81 #include <swcss1.hxx>
82 #include <swhtml.hxx>
83 #include <numrule.hxx>
84 #include <boost/shared_ptr.hpp>
86 using namespace ::com::sun::star;
89 HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[] =
91 { OOO_STRING_SVTOOLS_HTML_AL_left, text::HoriOrientation::LEFT },
92 { OOO_STRING_SVTOOLS_HTML_AL_right, text::HoriOrientation::RIGHT },
93 { 0, 0 }
97 HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[] =
99 { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::LINE_TOP },
100 { OOO_STRING_SVTOOLS_HTML_VA_texttop, text::VertOrientation::CHAR_TOP },
101 { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER },
102 { OOO_STRING_SVTOOLS_HTML_AL_center, text::VertOrientation::CENTER },
103 { OOO_STRING_SVTOOLS_HTML_VA_absmiddle, text::VertOrientation::LINE_CENTER },
104 { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::TOP },
105 { OOO_STRING_SVTOOLS_HTML_VA_baseline, text::VertOrientation::TOP },
106 { OOO_STRING_SVTOOLS_HTML_VA_absbottom, text::VertOrientation::LINE_BOTTOM },
107 { 0, 0 }
110 SV_IMPL_PTRARR( ImageMaps, ImageMapPtr )
112 ImageMap *SwHTMLParser::FindImageMap( const String& rName ) const
114 ImageMap *pMap = 0;
116 ASSERT( rName.GetChar(0) != '#', "FindImageName: Name beginnt mit #!" );
118 if( pImageMaps )
120 for( USHORT i=0; i<pImageMaps->Count(); i++ )
122 ImageMap *pIMap = (*pImageMaps)[i];
123 if( rName.EqualsIgnoreCaseAscii( pIMap->GetName() ) )
125 pMap = pIMap;
126 break;
130 return pMap;
133 void SwHTMLParser::ConnectImageMaps()
135 SwNodes& rNds = pDoc->GetNodes();
136 // auf den Start-Node der 1. Section
137 ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 1;
138 ULONG nEndIdx = rNds.GetEndOfAutotext().GetIndex();
140 SwGrfNode* pGrfNd;
141 while( nMissingImgMaps > 0 && nIdx < nEndIdx )
143 SwNode *pNd = rNds[nIdx + 1];
144 if( 0 != (pGrfNd = pNd->GetGrfNode()) )
146 SwFrmFmt *pFmt = pGrfNd->GetFlyFmt();
147 SwFmtURL aURL( pFmt->GetURL() );
148 const ImageMap *pIMap = aURL.GetMap();
149 if( pIMap && pIMap->GetIMapObjectCount()==0 )
151 // Die (leere) Image-Map des Nodes wird entweder
152 // durch die jetzt gefundene Image-Map ersetzt
153 // oder geloescht.
154 ImageMap *pNewIMap =
155 FindImageMap( pIMap->GetName() );
156 aURL.SetMap( pNewIMap );
157 pFmt->SetFmtAttr( aURL );
158 if( !pGrfNd->IsScaleImageMap() )
160 // die Grafikgroesse ist mitlerweile da oder dir
161 // Grafik muss nicht skaliert werden
162 pGrfNd->ScaleImageMap();
164 nMissingImgMaps--; // eine Map weniger suchen
167 nIdx = rNds[nIdx]->EndOfSectionIndex() + 1;
172 /* \f */
174 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
175 sal_Int16 eHoriOri,
176 const SfxItemSet &rCSS1ItemSet,
177 const SvxCSS1PropertyInfo &rCSS1PropInfo,
178 SfxItemSet& rFrmItemSet )
180 const SfxItemSet *pCntnrItemSet = 0;
181 USHORT i = aContexts.Count();
182 while( !pCntnrItemSet && i > nContextStMin )
183 pCntnrItemSet = aContexts[--i]->GetFrmItemSet();
185 if( pCntnrItemSet )
187 // Wenn wir und in einem Container befinden wird die Verankerung
188 // des Containers uebernommen.
189 rFrmItemSet.Put( *pCntnrItemSet );
191 else if( pCSS1Parser->MayBePositioned( rCSS1PropInfo, TRUE ) )
193 // Wenn die Ausrichtung anhand der CSS1-Optionen gesetzt werden kann
194 // werden die benutzt.
195 SetAnchorAndAdjustment( rCSS1ItemSet, rCSS1PropInfo, rFrmItemSet );
197 else
199 // Sonst wird die Ausrichtung entsprechend der normalen HTML-Optionen
200 // gesetzt.
201 SetAnchorAndAdjustment( eVertOri, eHoriOri, rFrmItemSet );
205 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
206 sal_Int16 eHoriOri,
207 SfxItemSet& rFrmSet,
208 BOOL bDontAppend )
210 BOOL bMoveBackward = FALSE;
211 SwFmtAnchor aAnchor( FLY_IN_CNTNT );
212 sal_Int16 eVertRel = text::RelOrientation::FRAME;
214 if( text::HoriOrientation::NONE != eHoriOri )
216 // den Absatz-Einzug bestimmen
217 USHORT nLeftSpace = 0, nRightSpace = 0;
218 short nIndent = 0;
219 GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
221 // Horizonale Ausrichtung und Umlauf bestimmen.
222 sal_Int16 eHoriRel;
223 SwSurround eSurround;
224 switch( eHoriOri )
226 case text::HoriOrientation::LEFT:
227 eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
228 eSurround = SURROUND_RIGHT;
229 break;
230 case text::HoriOrientation::RIGHT:
231 eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
232 eSurround = SURROUND_LEFT;
233 break;
234 case text::HoriOrientation::CENTER: // fuer Tabellen
235 eHoriRel = text::RelOrientation::FRAME;
236 eSurround = SURROUND_NONE;
237 break;
238 default:
239 eHoriRel = text::RelOrientation::FRAME;
240 eSurround = SURROUND_PARALLEL;
241 break;
244 // Einen neuen Absatz aufmachen, wenn der aktuelle
245 // absatzgebundene Rahmen ohne Umlauf enthaelt.
246 if( !bDontAppend && HasCurrentParaFlys( TRUE ) )
248 // Wenn der Absatz nur Grafiken enthaelt, braucht er
249 // auch keinen unteren Absatz-Abstand. Da hier auch bei
250 // Verwendung von Styles kein Abstand enstehen soll, wird
251 // hier auch geweohnlich attributiert !!!
252 USHORT nUpper=0, nLower=0;
253 GetULSpaceFromContext( nUpper, nLower );
254 InsertAttr( SvxULSpaceItem( nUpper, 0, RES_UL_SPACE ), FALSE, TRUE );
256 AppendTxtNode( AM_NOSPACE );
258 if( nUpper )
260 NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, nLower, RES_UL_SPACE ) );
261 aParaAttrs.Insert( aAttrTab.pULSpace, aParaAttrs.Count() );
262 EndAttr( aAttrTab.pULSpace, 0, FALSE );
266 // Vertikale Ausrichtung und Verankerung bestimmen.
267 xub_StrLen nCntnt = pPam->GetPoint()->nContent.GetIndex();
268 if( nCntnt )
270 aAnchor.SetType( FLY_AUTO_CNTNT );
271 bMoveBackward = TRUE;
272 eVertOri = text::VertOrientation::CHAR_BOTTOM;
273 eVertRel = text::RelOrientation::CHAR;
275 else
277 aAnchor.SetType( FLY_AT_CNTNT );
278 eVertOri = text::VertOrientation::TOP;
279 eVertRel = text::RelOrientation::PRINT_AREA;
282 rFrmSet.Put( SwFmtHoriOrient( 0, eHoriOri, eHoriRel) );
284 rFrmSet.Put( SwFmtSurround( eSurround ) );
286 rFrmSet.Put( SwFmtVertOrient( 0, eVertOri, eVertRel) );
288 if( bMoveBackward )
289 pPam->Move( fnMoveBackward );
291 aAnchor.SetAnchor( pPam->GetPoint() );
293 if( bMoveBackward )
294 pPam->Move( fnMoveForward );
296 rFrmSet.Put( aAnchor );
299 void SwHTMLParser::RegisterFlyFrm( SwFrmFmt *pFlyFmt )
301 // automatisch verankerte Rahmen muessen noch um eine Position
302 // nach vorne verschoben werden.
303 if( RES_DRAWFRMFMT != pFlyFmt->Which() &&
304 FLY_AT_CNTNT == pFlyFmt->GetAnchor().GetAnchorId() &&
305 SURROUND_THROUGHT == pFlyFmt->GetSurround().GetSurround() )
307 aMoveFlyFrms.Insert( pFlyFmt, aMoveFlyFrms.Count() );
308 aMoveFlyCnts.Insert( pPam->GetPoint()->nContent.GetIndex(),
309 aMoveFlyCnts.Count() );
313 /* \f */
315 void SwHTMLParser::GetDefaultScriptType( ScriptType& rType,
316 String& rTypeStr ) const
318 SwDocShell *pDocSh = pDoc->GetDocShell();
319 SvKeyValueIterator* pHeaderAttrs = pDocSh ? pDocSh->GetHeaderAttributes()
320 : 0;
321 rType = GetScriptType( pHeaderAttrs );
322 rTypeStr = GetScriptTypeString( pHeaderAttrs );
325 /* \f */
327 void SwHTMLParser::InsertImage()
329 // und jetzt auswerten
330 String sGrfNm, sAltNm, aId, aClass, aStyle, aMap, sHTMLGrfName;
331 sal_Int16 eVertOri = text::VertOrientation::TOP;
332 sal_Int16 eHoriOri = text::HoriOrientation::NONE;
333 long nWidth=0, nHeight=0;
334 long nVSpace=0, nHSpace=0;
336 USHORT nBorder = (aAttrTab.pINetFmt ? 1 : 0);
337 BOOL bIsMap = FALSE;
338 BOOL bPrcWidth = FALSE;
339 BOOL bPrcHeight = FALSE;
340 SvxMacroItem aMacroItem(RES_FRMMACRO);
342 ScriptType eDfltScriptType;
343 String sDfltScriptType;
344 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
346 const HTMLOptions *pHTMLOptions = GetOptions();
347 for( USHORT i = pHTMLOptions->Count(); i; )
349 USHORT nEvent = 0;
350 ScriptType eScriptType2 = eDfltScriptType;
351 const HTMLOption *pOption = (*pHTMLOptions)[--i];
352 switch( pOption->GetToken() )
354 case HTML_O_ID:
355 aId = pOption->GetString();
356 break;
357 case HTML_O_STYLE:
358 aStyle = pOption->GetString();
359 break;
360 case HTML_O_CLASS:
361 aClass = pOption->GetString();
362 break;
363 case HTML_O_SRC:
364 sGrfNm = pOption->GetString();
365 if( !InternalImgToPrivateURL(sGrfNm) )
366 sGrfNm = INetURLObject::GetAbsURL( sBaseURL, sGrfNm );
367 break;
368 case HTML_O_ALIGN:
369 eVertOri =
370 pOption->GetEnum( aHTMLImgVAlignTable,
371 text::VertOrientation::TOP );
372 eHoriOri =
373 pOption->GetEnum( aHTMLImgHAlignTable,
374 text::HoriOrientation::NONE );
375 break;
376 case HTML_O_WIDTH:
377 // erstmal nur als Pixelwerte merken!
378 nWidth = pOption->GetNumber();
379 bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
380 if( bPrcWidth && nWidth>100 )
381 nWidth = 100;
382 break;
383 case HTML_O_HEIGHT:
384 // erstmal nur als Pixelwerte merken!
385 nHeight = pOption->GetNumber();
386 bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
387 if( bPrcHeight && nHeight>100 )
388 nHeight = 100;
389 break;
390 case HTML_O_VSPACE:
391 nVSpace = pOption->GetNumber();
392 break;
393 case HTML_O_HSPACE:
394 nHSpace = pOption->GetNumber();
395 break;
396 case HTML_O_ALT:
397 sAltNm = pOption->GetString();
398 break;
399 case HTML_O_BORDER:
400 nBorder = (USHORT)pOption->GetNumber();
401 break;
402 case HTML_O_ISMAP:
403 bIsMap = TRUE;
404 break;
405 case HTML_O_USEMAP:
406 aMap = pOption->GetString();
407 break;
408 case HTML_O_NAME:
409 sHTMLGrfName = pOption->GetString();
410 break;
412 case HTML_O_SDONLOAD:
413 eScriptType2 = STARBASIC;
414 case HTML_O_ONLOAD:
415 nEvent = SVX_EVENT_IMAGE_LOAD;
416 goto IMAGE_SETEVENT;
418 case HTML_O_SDONABORT:
419 eScriptType2 = STARBASIC;
420 case HTML_O_ONABORT:
421 nEvent = SVX_EVENT_IMAGE_ABORT;
422 goto IMAGE_SETEVENT;
424 case HTML_O_SDONERROR:
425 eScriptType2 = STARBASIC;
426 case HTML_O_ONERROR:
427 nEvent = SVX_EVENT_IMAGE_ERROR;
428 goto IMAGE_SETEVENT;
429 IMAGE_SETEVENT:
431 String sTmp( pOption->GetString() );
432 if( sTmp.Len() )
434 sTmp.ConvertLineEnd();
435 String sScriptType;
436 if( EXTENDED_STYPE == eScriptType2 )
437 sScriptType = sDfltScriptType;
438 aMacroItem.SetMacro( nEvent,
439 SvxMacro( sTmp, sScriptType, eScriptType2 ));
442 break;
446 if( !sGrfNm.Len() )
447 return;
449 // Wenn wir in einer Numerierung stehen und der Absatz noch leer und
450 // nicht numeriert ist, handelt es sich vielleicht um die Grafik
451 // einer Bullet-Liste
452 if( !pPam->GetPoint()->nContent.GetIndex() &&
453 GetNumInfo().GetDepth() > 0 && GetNumInfo().GetDepth() <= MAXLEVEL &&
454 aBulletGrfs[GetNumInfo().GetDepth()-1].Len() &&
455 aBulletGrfs[GetNumInfo().GetDepth()-1]==sGrfNm )
457 SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
459 if( pTxtNode && ! pTxtNode->IsCountedInList())
461 ASSERT( pTxtNode->GetActualListLevel() == GetNumInfo().GetLevel(),
462 "Numerierungs-Ebene stimmt nicht" );
464 pTxtNode->SetCountedInList( true );
466 // Rule invalisieren ist noetig, weil zwischem dem einlesen
467 // des LI und der Grafik ein EndAction gerufen worden sein kann.
468 if( GetNumInfo().GetNumRule() )
469 GetNumInfo().GetNumRule()->SetInvalidRule( TRUE );
471 // Die Vorlage novh mal setzen. Ist noetig, damit der
472 // Erstzeilen-Einzug stimmt.
473 SetTxtCollAttrs();
475 return;
479 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
480 SvxCSS1PropertyInfo aPropInfo;
481 if( HasStyleOptions( aStyle, aId, aClass ) )
482 ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
484 SfxItemSet aFrmSet( pDoc->GetAttrPool(),
485 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
486 if( !IsNewDoc() )
487 Reader::ResetFrmFmtAttrs( aFrmSet );
489 // Umrandung setzen
490 long nHBorderWidth = 0, nVBorderWidth = 0;
491 if( nBorder )
493 nHBorderWidth = (long)nBorder;
494 nVBorderWidth = (long)nBorder;
495 SvxCSS1Parser::PixelToTwip( nVBorderWidth, nHBorderWidth );
497 SvxBorderLine aHBorderLine;
498 SvxBorderLine aVBorderLine;
500 SvxCSS1Parser::SetBorderWidth( aHBorderLine,
501 (USHORT)nHBorderWidth, FALSE );
502 if( nHBorderWidth == nVBorderWidth )
503 aVBorderLine.SetOutWidth( aHBorderLine.GetOutWidth() );
504 else
505 SvxCSS1Parser::SetBorderWidth( aVBorderLine,
506 (USHORT)nVBorderWidth, FALSE );
508 // die tatsaechlich gesetzter Rahmenbreite benutzen und nicht die
509 // Wunschbreite!
510 nHBorderWidth = aHBorderLine.GetOutWidth();
511 nVBorderWidth = aVBorderLine.GetOutWidth();
513 if( aAttrTab.pINetFmt )
515 const String& rURL =
516 ((const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem()).GetValue();
518 pCSS1Parser->SetATagStyles();
519 USHORT nPoolId = static_cast< USHORT >(pDoc->IsVisitedURL( rURL )
520 ? RES_POOLCHR_INET_VISIT
521 : RES_POOLCHR_INET_NORMAL);
522 const SwCharFmt *pCharFmt = pCSS1Parser->GetCharFmtFromPool( nPoolId );
523 aHBorderLine.SetColor( pCharFmt->GetColor().GetValue() );
524 aVBorderLine.SetColor( aHBorderLine.GetColor() );
526 else
528 const SvxColorItem& rColorItem = aAttrTab.pFontColor ?
529 (const SvxColorItem &)aAttrTab.pFontColor->GetItem() :
530 (const SvxColorItem &)pDoc->GetDefault(RES_CHRATR_COLOR);
531 aHBorderLine.SetColor( rColorItem.GetValue() );
532 aVBorderLine.SetColor( aHBorderLine.GetColor() );
536 SvxBoxItem aBoxItem( RES_BOX );
537 aBoxItem.SetLine( &aHBorderLine, BOX_LINE_TOP );
538 aBoxItem.SetLine( &aHBorderLine, BOX_LINE_BOTTOM );
539 aBoxItem.SetLine( &aVBorderLine, BOX_LINE_LEFT );
540 aBoxItem.SetLine( &aVBorderLine, BOX_LINE_RIGHT );
541 aFrmSet.Put( aBoxItem );
544 // Ausrichtung setzen
545 SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet );
547 // Abstaende setzen
548 SetSpace( Size( nHSpace, nVSpace), aItemSet, aPropInfo, aFrmSet );
550 // Sonstige CSS1-Attribute Setzen
551 SetFrmFmtAttrs( aItemSet, aPropInfo, HTML_FF_BOX, aFrmSet );
553 Size aTwipSz( bPrcWidth ? 0 : nWidth, bPrcHeight ? 0 : nHeight );
554 if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
556 aTwipSz = Application::GetDefaultDevice()
557 ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
560 // CSS1-Groesse auf "normale" Groesse umrechnen
561 switch( aPropInfo.eWidthType )
563 case SVX_CSS1_LTYPE_TWIP:
564 aTwipSz.Width() = aPropInfo.nWidth;
565 nWidth = 1; // != 0
566 bPrcWidth = FALSE;
567 break;
568 case SVX_CSS1_LTYPE_PERCENTAGE:
569 aTwipSz.Width() = 0;
570 nWidth = aPropInfo.nWidth;
571 bPrcWidth = TRUE;
572 break;
573 default:
576 switch( aPropInfo.eHeightType )
578 case SVX_CSS1_LTYPE_TWIP:
579 aTwipSz.Height() = aPropInfo.nHeight;
580 nHeight = 1; // != 0
581 bPrcHeight = FALSE;
582 break;
583 case SVX_CSS1_LTYPE_PERCENTAGE:
584 aTwipSz.Height() = 0;
585 nHeight = aPropInfo.nHeight;
586 bPrcHeight = TRUE;
587 break;
588 default:
592 Size aGrfSz( 0, 0 );
593 BOOL bSetTwipSize = TRUE; // Twip-Size am Node setzen?
594 BOOL bChangeFrmSize = FALSE; // Frame-Format nachtraeglich anpassen?
595 BOOL bRequestGrfNow = FALSE;
596 BOOL bSetScaleImageMap = FALSE;
597 BYTE nPrcWidth = 0, nPrcHeight = 0;
599 if( !nWidth || !nHeight )
601 // Es fehlt die Breite oder die Hoehe
602 // Wenn die Grfik in einer Tabelle steht, wird sie gleich
603 // angefordert, damit sie eventuell schon da ist, bevor die
604 // Tabelle layoutet wird.
605 if( pTable!=0 && !nWidth )
607 bRequestGrfNow = TRUE;
608 IncGrfsThatResizeTable();
611 // Die Groesse des Rahmens wird nachtraeglich gesetzt
612 bChangeFrmSize = TRUE;
613 aGrfSz = aTwipSz;
614 if( !nWidth && !nHeight )
616 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
617 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
619 else if( nWidth )
621 // eine %-Angabe
622 if( bPrcWidth )
624 nPrcWidth = (BYTE)nWidth;
625 nPrcHeight = 255;
627 else
629 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
632 else if( nHeight )
634 if( bPrcHeight )
636 nPrcHeight = (BYTE)nHeight;
637 nPrcWidth = 255;
639 else
641 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
645 else
647 // Breite und Hoehe wurden angegeben und brauchen nicht gesetzt
648 // zu werden
649 bSetTwipSize = FALSE;
651 if( bPrcWidth )
652 nPrcWidth = (BYTE)nWidth;
654 if( bPrcHeight )
655 nPrcHeight = (BYTE)nHeight;
658 // Image-Map setzen
659 aMap.EraseTrailingChars();
660 if( aMap.Len() )
662 // Da wir nur lokale Image-Maps kennen nehmen wireinfach alles
663 // hinter dem # als Namen
664 xub_StrLen nPos = aMap.Search( '#' );
665 String aName;
666 if ( STRING_NOTFOUND==nPos )
667 aName = aMap ;
668 else
669 aName = aMap.Copy(nPos+1);
671 ImageMap *pImgMap = FindImageMap( aName );
672 if( pImgMap )
674 SwFmtURL aURL; aURL.SetMap( pImgMap );//wird kopieiert
676 bSetScaleImageMap = !nPrcWidth || !nPrcHeight;
677 aFrmSet.Put( aURL );
679 else
681 ImageMap aEmptyImgMap( aName );
682 SwFmtURL aURL; aURL.SetMap( &aEmptyImgMap );//wird kopieiert
683 aFrmSet.Put( aURL );
684 nMissingImgMaps++; // es fehlen noch Image-Maps
686 // die Grafik muss beim SetTwipSize skaliert werden, wenn
687 // wir keine Groesse am Node gesetzt haben oder die Groesse
688 // nicht der Grafikgroesse entsprach.
689 bSetScaleImageMap = sal_True;
693 // min. Werte einhalten !!
694 if( nPrcWidth )
696 ASSERT( !aTwipSz.Width(),
697 "Wieso ist da trotz %-Angabe eine Breite gesetzt?" );
698 aTwipSz.Width() = aGrfSz.Width() ? aGrfSz.Width()
699 : HTML_DFLT_IMG_WIDTH;
701 else
703 aTwipSz.Width() += 2*nVBorderWidth;
704 if( aTwipSz.Width() < MINFLY )
705 aTwipSz.Width() = MINFLY;
707 if( nPrcHeight )
709 ASSERT( !aTwipSz.Height(),
710 "Wieso ist da trotz %-Angabe eine Hoehe gesetzt?" );
711 aTwipSz.Height() = aGrfSz.Height() ? aGrfSz.Height()
712 : HTML_DFLT_IMG_HEIGHT;
714 else
716 aTwipSz.Height() += 2*nHBorderWidth;
717 if( aTwipSz.Height() < MINFLY )
718 aTwipSz.Height() = MINFLY;
721 SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() );
722 aFrmSize.SetWidthPercent( nPrcWidth );
723 aFrmSize.SetHeightPercent( nPrcHeight );
724 aFrmSet.Put( aFrmSize );
726 Graphic aEmptyGrf;
727 aEmptyGrf.SetDefaultType();
728 SwFrmFmt *pFlyFmt = pDoc->Insert( *pPam, sGrfNm, aEmptyStr, &aEmptyGrf,
729 &aFrmSet, NULL, NULL );
730 SwGrfNode *pGrfNd = pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
731 ->GetIndex()+1 ]->GetGrfNode();
733 if( sHTMLGrfName.Len() )
735 pFlyFmt->SetName( sHTMLGrfName );
737 // ggfs. eine Grafik anspringen
738 if( JUMPTO_GRAPHIC == eJumpTo && sHTMLGrfName == sJmpMark )
740 bChkJumpMark = TRUE;
741 eJumpTo = JUMPTO_NONE;
745 if( sAltNm.Len() )
746 pGrfNd->SetTitle( sAltNm );
748 if( bSetTwipSize )
749 pGrfNd->SetTwipSize( aGrfSz );
751 pGrfNd->SetChgTwipSize( bChangeFrmSize, bChangeFrmSize );
753 if( bSetScaleImageMap )
754 pGrfNd->SetScaleImageMap( TRUE );
756 if( aAttrTab.pINetFmt )
758 const SwFmtINetFmt &rINetFmt =
759 (const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem();
761 SwFmtURL aURL( pFlyFmt->GetURL() );
763 aURL.SetURL( rINetFmt.GetValue(), bIsMap );
764 aURL.SetTargetFrameName( rINetFmt.GetTargetFrame() );
765 aURL.SetName( rINetFmt.GetName() );
766 pFlyFmt->SetFmtAttr( aURL );
769 const SvxMacro *pMacro;
770 static USHORT __READONLY_DATA aEvents[] = {
771 SFX_EVENT_MOUSEOVER_OBJECT,
772 SFX_EVENT_MOUSECLICK_OBJECT,
773 SFX_EVENT_MOUSEOUT_OBJECT,
774 0 };
776 for( USHORT n = 0; aEvents[ n ]; ++n )
777 if( 0 != ( pMacro = rINetFmt.GetMacro( aEvents[ n ] ) ))
778 aMacroItem.SetMacro( aEvents[ n ], *pMacro );
781 if( FLY_IN_CNTNT == pFlyFmt->GetAnchor().GetAnchorId() &&
782 aAttrTab.pINetFmt->GetSttPara() ==
783 pPam->GetPoint()->nNode &&
784 aAttrTab.pINetFmt->GetSttCnt() ==
785 pPam->GetPoint()->nContent.GetIndex() - 1 )
787 // das Attribut wurde unmitellbar vor einer zeichengeb.
788 // Grafik eingefuegt, also verschieben wir es
789 aAttrTab.pINetFmt->SetStart( *pPam->GetPoint() );
791 // Wenn das Attribut auch ein Sprungziel ist, fuegen
792 // wir noch eine Bookmark vor der Grafik ein, weil das
793 // SwFmtURL kein Sprungziel ist.
794 if( rINetFmt.GetName().Len() )
796 pPam->Move( fnMoveBackward );
797 InsertBookmark( rINetFmt.GetName() );
798 pPam->Move( fnMoveForward );
804 if( aMacroItem.GetMacroTable().Count() )
805 pFlyFmt->SetFmtAttr( aMacroItem );
807 // Wenn die Grafik gleich angeforder wird, muss dies geschehen,
808 // nachdem das Format vollstaendig aufgebaut ist, weil es evtl.
809 // gleich (synchron) angepasst wird (war bug #40983#)
810 if( bRequestGrfNow )
812 pGrfNd->SetTransferPriority( SFX_TFPRIO_VISIBLE_LOWRES_GRAPHIC );
813 pGrfNd->SwapIn();
816 // Ggf. Frames anlegen und Auto-gebundenen Rahmen registrieren
817 RegisterFlyFrm( pFlyFmt );
819 if( aId.Len() )
820 InsertBookmark( aId );
823 /* \f */
825 void SwHTMLParser::InsertBodyOptions()
827 pDoc->SetTxtFmtColl( *pPam,
828 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
830 String aBackGround, aId, aStyle, aLang, aDir;
831 Color aBGColor, aTextColor, aLinkColor, aVLinkColor;
832 BOOL bBGColor=FALSE, bTextColor=FALSE;
833 BOOL bLinkColor=FALSE, bVLinkColor=FALSE;
835 ScriptType eDfltScriptType;
836 String sDfltScriptType;
837 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
839 const HTMLOptions *pHTMLOptions = GetOptions();
840 for( USHORT i = pHTMLOptions->Count(); i; )
842 const HTMLOption *pOption = (*pHTMLOptions)[--i];
843 ScriptType eScriptType2 = eDfltScriptType;
844 rtl::OUString aEvent;
845 BOOL bSetEvent = FALSE;
847 switch( pOption->GetToken() )
849 case HTML_O_ID:
850 aId = pOption->GetString();
851 break;
852 case HTML_O_BACKGROUND:
853 aBackGround = pOption->GetString();
854 break;
855 case HTML_O_BGCOLOR:
856 pOption->GetColor( aBGColor );
857 bBGColor = TRUE;
858 break;
859 case HTML_O_TEXT:
860 pOption->GetColor( aTextColor );
861 bTextColor = TRUE;
862 break;
863 case HTML_O_LINK:
864 pOption->GetColor( aLinkColor );
865 bLinkColor = TRUE;
866 break;
867 case HTML_O_VLINK:
868 pOption->GetColor( aVLinkColor );
869 bVLinkColor = TRUE;
870 break;
872 case HTML_O_SDONLOAD:
873 eScriptType2 = STARBASIC;
874 case HTML_O_ONLOAD:
875 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC );
876 bSetEvent = TRUE;
877 break;
879 case HTML_O_SDONUNLOAD:
880 eScriptType2 = STARBASIC;
881 case HTML_O_ONUNLOAD:
882 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_PREPARECLOSEDOC );
883 bSetEvent = TRUE;
884 break;
886 case HTML_O_SDONFOCUS:
887 eScriptType2 = STARBASIC;
888 case HTML_O_ONFOCUS:
889 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC );
890 bSetEvent = TRUE;
891 break;
893 case HTML_O_SDONBLUR:
894 eScriptType2 = STARBASIC;
895 case HTML_O_ONBLUR:
896 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC );
897 bSetEvent = TRUE;
898 break;
900 case HTML_O_ONERROR:
901 // if( bAnyStarBasic )
902 // InsertBasicDocEvent( SFX_EVENT_ACTIVATEDOC,
903 // pOption->GetString() );
904 break;
906 case HTML_O_STYLE:
907 aStyle = pOption->GetString();
908 bTextColor = TRUE;
909 break;
910 case HTML_O_LANG:
911 aLang = pOption->GetString();
912 break;
913 case HTML_O_DIR:
914 aDir = pOption->GetString();
915 break;
918 if( bSetEvent )
920 const String& rEvent = pOption->GetString();
921 if( rEvent.Len() )
922 InsertBasicDocEvent( aEvent, rEvent, eScriptType2,
923 sDfltScriptType );
927 if( bTextColor && !pCSS1Parser->IsBodyTextSet() )
929 // Die Textfarbe wird an der Standard-Vorlage gesetzt
930 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
931 ->SetFmtAttr( SvxColorItem(aTextColor, RES_CHRATR_COLOR) );
932 pCSS1Parser->SetBodyTextSet();
936 // Die Item fuer die Seitenvorlage vorbereiten (Hintergrund, Umrandung)
937 // Beim BrushItem muessen schon gesetzte werte erhalten bleiben!
938 SvxBrushItem aBrushItem( pCSS1Parser->GetPageDescBackground() );
939 BOOL bSetBrush = FALSE;
941 if( bBGColor && !pCSS1Parser->IsBodyBGColorSet() )
943 // Hintergrundfarbe aus "BGCOLOR"
944 String aLink;
945 if( aBrushItem.GetGraphicLink() )
946 aLink = *aBrushItem.GetGraphicLink();
947 SvxGraphicPosition ePos = aBrushItem.GetGraphicPos();
949 aBrushItem.SetColor( aBGColor );
951 if( aLink.Len() )
953 aBrushItem.SetGraphicLink( aLink );
954 aBrushItem.SetGraphicPos( ePos );
956 bSetBrush = TRUE;
957 pCSS1Parser->SetBodyBGColorSet();
960 if( aBackGround.Len() && !pCSS1Parser->IsBodyBackgroundSet() )
962 // Hintergrundgrafik aus "BACKGROUND"
963 aBrushItem.SetGraphicLink( INetURLObject::GetAbsURL( sBaseURL, aBackGround ) );
964 aBrushItem.SetGraphicPos( GPOS_TILED );
965 bSetBrush = TRUE;
966 pCSS1Parser->SetBodyBackgroundSet();
969 if( aStyle.Len() || aDir.Len() )
971 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
972 SvxCSS1PropertyInfo aPropInfo;
973 String aDummy;
974 ParseStyleOptions( aStyle, aDummy, aDummy, aItemSet, aPropInfo, 0, &aDir );
976 // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
977 // und zwar die, die nicht vererbit werden
978 pCSS1Parser->SetPageDescAttrs( bSetBrush ? &aBrushItem : 0,
979 &aItemSet );
981 const SfxPoolItem *pItem;
982 static USHORT aWhichIds[3] = { RES_CHRATR_FONTSIZE,
983 RES_CHRATR_CJK_FONTSIZE,
984 RES_CHRATR_CTL_FONTSIZE };
985 for( USHORT i=0; i<3; i++ )
987 if( SFX_ITEM_SET == aItemSet.GetItemState( aWhichIds[i], FALSE,
988 &pItem ) &&
989 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() != 100)
991 sal_uInt32 nHeight =
992 ( aFontHeights[2] *
993 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() ) / 100;
994 SvxFontHeightItem aNewItem( nHeight, 100, aWhichIds[i] );
995 aItemSet.Put( aNewItem );
999 // alle noch uebrigen Optionen koennen an der Standard-Vorlage
1000 // gesetzt werden und gelten dann automatisch als defaults
1001 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
1002 ->SetFmtAttr( aItemSet );
1004 else if( bSetBrush )
1006 pCSS1Parser->SetPageDescAttrs( &aBrushItem );
1009 if( bLinkColor && !pCSS1Parser->IsBodyLinkSet() )
1011 SwCharFmt *pCharFmt =
1012 pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_NORMAL);
1013 pCharFmt->SetFmtAttr( SvxColorItem(aLinkColor, RES_CHRATR_COLOR) );
1014 pCSS1Parser->SetBodyLinkSet();
1016 if( bVLinkColor && !pCSS1Parser->IsBodyVLinkSet() )
1018 SwCharFmt *pCharFmt =
1019 pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_VISIT);
1020 pCharFmt->SetFmtAttr( SvxColorItem(aVLinkColor, RES_CHRATR_COLOR) );
1021 pCSS1Parser->SetBodyVLinkSet();
1023 if( aLang.Len() )
1025 LanguageType eLang = MsLangId::convertIsoStringToLanguage( aLang );
1026 sal_uInt16 nWhich = 0;
1027 if( LANGUAGE_DONTKNOW != eLang )
1029 switch( SvtLanguageOptions::GetScriptTypeOfLanguage( eLang ) )
1031 case SCRIPTTYPE_LATIN:
1032 nWhich = RES_CHRATR_LANGUAGE;
1033 break;
1034 case SCRIPTTYPE_ASIAN:
1035 nWhich = RES_CHRATR_CJK_LANGUAGE;
1036 break;
1037 case SCRIPTTYPE_COMPLEX:
1038 nWhich = RES_CHRATR_CTL_LANGUAGE;
1039 break;
1041 if( nWhich )
1043 SvxLanguageItem aLanguage( eLang, nWhich );
1044 aLanguage.SetWhich( nWhich );
1045 pDoc->SetDefault( aLanguage );
1050 if( aId.Len() )
1051 InsertBookmark( aId );
1054 /* \f */
1056 void SwHTMLParser::NewAnchor()
1058 // den voherigen Link beenden, falls es einen gab
1059 _HTMLAttrContext *pOldCntxt = PopContext( HTML_ANCHOR_ON );
1060 if( pOldCntxt )
1062 // und ggf. die Attribute beenden
1063 EndContext( pOldCntxt );
1064 delete pOldCntxt;
1067 SvxMacroTableDtor aMacroTbl;
1068 String sHRef, aName, sTarget;
1069 String aId, aStyle, aClass, aLang, aDir;
1070 BOOL bHasHRef = FALSE, bFixed = FALSE;
1072 ScriptType eDfltScriptType;
1073 String sDfltScriptType;
1074 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
1076 const HTMLOptions *pHTMLOptions = GetOptions();
1077 for( USHORT i = pHTMLOptions->Count(); i; )
1079 USHORT nEvent = 0;
1080 ScriptType eScriptType2 = eDfltScriptType;
1081 const HTMLOption *pOption = (*pHTMLOptions)[--i];
1082 switch( pOption->GetToken() )
1084 case HTML_O_NAME:
1085 aName = pOption->GetString();
1086 break;
1088 case HTML_O_HREF:
1089 sHRef = pOption->GetString();
1090 bHasHRef = TRUE;
1091 break;
1092 case HTML_O_TARGET:
1093 sTarget = pOption->GetString();
1094 break;
1096 case HTML_O_STYLE:
1097 aStyle = pOption->GetString();
1098 break;
1099 case HTML_O_ID:
1100 aId = pOption->GetString();
1101 break;
1102 case HTML_O_CLASS:
1103 aClass = pOption->GetString();
1104 break;
1105 case HTML_O_SDFIXED:
1106 bFixed = TRUE;
1107 break;
1108 case HTML_O_LANG:
1109 aLang = pOption->GetString();
1110 break;
1111 case HTML_O_DIR:
1112 aDir = pOption->GetString();
1113 break;
1115 case HTML_O_SDONCLICK:
1116 eScriptType2 = STARBASIC;
1117 case HTML_O_ONCLICK:
1118 nEvent = SFX_EVENT_MOUSECLICK_OBJECT;
1119 goto ANCHOR_SETEVENT;
1121 case HTML_O_SDONMOUSEOVER:
1122 eScriptType2 = STARBASIC;
1123 case HTML_O_ONMOUSEOVER:
1124 nEvent = SFX_EVENT_MOUSEOVER_OBJECT;
1125 goto ANCHOR_SETEVENT;
1127 case HTML_O_SDONMOUSEOUT:
1128 eScriptType2 = STARBASIC;
1129 case HTML_O_ONMOUSEOUT:
1130 nEvent = SFX_EVENT_MOUSEOUT_OBJECT;
1131 goto ANCHOR_SETEVENT;
1132 ANCHOR_SETEVENT:
1134 String sTmp( pOption->GetString() );
1135 if( sTmp.Len() )
1137 sTmp.ConvertLineEnd();
1138 String sScriptType;
1139 if( EXTENDED_STYPE == eScriptType2 )
1140 sScriptType = sDfltScriptType;
1141 aMacroTbl.Insert( nEvent,
1142 new SvxMacro( sTmp, sScriptType, eScriptType2 ));
1145 break;
1150 // Sprungziele, die unseren ipmliziten Zielen entsprechen, schmeissen
1151 // wir hier ganz rigoros raus.
1152 if( aName.Len() )
1154 String sDecoded( INetURLObject::decode( aName, INET_HEX_ESCAPE,
1155 INetURLObject::DECODE_UNAMBIGUOUS,
1156 RTL_TEXTENCODING_UTF8 ));
1157 xub_StrLen nPos = sDecoded.SearchBackward( cMarkSeperator );
1158 if( STRING_NOTFOUND != nPos )
1160 String sCmp( sDecoded.Copy( nPos+1 ) );
1161 sCmp.EraseAllChars();
1162 if( sCmp.Len() )
1164 sCmp.ToLowerAscii();
1165 if( sCmp.EqualsAscii( pMarkToRegion ) ||
1166 sCmp.EqualsAscii( pMarkToFrame ) ||
1167 sCmp.EqualsAscii( pMarkToGraphic ) ||
1168 sCmp.EqualsAscii( pMarkToOLE ) ||
1169 sCmp.EqualsAscii( pMarkToTable ) ||
1170 sCmp.EqualsAscii( pMarkToOutline ) ||
1171 sCmp.EqualsAscii( pMarkToText ) )
1173 aName.Erase();
1179 // einen neuen Kontext anlegen
1180 _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_ANCHOR_ON );
1182 BOOL bEnAnchor = FALSE, bFtnAnchor = FALSE, bFtnEnSymbol = FALSE;
1183 String aFtnName;
1184 String aStrippedClass( aClass );
1185 SwCSS1Parser::GetScriptFromClass( aStrippedClass, sal_False );
1186 if( aStrippedClass.Len() >=9 && bHasHRef && sHRef.Len() > 1 &&
1187 ('s' == aStrippedClass.GetChar(0) || 'S' == aStrippedClass.GetChar(0)) &&
1188 ('d' == aStrippedClass.GetChar(1) || 'D' == aStrippedClass.GetChar(1)) )
1190 if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc ) )
1191 bEnAnchor = TRUE;
1192 else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc ) )
1193 bFtnAnchor = TRUE;
1194 else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym ) ||
1195 aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym ) )
1196 bFtnEnSymbol = TRUE;
1197 if( bEnAnchor || bFtnAnchor || bFtnEnSymbol )
1199 aFtnName = sHRef.Copy( 1 );
1200 aClass = aStrippedClass = aName = aEmptyStr;
1201 bHasHRef = FALSE;
1205 // Styles parsen
1206 if( HasStyleOptions( aStyle, aId, aStrippedClass, &aLang, &aDir ) )
1208 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
1209 SvxCSS1PropertyInfo aPropInfo;
1211 if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
1213 DoPositioning( aItemSet, aPropInfo, pCntxt );
1214 InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
1218 if( bHasHRef )
1220 if( sHRef.Len() )
1222 sHRef = URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), sHRef, Link(), false );
1224 else
1226 // Bei leerer URL das Directory nehmen
1227 INetURLObject aURLObj( aPathToFile );
1228 sHRef = aURLObj.GetPartBeforeLastName();
1231 pCSS1Parser->SetATagStyles();
1232 SwFmtINetFmt aINetFmt( sHRef, sTarget );
1233 aINetFmt.SetName( aName );
1235 if( aMacroTbl.Count() )
1236 aINetFmt.SetMacroTbl( &aMacroTbl );
1238 // das Default-Attribut setzen
1239 InsertAttr( &aAttrTab.pINetFmt, aINetFmt, pCntxt );
1241 else if( aName.Len() )
1243 InsertBookmark( aName );
1246 if( bEnAnchor || bFtnAnchor )
1248 InsertFootEndNote( aFtnName, bEnAnchor, bFixed );
1249 bInFootEndNoteAnchor = bCallNextToken = TRUE;
1251 else if( bFtnEnSymbol )
1253 bInFootEndNoteSymbol = bCallNextToken = TRUE;
1256 // den Kontext merken
1257 PushContext( pCntxt );
1260 void SwHTMLParser::EndAnchor()
1262 if( bInFootEndNoteAnchor )
1264 FinishFootEndNote();
1265 bInFootEndNoteAnchor = FALSE;
1267 else if( bInFootEndNoteSymbol )
1269 bInFootEndNoteSymbol = FALSE;
1272 EndTag( HTML_ANCHOR_OFF );
1275 /* \f */
1277 void SwHTMLParser::InsertBookmark( const String& rName )
1279 _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
1280 SfxStringItem( RES_FLTR_BOOKMARK, rName ));
1281 aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
1284 BOOL SwHTMLParser::HasCurrentParaBookmarks( BOOL bIgnoreStack ) const
1286 BOOL bHasMarks = FALSE;
1287 ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
1289 // first step: are there still bookmark in the attribute-stack?
1290 // bookmarks are added to the end of the stack - thus we only have
1291 // to check the last bookmark
1292 if( !bIgnoreStack )
1294 _HTMLAttr* pAttr;
1295 for( USHORT i = aSetAttrTab.Count(); i; )
1297 pAttr = aSetAttrTab[ --i ];
1298 if( RES_FLTR_BOOKMARK == pAttr->pItem->Which() )
1300 if( pAttr->GetSttParaIdx() == nNodeIdx )
1301 bHasMarks = TRUE;
1302 break;
1307 if( !bHasMarks )
1309 // second step: when we didnt find a bookmark, check if there is one
1310 // set already
1311 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1312 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
1313 ppMark != pMarkAccess->getMarksEnd();
1314 ppMark++)
1316 const ::sw::mark::IMark* pBookmark = ppMark->get();
1317 ULONG nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex();
1318 if( nBookNdIdx==nNodeIdx )
1320 bHasMarks = TRUE;
1321 break;
1323 else if( nBookNdIdx > nNodeIdx )
1324 break;
1328 return bHasMarks;
1331 /* \f */
1333 void SwHTMLParser::StripTrailingPara()
1335 BOOL bSetSmallFont = FALSE;
1337 SwCntntNode* pCNd = pPam->GetCntntNode();
1338 if( !pPam->GetPoint()->nContent.GetIndex() )
1340 if( pCNd && pCNd->StartOfSectionIndex()+2 <
1341 pCNd->EndOfSectionIndex() )
1343 ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
1345 USHORT i;
1347 const SwFrmFmt* pFmt;
1348 const SwFmtAnchor* pAnchor;
1349 const SwPosition* pAPos;
1350 const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
1352 for( i=0; i<rFrmFmtTbl.Count(); i++ )
1354 pFmt = rFrmFmtTbl[i];
1355 pAnchor = &pFmt->GetAnchor();
1356 if( 0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
1357 (FLY_AT_CNTNT == pAnchor->GetAnchorId() ||
1358 FLY_AUTO_CNTNT == pAnchor->GetAnchorId()) &&
1359 pAPos->nNode == nNodeIdx )
1361 return; // den Knoten duerfen wir nicht loeschen
1364 SetAttr( FALSE ); // die noch offenen Attribute muessen
1365 // beendet werden, bevor der Node
1366 // geloescht wird, weil sonst der
1367 // End-Index in die Botanik zeigt
1369 if( pCNd->Len() && pCNd->IsTxtNode() )
1371 // es wurden Felder in den Node eingefuegt, die muessen
1372 // wir jetzt verschieben
1373 SwTxtNode *pPrvNd = pDoc->GetNodes()[nNodeIdx-1]->GetTxtNode();
1374 if( pPrvNd )
1376 SwIndex aSrc( pCNd, 0 );
1377 pCNd->GetTxtNode()->CutText( pPrvNd, aSrc, pCNd->Len() );
1381 // jetz muessen wir noch eventuell vorhandene Bookmarks
1382 // verschieben
1383 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1384 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
1385 ppMark != pMarkAccess->getMarksEnd();
1386 ppMark++)
1388 ::sw::mark::IMark* pMark = ppMark->get();
1389 ULONG nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex();
1390 if(nBookNdIdx==nNodeIdx)
1392 SwNodeIndex nNewNdIdx(pPam->GetPoint()->nNode);
1393 SwCntntNode* pNd = pDoc->GetNodes().GoPrevious(&nNewNdIdx);
1394 if(!pNd)
1396 ASSERT(!this, "Hoppla, wo ist mein Vorgaenger-Node");
1397 return;
1399 // --> OD 2007-09-27 #i81002# - refactoring
1400 // Do not directly manipulate member of <SwBookmark>
1402 SwPosition aNewPos(*pNd);
1403 aNewPos.nContent.Assign(pNd, pNd->Len());
1404 const SwPaM aPaM(aNewPos);
1405 pMarkAccess->repositionMark(ppMark->get(), aPaM);
1407 // <--
1409 else if( nBookNdIdx > nNodeIdx )
1410 break;
1413 pPam->GetPoint()->nContent.Assign( 0, 0 );
1414 pPam->SetMark();
1415 pPam->DeleteMark();
1416 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
1417 pPam->Move( fnMoveBackward, fnGoNode );
1419 else if( pCNd && pCNd->IsTxtNode() && pTable )
1421 // In leeren Zellen stellen wir einen kleinen Font ein, damit die
1422 // Zelle nicht hoeher wird als die Grafik bzw. so niedrig wie
1423 // moeglich bleibt.
1424 bSetSmallFont = TRUE;
1427 else if( pCNd && pCNd->IsTxtNode() && pTable &&
1428 pCNd->StartOfSectionIndex()+2 ==
1429 pCNd->EndOfSectionIndex() )
1431 // Wenn die Zelle nur zeichengebundene Grafiken/Rahmen enthaelt
1432 // stellen wir ebenfalls einen kleinen Font ein.
1433 bSetSmallFont = TRUE;
1434 SwTxtNode* pTxtNd = pCNd->GetTxtNode();
1436 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
1437 while( bSetSmallFont && nPos>0 )
1439 --nPos;
1440 bSetSmallFont =
1441 (CH_TXTATR_BREAKWORD == pTxtNd->GetTxt().GetChar( nPos )) &&
1442 (0 != pTxtNd->GetTxtAttrForCharAt( nPos, RES_TXTATR_FLYCNT ));
1446 if( bSetSmallFont )
1448 SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
1449 pCNd->SetAttr( aFontHeight );
1450 aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
1451 pCNd->SetAttr( aFontHeight );
1452 aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
1453 pCNd->SetAttr( aFontHeight );