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