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_sw.hxx" 26 27 #include "hintids.hxx" 28 #include <vcl/svapp.hxx> 29 #include <vcl/wrkwin.hxx> 30 #include <svx/svxids.hrc> 31 #include <sfx2/sfx.hrc> 32 #include <i18npool/mslangid.hxx> 33 #include <svl/stritem.hxx> 34 #include <svl/urihelper.hxx> 35 #include <editeng/fhgtitem.hxx> 36 #include <editeng/lrspitem.hxx> 37 #include <editeng/adjitem.hxx> 38 #include <editeng/fhgtitem.hxx> 39 #include <editeng/brshitem.hxx> 40 #include <editeng/colritem.hxx> 41 #include <editeng/boxitem.hxx> 42 #include <editeng/ulspitem.hxx> 43 #include <editeng/langitem.hxx> 44 #include <editeng/scripttypeitem.hxx> 45 #include <sfx2/docfile.hxx> 46 #include <svtools/imap.hxx> 47 #include <svtools/htmltokn.h> 48 #include <svtools/htmlkywd.hxx> 49 #include <unotools/eventcfg.hxx> 50 51 #include <fmtornt.hxx> 52 #include <fmturl.hxx> 53 #include <fmtanchr.hxx> 54 #include <fmtsrnd.hxx> 55 #include <fmtinfmt.hxx> 56 #include <fmtcntnt.hxx> 57 #include <fmtanchr.hxx> 58 #include <fmtfsize.hxx> 59 #include <fmtinfmt.hxx> 60 #include "frmatr.hxx" 61 #include "charatr.hxx" 62 #include <frmfmt.hxx> 63 #include <charfmt.hxx> 64 #include <docary.hxx> 65 #include <docsh.hxx> 66 #include <pam.hxx> 67 #include <doc.hxx> 68 #include <ndtxt.hxx> 69 #include <shellio.hxx> 70 #include <poolfmt.hxx> 71 #include <IMark.hxx> 72 #include <ndgrf.hxx> 73 #include <htmlnum.hxx> 74 #include <swcss1.hxx> 75 #include <swhtml.hxx> 76 #include <numrule.hxx> 77 #include <boost/shared_ptr.hpp> 78 79 using namespace ::com::sun::star; 80 81 82 HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[] = 83 { 84 { OOO_STRING_SVTOOLS_HTML_AL_left, text::HoriOrientation::LEFT }, 85 { OOO_STRING_SVTOOLS_HTML_AL_right, text::HoriOrientation::RIGHT }, 86 { 0, 0 } 87 }; 88 89 90 HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[] = 91 { 92 { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::LINE_TOP }, 93 { OOO_STRING_SVTOOLS_HTML_VA_texttop, text::VertOrientation::CHAR_TOP }, 94 { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER }, 95 { OOO_STRING_SVTOOLS_HTML_AL_center, text::VertOrientation::CENTER }, 96 { OOO_STRING_SVTOOLS_HTML_VA_absmiddle, text::VertOrientation::LINE_CENTER }, 97 { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::TOP }, 98 { OOO_STRING_SVTOOLS_HTML_VA_baseline, text::VertOrientation::TOP }, 99 { OOO_STRING_SVTOOLS_HTML_VA_absbottom, text::VertOrientation::LINE_BOTTOM }, 100 { 0, 0 } 101 }; 102 103 SV_IMPL_PTRARR( ImageMaps, ImageMapPtr ) 104 105 ImageMap *SwHTMLParser::FindImageMap( const String& rName ) const 106 { 107 ImageMap *pMap = 0; 108 109 ASSERT( rName.GetChar(0) != '#', "FindImageName: Name beginnt mit #!" ); 110 111 if( pImageMaps ) 112 { 113 for( sal_uInt16 i=0; i<pImageMaps->Count(); i++ ) 114 { 115 ImageMap *pIMap = (*pImageMaps)[i]; 116 if( rName.EqualsIgnoreCaseAscii( pIMap->GetName() ) ) 117 { 118 pMap = pIMap; 119 break; 120 } 121 } 122 } 123 return pMap; 124 } 125 126 void SwHTMLParser::ConnectImageMaps() 127 { 128 SwNodes& rNds = pDoc->GetNodes(); 129 // auf den Start-Node der 1. Section 130 sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 1; 131 sal_uLong nEndIdx = rNds.GetEndOfAutotext().GetIndex(); 132 133 SwGrfNode* pGrfNd; 134 while( nMissingImgMaps > 0 && nIdx < nEndIdx ) 135 { 136 SwNode *pNd = rNds[nIdx + 1]; 137 if( 0 != (pGrfNd = pNd->GetGrfNode()) ) 138 { 139 SwFrmFmt *pFmt = pGrfNd->GetFlyFmt(); 140 SwFmtURL aURL( pFmt->GetURL() ); 141 const ImageMap *pIMap = aURL.GetMap(); 142 if( pIMap && pIMap->GetIMapObjectCount()==0 ) 143 { 144 // Die (leere) Image-Map des Nodes wird entweder 145 // durch die jetzt gefundene Image-Map ersetzt 146 // oder geloescht. 147 ImageMap *pNewIMap = 148 FindImageMap( pIMap->GetName() ); 149 aURL.SetMap( pNewIMap ); 150 pFmt->SetFmtAttr( aURL ); 151 if( !pGrfNd->IsScaleImageMap() ) 152 { 153 // die Grafikgroesse ist mitlerweile da oder dir 154 // Grafik muss nicht skaliert werden 155 pGrfNd->ScaleImageMap(); 156 } 157 nMissingImgMaps--; // eine Map weniger suchen 158 } 159 } 160 nIdx = rNds[nIdx]->EndOfSectionIndex() + 1; 161 } 162 } 163 164 165 /* */ 166 167 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri, 168 sal_Int16 eHoriOri, 169 const SfxItemSet &rCSS1ItemSet, 170 const SvxCSS1PropertyInfo &rCSS1PropInfo, 171 SfxItemSet& rFrmItemSet ) 172 { 173 const SfxItemSet *pCntnrItemSet = 0; 174 sal_uInt16 i = aContexts.Count(); 175 while( !pCntnrItemSet && i > nContextStMin ) 176 pCntnrItemSet = aContexts[--i]->GetFrmItemSet(); 177 178 if( pCntnrItemSet ) 179 { 180 // Wenn wir und in einem Container befinden wird die Verankerung 181 // des Containers uebernommen. 182 rFrmItemSet.Put( *pCntnrItemSet ); 183 } 184 else if( pCSS1Parser->MayBePositioned( rCSS1PropInfo, sal_True ) ) 185 { 186 // Wenn die Ausrichtung anhand der CSS1-Optionen gesetzt werden kann 187 // werden die benutzt. 188 SetAnchorAndAdjustment( rCSS1ItemSet, rCSS1PropInfo, rFrmItemSet ); 189 } 190 else 191 { 192 // Sonst wird die Ausrichtung entsprechend der normalen HTML-Optionen 193 // gesetzt. 194 SetAnchorAndAdjustment( eVertOri, eHoriOri, rFrmItemSet ); 195 } 196 } 197 198 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri, 199 sal_Int16 eHoriOri, 200 SfxItemSet& rFrmSet, 201 sal_Bool bDontAppend ) 202 { 203 sal_Bool bMoveBackward = sal_False; 204 SwFmtAnchor aAnchor( FLY_AS_CHAR ); 205 sal_Int16 eVertRel = text::RelOrientation::FRAME; 206 207 if( text::HoriOrientation::NONE != eHoriOri ) 208 { 209 // den Absatz-Einzug bestimmen 210 sal_uInt16 nLeftSpace = 0, nRightSpace = 0; 211 short nIndent = 0; 212 GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent ); 213 214 // Horizonale Ausrichtung und Umlauf bestimmen. 215 sal_Int16 eHoriRel; 216 SwSurround eSurround; 217 switch( eHoriOri ) 218 { 219 case text::HoriOrientation::LEFT: 220 eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME; 221 eSurround = SURROUND_RIGHT; 222 break; 223 case text::HoriOrientation::RIGHT: 224 eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME; 225 eSurround = SURROUND_LEFT; 226 break; 227 case text::HoriOrientation::CENTER: // fuer Tabellen 228 eHoriRel = text::RelOrientation::FRAME; 229 eSurround = SURROUND_NONE; 230 break; 231 default: 232 eHoriRel = text::RelOrientation::FRAME; 233 eSurround = SURROUND_PARALLEL; 234 break; 235 } 236 237 // Einen neuen Absatz aufmachen, wenn der aktuelle 238 // absatzgebundene Rahmen ohne Umlauf enthaelt. 239 if( !bDontAppend && HasCurrentParaFlys( sal_True ) ) 240 { 241 // Wenn der Absatz nur Grafiken enthaelt, braucht er 242 // auch keinen unteren Absatz-Abstand. Da hier auch bei 243 // Verwendung von Styles kein Abstand enstehen soll, wird 244 // hier auch geweohnlich attributiert !!! 245 sal_uInt16 nUpper=0, nLower=0; 246 GetULSpaceFromContext( nUpper, nLower ); 247 InsertAttr( SvxULSpaceItem( nUpper, 0, RES_UL_SPACE ), sal_False, sal_True ); 248 249 AppendTxtNode( AM_NOSPACE ); 250 251 if( nUpper ) 252 { 253 NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, nLower, RES_UL_SPACE ) ); 254 aParaAttrs.Insert( aAttrTab.pULSpace, aParaAttrs.Count() ); 255 EndAttr( aAttrTab.pULSpace, 0, sal_False ); 256 } 257 } 258 259 // Vertikale Ausrichtung und Verankerung bestimmen. 260 xub_StrLen nCntnt = pPam->GetPoint()->nContent.GetIndex(); 261 if( nCntnt ) 262 { 263 aAnchor.SetType( FLY_AT_CHAR ); 264 bMoveBackward = sal_True; 265 eVertOri = text::VertOrientation::CHAR_BOTTOM; 266 eVertRel = text::RelOrientation::CHAR; 267 } 268 else 269 { 270 aAnchor.SetType( FLY_AT_PARA ); 271 eVertOri = text::VertOrientation::TOP; 272 eVertRel = text::RelOrientation::PRINT_AREA; 273 } 274 275 rFrmSet.Put( SwFmtHoriOrient( 0, eHoriOri, eHoriRel) ); 276 277 rFrmSet.Put( SwFmtSurround( eSurround ) ); 278 } 279 rFrmSet.Put( SwFmtVertOrient( 0, eVertOri, eVertRel) ); 280 281 if( bMoveBackward ) 282 pPam->Move( fnMoveBackward ); 283 284 aAnchor.SetAnchor( pPam->GetPoint() ); 285 286 if( bMoveBackward ) 287 pPam->Move( fnMoveForward ); 288 289 rFrmSet.Put( aAnchor ); 290 } 291 292 void SwHTMLParser::RegisterFlyFrm( SwFrmFmt *pFlyFmt ) 293 { 294 // automatisch verankerte Rahmen muessen noch um eine Position 295 // nach vorne verschoben werden. 296 if( RES_DRAWFRMFMT != pFlyFmt->Which() && 297 (FLY_AT_PARA == pFlyFmt->GetAnchor().GetAnchorId()) && 298 SURROUND_THROUGHT == pFlyFmt->GetSurround().GetSurround() ) 299 { 300 aMoveFlyFrms.Insert( pFlyFmt, aMoveFlyFrms.Count() ); 301 aMoveFlyCnts.push_back( pPam->GetPoint()->nContent.GetIndex() ); 302 } 303 } 304 305 /* */ 306 307 void SwHTMLParser::GetDefaultScriptType( ScriptType& rType, 308 String& rTypeStr ) const 309 { 310 SwDocShell *pDocSh = pDoc->GetDocShell(); 311 SvKeyValueIterator* pHeaderAttrs = pDocSh ? pDocSh->GetHeaderAttributes() 312 : 0; 313 rType = GetScriptType( pHeaderAttrs ); 314 rTypeStr = GetScriptTypeString( pHeaderAttrs ); 315 } 316 317 /* */ 318 319 void SwHTMLParser::InsertImage() 320 { 321 // und jetzt auswerten 322 String sGrfNm, sAltNm, aId, aClass, aStyle, aMap, sHTMLGrfName; 323 sal_Int16 eVertOri = text::VertOrientation::TOP; 324 sal_Int16 eHoriOri = text::HoriOrientation::NONE; 325 long nWidth=0, nHeight=0; 326 long nVSpace=0, nHSpace=0; 327 328 sal_uInt16 nBorder = (aAttrTab.pINetFmt ? 1 : 0); 329 sal_Bool bIsMap = sal_False; 330 sal_Bool bPrcWidth = sal_False; 331 sal_Bool bPrcHeight = sal_False; 332 SvxMacroItem aMacroItem(RES_FRMMACRO); 333 334 ScriptType eDfltScriptType; 335 String sDfltScriptType; 336 GetDefaultScriptType( eDfltScriptType, sDfltScriptType ); 337 338 const HTMLOptions *pHTMLOptions = GetOptions(); 339 for( sal_uInt16 i = pHTMLOptions->Count(); i; ) 340 { 341 sal_uInt16 nEvent = 0; 342 ScriptType eScriptType2 = eDfltScriptType; 343 const HTMLOption *pOption = (*pHTMLOptions)[--i]; 344 switch( pOption->GetToken() ) 345 { 346 case HTML_O_ID: 347 aId = pOption->GetString(); 348 break; 349 case HTML_O_STYLE: 350 aStyle = pOption->GetString(); 351 break; 352 case HTML_O_CLASS: 353 aClass = pOption->GetString(); 354 break; 355 case HTML_O_SRC: 356 sGrfNm = pOption->GetString(); 357 if( !InternalImgToPrivateURL(sGrfNm) ) 358 sGrfNm = INetURLObject::GetAbsURL( sBaseURL, sGrfNm ); 359 break; 360 case HTML_O_ALIGN: 361 eVertOri = 362 pOption->GetEnum( aHTMLImgVAlignTable, 363 text::VertOrientation::TOP ); 364 eHoriOri = 365 pOption->GetEnum( aHTMLImgHAlignTable, 366 text::HoriOrientation::NONE ); 367 break; 368 case HTML_O_WIDTH: 369 // erstmal nur als Pixelwerte merken! 370 nWidth = pOption->GetNumber(); 371 bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND); 372 if( bPrcWidth && nWidth>100 ) 373 nWidth = 100; 374 break; 375 case HTML_O_HEIGHT: 376 // erstmal nur als Pixelwerte merken! 377 nHeight = pOption->GetNumber(); 378 bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND); 379 if( bPrcHeight && nHeight>100 ) 380 nHeight = 100; 381 break; 382 case HTML_O_VSPACE: 383 nVSpace = pOption->GetNumber(); 384 break; 385 case HTML_O_HSPACE: 386 nHSpace = pOption->GetNumber(); 387 break; 388 case HTML_O_ALT: 389 sAltNm = pOption->GetString(); 390 break; 391 case HTML_O_BORDER: 392 nBorder = (sal_uInt16)pOption->GetNumber(); 393 break; 394 case HTML_O_ISMAP: 395 bIsMap = sal_True; 396 break; 397 case HTML_O_USEMAP: 398 aMap = pOption->GetString(); 399 break; 400 case HTML_O_NAME: 401 sHTMLGrfName = pOption->GetString(); 402 break; 403 404 case HTML_O_SDONLOAD: 405 eScriptType2 = STARBASIC; 406 case HTML_O_ONLOAD: 407 nEvent = SVX_EVENT_IMAGE_LOAD; 408 goto IMAGE_SETEVENT; 409 410 case HTML_O_SDONABORT: 411 eScriptType2 = STARBASIC; 412 case HTML_O_ONABORT: 413 nEvent = SVX_EVENT_IMAGE_ABORT; 414 goto IMAGE_SETEVENT; 415 416 case HTML_O_SDONERROR: 417 eScriptType2 = STARBASIC; 418 case HTML_O_ONERROR: 419 nEvent = SVX_EVENT_IMAGE_ERROR; 420 goto IMAGE_SETEVENT; 421 IMAGE_SETEVENT: 422 { 423 String sTmp( pOption->GetString() ); 424 if( sTmp.Len() ) 425 { 426 sTmp.ConvertLineEnd(); 427 String sScriptType; 428 if( EXTENDED_STYPE == eScriptType2 ) 429 sScriptType = sDfltScriptType; 430 aMacroItem.SetMacro( nEvent, 431 SvxMacro( sTmp, sScriptType, eScriptType2 )); 432 } 433 } 434 break; 435 } 436 } 437 438 if( !sGrfNm.Len() ) 439 return; 440 441 // Wenn wir in einer Numerierung stehen und der Absatz noch leer und 442 // nicht numeriert ist, handelt es sich vielleicht um die Grafik 443 // einer Bullet-Liste 444 if( !pPam->GetPoint()->nContent.GetIndex() && 445 GetNumInfo().GetDepth() > 0 && GetNumInfo().GetDepth() <= MAXLEVEL && 446 aBulletGrfs[GetNumInfo().GetDepth()-1].Len() && 447 aBulletGrfs[GetNumInfo().GetDepth()-1]==sGrfNm ) 448 { 449 SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode(); 450 451 if( pTxtNode && ! pTxtNode->IsCountedInList()) 452 { 453 ASSERT( pTxtNode->GetActualListLevel() == GetNumInfo().GetLevel(), 454 "Numerierungs-Ebene stimmt nicht" ); 455 456 pTxtNode->SetCountedInList( true ); 457 458 // Rule invalisieren ist noetig, weil zwischem dem einlesen 459 // des LI und der Grafik ein EndAction gerufen worden sein kann. 460 if( GetNumInfo().GetNumRule() ) 461 GetNumInfo().GetNumRule()->SetInvalidRule( sal_True ); 462 463 // Die Vorlage novh mal setzen. Ist noetig, damit der 464 // Erstzeilen-Einzug stimmt. 465 SetTxtCollAttrs(); 466 467 return; 468 } 469 } 470 471 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() ); 472 SvxCSS1PropertyInfo aPropInfo; 473 if( HasStyleOptions( aStyle, aId, aClass ) ) 474 ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo ); 475 476 SfxItemSet aFrmSet( pDoc->GetAttrPool(), 477 RES_FRMATR_BEGIN, RES_FRMATR_END-1 ); 478 if( !IsNewDoc() ) 479 Reader::ResetFrmFmtAttrs( aFrmSet ); 480 481 // Umrandung setzen 482 long nHBorderWidth = 0, nVBorderWidth = 0; 483 if( nBorder ) 484 { 485 nHBorderWidth = (long)nBorder; 486 nVBorderWidth = (long)nBorder; 487 SvxCSS1Parser::PixelToTwip( nVBorderWidth, nHBorderWidth ); 488 489 SvxBorderLine aHBorderLine; 490 SvxBorderLine aVBorderLine; 491 492 SvxCSS1Parser::SetBorderWidth( aHBorderLine, 493 (sal_uInt16)nHBorderWidth, sal_False ); 494 if( nHBorderWidth == nVBorderWidth ) 495 aVBorderLine.SetOutWidth( aHBorderLine.GetOutWidth() ); 496 else 497 SvxCSS1Parser::SetBorderWidth( aVBorderLine, 498 (sal_uInt16)nVBorderWidth, sal_False ); 499 500 // die tatsaechlich gesetzter Rahmenbreite benutzen und nicht die 501 // Wunschbreite! 502 nHBorderWidth = aHBorderLine.GetOutWidth(); 503 nVBorderWidth = aVBorderLine.GetOutWidth(); 504 505 if( aAttrTab.pINetFmt ) 506 { 507 const String& rURL = 508 ((const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem()).GetValue(); 509 510 pCSS1Parser->SetATagStyles(); 511 sal_uInt16 nPoolId = static_cast< sal_uInt16 >(pDoc->IsVisitedURL( rURL ) 512 ? RES_POOLCHR_INET_VISIT 513 : RES_POOLCHR_INET_NORMAL); 514 const SwCharFmt *pCharFmt = pCSS1Parser->GetCharFmtFromPool( nPoolId ); 515 aHBorderLine.SetColor( pCharFmt->GetColor().GetValue() ); 516 aVBorderLine.SetColor( aHBorderLine.GetColor() ); 517 } 518 else 519 { 520 const SvxColorItem& rColorItem = aAttrTab.pFontColor ? 521 (const SvxColorItem &)aAttrTab.pFontColor->GetItem() : 522 (const SvxColorItem &)pDoc->GetDefault(RES_CHRATR_COLOR); 523 aHBorderLine.SetColor( rColorItem.GetValue() ); 524 aVBorderLine.SetColor( aHBorderLine.GetColor() ); 525 } 526 527 528 SvxBoxItem aBoxItem( RES_BOX ); 529 aBoxItem.SetLine( &aHBorderLine, BOX_LINE_TOP ); 530 aBoxItem.SetLine( &aHBorderLine, BOX_LINE_BOTTOM ); 531 aBoxItem.SetLine( &aVBorderLine, BOX_LINE_LEFT ); 532 aBoxItem.SetLine( &aVBorderLine, BOX_LINE_RIGHT ); 533 aFrmSet.Put( aBoxItem ); 534 } 535 536 // Ausrichtung setzen 537 SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet ); 538 539 // Abstaende setzen 540 SetSpace( Size( nHSpace, nVSpace), aItemSet, aPropInfo, aFrmSet ); 541 542 // Sonstige CSS1-Attribute Setzen 543 SetFrmFmtAttrs( aItemSet, aPropInfo, HTML_FF_BOX, aFrmSet ); 544 545 Size aTwipSz( bPrcWidth ? 0 : nWidth, bPrcHeight ? 0 : nHeight ); 546 if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() ) 547 { 548 aTwipSz = Application::GetDefaultDevice() 549 ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) ); 550 } 551 552 // CSS1-Groesse auf "normale" Groesse umrechnen 553 switch( aPropInfo.eWidthType ) 554 { 555 case SVX_CSS1_LTYPE_TWIP: 556 aTwipSz.Width() = aPropInfo.nWidth; 557 nWidth = 1; // != 0 558 bPrcWidth = sal_False; 559 break; 560 case SVX_CSS1_LTYPE_PERCENTAGE: 561 aTwipSz.Width() = 0; 562 nWidth = aPropInfo.nWidth; 563 bPrcWidth = sal_True; 564 break; 565 default: 566 ; 567 } 568 switch( aPropInfo.eHeightType ) 569 { 570 case SVX_CSS1_LTYPE_TWIP: 571 aTwipSz.Height() = aPropInfo.nHeight; 572 nHeight = 1; // != 0 573 bPrcHeight = sal_False; 574 break; 575 case SVX_CSS1_LTYPE_PERCENTAGE: 576 aTwipSz.Height() = 0; 577 nHeight = aPropInfo.nHeight; 578 bPrcHeight = sal_True; 579 break; 580 default: 581 ; 582 } 583 584 Size aGrfSz( 0, 0 ); 585 sal_Bool bSetTwipSize = sal_True; // Twip-Size am Node setzen? 586 sal_Bool bChangeFrmSize = sal_False; // Frame-Format nachtraeglich anpassen? 587 sal_Bool bRequestGrfNow = sal_False; 588 sal_Bool bSetScaleImageMap = sal_False; 589 sal_uInt8 nPrcWidth = 0, nPrcHeight = 0; 590 591 if( !nWidth || !nHeight ) 592 { 593 // Es fehlt die Breite oder die Hoehe 594 // Wenn die Grfik in einer Tabelle steht, wird sie gleich 595 // angefordert, damit sie eventuell schon da ist, bevor die 596 // Tabelle layoutet wird. 597 if( pTable!=0 && !nWidth ) 598 { 599 bRequestGrfNow = sal_True; 600 IncGrfsThatResizeTable(); 601 } 602 603 // Die Groesse des Rahmens wird nachtraeglich gesetzt 604 bChangeFrmSize = sal_True; 605 aGrfSz = aTwipSz; 606 if( !nWidth && !nHeight ) 607 { 608 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH; 609 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT; 610 } 611 else if( nWidth ) 612 { 613 // eine %-Angabe 614 if( bPrcWidth ) 615 { 616 nPrcWidth = (sal_uInt8)nWidth; 617 nPrcHeight = 255; 618 } 619 else 620 { 621 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT; 622 } 623 } 624 else if( nHeight ) 625 { 626 if( bPrcHeight ) 627 { 628 nPrcHeight = (sal_uInt8)nHeight; 629 nPrcWidth = 255; 630 } 631 else 632 { 633 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH; 634 } 635 } 636 } 637 else 638 { 639 // Breite und Hoehe wurden angegeben und brauchen nicht gesetzt 640 // zu werden 641 bSetTwipSize = sal_False; 642 643 if( bPrcWidth ) 644 nPrcWidth = (sal_uInt8)nWidth; 645 646 if( bPrcHeight ) 647 nPrcHeight = (sal_uInt8)nHeight; 648 } 649 650 // Image-Map setzen 651 aMap.EraseTrailingChars(); 652 if( aMap.Len() ) 653 { 654 // Da wir nur lokale Image-Maps kennen nehmen wireinfach alles 655 // hinter dem # als Namen 656 xub_StrLen nPos = aMap.Search( '#' ); 657 String aName; 658 if ( STRING_NOTFOUND==nPos ) 659 aName = aMap ; 660 else 661 aName = aMap.Copy(nPos+1); 662 663 ImageMap *pImgMap = FindImageMap( aName ); 664 if( pImgMap ) 665 { 666 SwFmtURL aURL; aURL.SetMap( pImgMap );//wird kopieiert 667 668 bSetScaleImageMap = !nPrcWidth || !nPrcHeight; 669 aFrmSet.Put( aURL ); 670 } 671 else 672 { 673 ImageMap aEmptyImgMap( aName ); 674 SwFmtURL aURL; aURL.SetMap( &aEmptyImgMap );//wird kopieiert 675 aFrmSet.Put( aURL ); 676 nMissingImgMaps++; // es fehlen noch Image-Maps 677 678 // die Grafik muss beim SetTwipSize skaliert werden, wenn 679 // wir keine Groesse am Node gesetzt haben oder die Groesse 680 // nicht der Grafikgroesse entsprach. 681 bSetScaleImageMap = sal_True; 682 } 683 } 684 685 // min. Werte einhalten !! 686 if( nPrcWidth ) 687 { 688 ASSERT( !aTwipSz.Width(), 689 "Wieso ist da trotz %-Angabe eine Breite gesetzt?" ); 690 aTwipSz.Width() = aGrfSz.Width() ? aGrfSz.Width() 691 : HTML_DFLT_IMG_WIDTH; 692 } 693 else 694 { 695 aTwipSz.Width() += 2*nVBorderWidth; 696 if( aTwipSz.Width() < MINFLY ) 697 aTwipSz.Width() = MINFLY; 698 } 699 if( nPrcHeight ) 700 { 701 ASSERT( !aTwipSz.Height(), 702 "Wieso ist da trotz %-Angabe eine Hoehe gesetzt?" ); 703 aTwipSz.Height() = aGrfSz.Height() ? aGrfSz.Height() 704 : HTML_DFLT_IMG_HEIGHT; 705 } 706 else 707 { 708 aTwipSz.Height() += 2*nHBorderWidth; 709 if( aTwipSz.Height() < MINFLY ) 710 aTwipSz.Height() = MINFLY; 711 } 712 713 SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() ); 714 aFrmSize.SetWidthPercent( nPrcWidth ); 715 aFrmSize.SetHeightPercent( nPrcHeight ); 716 aFrmSet.Put( aFrmSize ); 717 718 Graphic aEmptyGrf; 719 aEmptyGrf.SetDefaultType(); 720 SwFrmFmt *pFlyFmt = pDoc->Insert( *pPam, sGrfNm, aEmptyStr, &aEmptyGrf, 721 &aFrmSet, NULL, NULL ); 722 SwGrfNode *pGrfNd = pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx() 723 ->GetIndex()+1 ]->GetGrfNode(); 724 725 if( sHTMLGrfName.Len() ) 726 { 727 pFlyFmt->SetName( sHTMLGrfName ); 728 729 // ggfs. eine Grafik anspringen 730 if( JUMPTO_GRAPHIC == eJumpTo && sHTMLGrfName == sJmpMark ) 731 { 732 bChkJumpMark = sal_True; 733 eJumpTo = JUMPTO_NONE; 734 } 735 } 736 737 if( sAltNm.Len() ) 738 pGrfNd->SetTitle( sAltNm ); 739 740 if( bSetTwipSize ) 741 pGrfNd->SetTwipSize( aGrfSz ); 742 743 pGrfNd->SetChgTwipSize( bChangeFrmSize, bChangeFrmSize ); 744 745 if( bSetScaleImageMap ) 746 pGrfNd->SetScaleImageMap( sal_True ); 747 748 if( aAttrTab.pINetFmt ) 749 { 750 const SwFmtINetFmt &rINetFmt = 751 (const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem(); 752 753 SwFmtURL aURL( pFlyFmt->GetURL() ); 754 755 aURL.SetURL( rINetFmt.GetValue(), bIsMap ); 756 aURL.SetTargetFrameName( rINetFmt.GetTargetFrame() ); 757 aURL.SetName( rINetFmt.GetName() ); 758 pFlyFmt->SetFmtAttr( aURL ); 759 760 { 761 const SvxMacro *pMacro; 762 static sal_uInt16 __READONLY_DATA aEvents[] = { 763 SFX_EVENT_MOUSEOVER_OBJECT, 764 SFX_EVENT_MOUSECLICK_OBJECT, 765 SFX_EVENT_MOUSEOUT_OBJECT, 766 0 }; 767 768 for( sal_uInt16 n = 0; aEvents[ n ]; ++n ) 769 if( 0 != ( pMacro = rINetFmt.GetMacro( aEvents[ n ] ) )) 770 aMacroItem.SetMacro( aEvents[ n ], *pMacro ); 771 } 772 773 if ((FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()) && 774 aAttrTab.pINetFmt->GetSttPara() == 775 pPam->GetPoint()->nNode && 776 aAttrTab.pINetFmt->GetSttCnt() == 777 pPam->GetPoint()->nContent.GetIndex() - 1 ) 778 { 779 // das Attribut wurde unmitellbar vor einer zeichengeb. 780 // Grafik eingefuegt, also verschieben wir es 781 aAttrTab.pINetFmt->SetStart( *pPam->GetPoint() ); 782 783 // Wenn das Attribut auch ein Sprungziel ist, fuegen 784 // wir noch eine Bookmark vor der Grafik ein, weil das 785 // SwFmtURL kein Sprungziel ist. 786 if( rINetFmt.GetName().Len() ) 787 { 788 pPam->Move( fnMoveBackward ); 789 InsertBookmark( rINetFmt.GetName() ); 790 pPam->Move( fnMoveForward ); 791 } 792 } 793 794 } 795 796 if( aMacroItem.GetMacroTable().Count() ) 797 pFlyFmt->SetFmtAttr( aMacroItem ); 798 799 // Wenn die Grafik gleich angeforder wird, muss dies geschehen, 800 // nachdem das Format vollstaendig aufgebaut ist, weil es evtl. 801 // gleich (synchron) angepasst wird (war bug #40983#) 802 if( bRequestGrfNow ) 803 { 804 pGrfNd->SwapIn(); 805 } 806 807 // Ggf. Frames anlegen und Auto-gebundenen Rahmen registrieren 808 RegisterFlyFrm( pFlyFmt ); 809 810 if( aId.Len() ) 811 InsertBookmark( aId ); 812 } 813 814 /* */ 815 816 void SwHTMLParser::InsertBodyOptions() 817 { 818 pDoc->SetTxtFmtColl( *pPam, 819 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); 820 821 String aBackGround, aId, aStyle, aLang, aDir; 822 Color aBGColor, aTextColor, aLinkColor, aVLinkColor; 823 sal_Bool bBGColor=sal_False, bTextColor=sal_False; 824 sal_Bool bLinkColor=sal_False, bVLinkColor=sal_False; 825 826 ScriptType eDfltScriptType; 827 String sDfltScriptType; 828 GetDefaultScriptType( eDfltScriptType, sDfltScriptType ); 829 830 const HTMLOptions *pHTMLOptions = GetOptions(); 831 for( sal_uInt16 i = pHTMLOptions->Count(); i; ) 832 { 833 const HTMLOption *pOption = (*pHTMLOptions)[--i]; 834 ScriptType eScriptType2 = eDfltScriptType; 835 rtl::OUString aEvent; 836 sal_Bool bSetEvent = sal_False; 837 838 switch( pOption->GetToken() ) 839 { 840 case HTML_O_ID: 841 aId = pOption->GetString(); 842 break; 843 case HTML_O_BACKGROUND: 844 aBackGround = pOption->GetString(); 845 break; 846 case HTML_O_BGCOLOR: 847 pOption->GetColor( aBGColor ); 848 bBGColor = sal_True; 849 break; 850 case HTML_O_TEXT: 851 pOption->GetColor( aTextColor ); 852 bTextColor = sal_True; 853 break; 854 case HTML_O_LINK: 855 pOption->GetColor( aLinkColor ); 856 bLinkColor = sal_True; 857 break; 858 case HTML_O_VLINK: 859 pOption->GetColor( aVLinkColor ); 860 bVLinkColor = sal_True; 861 break; 862 863 case HTML_O_SDONLOAD: 864 eScriptType2 = STARBASIC; 865 case HTML_O_ONLOAD: 866 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC ); 867 bSetEvent = sal_True; 868 break; 869 870 case HTML_O_SDONUNLOAD: 871 eScriptType2 = STARBASIC; 872 case HTML_O_ONUNLOAD: 873 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_PREPARECLOSEDOC ); 874 bSetEvent = sal_True; 875 break; 876 877 case HTML_O_SDONFOCUS: 878 eScriptType2 = STARBASIC; 879 case HTML_O_ONFOCUS: 880 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC ); 881 bSetEvent = sal_True; 882 break; 883 884 case HTML_O_SDONBLUR: 885 eScriptType2 = STARBASIC; 886 case HTML_O_ONBLUR: 887 aEvent = GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC ); 888 bSetEvent = sal_True; 889 break; 890 891 case HTML_O_ONERROR: 892 // if( bAnyStarBasic ) 893 // InsertBasicDocEvent( SFX_EVENT_ACTIVATEDOC, 894 // pOption->GetString() ); 895 break; 896 897 case HTML_O_STYLE: 898 aStyle = pOption->GetString(); 899 bTextColor = sal_True; 900 break; 901 case HTML_O_LANG: 902 aLang = pOption->GetString(); 903 break; 904 case HTML_O_DIR: 905 aDir = pOption->GetString(); 906 break; 907 } 908 909 if( bSetEvent ) 910 { 911 const String& rEvent = pOption->GetString(); 912 if( rEvent.Len() ) 913 InsertBasicDocEvent( aEvent, rEvent, eScriptType2, 914 sDfltScriptType ); 915 } 916 } 917 918 if( bTextColor && !pCSS1Parser->IsBodyTextSet() ) 919 { 920 // Die Textfarbe wird an der Standard-Vorlage gesetzt 921 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) 922 ->SetFmtAttr( SvxColorItem(aTextColor, RES_CHRATR_COLOR) ); 923 pCSS1Parser->SetBodyTextSet(); 924 } 925 926 927 // Die Item fuer die Seitenvorlage vorbereiten (Hintergrund, Umrandung) 928 // Beim BrushItem muessen schon gesetzte werte erhalten bleiben! 929 SvxBrushItem aBrushItem( pCSS1Parser->GetPageDescBackground() ); 930 sal_Bool bSetBrush = sal_False; 931 932 if( bBGColor && !pCSS1Parser->IsBodyBGColorSet() ) 933 { 934 // Hintergrundfarbe aus "BGCOLOR" 935 String aLink; 936 if( aBrushItem.GetGraphicLink() ) 937 aLink = *aBrushItem.GetGraphicLink(); 938 SvxGraphicPosition ePos = aBrushItem.GetGraphicPos(); 939 940 aBrushItem.SetColor( aBGColor ); 941 942 if( aLink.Len() ) 943 { 944 aBrushItem.SetGraphicLink( aLink ); 945 aBrushItem.SetGraphicPos( ePos ); 946 } 947 bSetBrush = sal_True; 948 pCSS1Parser->SetBodyBGColorSet(); 949 } 950 951 if( aBackGround.Len() && !pCSS1Parser->IsBodyBackgroundSet() ) 952 { 953 // Hintergrundgrafik aus "BACKGROUND" 954 aBrushItem.SetGraphicLink( INetURLObject::GetAbsURL( sBaseURL, aBackGround ) ); 955 aBrushItem.SetGraphicPos( GPOS_TILED ); 956 bSetBrush = sal_True; 957 pCSS1Parser->SetBodyBackgroundSet(); 958 } 959 960 if( aStyle.Len() || aDir.Len() ) 961 { 962 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() ); 963 SvxCSS1PropertyInfo aPropInfo; 964 String aDummy; 965 ParseStyleOptions( aStyle, aDummy, aDummy, aItemSet, aPropInfo, 0, &aDir ); 966 967 // Ein par Attribute muessen an der Seitenvorlage gesetzt werden, 968 // und zwar die, die nicht vererbit werden 969 pCSS1Parser->SetPageDescAttrs( bSetBrush ? &aBrushItem : 0, 970 &aItemSet ); 971 972 const SfxPoolItem *pItem; 973 static sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE, 974 RES_CHRATR_CJK_FONTSIZE, 975 RES_CHRATR_CTL_FONTSIZE }; 976 for( sal_uInt16 i=0; i<3; i++ ) 977 { 978 if( SFX_ITEM_SET == aItemSet.GetItemState( aWhichIds[i], sal_False, 979 &pItem ) && 980 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() != 100) 981 { 982 sal_uInt32 nHeight = 983 ( aFontHeights[2] * 984 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() ) / 100; 985 SvxFontHeightItem aNewItem( nHeight, 100, aWhichIds[i] ); 986 aItemSet.Put( aNewItem ); 987 } 988 } 989 990 // alle noch uebrigen Optionen koennen an der Standard-Vorlage 991 // gesetzt werden und gelten dann automatisch als defaults 992 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) 993 ->SetFmtAttr( aItemSet ); 994 } 995 else if( bSetBrush ) 996 { 997 pCSS1Parser->SetPageDescAttrs( &aBrushItem ); 998 } 999 1000 if( bLinkColor && !pCSS1Parser->IsBodyLinkSet() ) 1001 { 1002 SwCharFmt *pCharFmt = 1003 pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_NORMAL); 1004 pCharFmt->SetFmtAttr( SvxColorItem(aLinkColor, RES_CHRATR_COLOR) ); 1005 pCSS1Parser->SetBodyLinkSet(); 1006 } 1007 if( bVLinkColor && !pCSS1Parser->IsBodyVLinkSet() ) 1008 { 1009 SwCharFmt *pCharFmt = 1010 pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_VISIT); 1011 pCharFmt->SetFmtAttr( SvxColorItem(aVLinkColor, RES_CHRATR_COLOR) ); 1012 pCSS1Parser->SetBodyVLinkSet(); 1013 } 1014 if( aLang.Len() ) 1015 { 1016 LanguageType eLang = MsLangId::convertIsoStringToLanguage( aLang ); 1017 sal_uInt16 nWhich = 0; 1018 if( LANGUAGE_DONTKNOW != eLang ) 1019 { 1020 switch( SvtLanguageOptions::GetScriptTypeOfLanguage( eLang ) ) 1021 { 1022 case SCRIPTTYPE_LATIN: 1023 nWhich = RES_CHRATR_LANGUAGE; 1024 break; 1025 case SCRIPTTYPE_ASIAN: 1026 nWhich = RES_CHRATR_CJK_LANGUAGE; 1027 break; 1028 case SCRIPTTYPE_COMPLEX: 1029 nWhich = RES_CHRATR_CTL_LANGUAGE; 1030 break; 1031 } 1032 if( nWhich ) 1033 { 1034 SvxLanguageItem aLanguage( eLang, nWhich ); 1035 aLanguage.SetWhich( nWhich ); 1036 pDoc->SetDefault( aLanguage ); 1037 } 1038 } 1039 } 1040 1041 if( aId.Len() ) 1042 InsertBookmark( aId ); 1043 } 1044 1045 /* */ 1046 1047 void SwHTMLParser::NewAnchor() 1048 { 1049 // den voherigen Link beenden, falls es einen gab 1050 _HTMLAttrContext *pOldCntxt = PopContext( HTML_ANCHOR_ON ); 1051 if( pOldCntxt ) 1052 { 1053 // und ggf. die Attribute beenden 1054 EndContext( pOldCntxt ); 1055 delete pOldCntxt; 1056 } 1057 1058 SvxMacroTableDtor aMacroTbl; 1059 String sHRef, aName, sTarget; 1060 String aId, aStyle, aClass, aLang, aDir; 1061 sal_Bool bHasHRef = sal_False, bFixed = sal_False; 1062 1063 ScriptType eDfltScriptType; 1064 String sDfltScriptType; 1065 GetDefaultScriptType( eDfltScriptType, sDfltScriptType ); 1066 1067 const HTMLOptions *pHTMLOptions = GetOptions(); 1068 for( sal_uInt16 i = pHTMLOptions->Count(); i; ) 1069 { 1070 sal_uInt16 nEvent = 0; 1071 ScriptType eScriptType2 = eDfltScriptType; 1072 const HTMLOption *pOption = (*pHTMLOptions)[--i]; 1073 switch( pOption->GetToken() ) 1074 { 1075 case HTML_O_NAME: 1076 aName = pOption->GetString(); 1077 break; 1078 1079 case HTML_O_HREF: 1080 sHRef = pOption->GetString(); 1081 bHasHRef = sal_True; 1082 break; 1083 case HTML_O_TARGET: 1084 sTarget = pOption->GetString(); 1085 break; 1086 1087 case HTML_O_STYLE: 1088 aStyle = pOption->GetString(); 1089 break; 1090 case HTML_O_ID: 1091 aId = pOption->GetString(); 1092 break; 1093 case HTML_O_CLASS: 1094 aClass = pOption->GetString(); 1095 break; 1096 case HTML_O_SDFIXED: 1097 bFixed = sal_True; 1098 break; 1099 case HTML_O_LANG: 1100 aLang = pOption->GetString(); 1101 break; 1102 case HTML_O_DIR: 1103 aDir = pOption->GetString(); 1104 break; 1105 1106 case HTML_O_SDONCLICK: 1107 eScriptType2 = STARBASIC; 1108 case HTML_O_ONCLICK: 1109 nEvent = SFX_EVENT_MOUSECLICK_OBJECT; 1110 goto ANCHOR_SETEVENT; 1111 1112 case HTML_O_SDONMOUSEOVER: 1113 eScriptType2 = STARBASIC; 1114 case HTML_O_ONMOUSEOVER: 1115 nEvent = SFX_EVENT_MOUSEOVER_OBJECT; 1116 goto ANCHOR_SETEVENT; 1117 1118 case HTML_O_SDONMOUSEOUT: 1119 eScriptType2 = STARBASIC; 1120 case HTML_O_ONMOUSEOUT: 1121 nEvent = SFX_EVENT_MOUSEOUT_OBJECT; 1122 goto ANCHOR_SETEVENT; 1123 ANCHOR_SETEVENT: 1124 { 1125 String sTmp( pOption->GetString() ); 1126 if( sTmp.Len() ) 1127 { 1128 sTmp.ConvertLineEnd(); 1129 String sScriptType; 1130 if( EXTENDED_STYPE == eScriptType2 ) 1131 sScriptType = sDfltScriptType; 1132 aMacroTbl.Insert( nEvent, 1133 new SvxMacro( sTmp, sScriptType, eScriptType2 )); 1134 } 1135 } 1136 break; 1137 1138 } 1139 } 1140 1141 // Sprungziele, die unseren ipmliziten Zielen entsprechen, schmeissen 1142 // wir hier ganz rigoros raus. 1143 if( aName.Len() ) 1144 { 1145 String sDecoded( INetURLObject::decode( aName, INET_HEX_ESCAPE, 1146 INetURLObject::DECODE_UNAMBIGUOUS, 1147 RTL_TEXTENCODING_UTF8 )); 1148 xub_StrLen nPos = sDecoded.SearchBackward( cMarkSeperator ); 1149 if( STRING_NOTFOUND != nPos ) 1150 { 1151 String sCmp( sDecoded.Copy( nPos+1 ) ); 1152 sCmp.EraseAllChars(); 1153 if( sCmp.Len() ) 1154 { 1155 sCmp.ToLowerAscii(); 1156 if( sCmp.EqualsAscii( pMarkToRegion ) || 1157 sCmp.EqualsAscii( pMarkToFrame ) || 1158 sCmp.EqualsAscii( pMarkToGraphic ) || 1159 sCmp.EqualsAscii( pMarkToOLE ) || 1160 sCmp.EqualsAscii( pMarkToTable ) || 1161 sCmp.EqualsAscii( pMarkToOutline ) || 1162 sCmp.EqualsAscii( pMarkToText ) ) 1163 { 1164 aName.Erase(); 1165 } 1166 } 1167 } 1168 } 1169 1170 // einen neuen Kontext anlegen 1171 _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_ANCHOR_ON ); 1172 1173 sal_Bool bEnAnchor = sal_False, bFtnAnchor = sal_False, bFtnEnSymbol = sal_False; 1174 String aFtnName; 1175 String aStrippedClass( aClass ); 1176 SwCSS1Parser::GetScriptFromClass( aStrippedClass, sal_False ); 1177 if( aStrippedClass.Len() >=9 && bHasHRef && sHRef.Len() > 1 && 1178 ('s' == aStrippedClass.GetChar(0) || 'S' == aStrippedClass.GetChar(0)) && 1179 ('d' == aStrippedClass.GetChar(1) || 'D' == aStrippedClass.GetChar(1)) ) 1180 { 1181 if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc ) ) 1182 bEnAnchor = sal_True; 1183 else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc ) ) 1184 bFtnAnchor = sal_True; 1185 else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym ) || 1186 aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym ) ) 1187 bFtnEnSymbol = sal_True; 1188 if( bEnAnchor || bFtnAnchor || bFtnEnSymbol ) 1189 { 1190 aFtnName = sHRef.Copy( 1 ); 1191 aClass = aStrippedClass = aName = aEmptyStr; 1192 bHasHRef = sal_False; 1193 } 1194 } 1195 1196 // Styles parsen 1197 if( HasStyleOptions( aStyle, aId, aStrippedClass, &aLang, &aDir ) ) 1198 { 1199 SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() ); 1200 SvxCSS1PropertyInfo aPropInfo; 1201 1202 if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) ) 1203 { 1204 DoPositioning( aItemSet, aPropInfo, pCntxt ); 1205 InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True ); 1206 } 1207 } 1208 1209 if( bHasHRef ) 1210 { 1211 if( sHRef.Len() ) 1212 { 1213 sHRef = URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), sHRef, Link(), false ); 1214 } 1215 else 1216 { 1217 // Bei leerer URL das Directory nehmen 1218 INetURLObject aURLObj( aPathToFile ); 1219 sHRef = aURLObj.GetPartBeforeLastName(); 1220 } 1221 1222 pCSS1Parser->SetATagStyles(); 1223 SwFmtINetFmt aINetFmt( sHRef, sTarget ); 1224 aINetFmt.SetName( aName ); 1225 1226 if( aMacroTbl.Count() ) 1227 aINetFmt.SetMacroTbl( &aMacroTbl ); 1228 1229 // das Default-Attribut setzen 1230 InsertAttr( &aAttrTab.pINetFmt, aINetFmt, pCntxt ); 1231 } 1232 else if( aName.Len() ) 1233 { 1234 InsertBookmark( aName ); 1235 } 1236 1237 if( bEnAnchor || bFtnAnchor ) 1238 { 1239 InsertFootEndNote( aFtnName, bEnAnchor, bFixed ); 1240 bInFootEndNoteAnchor = bCallNextToken = sal_True; 1241 } 1242 else if( bFtnEnSymbol ) 1243 { 1244 bInFootEndNoteSymbol = bCallNextToken = sal_True; 1245 } 1246 1247 // den Kontext merken 1248 PushContext( pCntxt ); 1249 } 1250 1251 void SwHTMLParser::EndAnchor() 1252 { 1253 if( bInFootEndNoteAnchor ) 1254 { 1255 FinishFootEndNote(); 1256 bInFootEndNoteAnchor = sal_False; 1257 } 1258 else if( bInFootEndNoteSymbol ) 1259 { 1260 bInFootEndNoteSymbol = sal_False; 1261 } 1262 1263 EndTag( HTML_ANCHOR_OFF ); 1264 } 1265 1266 /* */ 1267 1268 void SwHTMLParser::InsertBookmark( const String& rName ) 1269 { 1270 _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), 1271 SfxStringItem( RES_FLTR_BOOKMARK, rName )); 1272 aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() ); 1273 } 1274 1275 sal_Bool SwHTMLParser::HasCurrentParaBookmarks( sal_Bool bIgnoreStack ) const 1276 { 1277 sal_Bool bHasMarks = sal_False; 1278 sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex(); 1279 1280 // first step: are there still bookmark in the attribute-stack? 1281 // bookmarks are added to the end of the stack - thus we only have 1282 // to check the last bookmark 1283 if( !bIgnoreStack ) 1284 { 1285 _HTMLAttr* pAttr; 1286 for( sal_uInt16 i = aSetAttrTab.Count(); i; ) 1287 { 1288 pAttr = aSetAttrTab[ --i ]; 1289 if( RES_FLTR_BOOKMARK == pAttr->pItem->Which() ) 1290 { 1291 if( pAttr->GetSttParaIdx() == nNodeIdx ) 1292 bHasMarks = sal_True; 1293 break; 1294 } 1295 } 1296 } 1297 1298 if( !bHasMarks ) 1299 { 1300 // second step: when we didnt find a bookmark, check if there is one 1301 // set already 1302 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); 1303 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin(); 1304 ppMark != pMarkAccess->getMarksEnd(); 1305 ppMark++) 1306 { 1307 const ::sw::mark::IMark* pBookmark = ppMark->get(); 1308 sal_uLong nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex(); 1309 if( nBookNdIdx==nNodeIdx ) 1310 { 1311 bHasMarks = sal_True; 1312 break; 1313 } 1314 else if( nBookNdIdx > nNodeIdx ) 1315 break; 1316 } 1317 } 1318 1319 return bHasMarks; 1320 } 1321 1322 /* */ 1323 1324 void SwHTMLParser::StripTrailingPara() 1325 { 1326 sal_Bool bSetSmallFont = sal_False; 1327 1328 SwCntntNode* pCNd = pPam->GetCntntNode(); 1329 if( !pPam->GetPoint()->nContent.GetIndex() ) 1330 { 1331 if( pCNd && pCNd->StartOfSectionIndex()+2 < 1332 pCNd->EndOfSectionIndex() ) 1333 { 1334 sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex(); 1335 1336 const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts(); 1337 1338 for( sal_uInt16 i=0; i<rFrmFmtTbl.Count(); i++ ) 1339 { 1340 SwFrmFmt const*const pFmt = rFrmFmtTbl[i]; 1341 SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor(); 1342 SwPosition const*const pAPos = pAnchor->GetCntntAnchor(); 1343 if (pAPos && 1344 ((FLY_AT_PARA == pAnchor->GetAnchorId()) || 1345 (FLY_AT_CHAR == pAnchor->GetAnchorId())) && 1346 pAPos->nNode == nNodeIdx ) 1347 1348 return; // den Knoten duerfen wir nicht loeschen 1349 } 1350 1351 SetAttr( sal_False ); // die noch offenen Attribute muessen 1352 // beendet werden, bevor der Node 1353 // geloescht wird, weil sonst der 1354 // End-Index in die Botanik zeigt 1355 1356 if( pCNd->Len() && pCNd->IsTxtNode() ) 1357 { 1358 // es wurden Felder in den Node eingefuegt, die muessen 1359 // wir jetzt verschieben 1360 SwTxtNode *pPrvNd = pDoc->GetNodes()[nNodeIdx-1]->GetTxtNode(); 1361 if( pPrvNd ) 1362 { 1363 SwIndex aSrc( pCNd, 0 ); 1364 pCNd->GetTxtNode()->CutText( pPrvNd, aSrc, pCNd->Len() ); 1365 } 1366 } 1367 1368 // jetz muessen wir noch eventuell vorhandene Bookmarks 1369 // verschieben 1370 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); 1371 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin(); 1372 ppMark != pMarkAccess->getMarksEnd(); 1373 ppMark++) 1374 { 1375 ::sw::mark::IMark* pMark = ppMark->get(); 1376 sal_uLong nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex(); 1377 if(nBookNdIdx==nNodeIdx) 1378 { 1379 SwNodeIndex nNewNdIdx(pPam->GetPoint()->nNode); 1380 SwCntntNode* pNd = pDoc->GetNodes().GoPrevious(&nNewNdIdx); 1381 if(!pNd) 1382 { 1383 ASSERT(!this, "Hoppla, wo ist mein Vorgaenger-Node"); 1384 return; 1385 } 1386 // --> OD 2007-09-27 #i81002# - refactoring 1387 // Do not directly manipulate member of <SwBookmark> 1388 { 1389 SwPosition aNewPos(*pNd); 1390 aNewPos.nContent.Assign(pNd, pNd->Len()); 1391 const SwPaM aPaM(aNewPos); 1392 pMarkAccess->repositionMark(ppMark->get(), aPaM); 1393 } 1394 // <-- 1395 } 1396 else if( nBookNdIdx > nNodeIdx ) 1397 break; 1398 } 1399 1400 pPam->GetPoint()->nContent.Assign( 0, 0 ); 1401 pPam->SetMark(); 1402 pPam->DeleteMark(); 1403 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode ); 1404 pPam->Move( fnMoveBackward, fnGoNode ); 1405 } 1406 else if( pCNd && pCNd->IsTxtNode() && pTable ) 1407 { 1408 // In leeren Zellen stellen wir einen kleinen Font ein, damit die 1409 // Zelle nicht hoeher wird als die Grafik bzw. so niedrig wie 1410 // moeglich bleibt. 1411 bSetSmallFont = sal_True; 1412 } 1413 } 1414 else if( pCNd && pCNd->IsTxtNode() && pTable && 1415 pCNd->StartOfSectionIndex()+2 == 1416 pCNd->EndOfSectionIndex() ) 1417 { 1418 // Wenn die Zelle nur zeichengebundene Grafiken/Rahmen enthaelt 1419 // stellen wir ebenfalls einen kleinen Font ein. 1420 bSetSmallFont = sal_True; 1421 SwTxtNode* pTxtNd = pCNd->GetTxtNode(); 1422 1423 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex(); 1424 while( bSetSmallFont && nPos>0 ) 1425 { 1426 --nPos; 1427 bSetSmallFont = 1428 (CH_TXTATR_BREAKWORD == pTxtNd->GetTxt().GetChar( nPos )) && 1429 (0 != pTxtNd->GetTxtAttrForCharAt( nPos, RES_TXTATR_FLYCNT )); 1430 } 1431 } 1432 1433 if( bSetSmallFont ) 1434 { 1435 SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE ); 1436 pCNd->SetAttr( aFontHeight ); 1437 aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE ); 1438 pCNd->SetAttr( aFontHeight ); 1439 aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE ); 1440 pCNd->SetAttr( aFontHeight ); 1441 } 1442 } 1443 1444