Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/wrkwin.hxx>
31 : : #include <vcl/dialog.hxx>
32 : : #include <vcl/msgbox.hxx>
33 : : #include <vcl/svapp.hxx>
34 : : #include <eehtml.hxx>
35 : : #include <editeng/adjitem.hxx>
36 : : #include <editeng/flditem.hxx>
37 : : #include <tools/urlobj.hxx>
38 : : #include <editeng/fhgtitem.hxx>
39 : : #include <editeng/fontitem.hxx>
40 : : #include <editeng/ulspitem.hxx>
41 : : #include <editeng/wghtitem.hxx>
42 : : #include <svtools/htmltokn.h>
43 : : #include <svtools/htmlkywd.hxx>
44 : : #include <tools/tenccvt.hxx>
45 : :
46 : : #include "editeng/editeng.hxx"
47 : :
48 : : #define ACTION_INSERTTEXT 1
49 : : #define ACTION_INSERTPARABRK 2
50 : :
51 : : #define STYLE_PRE 101
52 : :
53 : 3 : EditHTMLParser::EditHTMLParser( SvStream& rIn, const String& rBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs )
54 : : : HTMLParser( rIn, true ),
55 : : aBaseURL( rBaseURL ),
56 : : mpEditEngine(NULL),
57 : : pCurAnchor(NULL),
58 : : bInPara(false),
59 : : bWasInPara(false),
60 : : bFieldsInserted(false),
61 : : bInTitle(false),
62 : : nInTable(0),
63 : : nInCell(0),
64 [ + - ][ + - ]: 3 : nDefListLevel(0)
65 : : {
66 : : DBG_ASSERT( RTL_TEXTENCODING_DONTKNOW == GetSrcEncoding( ), "EditHTMLParser::EditHTMLParser: Where does the encoding come from?" );
67 : : DBG_ASSERT( !IsSwitchToUCS2(), "EditHTMLParser::::EditHTMLParser: Switch to UCS2?" );
68 : :
69 : : // Altough the real default encoding is ISO8859-1, we use MS-1252
70 : : // als default encoding.
71 [ + - ][ + - ]: 3 : SetSrcEncoding( GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
72 : :
73 : : // If the file starts with a BOM, switch to UCS2.
74 : 3 : SetSwitchToUCS2( true );
75 : :
76 [ + - ]: 3 : if ( pHTTPHeaderAttrs )
77 [ + - ]: 3 : SetEncodingByHTTPHeader( pHTTPHeaderAttrs );
78 : 3 : }
79 : :
80 [ + - ]: 3 : EditHTMLParser::~EditHTMLParser()
81 : : {
82 [ - + ][ # # ]: 3 : delete pCurAnchor;
83 [ - + ]: 6 : }
84 : :
85 : 3 : SvParserState EditHTMLParser::CallParser(EditEngine* pEE, const EditPaM& rPaM)
86 : : {
87 : : DBG_ASSERT(pEE, "CallParser: ImpEditEngine ?!");
88 : 3 : mpEditEngine = pEE;
89 : 3 : SvParserState _eState = SVPAR_NOTSTARTED;
90 [ + - ]: 3 : if ( mpEditEngine )
91 : : {
92 : : // Build in wrap mimic in RTF import?
93 [ + - ]: 3 : aCurSel = EditSelection( rPaM, rPaM );
94 : :
95 [ + - ]: 3 : if (mpEditEngine->IsImportHandlerSet())
96 : : {
97 [ + - ][ + - ]: 3 : ImportInfo aImportInfo(HTMLIMP_START, this, mpEditEngine->CreateESelection(aCurSel));
98 [ + - ][ + - ]: 3 : mpEditEngine->CallImportHandler(aImportInfo);
99 : : }
100 : :
101 : 3 : ImpSetStyleSheet( 0 );
102 : 3 : _eState = HTMLParser::CallParser();
103 : :
104 [ + - ]: 3 : if (mpEditEngine->IsImportHandlerSet())
105 : : {
106 [ + - ][ + - ]: 3 : ImportInfo aImportInfo(HTMLIMP_END, this, mpEditEngine->CreateESelection(aCurSel));
107 [ + - ][ + - ]: 3 : mpEditEngine->CallImportHandler(aImportInfo);
108 : : }
109 : :
110 [ - + ]: 3 : if ( bFieldsInserted )
111 : 0 : mpEditEngine->UpdateFieldsOnly();
112 : : }
113 : 3 : return _eState;
114 : : }
115 : :
116 : 102 : void EditHTMLParser::NextToken( int nToken )
117 : : {
118 : : #ifdef DBG_UTIL
119 : : HTML_TOKEN_IDS xID = (HTML_TOKEN_IDS)nToken;
120 : : (void)xID;
121 : : #endif
122 : :
123 [ - - - - : 102 : switch( nToken )
- - - + -
- - - - -
- - - - +
+ + - + -
+ - - - -
+ - ]
124 : : {
125 : : case HTML_META:
126 : : {
127 : 0 : const HTMLOptions& aOptions = GetOptions();
128 : 0 : size_t nArrLen = aOptions.size();
129 : 0 : bool bEquiv = false;
130 [ # # ]: 0 : for ( size_t i = 0; i < nArrLen; i++ )
131 : : {
132 : 0 : const HTMLOption& aOption = aOptions[i];
133 [ # # # ]: 0 : switch( aOption.GetToken() )
134 : : {
135 : : case HTML_O_HTTPEQUIV:
136 : : {
137 : 0 : bEquiv = true;
138 : : }
139 : 0 : break;
140 : : case HTML_O_CONTENT:
141 : : {
142 [ # # ]: 0 : if ( bEquiv )
143 : : {
144 : 0 : rtl_TextEncoding eEnc = GetEncodingByMIME( aOption.GetString() );
145 [ # # ]: 0 : if ( eEnc != RTL_TEXTENCODING_DONTKNOW )
146 : 0 : SetSrcEncoding( eEnc );
147 : : }
148 : : }
149 : 0 : break;
150 : : }
151 : : }
152 : :
153 : : }
154 : 0 : break;
155 : : case HTML_PLAINTEXT_ON:
156 : : case HTML_PLAINTEXT2_ON:
157 : 0 : bInPara = true;
158 : 0 : break;
159 : : case HTML_PLAINTEXT_OFF:
160 : : case HTML_PLAINTEXT2_OFF:
161 : 0 : bInPara = false;
162 : 0 : break;
163 : :
164 : : case HTML_LINEBREAK:
165 : : case HTML_NEWPARA:
166 : : {
167 [ # # ][ # # ]: 0 : if ( ( bInPara || nInTable ) &&
[ # # # # ]
[ # # ]
168 : 0 : ( ( nToken == HTML_LINEBREAK ) || HasTextInCurrentPara() ) )
169 : : {
170 : 0 : ImpInsertParaBreak();
171 : : }
172 : : }
173 : 0 : break;
174 : : case HTML_HORZRULE:
175 : : {
176 [ # # ]: 0 : if ( HasTextInCurrentPara() )
177 : 0 : ImpInsertParaBreak();
178 : 0 : ImpInsertParaBreak();
179 : : }
180 : : case HTML_NONBREAKSPACE:
181 : : {
182 [ # # ]: 0 : if ( bInPara )
183 : : {
184 [ # # ]: 0 : ImpInsertText( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
185 : : }
186 : : }
187 : 0 : break;
188 : : case HTML_RAWDATA:
189 [ # # ][ # # ]: 0 : if (IsReadStyle() && aToken.Len())
[ # # ]
190 : : {
191 : : // Each token represents a single line.
192 [ # # ]: 0 : maStyleSource.append(aToken);
193 : 0 : maStyleSource.append(sal_Unicode('\n'));
194 : : }
195 : 0 : break;
196 : : case HTML_TEXTTOKEN:
197 : : {
198 : : // #i110937# for <title> content, call aImportHdl (no SkipGroup), but don't insert the text into the EditEngine
199 [ + - ]: 39 : if (!bInTitle)
200 : : {
201 [ + + ]: 39 : if ( !bInPara )
202 [ + - ]: 9 : StartPara( false );
203 : :
204 [ + - ]: 39 : String aText = aToken;
205 [ + - ][ + + ]: 81 : if ( aText.Len() && ( aText.GetChar( 0 ) == ' ' )
[ + - + - ]
[ + + ]
206 [ + - ]: 42 : && ThrowAwayBlank() && !IsReadPRE() )
207 [ + - ]: 21 : aText.Erase( 0, 1 );
208 : :
209 [ - + ]: 39 : if ( pCurAnchor )
210 : : {
211 [ # # ]: 0 : pCurAnchor->aText += aText;
212 : : }
213 : : else
214 : : {
215 : : // Only written until HTML with 319?
216 [ - + ]: 39 : if ( IsReadPRE() )
217 : : {
218 [ # # ]: 0 : sal_uInt16 nTabPos = aText.Search( '\t', 0 );
219 [ # # ]: 0 : while ( nTabPos != STRING_NOTFOUND )
220 : : {
221 [ # # ]: 0 : aText.Erase( nTabPos, 1 );
222 [ # # ][ # # ]: 0 : aText.Insert( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ), nTabPos );
[ # # ]
223 [ # # ]: 0 : nTabPos = aText.Search( '\t', nTabPos+8 );
224 : : }
225 : : }
226 [ + - ]: 39 : ImpInsertText( aText );
227 [ + - ]: 39 : }
228 : : }
229 : : }
230 : 39 : break;
231 : :
232 : : case HTML_CENTER_ON:
233 : : case HTML_CENTER_OFF:
234 : : {
235 [ # # ][ # # ]: 0 : sal_uInt16 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
[ # # ]
236 [ # # ][ # # ]: 0 : SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
237 [ # # ]: 0 : aItems.ClearItem( EE_PARA_JUST );
238 [ # # ]: 0 : if ( nToken == HTML_CENTER_ON )
239 [ # # ][ # # ]: 0 : aItems.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
[ # # ]
240 [ # # ][ # # ]: 0 : mpEditEngine->SetParaAttribsOnly(nNode, aItems);
241 : : }
242 : 0 : break;
243 : :
244 : 0 : case HTML_ANCHOR_ON: AnchorStart();
245 : 0 : break;
246 : 0 : case HTML_ANCHOR_OFF: AnchorEnd();
247 : 0 : break;
248 : :
249 : : case HTML_PARABREAK_ON:
250 [ # # ][ # # ]: 0 : if( bInPara && HasTextInCurrentPara() )
[ # # ]
251 : 0 : EndPara( true );
252 : 0 : StartPara( true );
253 : 0 : break;
254 : :
255 : : case HTML_PARABREAK_OFF:
256 [ # # ]: 0 : if( bInPara )
257 : 0 : EndPara( true );
258 : 0 : break;
259 : :
260 : : case HTML_HEAD1_ON:
261 : : case HTML_HEAD2_ON:
262 : : case HTML_HEAD3_ON:
263 : : case HTML_HEAD4_ON:
264 : : case HTML_HEAD5_ON:
265 : : case HTML_HEAD6_ON:
266 : : {
267 : 0 : HeadingStart( nToken );
268 : : }
269 : 0 : break;
270 : :
271 : : case HTML_HEAD1_OFF:
272 : : case HTML_HEAD2_OFF:
273 : : case HTML_HEAD3_OFF:
274 : : case HTML_HEAD4_OFF:
275 : : case HTML_HEAD5_OFF:
276 : : case HTML_HEAD6_OFF:
277 : : {
278 : 0 : HeadingEnd( nToken );
279 : : }
280 : 0 : break;
281 : :
282 : : case HTML_PREFORMTXT_ON:
283 : : case HTML_XMP_ON:
284 : : case HTML_LISTING_ON:
285 : : {
286 : 0 : StartPara( true );
287 : 0 : ImpSetStyleSheet( STYLE_PRE );
288 : : }
289 : 0 : break;
290 : :
291 : : case HTML_DEFLIST_ON:
292 : : {
293 : 0 : nDefListLevel++;
294 : : }
295 : 0 : break;
296 : :
297 : : case HTML_DEFLIST_OFF:
298 : : {
299 [ # # ]: 0 : if( nDefListLevel )
300 : 0 : nDefListLevel--;
301 : : }
302 : 0 : break;
303 : :
304 : 3 : case HTML_TABLE_ON: nInTable++;
305 : 3 : break;
306 : : case HTML_TABLE_OFF: DBG_ASSERT( nInTable, "Not in Table, but TABLE_OFF?" );
307 : 3 : nInTable--;
308 : 3 : break;
309 : :
310 : : case HTML_TABLEHEADER_ON:
311 : : case HTML_TABLEDATA_ON:
312 : 18 : nInCell++;
313 : : // fall through
314 : : case HTML_BLOCKQUOTE_ON:
315 : : case HTML_BLOCKQUOTE_OFF:
316 : : case HTML_BLOCKQUOTE30_ON:
317 : : case HTML_BLOCKQUOTE30_OFF:
318 : : case HTML_LISTHEADER_ON:
319 : : case HTML_LI_ON:
320 : : case HTML_DD_ON:
321 : : case HTML_DT_ON:
322 : : case HTML_ORDERLIST_ON:
323 : : case HTML_UNORDERLIST_ON:
324 : : {
325 : 18 : bool bHasText = HasTextInCurrentPara();
326 [ - + ]: 18 : if ( bHasText )
327 : 0 : ImpInsertParaBreak();
328 : 18 : StartPara( false );
329 : : }
330 : 18 : break;
331 : :
332 : : case HTML_TABLEHEADER_OFF:
333 : : case HTML_TABLEDATA_OFF:
334 : : {
335 [ + - ]: 18 : if ( nInCell )
336 : 18 : nInCell--;
337 : : }
338 : : // fall through
339 : : case HTML_LISTHEADER_OFF:
340 : : case HTML_LI_OFF:
341 : : case HTML_DD_OFF:
342 : : case HTML_DT_OFF:
343 : : case HTML_ORDERLIST_OFF:
344 : 18 : case HTML_UNORDERLIST_OFF: EndPara( false );
345 : 18 : break;
346 : :
347 : : case HTML_TABLEROW_ON:
348 : : case HTML_TABLEROW_OFF: // A RETURN only after a CELL, for Calc
349 : :
350 : : case HTML_COL_ON:
351 : : case HTML_COLGROUP_ON:
352 : 12 : case HTML_COLGROUP_OFF: break;
353 : :
354 : : case HTML_FONT_ON: // ...
355 : 0 : break;
356 : : case HTML_FONT_OFF: // ...
357 : 0 : break;
358 : :
359 : : case HTML_TITLE_ON:
360 : 0 : bInTitle = true;
361 : 0 : break;
362 : : case HTML_TITLE_OFF:
363 : 0 : bInTitle = false;
364 : 0 : break;
365 : :
366 : : // globals
367 : : case HTML_HTML_ON:
368 : : case HTML_HTML_OFF:
369 : : case HTML_STYLE_ON:
370 : : case HTML_STYLE_OFF:
371 : : case HTML_BODY_ON:
372 : : case HTML_BODY_OFF:
373 : : case HTML_HEAD_ON:
374 : : case HTML_HEAD_OFF:
375 : : case HTML_FORM_ON:
376 : : case HTML_FORM_OFF:
377 : : case HTML_THEAD_ON:
378 : : case HTML_THEAD_OFF:
379 : : case HTML_TBODY_ON:
380 : : case HTML_TBODY_OFF:
381 : : // inline elements, structural markup
382 : : // HTML 3.0
383 : : case HTML_BANNER_ON:
384 : : case HTML_BANNER_OFF:
385 : : case HTML_DIVISION_ON:
386 : : case HTML_DIVISION_OFF:
387 : : // case HTML_LISTHEADER_ON: //! special handling
388 : : // case HTML_LISTHEADER_OFF:
389 : : case HTML_NOTE_ON:
390 : : case HTML_NOTE_OFF:
391 : : // inline elements, logical markup
392 : : // HTML 2.0
393 : : case HTML_ADDRESS_ON:
394 : : case HTML_ADDRESS_OFF:
395 : : // case HTML_BLOCKQUOTE_ON: //! special handling
396 : : // case HTML_BLOCKQUOTE_OFF:
397 : : case HTML_CITIATION_ON:
398 : : case HTML_CITIATION_OFF:
399 : : case HTML_CODE_ON:
400 : : case HTML_CODE_OFF:
401 : : case HTML_DEFINSTANCE_ON:
402 : : case HTML_DEFINSTANCE_OFF:
403 : : case HTML_EMPHASIS_ON:
404 : : case HTML_EMPHASIS_OFF:
405 : : case HTML_KEYBOARD_ON:
406 : : case HTML_KEYBOARD_OFF:
407 : : case HTML_SAMPLE_ON:
408 : : case HTML_SAMPLE_OFF:
409 : : case HTML_STRIKE_ON:
410 : : case HTML_STRIKE_OFF:
411 : : case HTML_STRONG_ON:
412 : : case HTML_STRONG_OFF:
413 : : case HTML_VARIABLE_ON:
414 : : case HTML_VARIABLE_OFF:
415 : : // HTML 3.0
416 : : case HTML_ABBREVIATION_ON:
417 : : case HTML_ABBREVIATION_OFF:
418 : : case HTML_ACRONYM_ON:
419 : : case HTML_ACRONYM_OFF:
420 : : case HTML_AUTHOR_ON:
421 : : case HTML_AUTHOR_OFF:
422 : : // case HTML_BLOCKQUOTE30_ON: //! special handling
423 : : // case HTML_BLOCKQUOTE30_OFF:
424 : : case HTML_DELETEDTEXT_ON:
425 : : case HTML_DELETEDTEXT_OFF:
426 : : case HTML_INSERTEDTEXT_ON:
427 : : case HTML_INSERTEDTEXT_OFF:
428 : : case HTML_LANGUAGE_ON:
429 : : case HTML_LANGUAGE_OFF:
430 : : case HTML_PERSON_ON:
431 : : case HTML_PERSON_OFF:
432 : : case HTML_SHORTQUOTE_ON:
433 : : case HTML_SHORTQUOTE_OFF:
434 : : case HTML_SUBSCRIPT_ON:
435 : : case HTML_SUBSCRIPT_OFF:
436 : : case HTML_SUPERSCRIPT_ON:
437 : : case HTML_SUPERSCRIPT_OFF:
438 : : // inline elements, visual markup
439 : : // HTML 2.0
440 : : case HTML_BOLD_ON:
441 : : case HTML_BOLD_OFF:
442 : : case HTML_ITALIC_ON:
443 : : case HTML_ITALIC_OFF:
444 : : case HTML_TELETYPE_ON:
445 : : case HTML_TELETYPE_OFF:
446 : : case HTML_UNDERLINE_ON:
447 : : case HTML_UNDERLINE_OFF:
448 : : // HTML 3.0
449 : : case HTML_BIGPRINT_ON:
450 : : case HTML_BIGPRINT_OFF:
451 : : case HTML_STRIKETHROUGH_ON:
452 : : case HTML_STRIKETHROUGH_OFF:
453 : : case HTML_SMALLPRINT_ON:
454 : : case HTML_SMALLPRINT_OFF:
455 : : // figures
456 : : case HTML_FIGURE_ON:
457 : : case HTML_FIGURE_OFF:
458 : : case HTML_CAPTION_ON:
459 : : case HTML_CAPTION_OFF:
460 : : case HTML_CREDIT_ON:
461 : : case HTML_CREDIT_OFF:
462 : : // misc
463 : : case HTML_DIRLIST_ON:
464 : : case HTML_DIRLIST_OFF:
465 : : case HTML_FOOTNOTE_ON: //! land so im Text
466 : : case HTML_FOOTNOTE_OFF:
467 : : case HTML_MENULIST_ON:
468 : : case HTML_MENULIST_OFF:
469 : : // case HTML_PLAINTEXT_ON: //! special handling
470 : : // case HTML_PLAINTEXT_OFF:
471 : : // case HTML_PREFORMTXT_ON: //! special handling
472 : : // case HTML_PREFORMTXT_OFF:
473 : : case HTML_SPAN_ON:
474 : : case HTML_SPAN_OFF:
475 : : // obsolete
476 : : // case HTML_XMP_ON: //! special handling
477 : : // case HTML_XMP_OFF:
478 : : // case HTML_LISTING_ON: //! special handling
479 : : // case HTML_LISTING_OFF:
480 : : // Netscape
481 : : case HTML_BLINK_ON:
482 : : case HTML_BLINK_OFF:
483 : : case HTML_NOBR_ON:
484 : : case HTML_NOBR_OFF:
485 : : case HTML_NOEMBED_ON:
486 : : case HTML_NOEMBED_OFF:
487 : : case HTML_NOFRAMES_ON:
488 : : case HTML_NOFRAMES_OFF:
489 : : // Internet Explorer
490 : : case HTML_MARQUEE_ON:
491 : : case HTML_MARQUEE_OFF:
492 : : // case HTML_PLAINTEXT2_ON: //! special handling
493 : : // case HTML_PLAINTEXT2_OFF:
494 : 9 : break;
495 : :
496 : : default:
497 : : {
498 [ # # ]: 0 : if ( nToken & HTML_TOKEN_ONOFF )
499 : : {
500 [ # # ][ # # ]: 0 : if ( ( nToken == HTML_UNKNOWNCONTROL_ON ) || ( nToken == HTML_UNKNOWNCONTROL_OFF ) )
501 : : {
502 : : ;
503 : : }
504 [ # # ]: 0 : else if ( !(nToken & 1) )
505 : : {
506 : : DBG_ASSERT( !( nToken & 1 ), "No Start-Token ?!" );
507 : 0 : SkipGroup( nToken + 1 );
508 : : }
509 : : }
510 : : }
511 : : } // SWITCH
512 : :
513 [ + - ]: 102 : if (mpEditEngine->IsImportHandlerSet())
514 : : {
515 [ + - ][ + - ]: 102 : ImportInfo aImportInfo(HTMLIMP_NEXTTOKEN, this, mpEditEngine->CreateESelection(aCurSel));
516 : 102 : aImportInfo.nToken = nToken;
517 : 102 : aImportInfo.nTokenValue = (short)nTokenValue;
518 [ + + ]: 102 : if ( nToken == HTML_TEXTTOKEN )
519 [ + - ]: 39 : aImportInfo.aText = aToken;
520 [ - + ]: 63 : else if (nToken == HTML_STYLE_OFF)
521 [ # # ][ # # ]: 0 : aImportInfo.aText = maStyleSource.makeStringAndClear();
522 [ + - ][ + - ]: 102 : mpEditEngine->CallImportHandler(aImportInfo);
523 : : }
524 : :
525 : 102 : }
526 : :
527 : 18 : void EditHTMLParser::ImpInsertParaBreak()
528 : : {
529 [ + - ]: 18 : if (mpEditEngine->IsImportHandlerSet())
530 : : {
531 [ + - ][ + - ]: 18 : ImportInfo aImportInfo(HTMLIMP_INSERTPARA, this, mpEditEngine->CreateESelection(aCurSel));
532 [ + - ][ + - ]: 18 : mpEditEngine->CallImportHandler(aImportInfo);
533 : : }
534 [ + - ]: 18 : aCurSel = mpEditEngine->InsertParaBreak(aCurSel);
535 : 18 : }
536 : :
537 : 0 : void EditHTMLParser::ImpSetAttribs( const SfxItemSet& rItems, EditSelection* pSel )
538 : : {
539 : : // pSel, when character attributes, otherwise paragraph attributes for
540 : : // the current paragraph.
541 : : DBG_ASSERT( pSel || ( aCurSel.Min().GetNode() == aCurSel.Max().GetNode() ), "ImpInsertAttribs: Selection?" );
542 : :
543 [ # # ][ # # ]: 0 : EditPaM aStartPaM( pSel ? pSel->Min() : aCurSel.Min() );
544 [ # # ][ # # ]: 0 : EditPaM aEndPaM( pSel ? pSel->Max() : aCurSel.Max() );
545 : :
546 [ # # ]: 0 : if ( !pSel )
547 : : {
548 : 0 : aStartPaM.SetIndex( 0 );
549 [ # # ][ # # ]: 0 : aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );
550 : : }
551 : :
552 [ # # ][ # # ]: 0 : if (mpEditEngine->IsImportHandlerSet())
553 : : {
554 [ # # ]: 0 : EditSelection aSel( aStartPaM, aEndPaM );
555 [ # # ][ # # ]: 0 : ImportInfo aImportInfo(HTMLIMP_SETATTR, this, mpEditEngine->CreateESelection(aSel));
556 : 0 : aImportInfo.pAttrs = (void*)&rItems;
557 [ # # ][ # # ]: 0 : mpEditEngine->CallImportHandler(aImportInfo);
558 : : }
559 : :
560 [ # # ]: 0 : ContentNode* pSN = aStartPaM.GetNode();
561 [ # # ][ # # ]: 0 : sal_uInt16 nStartNode = mpEditEngine->GetEditDoc().GetPos( pSN );
562 : :
563 : : // If an attribute goes from 0 to current Paragraph length,
564 : : // then it should be a paragraph attribute!
565 : :
566 : : // Note: Selection can reach over several Paragraphs.
567 : : // All complete paragraphs are paragraph attributes ...
568 : :
569 : : // not really HTML:
570 : : #ifdef DBG_UTIL
571 : : ContentNode* pEN = aEndPaM.GetNode();
572 : : sal_uInt16 nEndNode = mpEditEngine->GetEditDoc().GetPos( pEN );
573 : : DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Several paragraphs?" );
574 : : #endif
575 : :
576 [ # # ][ # # ]: 0 : if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
[ # # ][ # # ]
[ # # ]
577 : : {
578 : : // Has to be merged:
579 [ # # ][ # # ]: 0 : SfxItemSet aItems = mpEditEngine->GetBaseParaAttribs(nStartNode);
580 [ # # ]: 0 : aItems.Put( rItems );
581 [ # # ][ # # ]: 0 : mpEditEngine->SetParaAttribsOnly(nStartNode, aItems);
582 : : }
583 : : else
584 [ # # ][ # # ]: 0 : mpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rItems );
585 : 0 : }
586 : :
587 : 3 : void EditHTMLParser::ImpSetStyleSheet( sal_uInt16 nHLevel )
588 : : {
589 : : /*
590 : : nHLevel: 0: Turn off
591 : : 1-6: Heading
592 : : STYLE_PRE: Preformatted
593 : : */
594 : : // Create hard attributes ...
595 : : // Enough for Calc, would have to be clarified with StyleSheets
596 : : // that they should also be in the app so that when they are feed
597 : : // in a different engine still are here ...
598 [ + - ][ + - ]: 3 : sal_uInt16 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
[ + - ]
599 : :
600 [ + - ][ + - ]: 3 : SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
601 : :
602 [ + - ]: 3 : aItems.ClearItem( EE_PARA_ULSPACE );
603 : :
604 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTHEIGHT );
605 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTINFO );
606 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_WEIGHT );
607 : :
608 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTHEIGHT_CJK );
609 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTINFO_CJK );
610 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_WEIGHT_CJK );
611 : :
612 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTHEIGHT_CTL );
613 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_FONTINFO_CTL );
614 [ + - ]: 3 : aItems.ClearItem( EE_CHAR_WEIGHT_CTL );
615 : :
616 : : // Bold in the first 3 Headings
617 [ - + ][ # # ]: 3 : if ( ( nHLevel >= 1 ) && ( nHLevel <= 3 ) )
618 : : {
619 [ # # ]: 0 : SvxWeightItem aWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
620 [ # # ]: 0 : aItems.Put( aWeightItem );
621 : :
622 [ # # ]: 0 : SvxWeightItem aWeightItemCJK( WEIGHT_BOLD, EE_CHAR_WEIGHT_CJK );
623 [ # # ]: 0 : aItems.Put( aWeightItem );
624 : :
625 [ # # ]: 0 : SvxWeightItem aWeightItemCTL( WEIGHT_BOLD, EE_CHAR_WEIGHT_CTL );
626 [ # # ][ # # ]: 0 : aItems.Put( aWeightItem );
[ # # ][ # # ]
627 : : }
628 : :
629 : : // Font hight and margins, when LogicToLogic is possible:
630 [ + - ][ + - ]: 3 : MapUnit eUnit = mpEditEngine->GetRefMapMode().GetMapUnit();
631 [ + - ][ + - ]: 3 : if ( ( eUnit != MAP_PIXEL ) && ( eUnit != MAP_SYSFONT ) &&
[ + - ][ + - ]
632 : : ( eUnit != MAP_APPFONT ) && ( eUnit != MAP_RELATIVE ) )
633 : : {
634 : 3 : long nPoints = 10;
635 [ - + ]: 3 : if ( nHLevel == 1 )
636 : 0 : nPoints = 22;
637 [ - + ]: 3 : else if ( nHLevel == 2 )
638 : 0 : nPoints = 16;
639 [ - + ]: 3 : else if ( nHLevel == 3 )
640 : 0 : nPoints = 12;
641 [ - + ]: 3 : else if ( nHLevel == 4 )
642 : 0 : nPoints = 11;
643 : :
644 [ + - ]: 3 : nPoints = OutputDevice::LogicToLogic( nPoints, MAP_POINT, eUnit );
645 : :
646 [ + - ]: 3 : SvxFontHeightItem aHeightItem( nPoints, 100, EE_CHAR_FONTHEIGHT );
647 [ + - ]: 3 : aItems.Put( aHeightItem );
648 : :
649 [ + - ]: 3 : SvxFontHeightItem aHeightItemCJK( nPoints, 100, EE_CHAR_FONTHEIGHT_CJK );
650 [ + - ]: 3 : aItems.Put( aHeightItemCJK );
651 : :
652 [ + - ]: 3 : SvxFontHeightItem aHeightItemCTL( nPoints, 100, EE_CHAR_FONTHEIGHT_CTL );
653 [ + - ]: 3 : aItems.Put( aHeightItemCTL );
654 : :
655 : : // Paragraph margins, when Heading:
656 [ - + ][ # # ]: 3 : if ( !nHLevel || ((nHLevel >= 1) && (nHLevel <= 6)) )
[ # # ]
657 : : {
658 [ + - ]: 3 : SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
659 [ + - ]: 3 : aULSpaceItem.SetUpper( (sal_uInt16)OutputDevice::LogicToLogic( 42, MAP_10TH_MM, eUnit ) );
660 [ + - ]: 3 : aULSpaceItem.SetLower( (sal_uInt16)OutputDevice::LogicToLogic( 35, MAP_10TH_MM, eUnit ) );
661 [ + - ][ + - ]: 3 : aItems.Put( aULSpaceItem );
662 [ + - ][ + - ]: 3 : }
[ + - ]
663 : : }
664 : :
665 : : // Choose a proportional Font for Pre
666 [ - + ]: 3 : if ( nHLevel == STYLE_PRE )
667 : : {
668 [ # # ]: 0 : Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, 0 );
669 [ # # ][ # # ]: 0 : SvxFontItem aFontItem( aFont.GetFamily(), aFont.GetName(), XubString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
670 [ # # ]: 0 : aItems.Put( aFontItem );
671 : :
672 [ # # ][ # # ]: 0 : SvxFontItem aFontItemCJK( aFont.GetFamily(), aFont.GetName(), XubString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CJK );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
673 [ # # ]: 0 : aItems.Put( aFontItemCJK );
674 : :
675 [ # # ][ # # ]: 0 : SvxFontItem aFontItemCTL( aFont.GetFamily(), aFont.GetName(), XubString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CTL );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
676 [ # # ][ # # ]: 0 : aItems.Put( aFontItemCTL );
[ # # ][ # # ]
[ # # ]
677 : : }
678 : :
679 [ + - ][ + - ]: 3 : mpEditEngine->SetParaAttribsOnly(nNode, aItems);
680 : 3 : }
681 : :
682 : 39 : void EditHTMLParser::ImpInsertText( const String& rText )
683 : : {
684 [ + - ]: 39 : String aText( rText );
685 [ + - ][ + - ]: 39 : if (mpEditEngine->IsImportHandlerSet())
686 : : {
687 [ + - ][ + - ]: 39 : ImportInfo aImportInfo(HTMLIMP_INSERTTEXT, this, mpEditEngine->CreateESelection(aCurSel));
688 [ + - ]: 39 : aImportInfo.aText = aText;
689 [ + - ][ + - ]: 39 : mpEditEngine->CallImportHandler(aImportInfo);
690 : : }
691 : :
692 [ + - ][ + - ]: 39 : aCurSel = mpEditEngine->InsertText(aCurSel, aText);
[ + - ]
693 : 39 : }
694 : :
695 : 0 : void EditHTMLParser::SkipGroup( int nEndToken )
696 : : {
697 : : // groups in cells are closed upon leaving the cell, because those
698 : : // ******* web authors don't know their job
699 : : // for example: <td><form></td> lacks a closing </form>
700 : 0 : sal_uInt8 nCellLevel = nInCell;
701 : : int nToken;
702 [ # # ][ # # ]: 0 : while( nCellLevel <= nInCell && ( (nToken = GetNextToken() ) != nEndToken ) && nToken )
[ # # ][ # # ]
703 : : {
704 [ # # # ]: 0 : switch ( nToken )
705 : : {
706 : : case HTML_TABLEHEADER_ON:
707 : : case HTML_TABLEDATA_ON:
708 : 0 : nInCell++;
709 : 0 : break;
710 : : case HTML_TABLEHEADER_OFF:
711 : : case HTML_TABLEDATA_OFF:
712 [ # # ]: 0 : if ( nInCell )
713 : 0 : nInCell--;
714 : 0 : break;
715 : : }
716 : : }
717 : 0 : }
718 : :
719 : 27 : void EditHTMLParser::StartPara( bool bReal )
720 : : {
721 [ - + ]: 27 : if ( bReal )
722 : : {
723 [ # # ]: 0 : const HTMLOptions& aOptions = GetOptions();
724 : 0 : SvxAdjust eAdjust = SVX_ADJUST_LEFT;
725 [ # # ]: 0 : for ( size_t i = 0, n = aOptions.size(); i < n; ++i )
726 : : {
727 [ # # ]: 0 : const HTMLOption& aOption = aOptions[i];
728 [ # # ]: 0 : switch( aOption.GetToken() )
729 : : {
730 : : case HTML_O_ALIGN:
731 : : {
732 [ # # ][ # # ]: 0 : if ( aOption.GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
733 : 0 : eAdjust = SVX_ADJUST_RIGHT;
734 [ # # ][ # # ]: 0 : else if ( aOption.GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_middle ) == COMPARE_EQUAL )
735 : 0 : eAdjust = SVX_ADJUST_CENTER;
736 [ # # ][ # # ]: 0 : else if ( aOption.GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
737 : 0 : eAdjust = SVX_ADJUST_CENTER;
738 : : else
739 : 0 : eAdjust = SVX_ADJUST_LEFT;
740 : : }
741 : 0 : break;
742 : : }
743 : : }
744 [ # # ][ # # ]: 0 : SfxItemSet aItemSet = mpEditEngine->GetEmptyItemSet();
745 [ # # ][ # # ]: 0 : aItemSet.Put( SvxAdjustItem( eAdjust, EE_PARA_JUST ) );
[ # # ]
746 [ # # ][ # # ]: 0 : ImpSetAttribs( aItemSet );
747 : : }
748 : 27 : bInPara = true;
749 : 27 : }
750 : :
751 : 18 : void EditHTMLParser::EndPara( bool )
752 : : {
753 [ + - ]: 18 : if ( bInPara )
754 : : {
755 : 18 : bool bHasText = HasTextInCurrentPara();
756 [ + - ]: 18 : if ( bHasText )
757 : 18 : ImpInsertParaBreak();
758 : : }
759 : 18 : bInPara = false;
760 : 18 : }
761 : :
762 : 21 : bool EditHTMLParser::ThrowAwayBlank()
763 : : {
764 : : // A blank must be thrown away if the new text begins with a Blank and
765 : : // if the current paragraph is empty or ends with a Blank...
766 : 21 : ContentNode* pNode = aCurSel.Max().GetNode();
767 [ # # ][ - + ]: 21 : if ( pNode->Len() && ( pNode->GetChar( pNode->Len()-1 ) != ' ' ) )
[ - + ]
768 : 0 : return false;
769 : 21 : return true;
770 : : }
771 : :
772 : 36 : bool EditHTMLParser::HasTextInCurrentPara()
773 : : {
774 : 36 : return aCurSel.Max().GetNode()->Len() ? true : false;
775 : : }
776 : :
777 : 0 : void EditHTMLParser::AnchorStart()
778 : : {
779 : : // ignore anchor in anchor
780 [ # # ]: 0 : if ( !pCurAnchor )
781 : : {
782 [ # # ]: 0 : const HTMLOptions& aOptions = GetOptions();
783 [ # # ]: 0 : String aRef;
784 : :
785 [ # # ]: 0 : for ( size_t i = 0, n = aOptions.size(); i < n; ++i )
786 : : {
787 [ # # ]: 0 : const HTMLOption& aOption = aOptions[i];
788 [ # # ]: 0 : switch( aOption.GetToken() )
789 : : {
790 : : case HTML_O_HREF:
791 [ # # ]: 0 : aRef = aOption.GetString();
792 : 0 : break;
793 : : }
794 : : }
795 : :
796 [ # # ]: 0 : if ( aRef.Len() )
797 : : {
798 [ # # ]: 0 : String aURL = aRef;
799 [ # # ][ # # ]: 0 : if ( aURL.Len() && ( aURL.GetChar( 0 ) != '#' ) )
[ # # ]
800 : : {
801 [ # # ]: 0 : INetURLObject aTargetURL;
802 [ # # ][ # # ]: 0 : INetURLObject aRootURL( aBaseURL );
803 [ # # ][ # # ]: 0 : aRootURL.GetNewAbsURL( aRef, &aTargetURL );
804 [ # # ][ # # ]: 0 : aURL = aTargetURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
[ # # ][ # # ]
805 : : }
806 [ # # ][ # # ]: 0 : pCurAnchor = new AnchorInfo;
807 [ # # ][ # # ]: 0 : pCurAnchor->aHRef = aURL;
808 [ # # ]: 0 : }
809 : : }
810 : 0 : }
811 : :
812 : 0 : void EditHTMLParser::AnchorEnd()
813 : : {
814 [ # # ]: 0 : if ( pCurAnchor )
815 : : {
816 : : // Insert as URL-Field...
817 [ # # ][ # # ]: 0 : SvxFieldItem aFld( SvxURLField( pCurAnchor->aHRef, pCurAnchor->aText, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
[ # # ][ # # ]
[ # # ]
818 [ # # ][ # # ]: 0 : aCurSel = mpEditEngine->InsertField(aCurSel, aFld);
819 : 0 : bFieldsInserted = true;
820 [ # # ][ # # ]: 0 : delete pCurAnchor;
821 : 0 : pCurAnchor = NULL;
822 : :
823 [ # # ][ # # ]: 0 : if (mpEditEngine->IsImportHandlerSet())
824 : : {
825 [ # # ][ # # ]: 0 : ImportInfo aImportInfo(HTMLIMP_INSERTFIELD, this, mpEditEngine->CreateESelection(aCurSel));
826 [ # # ][ # # ]: 0 : mpEditEngine->CallImportHandler(aImportInfo);
827 [ # # ]: 0 : }
828 : : }
829 : 0 : }
830 : :
831 : 0 : void EditHTMLParser::HeadingStart( int nToken )
832 : : {
833 : 0 : bWasInPara = bInPara;
834 : 0 : StartPara( false );
835 : :
836 [ # # ][ # # ]: 0 : if ( bWasInPara && HasTextInCurrentPara() )
[ # # ]
837 : 0 : ImpInsertParaBreak();
838 : :
839 : : sal_uInt16 nId = sal::static_int_cast< sal_uInt16 >(
840 : 0 : 1 + ( ( nToken - HTML_HEAD1_ON ) / 2 ) );
841 : : DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID can not be correct!" );
842 : 0 : ImpSetStyleSheet( nId );
843 : 0 : }
844 : :
845 : 0 : void EditHTMLParser::HeadingEnd( int )
846 : : {
847 : 0 : EndPara( false );
848 : 0 : ImpSetStyleSheet( 0 );
849 : :
850 [ # # ]: 0 : if ( bWasInPara )
851 : : {
852 : 0 : bInPara = true;
853 : 0 : bWasInPara = false;
854 : : }
855 : 0 : }
856 : :
857 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|