build fix
[LibreOffice.git] / sw / source / filter / html / htmlgrin.cxx
blob72078ba857544fdcd2ac14faceee2472269c48dd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "hintids.hxx"
21 #include <comphelper/string.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/wrkwin.hxx>
24 #include <svx/svxids.hrc>
25 #include <sfx2/sfx.hrc>
26 #include <i18nlangtag/languagetag.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/urihelper.hxx>
29 #include <editeng/fhgtitem.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <editeng/adjustitem.hxx>
32 #include <editeng/brushitem.hxx>
33 #include <editeng/colritem.hxx>
34 #include <editeng/boxitem.hxx>
35 #include <editeng/ulspitem.hxx>
36 #include <editeng/langitem.hxx>
37 #include <editeng/scripttypeitem.hxx>
38 #include <sfx2/docfile.hxx>
39 #include <svtools/imap.hxx>
40 #include <svtools/htmltokn.h>
41 #include <svtools/htmlkywd.hxx>
42 #include <unotools/eventcfg.hxx>
44 #include <fmtornt.hxx>
45 #include <fmturl.hxx>
46 #include <fmtsrnd.hxx>
47 #include <fmtinfmt.hxx>
48 #include <fmtcntnt.hxx>
49 #include <fmtanchr.hxx>
50 #include <fmtfsize.hxx>
51 #include "frmatr.hxx"
52 #include "charatr.hxx"
53 #include <frmfmt.hxx>
54 #include <charfmt.hxx>
55 #include <docary.hxx>
56 #include <docsh.hxx>
57 #include <pam.hxx>
58 #include <doc.hxx>
59 #include <ndtxt.hxx>
60 #include <shellio.hxx>
61 #include <poolfmt.hxx>
62 #include <IMark.hxx>
63 #include <ndgrf.hxx>
64 #include <htmlnum.hxx>
65 #include <swcss1.hxx>
66 #include <swhtml.hxx>
67 #include <numrule.hxx>
69 #include <vcl/graphicfilter.hxx>
70 #include <tools/urlobj.hxx>
72 using namespace ::com::sun::star;
74 HTMLOptionEnum aHTMLImgHAlignTable[] =
76 { OOO_STRING_SVTOOLS_HTML_AL_left, text::HoriOrientation::LEFT },
77 { OOO_STRING_SVTOOLS_HTML_AL_right, text::HoriOrientation::RIGHT },
78 { nullptr, 0 }
81 HTMLOptionEnum aHTMLImgVAlignTable[] =
83 { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::LINE_TOP },
84 { OOO_STRING_SVTOOLS_HTML_VA_texttop, text::VertOrientation::CHAR_TOP },
85 { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER },
86 { OOO_STRING_SVTOOLS_HTML_AL_center, text::VertOrientation::CENTER },
87 { OOO_STRING_SVTOOLS_HTML_VA_absmiddle, text::VertOrientation::LINE_CENTER },
88 { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::TOP },
89 { OOO_STRING_SVTOOLS_HTML_VA_baseline, text::VertOrientation::TOP },
90 { OOO_STRING_SVTOOLS_HTML_VA_absbottom, text::VertOrientation::LINE_BOTTOM },
91 { nullptr, 0 }
94 ImageMap *SwHTMLParser::FindImageMap( const OUString& rName ) const
96 OSL_ENSURE( rName[0] != '#', "FindImageMap: name begins with '#'!" );
98 if (m_pImageMaps)
100 for (auto &rpIMap : *m_pImageMaps)
102 if (rName.equalsIgnoreAsciiCase(rpIMap->GetName()))
104 return rpIMap.get();
108 return nullptr;
111 void SwHTMLParser::ConnectImageMaps()
113 SwNodes& rNds = m_pDoc->GetNodes();
114 // auf den Start-Node der 1. Section
115 sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 1;
116 sal_uLong nEndIdx = rNds.GetEndOfAutotext().GetIndex();
118 SwGrfNode* pGrfNd;
119 while( m_nMissingImgMaps > 0 && nIdx < nEndIdx )
121 SwNode *pNd = rNds[nIdx + 1];
122 if( nullptr != (pGrfNd = pNd->GetGrfNode()) )
124 SwFrameFormat *pFormat = pGrfNd->GetFlyFormat();
125 SwFormatURL aURL( pFormat->GetURL() );
126 const ImageMap *pIMap = aURL.GetMap();
127 if( pIMap && pIMap->GetIMapObjectCount()==0 )
129 // Die (leere) Image-Map des Nodes wird entweder
130 // durch die jetzt gefundene Image-Map ersetzt
131 // oder geloescht.
132 ImageMap *pNewIMap =
133 FindImageMap( pIMap->GetName() );
134 aURL.SetMap( pNewIMap );
135 pFormat->SetFormatAttr( aURL );
136 if( !pGrfNd->IsScaleImageMap() )
138 // die Grafikgroesse ist mitlerweile da oder dir
139 // Grafik muss nicht skaliert werden
140 pGrfNd->ScaleImageMap();
142 m_nMissingImgMaps--; // eine Map weniger suchen
145 nIdx = rNds[nIdx]->EndOfSectionIndex() + 1;
149 /* */
151 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
152 sal_Int16 eHoriOri,
153 const SfxItemSet &rCSS1ItemSet,
154 const SvxCSS1PropertyInfo &rCSS1PropInfo,
155 SfxItemSet& rFrameItemSet )
157 const SfxItemSet *pCntnrItemSet = nullptr;
158 auto i = m_aContexts.size();
159 while( !pCntnrItemSet && i > m_nContextStMin )
160 pCntnrItemSet = m_aContexts[--i]->GetFrameItemSet();
162 if( pCntnrItemSet )
164 // Wenn wir und in einem Container befinden wird die Verankerung
165 // des Containers uebernommen.
166 rFrameItemSet.Put( *pCntnrItemSet );
168 else if( SwCSS1Parser::MayBePositioned( rCSS1PropInfo, true ) )
170 // Wenn die Ausrichtung anhand der CSS1-Optionen gesetzt werden kann
171 // werden die benutzt.
172 SetAnchorAndAdjustment( rCSS1ItemSet, rCSS1PropInfo, rFrameItemSet );
174 else
176 // Sonst wird die Ausrichtung entsprechend der normalen HTML-Optionen
177 // gesetzt.
178 SetAnchorAndAdjustment( eVertOri, eHoriOri, rFrameItemSet );
182 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
183 sal_Int16 eHoriOri,
184 SfxItemSet& rFrameSet,
185 bool bDontAppend )
187 bool bMoveBackward = false;
188 SwFormatAnchor aAnchor( FLY_AS_CHAR );
189 sal_Int16 eVertRel = text::RelOrientation::FRAME;
191 if( text::HoriOrientation::NONE != eHoriOri )
193 // den Absatz-Einzug bestimmen
194 sal_uInt16 nLeftSpace = 0, nRightSpace = 0;
195 short nIndent = 0;
196 GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
198 // Horizonale Ausrichtung und Umlauf bestimmen.
199 sal_Int16 eHoriRel;
200 SwSurround eSurround;
201 switch( eHoriOri )
203 case text::HoriOrientation::LEFT:
204 eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
205 eSurround = SURROUND_RIGHT;
206 break;
207 case text::HoriOrientation::RIGHT:
208 eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
209 eSurround = SURROUND_LEFT;
210 break;
211 case text::HoriOrientation::CENTER: // fuer Tabellen
212 eHoriRel = text::RelOrientation::FRAME;
213 eSurround = SURROUND_NONE;
214 break;
215 default:
216 eHoriRel = text::RelOrientation::FRAME;
217 eSurround = SURROUND_PARALLEL;
218 break;
221 // Einen neuen Absatz aufmachen, wenn der aktuelle
222 // absatzgebundene Rahmen ohne Umlauf enthaelt.
223 if( !bDontAppend && HasCurrentParaFlys( true ) )
225 // Wenn der Absatz nur Grafiken enthaelt, braucht er
226 // auch keinen unteren Absatz-Abstand. Da hier auch bei
227 // Verwendung von Styles kein Abstand enstehen soll, wird
228 // hier auch geweohnlich attributiert !!!
229 sal_uInt16 nUpper=0, nLower=0;
230 GetULSpaceFromContext( nUpper, nLower );
231 InsertAttr( SvxULSpaceItem( nUpper, 0, RES_UL_SPACE ), true );
233 AppendTextNode( AM_NOSPACE );
235 if( nUpper )
237 NewAttr( &m_aAttrTab.pULSpace, SvxULSpaceItem( 0, nLower, RES_UL_SPACE ) );
238 m_aParaAttrs.push_back( m_aAttrTab.pULSpace );
239 EndAttr( m_aAttrTab.pULSpace, false );
243 // Vertikale Ausrichtung und Verankerung bestimmen.
244 const sal_Int32 nContent = m_pPam->GetPoint()->nContent.GetIndex();
245 if( nContent )
247 aAnchor.SetType( FLY_AT_CHAR );
248 bMoveBackward = true;
249 eVertOri = text::VertOrientation::CHAR_BOTTOM;
250 eVertRel = text::RelOrientation::CHAR;
252 else
254 aAnchor.SetType( FLY_AT_PARA );
255 eVertOri = text::VertOrientation::TOP;
256 eVertRel = text::RelOrientation::PRINT_AREA;
259 rFrameSet.Put( SwFormatHoriOrient( 0, eHoriOri, eHoriRel) );
261 rFrameSet.Put( SwFormatSurround( eSurround ) );
263 rFrameSet.Put( SwFormatVertOrient( 0, eVertOri, eVertRel) );
265 if( bMoveBackward )
266 m_pPam->Move( fnMoveBackward );
268 aAnchor.SetAnchor( m_pPam->GetPoint() );
270 if( bMoveBackward )
271 m_pPam->Move( fnMoveForward );
273 rFrameSet.Put( aAnchor );
276 void SwHTMLParser::RegisterFlyFrame( SwFrameFormat *pFlyFormat )
278 // automatisch verankerte Rahmen muessen noch um eine Position
279 // nach vorne verschoben werden.
280 if( RES_DRAWFRMFMT != pFlyFormat->Which() &&
281 (FLY_AT_PARA == pFlyFormat->GetAnchor().GetAnchorId()) &&
282 SURROUND_THROUGHT == pFlyFormat->GetSurround().GetSurround() )
284 m_aMoveFlyFrames.push_back( pFlyFormat );
285 m_aMoveFlyCnts.push_back( m_pPam->GetPoint()->nContent.GetIndex() );
289 /* */
291 void SwHTMLParser::GetDefaultScriptType( ScriptType& rType,
292 OUString& rTypeStr ) const
294 SwDocShell *pDocSh = m_pDoc->GetDocShell();
295 SvKeyValueIterator* pHeaderAttrs = pDocSh ? pDocSh->GetHeaderAttributes()
296 : nullptr;
297 rType = GetScriptType( pHeaderAttrs );
298 rTypeStr = GetScriptTypeString( pHeaderAttrs );
301 /* */
303 void SwHTMLParser::InsertImage()
305 // und jetzt auswerten
306 OUString sAltNm, aId, aClass, aStyle, aMap, sHTMLGrfName;
307 OUString sGrfNm;
308 sal_Int16 eVertOri = text::VertOrientation::TOP;
309 sal_Int16 eHoriOri = text::HoriOrientation::NONE;
310 bool bWidthProvided=false, bHeightProvided=false;
311 long nWidth=0, nHeight=0;
312 long nVSpace=0, nHSpace=0;
314 sal_uInt16 nBorder = (m_aAttrTab.pINetFormat ? 1 : 0);
315 bool bIsMap = false;
316 bool bPrcWidth = false;
317 bool bPrcHeight = false;
318 SvxMacroItem aMacroItem(RES_FRMMACRO);
320 ScriptType eDfltScriptType;
321 OUString sDfltScriptType;
322 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
324 const HTMLOptions& rHTMLOptions = GetOptions();
325 for (size_t i = rHTMLOptions.size(); i; )
327 sal_uInt16 nEvent = 0;
328 ScriptType eScriptType2 = eDfltScriptType;
329 const HTMLOption& rOption = rHTMLOptions[--i];
330 switch( rOption.GetToken() )
332 case HTML_O_ID:
333 aId = rOption.GetString();
334 break;
335 case HTML_O_STYLE:
336 aStyle = rOption.GetString();
337 break;
338 case HTML_O_CLASS:
339 aClass = rOption.GetString();
340 break;
341 case HTML_O_SRC:
342 sGrfNm = rOption.GetString();
343 if( !InternalImgToPrivateURL(sGrfNm) )
344 sGrfNm = INetURLObject::GetAbsURL( m_sBaseURL, sGrfNm );
345 break;
346 case HTML_O_ALIGN:
347 eVertOri =
348 rOption.GetEnum( aHTMLImgVAlignTable,
349 text::VertOrientation::TOP );
350 eHoriOri =
351 rOption.GetEnum( aHTMLImgHAlignTable );
352 break;
353 case HTML_O_WIDTH:
354 // erstmal nur als Pixelwerte merken!
355 nWidth = rOption.GetNumber();
356 bPrcWidth = (rOption.GetString().indexOf('%') != -1);
357 if( bPrcWidth && nWidth>100 )
358 nWidth = 100;
359 bWidthProvided = true;
360 break;
361 case HTML_O_HEIGHT:
362 // erstmal nur als Pixelwerte merken!
363 nHeight = rOption.GetNumber();
364 bPrcHeight = (rOption.GetString().indexOf('%') != -1);
365 if( bPrcHeight && nHeight>100 )
366 nHeight = 100;
367 bHeightProvided = true;
368 break;
369 case HTML_O_VSPACE:
370 nVSpace = rOption.GetNumber();
371 break;
372 case HTML_O_HSPACE:
373 nHSpace = rOption.GetNumber();
374 break;
375 case HTML_O_ALT:
376 sAltNm = rOption.GetString();
377 break;
378 case HTML_O_BORDER:
379 nBorder = (sal_uInt16)rOption.GetNumber();
380 break;
381 case HTML_O_ISMAP:
382 bIsMap = true;
383 break;
384 case HTML_O_USEMAP:
385 aMap = rOption.GetString();
386 break;
387 case HTML_O_NAME:
388 sHTMLGrfName = rOption.GetString();
389 break;
391 case HTML_O_SDONLOAD:
392 eScriptType2 = STARBASIC;
393 SAL_FALLTHROUGH;
394 case HTML_O_ONLOAD:
395 nEvent = SVX_EVENT_IMAGE_LOAD;
396 goto IMAGE_SETEVENT;
398 case HTML_O_SDONABORT:
399 eScriptType2 = STARBASIC;
400 SAL_FALLTHROUGH;
401 case HTML_O_ONABORT:
402 nEvent = SVX_EVENT_IMAGE_ABORT;
403 goto IMAGE_SETEVENT;
405 case HTML_O_SDONERROR:
406 eScriptType2 = STARBASIC;
407 SAL_FALLTHROUGH;
408 case HTML_O_ONERROR:
409 nEvent = SVX_EVENT_IMAGE_ERROR;
410 goto IMAGE_SETEVENT;
411 IMAGE_SETEVENT:
413 OUString sTmp( rOption.GetString() );
414 if( !sTmp.isEmpty() )
416 sTmp = convertLineEnd(sTmp, GetSystemLineEnd());
417 OUString sScriptType;
418 if( EXTENDED_STYPE == eScriptType2 )
419 sScriptType = sDfltScriptType;
420 aMacroItem.SetMacro( nEvent,
421 SvxMacro( sTmp, sScriptType, eScriptType2 ));
424 break;
428 if( sGrfNm.isEmpty() )
429 return;
431 // Wenn wir in einer Numerierung stehen und der Absatz noch leer und
432 // nicht numeriert ist, handelt es sich vielleicht um die Grafik
433 // einer Bullet-Liste
434 if( !m_pPam->GetPoint()->nContent.GetIndex() &&
435 GetNumInfo().GetDepth() > 0 && GetNumInfo().GetDepth() <= MAXLEVEL &&
436 !m_aBulletGrfs[GetNumInfo().GetDepth()-1].isEmpty() &&
437 m_aBulletGrfs[GetNumInfo().GetDepth()-1]==sGrfNm )
439 SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode();
441 if( pTextNode && ! pTextNode->IsCountedInList())
443 OSL_ENSURE( pTextNode->GetActualListLevel() == GetNumInfo().GetLevel(),
444 "Numbering level is wrong" );
446 pTextNode->SetCountedInList( true );
448 // Rule invalisieren ist noetig, weil zwischem dem einlesen
449 // des LI und der Grafik ein EndAction gerufen worden sein kann.
450 if( GetNumInfo().GetNumRule() )
451 GetNumInfo().GetNumRule()->SetInvalidRule( true );
453 // Die Vorlage novh mal setzen. Ist noetig, damit der
454 // Erstzeilen-Einzug stimmt.
455 SetTextCollAttrs();
457 return;
461 Graphic aGraphic;
462 INetURLObject aGraphicURL( sGrfNm );
463 if( aGraphicURL.GetProtocol() == INetProtocol::Data )
465 std::unique_ptr<SvMemoryStream> const pStream(aGraphicURL.getData());
466 if (pStream)
468 if (GRFILTER_OK == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, "", *pStream))
469 sGrfNm.clear();
472 else if (m_sBaseURL.isEmpty()) // sBaseURL is empty if the source is clipboard
474 if (GRFILTER_OK == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, aGraphicURL))
475 sGrfNm.clear();
478 if (!sGrfNm.isEmpty())
480 aGraphic.SetDefaultType();
483 if (!bHeightProvided || !bWidthProvided)
485 Size aPixelSize = aGraphic.GetSizePixel(Application::GetDefaultDevice());
486 if (!bWidthProvided)
487 nWidth = aPixelSize.Width();
488 if (!bHeightProvided)
489 nHeight = aPixelSize.Height();
492 SfxItemSet aItemSet( m_pDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
493 SvxCSS1PropertyInfo aPropInfo;
494 if( HasStyleOptions( aStyle, aId, aClass ) )
495 ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
497 SfxItemSet aFrameSet( m_pDoc->GetAttrPool(),
498 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
499 if( !IsNewDoc() )
500 Reader::ResetFrameFormatAttrs( aFrameSet );
502 // Umrandung setzen
503 long nHBorderWidth = 0, nVBorderWidth = 0;
504 if( nBorder )
506 nHBorderWidth = (long)nBorder;
507 nVBorderWidth = (long)nBorder;
508 SvxCSS1Parser::PixelToTwip( nVBorderWidth, nHBorderWidth );
510 ::editeng::SvxBorderLine aHBorderLine( nullptr, nHBorderWidth );
511 ::editeng::SvxBorderLine aVBorderLine( nullptr, nVBorderWidth );
513 if( m_aAttrTab.pINetFormat )
515 const OUString& rURL =
516 static_cast<const SwFormatINetFormat&>(m_aAttrTab.pINetFormat->GetItem()).GetValue();
518 m_pCSS1Parser->SetATagStyles();
519 sal_uInt16 nPoolId = static_cast< sal_uInt16 >(m_pDoc->IsVisitedURL( rURL )
520 ? RES_POOLCHR_INET_VISIT
521 : RES_POOLCHR_INET_NORMAL);
522 const SwCharFormat *pCharFormat = m_pCSS1Parser->GetCharFormatFromPool( nPoolId );
523 aHBorderLine.SetColor( pCharFormat->GetColor().GetValue() );
524 aVBorderLine.SetColor( aHBorderLine.GetColor() );
526 else
528 const SvxColorItem& rColorItem = m_aAttrTab.pFontColor ?
529 static_cast<const SvxColorItem &>(m_aAttrTab.pFontColor->GetItem()) :
530 static_cast<const SvxColorItem &>(m_pDoc->GetDefault(RES_CHRATR_COLOR));
531 aHBorderLine.SetColor( rColorItem.GetValue() );
532 aVBorderLine.SetColor( aHBorderLine.GetColor() );
535 SvxBoxItem aBoxItem( RES_BOX );
536 aBoxItem.SetLine( &aHBorderLine, SvxBoxItemLine::TOP );
537 aBoxItem.SetLine( &aHBorderLine, SvxBoxItemLine::BOTTOM );
538 aBoxItem.SetLine( &aVBorderLine, SvxBoxItemLine::LEFT );
539 aBoxItem.SetLine( &aVBorderLine, SvxBoxItemLine::RIGHT );
540 aFrameSet.Put( aBoxItem );
543 // Ausrichtung setzen
544 SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrameSet );
546 // Abstaende setzen
547 SetSpace( Size( nHSpace, nVSpace), aItemSet, aPropInfo, aFrameSet );
549 // Sonstige CSS1-Attribute Setzen
550 SetFrameFormatAttrs( aItemSet, aPropInfo, HtmlFrameFormatFlags::Box, aFrameSet );
552 Size aTwipSz( bPrcWidth ? 0 : nWidth, bPrcHeight ? 0 : nHeight );
553 if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
555 aTwipSz = Application::GetDefaultDevice()
556 ->PixelToLogic( aTwipSz, MapMode( MapUnit::MapTwip ) );
559 // CSS1-Groesse auf "normale" Groesse umrechnen
560 switch( aPropInfo.m_eWidthType )
562 case SVX_CSS1_LTYPE_TWIP:
563 aTwipSz.Width() = aPropInfo.m_nWidth;
564 nWidth = 1; // != 0
565 bPrcWidth = false;
566 break;
567 case SVX_CSS1_LTYPE_PERCENTAGE:
568 aTwipSz.Width() = 0;
569 nWidth = aPropInfo.m_nWidth;
570 bPrcWidth = true;
571 break;
572 default:
575 switch( aPropInfo.m_eHeightType )
577 case SVX_CSS1_LTYPE_TWIP:
578 aTwipSz.Height() = aPropInfo.m_nHeight;
579 nHeight = 1; // != 0
580 bPrcHeight = false;
581 break;
582 case SVX_CSS1_LTYPE_PERCENTAGE:
583 aTwipSz.Height() = 0;
584 nHeight = aPropInfo.m_nHeight;
585 bPrcHeight = true;
586 break;
587 default:
591 Size aGrfSz( 0, 0 );
592 bool bSetTwipSize = true; // Twip-Size am Node setzen?
593 bool bChangeFrameSize = false; // Frame-Format nachtraeglich anpassen?
594 bool bRequestGrfNow = false;
595 bool bSetScaleImageMap = false;
596 sal_uInt8 nPrcWidth = 0, nPrcHeight = 0;
598 if( !nWidth || !nHeight )
600 // Es fehlt die Breite oder die Hoehe
601 // Wenn die Grfik in einer Tabelle steht, wird sie gleich
602 // angefordert, damit sie eventuell schon da ist, bevor die
603 // Tabelle layoutet wird.
604 if( m_pTable!=nullptr && !nWidth )
606 bRequestGrfNow = true;
607 IncGrfsThatResizeTable();
610 // Die Groesse des Rahmens wird nachtraeglich gesetzt
611 bChangeFrameSize = true;
612 aGrfSz = aTwipSz;
613 if( !nWidth && !nHeight )
615 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
616 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
618 else if( nWidth )
620 // eine %-Angabe
621 if( bPrcWidth )
623 nPrcWidth = (sal_uInt8)nWidth;
624 nPrcHeight = 255;
626 else
628 aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
631 else if( nHeight )
633 if( bPrcHeight )
635 nPrcHeight = (sal_uInt8)nHeight;
636 nPrcWidth = 255;
638 else
640 aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
644 else
646 // Breite und Hoehe wurden angegeben und brauchen nicht gesetzt
647 // zu werden
648 bSetTwipSize = false;
650 if( bPrcWidth )
651 nPrcWidth = (sal_uInt8)nWidth;
653 if( bPrcHeight )
654 nPrcHeight = (sal_uInt8)nHeight;
657 // Image-Map setzen
658 aMap = comphelper::string::stripEnd(aMap, ' ');
659 if( !aMap.isEmpty() )
661 // Da wir nur lokale Image-Maps kennen nehmen wireinfach alles
662 // hinter dem # als Namen
663 sal_Int32 nPos = aMap.indexOf( '#' );
664 OUString aName;
665 if ( -1 == nPos )
666 aName = aMap ;
667 else
668 aName = aMap.copy(nPos+1);
670 ImageMap *pImgMap = FindImageMap( aName );
671 if( pImgMap )
673 SwFormatURL aURL; aURL.SetMap( pImgMap );//wird kopieiert
675 bSetScaleImageMap = !nPrcWidth || !nPrcHeight;
676 aFrameSet.Put( aURL );
678 else
680 ImageMap aEmptyImgMap( aName );
681 SwFormatURL aURL; aURL.SetMap( &aEmptyImgMap );//wird kopieiert
682 aFrameSet.Put( aURL );
683 m_nMissingImgMaps++; // es fehlen noch Image-Maps
685 // die Grafik muss beim SetTwipSize skaliert werden, wenn
686 // wir keine Groesse am Node gesetzt haben oder die Groesse
687 // nicht der Grafikgroesse entsprach.
688 bSetScaleImageMap = true;
692 // min. Werte einhalten !!
693 if( nPrcWidth )
695 OSL_ENSURE( !aTwipSz.Width(),
696 "Wieso ist da trotz %-Angabe eine Breite gesetzt?" );
697 aTwipSz.Width() = aGrfSz.Width() ? aGrfSz.Width()
698 : HTML_DFLT_IMG_WIDTH;
700 else
702 aTwipSz.Width() += 2*nVBorderWidth;
703 if( aTwipSz.Width() < MINFLY )
704 aTwipSz.Width() = MINFLY;
706 if( nPrcHeight )
708 OSL_ENSURE( !aTwipSz.Height(),
709 "Wieso ist da trotz %-Angabe eine Hoehe gesetzt?" );
710 aTwipSz.Height() = aGrfSz.Height() ? aGrfSz.Height()
711 : HTML_DFLT_IMG_HEIGHT;
713 else
715 aTwipSz.Height() += 2*nHBorderWidth;
716 if( aTwipSz.Height() < MINFLY )
717 aTwipSz.Height() = MINFLY;
720 SwFormatFrameSize aFrameSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() );
721 aFrameSize.SetWidthPercent( nPrcWidth );
722 aFrameSize.SetHeightPercent( nPrcHeight );
723 aFrameSet.Put( aFrameSize );
725 // passing empty sGrfNm here, means we don't want the graphic to be linked
726 SwFrameFormat *pFlyFormat = m_pDoc->getIDocumentContentOperations().Insert( *m_pPam, sGrfNm, aEmptyOUStr, &aGraphic,
727 &aFrameSet, nullptr, nullptr );
728 SwGrfNode *pGrfNd = m_pDoc->GetNodes()[ pFlyFormat->GetContent().GetContentIdx()
729 ->GetIndex()+1 ]->GetGrfNode();
731 if( !sHTMLGrfName.isEmpty() )
733 pFlyFormat->SetName( sHTMLGrfName );
735 // ggfs. eine Grafik anspringen
736 if( JUMPTO_GRAPHIC == m_eJumpTo && sHTMLGrfName == m_sJmpMark )
738 m_bChkJumpMark = true;
739 m_eJumpTo = JUMPTO_NONE;
743 if (pGrfNd)
745 if( !sAltNm.isEmpty() )
746 pGrfNd->SetTitle( sAltNm );
748 if( bSetTwipSize )
749 pGrfNd->SetTwipSize( aGrfSz );
751 pGrfNd->SetChgTwipSize( bChangeFrameSize );
753 if( bSetScaleImageMap )
754 pGrfNd->SetScaleImageMap( true );
757 if( m_aAttrTab.pINetFormat )
759 const SwFormatINetFormat &rINetFormat =
760 static_cast<const SwFormatINetFormat&>(m_aAttrTab.pINetFormat->GetItem());
762 SwFormatURL aURL( pFlyFormat->GetURL() );
764 aURL.SetURL( rINetFormat.GetValue(), bIsMap );
765 aURL.SetTargetFrameName( rINetFormat.GetTargetFrame() );
766 aURL.SetName( rINetFormat.GetName() );
767 pFlyFormat->SetFormatAttr( aURL );
770 static const sal_uInt16 aEvents[] = {
771 SFX_EVENT_MOUSEOVER_OBJECT,
772 SFX_EVENT_MOUSECLICK_OBJECT,
773 SFX_EVENT_MOUSEOUT_OBJECT,
774 0 };
776 for( int n = 0; aEvents[ n ]; ++n )
778 const SvxMacro *pMacro = rINetFormat.GetMacro( aEvents[ n ] );
779 if( nullptr != pMacro )
780 aMacroItem.SetMacro( aEvents[ n ], *pMacro );
784 if ((FLY_AS_CHAR == pFlyFormat->GetAnchor().GetAnchorId()) &&
785 m_aAttrTab.pINetFormat->GetSttPara() ==
786 m_pPam->GetPoint()->nNode &&
787 m_aAttrTab.pINetFormat->GetSttCnt() ==
788 m_pPam->GetPoint()->nContent.GetIndex() - 1 )
790 // das Attribut wurde unmitellbar vor einer zeichengeb.
791 // Grafik eingefuegt, also verschieben wir es
792 m_aAttrTab.pINetFormat->SetStart( *m_pPam->GetPoint() );
794 // Wenn das Attribut auch ein Sprungziel ist, fuegen
795 // wir noch eine Bookmark vor der Grafik ein, weil das
796 // SwFormatURL kein Sprungziel ist.
797 if( !rINetFormat.GetName().isEmpty() )
799 m_pPam->Move( fnMoveBackward );
800 InsertBookmark( rINetFormat.GetName() );
801 m_pPam->Move( fnMoveForward );
807 if( !aMacroItem.GetMacroTable().empty() )
808 pFlyFormat->SetFormatAttr( aMacroItem );
810 // tdf#87083 If the graphic has not been loaded yet, then load it now.
811 // Otherwise it may be loaded during the first paint of the object and it
812 // will be too late to adapt the size of the graphic at that point.
813 if (bRequestGrfNow && pGrfNd)
815 Size aUpdatedSize = pGrfNd->GetTwipSize(); //trigger a swap-in
816 SAL_WARN_IF(!aUpdatedSize.Width() || !aUpdatedSize.Height(), "sw.html", "html image with no width or height");
819 // Ggf. Frames anlegen und Auto-gebundenen Rahmen registrieren
820 RegisterFlyFrame( pFlyFormat );
822 if( !aId.isEmpty() )
823 InsertBookmark( aId );
826 /* */
828 void SwHTMLParser::InsertBodyOptions()
830 m_pDoc->SetTextFormatColl( *m_pPam,
831 m_pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_TEXT ) );
833 OUString aBackGround, aId, aStyle, aLang, aDir;
834 Color aBGColor, aTextColor, aLinkColor, aVLinkColor;
835 bool bBGColor=false, bTextColor=false;
836 bool bLinkColor=false, bVLinkColor=false;
838 ScriptType eDfltScriptType;
839 OUString sDfltScriptType;
840 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
842 const HTMLOptions& rHTMLOptions = GetOptions();
843 for (size_t i = rHTMLOptions.size(); i; )
845 const HTMLOption& rOption = rHTMLOptions[--i];
846 ScriptType eScriptType2 = eDfltScriptType;
847 OUString aEvent;
848 bool bSetEvent = false;
850 switch( rOption.GetToken() )
852 case HTML_O_ID:
853 aId = rOption.GetString();
854 break;
855 case HTML_O_BACKGROUND:
856 aBackGround = rOption.GetString();
857 break;
858 case HTML_O_BGCOLOR:
859 rOption.GetColor( aBGColor );
860 bBGColor = true;
861 break;
862 case HTML_O_TEXT:
863 rOption.GetColor( aTextColor );
864 bTextColor = true;
865 break;
866 case HTML_O_LINK:
867 rOption.GetColor( aLinkColor );
868 bLinkColor = true;
869 break;
870 case HTML_O_VLINK:
871 rOption.GetColor( aVLinkColor );
872 bVLinkColor = true;
873 break;
875 case HTML_O_SDONLOAD:
876 eScriptType2 = STARBASIC;
877 SAL_FALLTHROUGH;
878 case HTML_O_ONLOAD:
879 aEvent = GlobalEventConfig::GetEventName( GlobalEventId::OPENDOC );
880 bSetEvent = true;
881 break;
883 case HTML_O_SDONUNLOAD:
884 eScriptType2 = STARBASIC;
885 SAL_FALLTHROUGH;
886 case HTML_O_ONUNLOAD:
887 aEvent = GlobalEventConfig::GetEventName( GlobalEventId::PREPARECLOSEDOC );
888 bSetEvent = true;
889 break;
891 case HTML_O_SDONFOCUS:
892 eScriptType2 = STARBASIC;
893 SAL_FALLTHROUGH;
894 case HTML_O_ONFOCUS:
895 aEvent = GlobalEventConfig::GetEventName( GlobalEventId::ACTIVATEDOC );
896 bSetEvent = true;
897 break;
899 case HTML_O_SDONBLUR:
900 eScriptType2 = STARBASIC;
901 SAL_FALLTHROUGH;
902 case HTML_O_ONBLUR:
903 aEvent = GlobalEventConfig::GetEventName( GlobalEventId::DEACTIVATEDOC );
904 bSetEvent = true;
905 break;
907 case HTML_O_ONERROR:
908 break;
910 case HTML_O_STYLE:
911 aStyle = rOption.GetString();
912 bTextColor = true;
913 break;
914 case HTML_O_LANG:
915 aLang = rOption.GetString();
916 break;
917 case HTML_O_DIR:
918 aDir = rOption.GetString();
919 break;
922 if( bSetEvent )
924 const OUString& rEvent = rOption.GetString();
925 if( !rEvent.isEmpty() )
926 InsertBasicDocEvent( aEvent, rEvent, eScriptType2,
927 sDfltScriptType );
931 if( bTextColor && !m_pCSS1Parser->IsBodyTextSet() )
933 // Die Textfarbe wird an der Standard-Vorlage gesetzt
934 m_pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_STANDARD )
935 ->SetFormatAttr( SvxColorItem(aTextColor, RES_CHRATR_COLOR) );
936 m_pCSS1Parser->SetBodyTextSet();
939 // Die Item fuer die Seitenvorlage vorbereiten (Hintergrund, Umrandung)
940 // Beim BrushItem muessen schon gesetzte werte erhalten bleiben!
941 SvxBrushItem aBrushItem( m_pCSS1Parser->makePageDescBackground() );
942 bool bSetBrush = false;
944 if( bBGColor && !m_pCSS1Parser->IsBodyBGColorSet() )
946 // Hintergrundfarbe aus "BGCOLOR"
947 OUString aLink;
948 if( !aBrushItem.GetGraphicLink().isEmpty() )
949 aLink = aBrushItem.GetGraphicLink();
950 SvxGraphicPosition ePos = aBrushItem.GetGraphicPos();
952 aBrushItem.SetColor( aBGColor );
954 if( !aLink.isEmpty() )
956 aBrushItem.SetGraphicLink( aLink );
957 aBrushItem.SetGraphicPos( ePos );
959 bSetBrush = true;
960 m_pCSS1Parser->SetBodyBGColorSet();
963 if( !aBackGround.isEmpty() && !m_pCSS1Parser->IsBodyBackgroundSet() )
965 // Hintergrundgrafik aus "BACKGROUND"
966 aBrushItem.SetGraphicLink( INetURLObject::GetAbsURL( m_sBaseURL, aBackGround ) );
967 aBrushItem.SetGraphicPos( GPOS_TILED );
968 bSetBrush = true;
969 m_pCSS1Parser->SetBodyBackgroundSet();
972 if( !aStyle.isEmpty() || !aDir.isEmpty() )
974 SfxItemSet aItemSet( m_pDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
975 SvxCSS1PropertyInfo aPropInfo;
976 OUString aDummy;
977 ParseStyleOptions( aStyle, aDummy, aDummy, aItemSet, aPropInfo, nullptr, &aDir );
979 // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
980 // und zwar die, die nicht vererbit werden
981 m_pCSS1Parser->SetPageDescAttrs( bSetBrush ? &aBrushItem : nullptr,
982 &aItemSet );
984 const SfxPoolItem *pItem;
985 static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,
986 RES_CHRATR_CJK_FONTSIZE,
987 RES_CHRATR_CTL_FONTSIZE };
988 for(sal_uInt16 i : aWhichIds)
990 if( SfxItemState::SET == aItemSet.GetItemState( i, false,
991 &pItem ) &&
992 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() != 100)
994 sal_uInt32 nHeight =
995 ( m_aFontHeights[2] *
996 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() ) / 100;
997 SvxFontHeightItem aNewItem( nHeight, 100, i );
998 aItemSet.Put( aNewItem );
1002 // alle noch uebrigen Optionen koennen an der Standard-Vorlage
1003 // gesetzt werden und gelten dann automatisch als defaults
1004 m_pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_STANDARD )
1005 ->SetFormatAttr( aItemSet );
1007 else if( bSetBrush )
1009 m_pCSS1Parser->SetPageDescAttrs( &aBrushItem );
1012 if( bLinkColor && !m_pCSS1Parser->IsBodyLinkSet() )
1014 SwCharFormat *pCharFormat =
1015 m_pCSS1Parser->GetCharFormatFromPool(RES_POOLCHR_INET_NORMAL);
1016 pCharFormat->SetFormatAttr( SvxColorItem(aLinkColor, RES_CHRATR_COLOR) );
1017 m_pCSS1Parser->SetBodyLinkSet();
1019 if( bVLinkColor && !m_pCSS1Parser->IsBodyVLinkSet() )
1021 SwCharFormat *pCharFormat =
1022 m_pCSS1Parser->GetCharFormatFromPool(RES_POOLCHR_INET_VISIT);
1023 pCharFormat->SetFormatAttr( SvxColorItem(aVLinkColor, RES_CHRATR_COLOR) );
1024 m_pCSS1Parser->SetBodyVLinkSet();
1026 if( !aLang.isEmpty() )
1028 LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( aLang );
1029 if( LANGUAGE_DONTKNOW != eLang )
1031 sal_uInt16 nWhich = 0;
1032 switch( SvtLanguageOptions::GetScriptTypeOfLanguage( eLang ) )
1034 case SvtScriptType::LATIN:
1035 nWhich = RES_CHRATR_LANGUAGE;
1036 break;
1037 case SvtScriptType::ASIAN:
1038 nWhich = RES_CHRATR_CJK_LANGUAGE;
1039 break;
1040 case SvtScriptType::COMPLEX:
1041 nWhich = RES_CHRATR_CTL_LANGUAGE;
1042 break;
1043 default: break;
1045 if( nWhich )
1047 SvxLanguageItem aLanguage( eLang, nWhich );
1048 aLanguage.SetWhich( nWhich );
1049 m_pDoc->SetDefault( aLanguage );
1054 if( !aId.isEmpty() )
1055 InsertBookmark( aId );
1058 /* */
1060 void SwHTMLParser::NewAnchor()
1062 // den voherigen Link beenden, falls es einen gab
1063 HTMLAttrContext *pOldCntxt = PopContext( HTML_ANCHOR_ON );
1064 if( pOldCntxt )
1066 // und ggf. die Attribute beenden
1067 EndContext( pOldCntxt );
1068 delete pOldCntxt;
1071 SvxMacroTableDtor aMacroTable;
1072 OUString sHRef, aName, sTarget;
1073 OUString aId, aStyle, aClass, aLang, aDir;
1074 bool bHasHRef = false, bFixed = false;
1076 ScriptType eDfltScriptType;
1077 OUString sDfltScriptType;
1078 GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
1080 const HTMLOptions& rHTMLOptions = GetOptions();
1081 for (size_t i = rHTMLOptions.size(); i; )
1083 sal_uInt16 nEvent = 0;
1084 ScriptType eScriptType2 = eDfltScriptType;
1085 const HTMLOption& rOption = rHTMLOptions[--i];
1086 switch( rOption.GetToken() )
1088 case HTML_O_NAME:
1089 aName = rOption.GetString();
1090 break;
1092 case HTML_O_HREF:
1093 sHRef = rOption.GetString();
1094 bHasHRef = true;
1095 break;
1096 case HTML_O_TARGET:
1097 sTarget = rOption.GetString();
1098 break;
1100 case HTML_O_STYLE:
1101 aStyle = rOption.GetString();
1102 break;
1103 case HTML_O_ID:
1104 aId = rOption.GetString();
1105 break;
1106 case HTML_O_CLASS:
1107 aClass = rOption.GetString();
1108 break;
1109 case HTML_O_SDFIXED:
1110 bFixed = true;
1111 break;
1112 case HTML_O_LANG:
1113 aLang = rOption.GetString();
1114 break;
1115 case HTML_O_DIR:
1116 aDir = rOption.GetString();
1117 break;
1119 case HTML_O_SDONCLICK:
1120 eScriptType2 = STARBASIC;
1121 SAL_FALLTHROUGH;
1122 case HTML_O_ONCLICK:
1123 nEvent = SFX_EVENT_MOUSECLICK_OBJECT;
1124 goto ANCHOR_SETEVENT;
1126 case HTML_O_SDONMOUSEOVER:
1127 eScriptType2 = STARBASIC;
1128 SAL_FALLTHROUGH;
1129 case HTML_O_ONMOUSEOVER:
1130 nEvent = SFX_EVENT_MOUSEOVER_OBJECT;
1131 goto ANCHOR_SETEVENT;
1133 case HTML_O_SDONMOUSEOUT:
1134 eScriptType2 = STARBASIC;
1135 SAL_FALLTHROUGH;
1136 case HTML_O_ONMOUSEOUT:
1137 nEvent = SFX_EVENT_MOUSEOUT_OBJECT;
1138 goto ANCHOR_SETEVENT;
1139 ANCHOR_SETEVENT:
1141 OUString sTmp( rOption.GetString() );
1142 if( !sTmp.isEmpty() )
1144 sTmp = convertLineEnd(sTmp, GetSystemLineEnd());
1145 OUString sScriptType;
1146 if( EXTENDED_STYPE == eScriptType2 )
1147 sScriptType = sDfltScriptType;
1148 aMacroTable.Insert( nEvent, SvxMacro( sTmp, sScriptType, eScriptType2 ));
1151 break;
1156 // Sprungziele, die unseren ipmliziten Zielen entsprechen, schmeissen
1157 // wir hier ganz rigoros raus.
1158 if( !aName.isEmpty() )
1160 OUString sDecoded( INetURLObject::decode( aName,
1161 INetURLObject::DecodeMechanism::Unambiguous ));
1162 sal_Int32 nPos = sDecoded.lastIndexOf( cMarkSeparator );
1163 if( nPos != -1 )
1165 OUString sCmp= sDecoded.copy(nPos+1).replaceAll(" ","");
1166 if( !sCmp.isEmpty() )
1168 sCmp = sCmp.toAsciiLowerCase();
1169 if( sCmp == "region" ||
1170 sCmp == "frame" ||
1171 sCmp == "graphic" ||
1172 sCmp == "ole" ||
1173 sCmp == "table" ||
1174 sCmp == "outline" ||
1175 sCmp == "text" )
1177 aName.clear();
1183 // einen neuen Kontext anlegen
1184 HTMLAttrContext *pCntxt = new HTMLAttrContext( HTML_ANCHOR_ON );
1186 bool bEnAnchor = false, bFootnoteAnchor = false, bFootnoteEnSymbol = false;
1187 OUString aFootnoteName;
1188 OUString aStrippedClass( aClass );
1189 SwCSS1Parser::GetScriptFromClass( aStrippedClass, false );
1190 if( aStrippedClass.getLength() >=9 && bHasHRef && sHRef.getLength() > 1 &&
1191 ('s' == aStrippedClass[0] || 'S' == aStrippedClass[0]) &&
1192 ('d' == aStrippedClass[1] || 'D' == aStrippedClass[1]) )
1194 if( aStrippedClass.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdendnote_anc ) )
1195 bEnAnchor = true;
1196 else if( aStrippedClass.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc ) )
1197 bFootnoteAnchor = true;
1198 else if( aStrippedClass.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdendnote_sym ) ||
1199 aStrippedClass.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym ) )
1200 bFootnoteEnSymbol = true;
1201 if( bEnAnchor || bFootnoteAnchor || bFootnoteEnSymbol )
1203 aFootnoteName = sHRef.copy( 1 );
1204 aClass = aStrippedClass = aName = aEmptyOUStr;
1205 bHasHRef = false;
1209 // Styles parsen
1210 if( HasStyleOptions( aStyle, aId, aStrippedClass, &aLang, &aDir ) )
1212 SfxItemSet aItemSet( m_pDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
1213 SvxCSS1PropertyInfo aPropInfo;
1215 if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
1217 DoPositioning( aItemSet, aPropInfo, pCntxt );
1218 InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
1222 if( bHasHRef )
1224 if( !sHRef.isEmpty() )
1226 sHRef = URIHelper::SmartRel2Abs( INetURLObject(m_sBaseURL), sHRef, Link<OUString *, bool>(), false );
1228 else
1230 // Bei leerer URL das Directory nehmen
1231 INetURLObject aURLObj( m_aPathToFile );
1232 sHRef = aURLObj.GetPartBeforeLastName();
1235 m_pCSS1Parser->SetATagStyles();
1236 SwFormatINetFormat aINetFormat( sHRef, sTarget );
1237 aINetFormat.SetName( aName );
1239 if( !aMacroTable.empty() )
1240 aINetFormat.SetMacroTable( &aMacroTable );
1242 // das Default-Attribut setzen
1243 InsertAttr( &m_aAttrTab.pINetFormat, aINetFormat, pCntxt );
1245 else if( !aName.isEmpty() )
1247 InsertBookmark( aName );
1250 if( bEnAnchor || bFootnoteAnchor )
1252 InsertFootEndNote( aFootnoteName, bEnAnchor, bFixed );
1253 m_bInFootEndNoteAnchor = m_bCallNextToken = true;
1255 else if( bFootnoteEnSymbol )
1257 m_bInFootEndNoteSymbol = m_bCallNextToken = true;
1260 // den Kontext merken
1261 PushContext( pCntxt );
1264 void SwHTMLParser::EndAnchor()
1266 if( m_bInFootEndNoteAnchor )
1268 FinishFootEndNote();
1269 m_bInFootEndNoteAnchor = false;
1271 else if( m_bInFootEndNoteSymbol )
1273 m_bInFootEndNoteSymbol = false;
1276 EndTag( HTML_ANCHOR_OFF );
1279 /* */
1281 void SwHTMLParser::InsertBookmark( const OUString& rName )
1283 HTMLAttr* pTmp = new HTMLAttr( *m_pPam->GetPoint(),
1284 SfxStringItem( RES_FLTR_BOOKMARK, rName ));
1285 m_aSetAttrTab.push_back( pTmp );
1288 bool SwHTMLParser::HasCurrentParaBookmarks( bool bIgnoreStack ) const
1290 bool bHasMarks = false;
1291 sal_uLong nNodeIdx = m_pPam->GetPoint()->nNode.GetIndex();
1293 // first step: are there still bookmark in the attribute-stack?
1294 // bookmarks are added to the end of the stack - thus we only have
1295 // to check the last bookmark
1296 if( !bIgnoreStack )
1298 for( auto i = m_aSetAttrTab.size(); i; )
1300 HTMLAttr* pAttr = m_aSetAttrTab[ --i ];
1301 if( RES_FLTR_BOOKMARK == pAttr->pItem->Which() )
1303 if( pAttr->GetSttParaIdx() == nNodeIdx )
1304 bHasMarks = true;
1305 break;
1310 if( !bHasMarks )
1312 // second step: when we didn't find a bookmark, check if there is one set already
1313 IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1314 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
1315 ppMark != pMarkAccess->getAllMarksEnd();
1316 ++ppMark)
1318 const ::sw::mark::IMark* pBookmark = ppMark->get();
1320 const sal_uLong nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex();
1321 if( nBookNdIdx==nNodeIdx )
1323 bHasMarks = true;
1324 break;
1326 else if( nBookNdIdx > nNodeIdx )
1327 break;
1331 return bHasMarks;
1334 /* */
1336 void SwHTMLParser::StripTrailingPara()
1338 bool bSetSmallFont = false;
1340 SwContentNode* pCNd = m_pPam->GetContentNode();
1341 if( !m_pPam->GetPoint()->nContent.GetIndex() )
1343 if( pCNd && pCNd->StartOfSectionIndex()+2 <
1344 pCNd->EndOfSectionIndex() )
1346 sal_uLong nNodeIdx = m_pPam->GetPoint()->nNode.GetIndex();
1348 const SwFrameFormats& rFrameFormatTable = *m_pDoc->GetSpzFrameFormats();
1350 for( auto pFormat : rFrameFormatTable )
1352 SwFormatAnchor const*const pAnchor = &pFormat->GetAnchor();
1353 SwPosition const*const pAPos = pAnchor->GetContentAnchor();
1354 if (pAPos &&
1355 ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
1356 (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
1357 pAPos->nNode == nNodeIdx )
1359 return; // den Knoten duerfen wir nicht loeschen
1362 SetAttr( false ); // die noch offenen Attribute muessen
1363 // beendet werden, bevor der Node
1364 // geloescht wird, weil sonst der
1365 // End-Index in die Botanik zeigt
1367 if( pCNd->Len() && pCNd->IsTextNode() )
1369 // es wurden Felder in den Node eingefuegt, die muessen
1370 // wir jetzt verschieben
1371 SwTextNode *pPrvNd = m_pDoc->GetNodes()[nNodeIdx-1]->GetTextNode();
1372 if( pPrvNd )
1374 SwIndex aSrc( pCNd, 0 );
1375 pCNd->GetTextNode()->CutText( pPrvNd, aSrc, pCNd->Len() );
1379 // jetz muessen wir noch eventuell vorhandene Bookmarks verschieben
1380 IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1381 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
1382 ppMark != pMarkAccess->getAllMarksEnd();
1383 ++ppMark)
1385 ::sw::mark::IMark* pMark = ppMark->get();
1387 sal_uLong nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex();
1388 if(nBookNdIdx==nNodeIdx)
1390 SwNodeIndex nNewNdIdx(m_pPam->GetPoint()->nNode);
1391 SwContentNode* pNd = SwNodes::GoPrevious(&nNewNdIdx);
1392 if(!pNd)
1394 OSL_ENSURE(false, "Oops, where is my predecessor node?");
1395 return;
1397 // #i81002# - refactoring
1398 // Do not directly manipulate member of <SwBookmark>
1400 SwPosition aNewPos(*pNd);
1401 aNewPos.nContent.Assign(pNd, pNd->Len());
1402 const SwPaM aPaM(aNewPos);
1403 pMarkAccess->repositionMark(ppMark->get(), aPaM);
1406 else if( nBookNdIdx > nNodeIdx )
1407 break;
1410 m_pPam->GetPoint()->nContent.Assign( nullptr, 0 );
1411 m_pPam->SetMark();
1412 m_pPam->DeleteMark();
1413 m_pDoc->GetNodes().Delete( m_pPam->GetPoint()->nNode );
1414 m_pPam->Move( fnMoveBackward, GoInNode );
1416 else if( pCNd && pCNd->IsTextNode() && m_pTable )
1418 // In leeren Zellen stellen wir einen kleinen Font ein, damit die
1419 // Zelle nicht hoeher wird als die Grafik bzw. so niedrig wie
1420 // moeglich bleibt.
1421 bSetSmallFont = true;
1424 else if( pCNd && pCNd->IsTextNode() && m_pTable &&
1425 pCNd->StartOfSectionIndex()+2 ==
1426 pCNd->EndOfSectionIndex() )
1428 // Wenn die Zelle nur zeichengebundene Grafiken/Rahmen enthaelt
1429 // stellen wir ebenfalls einen kleinen Font ein.
1430 bSetSmallFont = true;
1431 SwTextNode* pTextNd = pCNd->GetTextNode();
1433 sal_Int32 nPos = m_pPam->GetPoint()->nContent.GetIndex();
1434 while( bSetSmallFont && nPos>0 )
1436 --nPos;
1437 bSetSmallFont =
1438 (CH_TXTATR_BREAKWORD == pTextNd->GetText()[nPos]) &&
1439 (nullptr != pTextNd->GetTextAttrForCharAt( nPos, RES_TXTATR_FLYCNT ));
1443 if( bSetSmallFont )
1445 //Added default to CJK and CTL
1446 SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
1447 pCNd->SetAttr( aFontHeight );
1448 SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
1449 pCNd->SetAttr( aFontHeightCJK );
1450 SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
1451 pCNd->SetAttr( aFontHeightCTL );
1455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */