LibreOffice Module editeng (master) 1
eehtml.cxx
Go to the documentation of this file.
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
21#include "eehtml.hxx"
23#include <editeng/flditem.hxx>
24#include <tools/urlobj.hxx>
25#include <editeng/fhgtitem.hxx>
26#include <editeng/fontitem.hxx>
27#include <editeng/ulspitem.hxx>
28#include <editeng/wghtitem.hxx>
29#include <svtools/htmltokn.h>
30#include <svtools/htmlkywd.hxx>
31#include <tools/tenccvt.hxx>
32
33#include <editeng/editeng.hxx>
34#include <utility>
35
36#define STYLE_PRE 101
37
38EditHTMLParser::EditHTMLParser( SvStream& rIn, OUString _aBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs )
39 : HTMLParser( rIn, true ),
40 aBaseURL(std::move( _aBaseURL )),
41 mpEditEngine(nullptr),
42 bInPara(false),
43 bWasInPara(false),
44 bFieldsInserted(false),
45 bInTitle(false),
46 nInTable(0),
47 nInCell(0),
48 nDefListLevel(0)
49{
50 DBG_ASSERT( !IsSwitchToUCS2(), "EditHTMLParser::::EditHTMLParser: Switch to UCS2?" );
51
52 // Although the real default encoding is ISO8859-1, we use MS-1252
53 // as default encoding.
54 SetSrcEncoding( GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
55
56 // If the file starts with a BOM, switch to UCS2.
57 SetSwitchToUCS2( true );
58
59 if ( pHTTPHeaderAttrs )
60 SetEncodingByHTTPHeader( pHTTPHeaderAttrs );
61}
62
64{
65}
66
68{
69 DBG_ASSERT(pEE, "CallParser: ImpEditEngine ?!");
70 mpEditEngine = pEE;
71 SvParserState _eState = SvParserState::NotStarted;
72 if ( mpEditEngine )
73 {
74 // Build in wrap mimic in RTF import?
75 aCurSel = EditSelection( rPaM, rPaM );
76
78 {
81 }
82
84 _eState = HTMLParser::CallParser();
85
87 {
90 }
91
92 if ( bFieldsInserted )
94 }
95 return _eState;
96}
97
99{
100 switch( nToken )
101 {
102 case HtmlTokenId::META:
103 {
104 const HTMLOptions& aOptions = GetOptions();
105 size_t nArrLen = aOptions.size();
106 bool bEquiv = false;
107 for ( size_t i = 0; i < nArrLen; i++ )
108 {
109 const HTMLOption& aOption = aOptions[i];
110 switch( aOption.GetToken() )
111 {
112 case HtmlOptionId::HTTPEQUIV:
113 {
114 bEquiv = true;
115 }
116 break;
117 case HtmlOptionId::CONTENT:
118 {
119 if ( bEquiv )
120 {
121 rtl_TextEncoding eEnc = GetEncodingByMIME( aOption.GetString() );
122 if ( eEnc != RTL_TEXTENCODING_DONTKNOW )
123 SetSrcEncoding( eEnc );
124 }
125 }
126 break;
127 default: break;
128 }
129 }
130
131 }
132 break;
133 case HtmlTokenId::PLAINTEXT_ON:
134 case HtmlTokenId::PLAINTEXT2_ON:
135 bInPara = true;
136 break;
137 case HtmlTokenId::PLAINTEXT_OFF:
138 case HtmlTokenId::PLAINTEXT2_OFF:
139 bInPara = false;
140 break;
141
142 case HtmlTokenId::LINEBREAK:
143 case HtmlTokenId::NEWPARA:
144 {
145 if ( ( bInPara || nInTable ) &&
146 ( ( nToken == HtmlTokenId::LINEBREAK ) || HasTextInCurrentPara() ) )
147 {
149 }
150 }
151 break;
152 case HtmlTokenId::HORZRULE:
153 {
154 if ( HasTextInCurrentPara() )
157 }
158 break;
159 case HtmlTokenId::NONBREAKSPACE:
160 {
161 if ( bInPara )
162 {
163 ImpInsertText( " " );
164 }
165 }
166 break;
167 case HtmlTokenId::RAWDATA:
168 if (IsReadStyle() && !aToken.isEmpty())
169 {
170 // Each token represents a single line.
171 maStyleSource.append(aToken);
172 maStyleSource.append('\n');
173 }
174 break;
175 case HtmlTokenId::TEXTTOKEN:
176 {
177 // #i110937# for <title> content, call aImportHdl (no SkipGroup), but don't insert the text into the EditEngine
178 if (!bInTitle)
179 {
180 if ( !bInPara )
181 StartPara( false );
182
183 OUString aText = aToken.toString();
184 if ( aText.startsWith(" ") && ThrowAwayBlank() && !IsReadPRE() )
185 aText = aText.copy( 1 );
186
187 if ( moCurAnchor )
188 {
189 moCurAnchor->aText += aText;
190 }
191 else
192 {
193 // Only written until HTML with 319?
194 if ( IsReadPRE() )
195 aText = aText.replaceAll(u"\t", u" ");
196 ImpInsertText( aText );
197 }
198 }
199 }
200 break;
201
202 case HtmlTokenId::CENTER_ON:
203 case HtmlTokenId::CENTER_OFF:
204 {
205 sal_Int32 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
207 aItems.ClearItem( EE_PARA_JUST );
208 if ( nToken == HtmlTokenId::CENTER_ON )
210 mpEditEngine->SetParaAttribsOnly(nNode, aItems);
211 }
212 break;
213
214 case HtmlTokenId::ANCHOR_ON: AnchorStart();
215 break;
216 case HtmlTokenId::ANCHOR_OFF: AnchorEnd();
217 break;
218
219 case HtmlTokenId::PARABREAK_ON:
221 EndPara();
222 StartPara( true );
223 break;
224
225 case HtmlTokenId::PARABREAK_OFF:
226 if( bInPara )
227 EndPara();
228 break;
229
230 case HtmlTokenId::HEAD1_ON:
231 case HtmlTokenId::HEAD2_ON:
232 case HtmlTokenId::HEAD3_ON:
233 case HtmlTokenId::HEAD4_ON:
234 case HtmlTokenId::HEAD5_ON:
235 case HtmlTokenId::HEAD6_ON:
236 {
238 }
239 break;
240
241 case HtmlTokenId::HEAD1_OFF:
242 case HtmlTokenId::HEAD2_OFF:
243 case HtmlTokenId::HEAD3_OFF:
244 case HtmlTokenId::HEAD4_OFF:
245 case HtmlTokenId::HEAD5_OFF:
246 case HtmlTokenId::HEAD6_OFF:
247 {
248 HeadingEnd();
249 }
250 break;
251
252 case HtmlTokenId::PREFORMTXT_ON:
253 case HtmlTokenId::XMP_ON:
254 case HtmlTokenId::LISTING_ON:
255 {
256 StartPara( true );
258 }
259 break;
260
261 case HtmlTokenId::DEFLIST_ON:
262 {
264 }
265 break;
266
267 case HtmlTokenId::DEFLIST_OFF:
268 {
269 if( nDefListLevel )
271 }
272 break;
273
274 case HtmlTokenId::TABLE_ON: nInTable++;
275 break;
276 case HtmlTokenId::TABLE_OFF: DBG_ASSERT( nInTable, "Not in Table, but TABLE_OFF?" );
277 nInTable--;
278 break;
279
280 case HtmlTokenId::TABLEHEADER_ON:
281 case HtmlTokenId::TABLEDATA_ON:
282 nInCell++;
283 [[fallthrough]];
284 case HtmlTokenId::BLOCKQUOTE_ON:
285 case HtmlTokenId::BLOCKQUOTE_OFF:
286 case HtmlTokenId::BLOCKQUOTE30_ON:
287 case HtmlTokenId::BLOCKQUOTE30_OFF:
288 case HtmlTokenId::LISTHEADER_ON:
289 case HtmlTokenId::LI_ON:
290 case HtmlTokenId::DD_ON:
291 case HtmlTokenId::DT_ON:
292 case HtmlTokenId::ORDERLIST_ON:
293 case HtmlTokenId::UNORDERLIST_ON:
294 {
295 bool bHasText = HasTextInCurrentPara();
296 if ( bHasText )
298 StartPara( false );
299 }
300 break;
301
302 case HtmlTokenId::TABLEHEADER_OFF:
303 case HtmlTokenId::TABLEDATA_OFF:
304 {
305 if ( nInCell )
306 nInCell--;
307 [[fallthrough]];
308 }
309 case HtmlTokenId::LISTHEADER_OFF:
310 case HtmlTokenId::LI_OFF:
311 case HtmlTokenId::DD_OFF:
312 case HtmlTokenId::DT_OFF:
313 case HtmlTokenId::ORDERLIST_OFF:
314 case HtmlTokenId::UNORDERLIST_OFF: EndPara();
315 break;
316
317 case HtmlTokenId::TABLEROW_ON:
318 case HtmlTokenId::TABLEROW_OFF: // A RETURN only after a CELL, for Calc
319
320 case HtmlTokenId::COL_ON:
321 case HtmlTokenId::COLGROUP_ON:
322 case HtmlTokenId::COLGROUP_OFF: break;
323
324 case HtmlTokenId::FONT_ON:
325 break;
326 case HtmlTokenId::FONT_OFF:
327 break;
328
329 case HtmlTokenId::TITLE_ON:
330 bInTitle = true;
331 break;
332 case HtmlTokenId::TITLE_OFF:
333 bInTitle = false;
334 break;
335
336 // globals
337 case HtmlTokenId::HTML_ON:
338 case HtmlTokenId::HTML_OFF:
339 case HtmlTokenId::STYLE_ON:
340 case HtmlTokenId::STYLE_OFF:
341 case HtmlTokenId::BODY_ON:
342 case HtmlTokenId::BODY_OFF:
343 case HtmlTokenId::HEAD_ON:
344 case HtmlTokenId::HEAD_OFF:
345 case HtmlTokenId::FORM_ON:
346 case HtmlTokenId::FORM_OFF:
347 case HtmlTokenId::THEAD_ON:
348 case HtmlTokenId::THEAD_OFF:
349 case HtmlTokenId::TBODY_ON:
350 case HtmlTokenId::TBODY_OFF:
351 // inline elements, structural markup
352 // HTML 3.0
353 case HtmlTokenId::BANNER_ON:
354 case HtmlTokenId::BANNER_OFF:
355 case HtmlTokenId::DIVISION_ON:
356 case HtmlTokenId::DIVISION_OFF:
357// case HtmlTokenId::LISTHEADER_ON: //! special handling
358// case HtmlTokenId::LISTHEADER_OFF:
359 case HtmlTokenId::NOTE_ON:
360 case HtmlTokenId::NOTE_OFF:
361 // inline elements, logical markup
362 // HTML 2.0
363 case HtmlTokenId::ADDRESS_ON:
364 case HtmlTokenId::ADDRESS_OFF:
365// case HtmlTokenId::BLOCKQUOTE_ON: //! special handling
366// case HtmlTokenId::BLOCKQUOTE_OFF:
367 case HtmlTokenId::CITATION_ON:
368 case HtmlTokenId::CITATION_OFF:
369 case HtmlTokenId::CODE_ON:
370 case HtmlTokenId::CODE_OFF:
371 case HtmlTokenId::DEFINSTANCE_ON:
372 case HtmlTokenId::DEFINSTANCE_OFF:
373 case HtmlTokenId::EMPHASIS_ON:
374 case HtmlTokenId::EMPHASIS_OFF:
375 case HtmlTokenId::KEYBOARD_ON:
376 case HtmlTokenId::KEYBOARD_OFF:
377 case HtmlTokenId::SAMPLE_ON:
378 case HtmlTokenId::SAMPLE_OFF:
379 case HtmlTokenId::STRIKE_ON:
380 case HtmlTokenId::STRIKE_OFF:
381 case HtmlTokenId::STRONG_ON:
382 case HtmlTokenId::STRONG_OFF:
383 case HtmlTokenId::VARIABLE_ON:
384 case HtmlTokenId::VARIABLE_OFF:
385 // HTML 3.0
386 case HtmlTokenId::ABBREVIATION_ON:
387 case HtmlTokenId::ABBREVIATION_OFF:
388 case HtmlTokenId::ACRONYM_ON:
389 case HtmlTokenId::ACRONYM_OFF:
390 case HtmlTokenId::AUTHOR_ON:
391 case HtmlTokenId::AUTHOR_OFF:
392// case HtmlTokenId::BLOCKQUOTE30_ON: //! special handling
393// case HtmlTokenId::BLOCKQUOTE30_OFF:
394 case HtmlTokenId::DELETEDTEXT_ON:
395 case HtmlTokenId::DELETEDTEXT_OFF:
396 case HtmlTokenId::INSERTEDTEXT_ON:
397 case HtmlTokenId::INSERTEDTEXT_OFF:
398 case HtmlTokenId::LANGUAGE_ON:
399 case HtmlTokenId::LANGUAGE_OFF:
400 case HtmlTokenId::PERSON_ON:
401 case HtmlTokenId::PERSON_OFF:
402 case HtmlTokenId::SHORTQUOTE_ON:
403 case HtmlTokenId::SHORTQUOTE_OFF:
404 case HtmlTokenId::SUBSCRIPT_ON:
405 case HtmlTokenId::SUBSCRIPT_OFF:
406 case HtmlTokenId::SUPERSCRIPT_ON:
407 case HtmlTokenId::SUPERSCRIPT_OFF:
408 // inline elements, visual markup
409 // HTML 2.0
410 case HtmlTokenId::BOLD_ON:
411 case HtmlTokenId::BOLD_OFF:
412 case HtmlTokenId::ITALIC_ON:
413 case HtmlTokenId::ITALIC_OFF:
414 case HtmlTokenId::TELETYPE_ON:
415 case HtmlTokenId::TELETYPE_OFF:
416 case HtmlTokenId::UNDERLINE_ON:
417 case HtmlTokenId::UNDERLINE_OFF:
418 // HTML 3.0
419 case HtmlTokenId::BIGPRINT_ON:
420 case HtmlTokenId::BIGPRINT_OFF:
421 case HtmlTokenId::STRIKETHROUGH_ON:
422 case HtmlTokenId::STRIKETHROUGH_OFF:
423 case HtmlTokenId::SMALLPRINT_ON:
424 case HtmlTokenId::SMALLPRINT_OFF:
425 // figures
426 case HtmlTokenId::FIGURE_ON:
427 case HtmlTokenId::FIGURE_OFF:
428 case HtmlTokenId::CAPTION_ON:
429 case HtmlTokenId::CAPTION_OFF:
430 case HtmlTokenId::CREDIT_ON:
431 case HtmlTokenId::CREDIT_OFF:
432 // misc
433 case HtmlTokenId::DIRLIST_ON:
434 case HtmlTokenId::DIRLIST_OFF:
435 case HtmlTokenId::FOOTNOTE_ON:
436 case HtmlTokenId::FOOTNOTE_OFF:
437 case HtmlTokenId::MENULIST_ON:
438 case HtmlTokenId::MENULIST_OFF:
439// case HtmlTokenId::PLAINTEXT_ON: //! special handling
440// case HtmlTokenId::PLAINTEXT_OFF:
441// case HtmlTokenId::PREFORMTXT_ON: //! special handling
442// case HtmlTokenId::PREFORMTXT_OFF:
443 case HtmlTokenId::SPAN_ON:
444 case HtmlTokenId::SPAN_OFF:
445 // obsolete
446// case HtmlTokenId::XMP_ON: //! special handling
447// case HtmlTokenId::XMP_OFF:
448// case HtmlTokenId::LISTING_ON: //! special handling
449// case HtmlTokenId::LISTING_OFF:
450 // Netscape
451 case HtmlTokenId::BLINK_ON:
452 case HtmlTokenId::BLINK_OFF:
453 case HtmlTokenId::NOBR_ON:
454 case HtmlTokenId::NOBR_OFF:
455 case HtmlTokenId::NOEMBED_ON:
456 case HtmlTokenId::NOEMBED_OFF:
457 case HtmlTokenId::NOFRAMES_ON:
458 case HtmlTokenId::NOFRAMES_OFF:
459 // Internet Explorer
460 case HtmlTokenId::MARQUEE_ON:
461 case HtmlTokenId::MARQUEE_OFF:
462// case HtmlTokenId::PLAINTEXT2_ON: //! special handling
463// case HtmlTokenId::PLAINTEXT2_OFF:
464 break;
465
466 default:
467 {
468 if ( nToken >= HtmlTokenId::ONOFF_START )
469 {
470 if ( ( nToken == HtmlTokenId::UNKNOWNCONTROL_ON ) || ( nToken == HtmlTokenId::UNKNOWNCONTROL_OFF ) )
471 {
472 ;
473 }
474 else if ( !isOffToken(nToken) )
475 {
476 DBG_ASSERT( !isOffToken( nToken ), "No Start-Token ?!" );
477 SkipGroup( static_cast<HtmlTokenId>(static_cast<int>(nToken) + 1) );
478 }
479 }
480 }
481 } // SWITCH
482
484 {
486 aImportInfo.nToken = nToken;
487 if ( nToken == HtmlTokenId::TEXTTOKEN )
488 aImportInfo.aText = aToken;
489 else if (nToken == HtmlTokenId::STYLE_OFF)
490 aImportInfo.aText = maStyleSource.makeStringAndClear();
492 }
493
494}
495
497{
499 {
502 }
504}
505
507{
508 // pSel, when character attributes, otherwise paragraph attributes for
509 // the current paragraph.
510 DBG_ASSERT( aCurSel.Min().GetNode() == aCurSel.Max().GetNode(), "ImpInsertAttribs: Selection?" );
511
512 EditPaM aStartPaM( aCurSel.Min() );
513 EditPaM aEndPaM( aCurSel.Max() );
514
515 aStartPaM.SetIndex( 0 );
516 aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );
517
519 {
520 EditSelection aSel( aStartPaM, aEndPaM );
523 }
524
525 ContentNode* pSN = aStartPaM.GetNode();
526 sal_Int32 nStartNode = mpEditEngine->GetEditDoc().GetPos( pSN );
527
528 // If an attribute goes from 0 to current Paragraph length,
529 // then it should be a paragraph attribute!
530
531 // Note: Selection can reach over several Paragraphs.
532 // All complete paragraphs are paragraph attributes ...
533
534 // not really HTML:
535#ifdef DBG_UTIL
536 ContentNode* pEN = aEndPaM.GetNode();
537 sal_Int32 nEndNode = mpEditEngine->GetEditDoc().GetPos( pEN );
538 DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Several paragraphs?" );
539#endif
540
541 if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
542 {
543 // Has to be merged:
544 SfxItemSet aItems = mpEditEngine->GetBaseParaAttribs(nStartNode);
545 aItems.Put( rItems );
546 mpEditEngine->SetParaAttribsOnly(nStartNode, aItems);
547 }
548 else
549 mpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rItems );
550}
551
552void EditHTMLParser::ImpSetStyleSheet( sal_uInt16 nHLevel )
553{
554 /*
555 nHLevel: 0: Turn off
556 1-6: Heading
557 STYLE_PRE: Preformatted
558 */
559 // Create hard attributes ...
560 // Enough for Calc, would have to be clarified with StyleSheets
561 // that they should also be in the app so that when they are feed
562 // in a different engine still are here ...
563 sal_Int32 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
564
566
567 aItems.ClearItem( EE_PARA_ULSPACE );
568
570 aItems.ClearItem( EE_CHAR_FONTINFO );
571 aItems.ClearItem( EE_CHAR_WEIGHT );
572
576
580
581 // Bold in the first 3 Headings
582 if ( ( nHLevel >= 1 ) && ( nHLevel <= 3 ) )
583 {
585 aItems.Put( aWeightItem );
586
588 aItems.Put( aWeightItemCJK );
589
591 aItems.Put( aWeightItemCTL );
592 }
593
594 // Font height and margins, when LogicToLogic is possible:
596 if ( ( eUnit != MapUnit::MapPixel ) && ( eUnit != MapUnit::MapSysFont ) &&
597 ( eUnit != MapUnit::MapAppFont ) && ( eUnit != MapUnit::MapRelative ) )
598 {
599 tools::Long nPoints = 10;
600 if ( nHLevel == 1 )
601 nPoints = 22;
602 else if ( nHLevel == 2 )
603 nPoints = 16;
604 else if ( nHLevel == 3 )
605 nPoints = 12;
606 else if ( nHLevel == 4 )
607 nPoints = 11;
608
609 nPoints = OutputDevice::LogicToLogic( nPoints, MapUnit::MapPoint, eUnit );
610
611 SvxFontHeightItem aHeightItem( nPoints, 100, EE_CHAR_FONTHEIGHT );
612 aItems.Put( aHeightItem );
613
614 SvxFontHeightItem aHeightItemCJK( nPoints, 100, EE_CHAR_FONTHEIGHT_CJK );
615 aItems.Put( aHeightItemCJK );
616
617 SvxFontHeightItem aHeightItemCTL( nPoints, 100, EE_CHAR_FONTHEIGHT_CTL );
618 aItems.Put( aHeightItemCTL );
619
620 // Paragraph margins, when Heading:
621 if (nHLevel <= 6)
622 {
623 SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
624 aULSpaceItem.SetUpper( static_cast<sal_uInt16>(OutputDevice::LogicToLogic( 42, MapUnit::Map10thMM, eUnit )) );
625 aULSpaceItem.SetLower( static_cast<sal_uInt16>(OutputDevice::LogicToLogic( 35, MapUnit::Map10thMM, eUnit )) );
626 aItems.Put( aULSpaceItem );
627 }
628 }
629
630 // Choose a proportional Font for Pre
631 if ( nHLevel == STYLE_PRE )
632 {
633 vcl::Font aFont = OutputDevice::GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_SYSTEM, GetDefaultFontFlags::NONE );
634 SvxFontItem aFontItem( aFont.GetFamilyType(), aFont.GetFamilyName(), OUString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO );
635 aItems.Put( aFontItem );
636
637 SvxFontItem aFontItemCJK( aFont.GetFamilyType(), aFont.GetFamilyName(), OUString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CJK );
638 aItems.Put( aFontItemCJK );
639
640 SvxFontItem aFontItemCTL( aFont.GetFamilyType(), aFont.GetFamilyName(), OUString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CTL );
641 aItems.Put( aFontItemCTL );
642 }
643
644 mpEditEngine->SetParaAttribsOnly(nNode, aItems);
645}
646
647void EditHTMLParser::ImpInsertText( const OUString& rText )
648{
650 {
652 aImportInfo.aText = rText;
654 }
655
657}
658
660{
661 // groups in cells are closed upon leaving the cell, because those
662 // ******* web authors don't know their job
663 // for example: <td><form></td> lacks a closing </form>
664 sal_uInt8 nCellLevel = nInCell;
666 while( nCellLevel <= nInCell )
667 {
669 if (nToken == nEndToken || nToken == HtmlTokenId::NONE)
670 break;
671 switch ( nToken )
672 {
673 case HtmlTokenId::TABLEHEADER_ON:
674 case HtmlTokenId::TABLEDATA_ON:
675 nInCell++;
676 break;
677 case HtmlTokenId::TABLEHEADER_OFF:
678 case HtmlTokenId::TABLEDATA_OFF:
679 if ( nInCell )
680 nInCell--;
681 break;
682 default: break;
683 }
684 }
685}
686
688{
689 if ( bReal )
690 {
691 const HTMLOptions& aOptions = GetOptions();
692 SvxAdjust eAdjust = SvxAdjust::Left;
693 for (const auto & aOption : aOptions)
694 {
695 if( aOption.GetToken() == HtmlOptionId::ALIGN )
696 {
697 OUString const& rTmp(aOption.GetString());
698 if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_right))
699 eAdjust = SvxAdjust::Right;
700 else if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_middle))
701 eAdjust = SvxAdjust::Center;
702 else if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_center))
703 eAdjust = SvxAdjust::Center;
704 else
705 eAdjust = SvxAdjust::Left;
706 }
707 }
709 aItemSet.Put( SvxAdjustItem( eAdjust, EE_PARA_JUST ) );
710 ImpSetAttribs( aItemSet );
711 }
712 bInPara = true;
713}
714
716{
717 if ( bInPara )
718 {
719 bool bHasText = HasTextInCurrentPara();
720 if ( bHasText )
722 }
723 bInPara = false;
724}
725
727{
728 // A blank must be thrown away if the new text begins with a Blank and
729 // if the current paragraph is empty or ends with a Blank...
730 ContentNode* pNode = aCurSel.Max().GetNode();
731 return !(pNode->Len() && ( pNode->GetChar( pNode->Len()-1 ) != ' ' ));
732}
733
735{
736 return aCurSel.Max().GetNode()->Len() != 0;
737}
738
740{
741 // ignore anchor in anchor
742 if ( moCurAnchor )
743 return;
744
745 const HTMLOptions& aOptions = GetOptions();
746 OUString aRef;
747
748 for (const auto & aOption : aOptions)
749 {
750 if( aOption.GetToken() == HtmlOptionId::HREF)
751 aRef = aOption.GetString();
752 }
753
754 if ( aRef.isEmpty() )
755 return;
756
757 OUString aURL = aRef;
758 if ( !aURL.isEmpty() && ( aURL[ 0 ] != '#' ) )
759 {
761 INetURLObject aRootURL( aBaseURL );
762 aRootURL.GetNewAbsURL( aRef, &aTargetURL );
764 }
765 moCurAnchor.emplace();
766 moCurAnchor->aHRef = aURL;
767}
768
770{
771 if ( !moCurAnchor )
772 return;
773
774 // Insert as URL-Field...
777 bFieldsInserted = true;
778 moCurAnchor.reset();
779
781 {
784 }
785}
786
788{
790 StartPara( false );
791
794
795 sal_uInt16 nId = sal::static_int_cast< sal_uInt16 >(
796 1 + ( ( static_cast<int>(nToken) - int(HtmlTokenId::HEAD1_ON) ) / 2 ) );
797 DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID can not be correct!" );
799}
800
802{
803 EndPara();
804 ImpSetStyleSheet( 0 );
805
806 if ( bWasInPara )
807 {
808 bInPara = true;
809 bWasInPara = false;
810 }
811}
812
813/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxItemSet & GetItems()
Definition: editdoc.hxx:166
sal_Unicode GetChar(sal_Int32 nPos) const
Definition: editdoc.cxx:1766
ContentAttribs & GetContentAttribs()
Definition: editdoc.hxx:254
sal_Int32 Len() const
Definition: editdoc.cxx:1615
sal_Int32 GetPos(const ContentNode *pNode) const
Definition: editdoc.cxx:2086
const SfxItemSet & GetBaseParaAttribs(sal_Int32 nPara) const
Definition: editeng.cxx:950
ESelection CreateESelection(const EditSelection &rSel) const
Definition: editeng.cxx:940
void CallHtmlImportHandler(HtmlImportInfo &rInfo)
Definition: editeng.cxx:2855
bool IsHtmlImportHandlerSet() const
Definition: editeng.cxx:2840
EditPaM InsertField(const EditSelection &rEditSelection, const SvxFieldItem &rFld)
Definition: editeng.cxx:835
bool UpdateFieldsOnly()
Definition: editeng.cxx:2372
MapMode const & GetRefMapMode() const
Definition: editeng.cxx:164
void SetParaAttribsOnly(sal_Int32 nPara, const SfxItemSet &rSet)
Definition: editeng.cxx:955
EditSelection InsertText(css::uno::Reference< css::datatransfer::XTransferable > const &rxDataObj, const OUString &rBaseURL, const EditPaM &rPaM, bool bUseSpecial)
const SfxItemSet & GetEmptyItemSet() const
Definition: editeng.cxx:199
EditPaM InsertParaBreak(const EditSelection &rEditSelection)
Definition: editeng.cxx:2865
void SetAttribs(const EditSelection &rSel, const SfxItemSet &rSet, SetAttribsMode nSpecial=SetAttribsMode::NONE)
Definition: editeng.cxx:960
EditDoc & GetEditDoc()
Definition: editeng.cxx:905
bool bFieldsInserted
Definition: eehtml.hxx:48
bool HasTextInCurrentPara()
Definition: eehtml.cxx:734
OUString aBaseURL
Definition: eehtml.hxx:42
virtual ~EditHTMLParser() override
Definition: eehtml.cxx:63
sal_uInt8 nDefListLevel
Definition: eehtml.hxx:53
void StartPara(bool bReal)
Definition: eehtml.cxx:687
void AnchorStart()
Definition: eehtml.cxx:739
void HeadingStart(HtmlTokenId nToken)
Definition: eehtml.cxx:787
void EndPara()
Definition: eehtml.cxx:715
bool bInPara
Definition: eehtml.hxx:46
bool bWasInPara
Definition: eehtml.hxx:47
void HeadingEnd()
Definition: eehtml.cxx:801
sal_uInt8 nInTable
Definition: eehtml.hxx:51
void ImpInsertParaBreak()
Definition: eehtml.cxx:496
EditHTMLParser(SvStream &rIn, OUString aBaseURL, SvKeyValueIterator *pHTTPHeaderAttrs)
Definition: eehtml.cxx:38
bool bInTitle
Definition: eehtml.hxx:49
EditSelection aCurSel
Definition: eehtml.hxx:41
std::optional< AnchorInfo > moCurAnchor
Definition: eehtml.hxx:44
virtual void NextToken(HtmlTokenId nToken) override
Definition: eehtml.cxx:98
void ImpInsertText(const OUString &rText)
Definition: eehtml.cxx:647
sal_uInt8 nInCell
Definition: eehtml.hxx:52
void ImpSetAttribs(const SfxItemSet &rItems)
Definition: eehtml.cxx:506
virtual SvParserState CallParser() override
bool ThrowAwayBlank()
Definition: eehtml.cxx:726
void SkipGroup(HtmlTokenId nEndToken)
Definition: eehtml.cxx:659
EditEngine * mpEditEngine
Definition: eehtml.hxx:43
void AnchorEnd()
Definition: eehtml.cxx:769
void ImpSetStyleSheet(sal_uInt16 nHeadingLevel)
Definition: eehtml.cxx:552
OUStringBuffer maStyleSource
Definition: eehtml.hxx:40
void SetIndex(sal_Int32 n)
Definition: editdoc.hxx:317
const ContentNode * GetNode() const
Definition: editdoc.hxx:312
sal_Int32 GetIndex() const
Definition: editdoc.hxx:316
EditPaM & Min()
Definition: editdoc.hxx:705
EditPaM & Max()
Definition: editdoc.hxx:706
HtmlOptionId GetToken() const
const OUString & GetString() const
bool IsReadStyle() const
static rtl_TextEncoding GetEncodingByMIME(const OUString &rMime)
virtual SvParserState CallParser() override
bool SetEncodingByHTTPHeader(SvKeyValueIterator *pHTTPHeader)
const HTMLOptions & GetOptions(HtmlOptionId const *pNoConvertToken=nullptr)
bool IsReadPRE() const
bool GetNewAbsURL(OUString const &rTheRelURIRef, INetURLObject *pTheAbsURIRef) const
MapUnit GetMapUnit() const
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void SetSrcEncoding(rtl_TextEncoding eSrcEnc)
bool IsSwitchToUCS2() const
void SetSwitchToUCS2(bool bSet)
OUStringBuffer aToken
This item stores a field (SvxFieldData).
Definition: flditem.hxx:70
This item describes a Font.
Definition: fontitem.hxx:30
void SetLower(const sal_uInt16 nL, const sal_uInt16 nProp=100)
Definition: ulspitem.hxx:86
void SetUpper(const sal_uInt16 nU, const sal_uInt16 nProp=100)
Definition: ulspitem.hxx:82
FontFamily GetFamilyType()
const OUString & GetFamilyName() const
FontPitch GetPitch()
rtl_TextEncoding GetCharSet() const
#define DBG_ASSERT(sCon, aError)
URL aURL
float u
#define STYLE_PRE
Definition: eehtml.cxx:36
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CJK(EE_CHAR_START+17)
constexpr TypedWhichId< SvxFieldItem > EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
constexpr TypedWhichId< SvxAdjustItem > EE_PARA_JUST(EE_PARA_START+16)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
constexpr TypedWhichId< SvxULSpaceItem > EE_PARA_ULSPACE(EE_PARA_START+14)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT_CTL(EE_CHAR_START+22)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CTL(EE_CHAR_START+20)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT_CJK(EE_CHAR_START+21)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CTL(EE_CHAR_START+18)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CJK(EE_CHAR_START+19)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
WEIGHT_BOLD
#define OOO_STRING_SVTOOLS_HTML_AL_center
#define OOO_STRING_SVTOOLS_HTML_AL_right
#define OOO_STRING_SVTOOLS_HTML_AL_middle
HtmlTokenId
constexpr bool isOffToken(HtmlTokenId nToken)
#define LANGUAGE_SYSTEM
MapUnit
int i
long Long
sal_Int16 nId
::std::vector< HTMLOption > HTMLOptions
DefTokenId nToken
HtmlTokenId nToken
Definition: editdata.hxx:235
OUString aText
Definition: editdata.hxx:237
SvParserState
SvxAdjust
Definition: svxenum.hxx:77
TOOLS_DLLPUBLIC rtl_TextEncoding GetExtendedCompatibilityTextEncoding(rtl_TextEncoding eEncoding)
unsigned char sal_uInt8
OUString aTargetURL