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 <config_features.h>
21 :
22 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
23 : #include <com/sun/star/document/XDocumentProperties.hpp>
24 : #include <com/sun/star/i18n/ScriptType.hpp>
25 : #include <comphelper/string.hxx>
26 : #include <rtl/ustrbuf.hxx>
27 : #include <sfx2/sfx.hrc>
28 : #include <svx/svxids.hrc>
29 : #if OSL_DEBUG_LEVEL > 0
30 : #include <stdlib.h>
31 : #endif
32 : #include <hintids.hxx>
33 :
34 : #include <svl/stritem.hxx>
35 : #include <svtools/imap.hxx>
36 : #include <svtools/htmltokn.h>
37 : #include <svtools/htmlkywd.hxx>
38 : #include <svtools/ctrltool.hxx>
39 : #include <unotools/pathoptions.hxx>
40 : #include <vcl/svapp.hxx>
41 : #include <vcl/wrkwin.hxx>
42 : #include <sfx2/fcontnr.hxx>
43 : #include <sfx2/docfile.hxx>
44 :
45 : #include <svtools/htmlcfg.hxx>
46 : #include <sfx2/linkmgr.hxx>
47 : #include <editeng/kernitem.hxx>
48 : #include <editeng/boxitem.hxx>
49 : #include <editeng/fhgtitem.hxx>
50 : #include <editeng/formatbreakitem.hxx>
51 : #include <editeng/postitem.hxx>
52 : #include <editeng/wghtitem.hxx>
53 : #include <editeng/crossedoutitem.hxx>
54 : #include <editeng/udlnitem.hxx>
55 : #include <editeng/escapementitem.hxx>
56 : #include <editeng/blinkitem.hxx>
57 : #include <editeng/ulspitem.hxx>
58 : #include <editeng/colritem.hxx>
59 : #include <editeng/fontitem.hxx>
60 : #include <editeng/adjustitem.hxx>
61 : #include <editeng/lrspitem.hxx>
62 : #include <editeng/protitem.hxx>
63 : #include <editeng/flstitem.hxx>
64 :
65 : #include <frmatr.hxx>
66 : #include <charatr.hxx>
67 : #include <fmtfld.hxx>
68 : #include <fmtpdsc.hxx>
69 : #include <txtfld.hxx>
70 : #include <fmtanchr.hxx>
71 : #include <fmtsrnd.hxx>
72 : #include <fmtfsize.hxx>
73 : #include <fmtclds.hxx>
74 : #include <fchrfmt.hxx>
75 : #include <fmtinfmt.hxx>
76 : #include <fmtfollowtextflow.hxx>
77 : #include <docary.hxx>
78 : #include <docstat.hxx>
79 : #include <doc.hxx>
80 : #include <IDocumentUndoRedo.hxx>
81 : #include <IDocumentSettingAccess.hxx>
82 : #include <IDocumentLayoutAccess.hxx>
83 : #include <IDocumentLinksAdministration.hxx>
84 : #include <IDocumentRedlineAccess.hxx>
85 : #include <IDocumentFieldsAccess.hxx>
86 : #include <IDocumentStylePoolAccess.hxx>
87 : #include <IDocumentStatistics.hxx>
88 : #include <IDocumentState.hxx>
89 : #include <pam.hxx>
90 : #include <ndtxt.hxx>
91 : #include <mdiexp.hxx>
92 : #include <expfld.hxx>
93 : #include <poolfmt.hxx>
94 : #include <pagedesc.hxx>
95 : #include <IMark.hxx>
96 : #include <docsh.hxx>
97 : #include <editsh.hxx>
98 : #include <docufld.hxx>
99 : #include <swcss1.hxx>
100 : #include <htmlvsh.hxx>
101 : #include <fltini.hxx>
102 : #include <htmltbl.hxx>
103 : #include <htmlnum.hxx>
104 : #include <swhtml.hxx>
105 : #include <linkenum.hxx>
106 : #include <breakit.hxx>
107 : #include <SwAppletImpl.hxx>
108 :
109 : #include <sfx2/viewfrm.hxx>
110 :
111 : #include <statstr.hrc>
112 : #include <swerror.h>
113 : #include <css1atr.hxx>
114 :
115 : #define FONTSIZE_MASK 7
116 :
117 : #define HTML_ESC_PROP 80
118 : #define HTML_ESC_SUPER DFLT_ESC_SUPER
119 : #define HTML_ESC_SUB DFLT_ESC_SUB
120 :
121 : #define HTML_SPTYPE_BLOCK 1
122 : #define HTML_SPTYPE_HORI 2
123 : #define HTML_SPTYPE_VERT 3
124 :
125 : using editeng::SvxBorderLine;
126 : using namespace ::com::sun::star;
127 :
128 : // <P ALIGN=xxx>, <Hn ALIGN=xxx>, <TD ALIGN=xxx> usw.
129 : HTMLOptionEnum aHTMLPAlignTable[] =
130 : {
131 : { OOO_STRING_SVTOOLS_HTML_AL_left, SVX_ADJUST_LEFT },
132 : { OOO_STRING_SVTOOLS_HTML_AL_center, SVX_ADJUST_CENTER },
133 : { OOO_STRING_SVTOOLS_HTML_AL_middle, SVX_ADJUST_CENTER }, // Netscape
134 : { OOO_STRING_SVTOOLS_HTML_AL_right, SVX_ADJUST_RIGHT },
135 : { OOO_STRING_SVTOOLS_HTML_AL_justify, SVX_ADJUST_BLOCK },
136 : { OOO_STRING_SVTOOLS_HTML_AL_char, SVX_ADJUST_LEFT },
137 : { 0, 0 }
138 : };
139 :
140 : // <SPACER TYPE=...>
141 : static HTMLOptionEnum aHTMLSpacerTypeTable[] =
142 : {
143 : { OOO_STRING_SVTOOLS_HTML_SPTYPE_block, HTML_SPTYPE_BLOCK },
144 : { OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal, HTML_SPTYPE_HORI },
145 : { OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical, HTML_SPTYPE_VERT },
146 : { 0, 0 }
147 : };
148 :
149 59 : HTMLReader::HTMLReader()
150 : {
151 59 : bTmplBrowseMode = true;
152 59 : }
153 :
154 4 : OUString HTMLReader::GetTemplateName() const
155 : {
156 4 : const OUString sTemplateWithoutExt("internal/html");
157 8 : SvtPathOptions aPathOpt;
158 :
159 : // first search for OpenDocument Writer/Web template
160 : // OpenDocument Writer/Web template (extension .oth)
161 8 : OUString sTemplate( sTemplateWithoutExt + ".oth" );
162 4 : if (aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ))
163 0 : return sTemplate;
164 :
165 : // no OpenDocument Writer/Web template found.
166 : // search for OpenOffice.org Writer/Web template
167 4 : sTemplate = sTemplateWithoutExt + ".stw";
168 4 : if (aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ))
169 4 : return sTemplate;
170 :
171 : OSL_ENSURE( false, "The default HTML template cannot be found in the defined template directories!");
172 :
173 4 : return OUString();
174 : }
175 :
176 16 : bool HTMLReader::SetStrmStgPtr()
177 : {
178 : OSL_ENSURE( pMedium, "Wo ist das Medium??" );
179 :
180 16 : if( pMedium->IsRemote() || !pMedium->IsStorage() )
181 : {
182 16 : pStrm = pMedium->GetInStream();
183 16 : return true;
184 : }
185 0 : return false;
186 :
187 : }
188 :
189 : // Aufruf fuer die allg. Reader-Schnittstelle
190 16 : sal_uLong HTMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPam, const OUString & rName )
191 : {
192 16 : if( !pStrm )
193 : {
194 : OSL_ENSURE( pStrm, "HTML-Read ohne Stream" );
195 0 : return ERR_SWG_READ_ERROR;
196 : }
197 :
198 16 : if( !bInsertMode )
199 : {
200 16 : Reader::ResetFrameFormats( rDoc );
201 :
202 : // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist,
203 : // sonst ist sie schon gesetzt.
204 16 : if( !rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) )
205 : {
206 15 : rDoc.getIDocumentContentOperations().InsertPoolItem( rPam, SwFormatPageDesc(
207 15 : rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false )) );
208 : }
209 : }
210 :
211 : // damit keiner das Doc klaut!
212 16 : rDoc.acquire();
213 16 : sal_uLong nRet = 0;
214 : SvParserRef xParser = new SwHTMLParser( &rDoc, rPam, *pStrm,
215 16 : rName, rBaseURL, !bInsertMode, pMedium,
216 16 : IsReadUTF8(),
217 32 : bIgnoreHTMLComments );
218 :
219 16 : SvParserState eState = xParser->CallParser();
220 :
221 16 : if( SVPAR_PENDING == eState )
222 0 : pStrm->ResetError();
223 16 : else if( SVPAR_ACCEPTED != eState )
224 : {
225 0 : const OUString sErr(OUString::number((sal_Int32)xParser->GetLineNr())
226 0 : + "," + OUString::number((sal_Int32)xParser->GetLinePos()));
227 :
228 : // den Stream als Fehlernummer Transporter benutzen
229 0 : nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
230 0 : ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
231 : }
232 :
233 16 : return nRet;
234 : }
235 :
236 16 : SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCrsr, SvStream& rIn,
237 : const OUString& rPath,
238 : const OUString& rBaseURL,
239 : bool bReadNewDoc,
240 : SfxMedium* pMed, bool bReadUTF8,
241 : bool bNoHTMLComments )
242 : : SfxHTMLParser( rIn, bReadNewDoc, pMed ),
243 : SwClient( 0 ),
244 : aPathToFile( rPath ),
245 : sBaseURL( rBaseURL ),
246 : pAppletImpl( 0 ),
247 : pCSS1Parser( 0 ),
248 16 : pNumRuleInfo( new SwHTMLNumRuleInfo ),
249 : pPendStack( 0 ),
250 : pDoc( pD ),
251 : pActionViewShell( 0 ),
252 : pSttNdIdx( 0 ),
253 : pTable(0),
254 : pFormImpl( 0 ),
255 : pMarquee( 0 ),
256 : pField( 0 ),
257 : pImageMap( 0 ),
258 : pImageMaps( 0 ),
259 : pFootEndNoteImpl( 0 ),
260 : nScriptStartLineNr( 0 ),
261 : nBaseFontStMin( 0 ),
262 : nFontStMin( 0 ),
263 : nDefListDeep( 0 ),
264 : nFontStHeadStart( 0 ),
265 : nSBModuleCnt( 0 ),
266 : nMissingImgMaps( 0 ),
267 : nParaCnt( 5 ),
268 : // #i83625#
269 : nContextStMin( 0 ),
270 : nContextStAttrMin( 0 ),
271 : nSelectEntryCnt( 0 ),
272 : nOpenParaToken( 0 ),
273 : eJumpTo( JUMPTO_NONE ),
274 : #ifdef DBG_UTIL
275 : m_nContinue( 0 ),
276 : #endif
277 : eParaAdjust( SVX_ADJUST_END ),
278 : bDocInitalized( false ),
279 : bSetModEnabled( false ),
280 : bInFloatingFrame( false ),
281 : bInField( false ),
282 : bCallNextToken( false ),
283 : bIgnoreRawData( false ),
284 : bLBEntrySelected ( false ),
285 : bTAIgnoreNewPara ( false ),
286 : bFixMarqueeWidth ( false ),
287 : bFixMarqueeHeight ( false ),
288 : bNoParSpace( false ),
289 : bInNoEmbed( false ),
290 : bInTitle( false ),
291 : bUpdateDocStat( false ),
292 : bFixSelectWidth( false ),
293 : bFixSelectHeight( false ),
294 : bTextArea( false ),
295 : bSelect( false ),
296 : bInFootEndNoteAnchor( false ),
297 : bInFootEndNoteSymbol( false ),
298 : bIgnoreHTMLComments( bNoHTMLComments ),
299 : bRemoveHidden( false ),
300 32 : pTempViewFrame(0)
301 : {
302 16 : nEventId = 0;
303 : bUpperSpace = bViewCreated = bChkJumpMark =
304 16 : bSetCrsr = false;
305 :
306 16 : eScriptLang = HTML_SL_UNKNOWN;
307 16 : bAnyStarBasic = true;
308 :
309 16 : rCrsr.DeleteMark();
310 16 : pPam = &rCrsr; // re-use existing cursor: avoids spurious ~SwIndexReg assert
311 16 : memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
312 :
313 : // Die Font-Groessen 1-7 aus der INI-Datei lesen
314 16 : SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
315 16 : aFontHeights[0] = rHtmlOptions.GetFontSize( 0 ) * 20;
316 16 : aFontHeights[1] = rHtmlOptions.GetFontSize( 1 ) * 20;
317 16 : aFontHeights[2] = rHtmlOptions.GetFontSize( 2 ) * 20;
318 16 : aFontHeights[3] = rHtmlOptions.GetFontSize( 3 ) * 20;
319 16 : aFontHeights[4] = rHtmlOptions.GetFontSize( 4 ) * 20;
320 16 : aFontHeights[5] = rHtmlOptions.GetFontSize( 5 ) * 20;
321 16 : aFontHeights[6] = rHtmlOptions.GetFontSize( 6 ) * 20;
322 :
323 16 : bKeepUnknown = rHtmlOptions.IsImportUnknown();
324 :
325 16 : if(bReadNewDoc)
326 : {
327 : //CJK has different defaults, so a different object should be used for this
328 : //RES_CHARTR_CJK_FONTSIZE is a valid value
329 16 : SvxFontHeightItem aFontHeight(aFontHeights[2], 100, RES_CHRATR_FONTSIZE);
330 16 : pDoc->SetDefault( aFontHeight );
331 32 : SvxFontHeightItem aFontHeightCJK(aFontHeights[2], 100, RES_CHRATR_CJK_FONTSIZE);
332 16 : pDoc->SetDefault( aFontHeightCJK );
333 32 : SvxFontHeightItem aFontHeightCTL(aFontHeights[2], 100, RES_CHRATR_CTL_FONTSIZE);
334 16 : pDoc->SetDefault( aFontHeightCTL );
335 :
336 : // #i18732# - adjust default of option 'FollowTextFlow'
337 : // TODO: not sure what the appropriate default for HTML should be?
338 32 : pDoc->SetDefault( SwFormatFollowTextFlow(true) );
339 : }
340 :
341 : // Waehrend des Imports in den HTML-Modus schalten, damit die
342 : // richrigen Vorlagen angelegt werden
343 16 : bOldIsHTMLMode = pDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE);
344 16 : pDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, true);
345 :
346 16 : pCSS1Parser = new SwCSS1Parser( pDoc, aFontHeights, sBaseURL, IsNewDoc() );
347 16 : pCSS1Parser->SetIgnoreFontFamily( rHtmlOptions.IsIgnoreFontFamily() );
348 :
349 16 : if( bReadUTF8 )
350 : {
351 0 : SetSrcEncoding( RTL_TEXTENCODING_UTF8 );
352 : }
353 : else
354 : {
355 16 : SwDocShell *pDocSh = pDoc->GetDocShell();
356 : SvKeyValueIterator *pHeaderAttrs =
357 16 : pDocSh->GetHeaderAttributes();
358 16 : if( pHeaderAttrs )
359 16 : SetEncodingByHTTPHeader( pHeaderAttrs );
360 : }
361 16 : pCSS1Parser->SetDfltEncoding( osl_getThreadTextEncoding() );
362 :
363 : // Timer nur bei ganz normalen Dokumenten aufsetzen!
364 16 : SwDocShell* pDocSh = pDoc->GetDocShell();
365 16 : if( pDocSh )
366 : {
367 16 : bViewCreated = true; // nicht, synchron laden
368 :
369 : // es ist ein Sprungziel vorgegeben.
370 :
371 16 : if( pMed )
372 : {
373 16 : sJmpMark = pMed->GetURLObject().GetMark();
374 16 : if( !sJmpMark.isEmpty() )
375 : {
376 0 : eJumpTo = JUMPTO_MARK;
377 0 : sal_Int32 nLastPos = sJmpMark.lastIndexOf( cMarkSeparator );
378 0 : sal_Int32 nPos = nLastPos != -1 ? nLastPos : 0;
379 :
380 0 : OUString sCmp;
381 0 : if (nPos)
382 : {
383 0 : sCmp = comphelper::string::remove(
384 0 : sJmpMark.copy(nPos + 1), ' ');
385 : }
386 :
387 0 : if( !sCmp.isEmpty() )
388 : {
389 0 : sCmp = sCmp.toAsciiLowerCase();
390 0 : if( sCmp == "region" )
391 0 : eJumpTo = JUMPTO_REGION;
392 0 : else if( sCmp == "table" )
393 0 : eJumpTo = JUMPTO_TABLE;
394 0 : else if( sCmp == "graphic" )
395 0 : eJumpTo = JUMPTO_GRAPHIC;
396 0 : else if( sCmp == "outline" ||
397 0 : sCmp == "text" ||
398 0 : sCmp == "frame" )
399 0 : eJumpTo = JUMPTO_NONE; // das ist nichts gueltiges!
400 : else
401 : // ansonsten ist das ein normaler (Book)Mark
402 0 : nPos = -1;
403 : }
404 : else
405 0 : nPos = -1;
406 :
407 0 : if( nPos != -1 )
408 0 : sJmpMark = sJmpMark.copy( 0, nPos );
409 0 : if( sJmpMark.isEmpty() )
410 0 : eJumpTo = JUMPTO_NONE;
411 : }
412 : }
413 : }
414 16 : }
415 :
416 48 : SwHTMLParser::~SwHTMLParser()
417 : {
418 : #ifdef DBG_UTIL
419 : OSL_ENSURE( !m_nContinue, "DTOR im Continue!" );
420 : #endif
421 16 : bool bAsync = pDoc->IsInLoadAsynchron();
422 16 : pDoc->SetInLoadAsynchron( false );
423 16 : pDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, bOldIsHTMLMode);
424 :
425 16 : if( pDoc->GetDocShell() && nEventId )
426 0 : Application::RemoveUserEvent( nEventId );
427 :
428 : // das DocumentDetected kann ggfs. die DocShells loeschen, darum nochmals
429 : // abfragen
430 16 : if( pDoc->GetDocShell() )
431 : {
432 : // Gelinkte Bereiche updaten
433 16 : sal_uInt16 nLinkMode = pDoc->getIDocumentSettingAccess().getLinkUpdateMode( true );
434 16 : if( nLinkMode != NEVER && bAsync &&
435 0 : SfxObjectCreateMode::INTERNAL!=pDoc->GetDocShell()->GetCreateMode() )
436 0 : pDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks( nLinkMode == MANUAL,
437 0 : true, false );
438 :
439 16 : if ( pDoc->GetDocShell()->IsLoading() )
440 : {
441 : // #i59688#
442 16 : pDoc->GetDocShell()->LoadingFinished();
443 : }
444 : }
445 :
446 16 : delete pSttNdIdx;
447 :
448 16 : if( !aSetAttrTab.empty() )
449 : {
450 : OSL_ENSURE( aSetAttrTab.empty(),"Es stehen noch Attribute auf dem Stack" );
451 0 : for ( _HTMLAttrs::const_iterator it = aSetAttrTab.begin();
452 0 : it != aSetAttrTab.end(); ++it )
453 0 : delete *it;
454 0 : aSetAttrTab.clear();
455 : }
456 :
457 16 : delete pCSS1Parser;
458 16 : delete pNumRuleInfo;
459 16 : DeleteFormImpl();
460 16 : DeleteFootEndNoteImpl();
461 :
462 : OSL_ENSURE( !pTable, "Es existiert noch eine offene Tabelle" );
463 16 : delete pImageMaps;
464 :
465 : OSL_ENSURE( !pPendStack,
466 : "SwHTMLParser::~SwHTMLParser: Hier sollte es keinen Pending-Stack mehr geben" );
467 32 : while( pPendStack )
468 : {
469 0 : SwPendingStack* pTmp = pPendStack;
470 0 : pPendStack = pPendStack->pNext;
471 0 : delete pTmp->pData;
472 0 : delete pTmp;
473 : }
474 :
475 16 : if( !pDoc->release() )
476 : {
477 : // keiner will mehr das Doc haben, also weg damit
478 0 : delete pDoc;
479 0 : pDoc = NULL;
480 : }
481 :
482 16 : if ( pTempViewFrame )
483 : {
484 1 : pTempViewFrame->DoClose();
485 :
486 : // the temporary view frame is hidden, so the hidden flag might need to be removed
487 1 : if ( bRemoveHidden && pDoc && pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() )
488 1 : pDoc->GetDocShell()->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN );
489 : }
490 32 : }
491 :
492 0 : IMPL_LINK_NOARG( SwHTMLParser, AsyncCallback )
493 : {
494 0 : nEventId=0;
495 :
496 : // #i47907# - If the document has already been destructed,
497 : // the parser should be aware of this:
498 0 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
499 0 : || 1 == pDoc->getReferenceCount() )
500 : {
501 : // wurde der Import vom SFX abgebrochen?
502 0 : eState = SVPAR_ERROR;
503 : }
504 :
505 0 : GetAsynchCallLink().Call(0);
506 0 : return 0;
507 : }
508 :
509 16 : SvParserState SwHTMLParser::CallParser()
510 : {
511 : // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
512 16 : pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
513 16 : if( !IsNewDoc() ) // in ein Dokument einfuegen ?
514 : {
515 0 : const SwPosition* pPos = pPam->GetPoint();
516 :
517 0 : pDoc->getIDocumentContentOperations().SplitNode( *pPos, false );
518 :
519 0 : *pSttNdIdx = pPos->nNode.GetIndex()-1;
520 0 : pDoc->getIDocumentContentOperations().SplitNode( *pPos, false );
521 :
522 0 : SwPaM aInsertionRangePam( *pPos );
523 :
524 0 : pPam->Move( fnMoveBackward );
525 :
526 : // split any redline over the insertion point
527 0 : aInsertionRangePam.SetMark();
528 0 : *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
529 0 : aInsertionRangePam.Move( fnMoveBackward );
530 0 : pDoc->getIDocumentRedlineAccess().SplitRedline( aInsertionRangePam );
531 :
532 : pDoc->SetTextFormatColl( *pPam,
533 0 : pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_STANDARD ));
534 : }
535 :
536 16 : if( GetMedium() )
537 : {
538 16 : if( !bViewCreated )
539 : {
540 0 : nEventId = Application::PostUserEvent( LINK( this, SwHTMLParser, AsyncCallback ), 0 );
541 : }
542 : else
543 : {
544 16 : bViewCreated = true;
545 16 : nEventId = 0;
546 : }
547 : }
548 :
549 : // Laufbalken anzeigen
550 0 : else if( !GetMedium() || !GetMedium()->IsRemote() )
551 : {
552 0 : rInput.Seek(STREAM_SEEK_TO_END);
553 0 : rInput.ResetError();
554 0 : ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(),
555 0 : pDoc->GetDocShell() );
556 0 : rInput.Seek(STREAM_SEEK_TO_BEGIN);
557 0 : rInput.ResetError();
558 : }
559 :
560 16 : pDoc->GetPageDesc( 0 ).Add( this );
561 :
562 16 : SvParserState eRet = HTMLParser::CallParser();
563 16 : return eRet;
564 : }
565 :
566 16 : void SwHTMLParser::Continue( int nToken )
567 : {
568 : #ifdef DBG_UTIL
569 : OSL_ENSURE(!m_nContinue, "Continue im Continue - not supposed to happen");
570 : m_nContinue++;
571 : #endif
572 :
573 : // Wenn der Import (vom SFX) abgebrochen wurde, wird ein Fehler
574 : // gesetzt aber trotzdem noch weiter gemacht, damit vernuenftig
575 : // aufgeraeumt wird.
576 : OSL_ENSURE( SVPAR_ERROR!=eState,
577 : "SwHTMLParser::Continue: bereits ein Fehler gesetzt" );
578 16 : if( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
579 0 : eState = SVPAR_ERROR;
580 :
581 : // Die SwViewShell vom Dokument holen, merken und als aktuelle setzen.
582 16 : SwViewShell *pInitVSh = CallStartAction();
583 :
584 16 : if( SVPAR_ERROR != eState && GetMedium() && !bViewCreated )
585 : {
586 : // Beim ersten Aufruf erstmal returnen, Doc anzeigen
587 : // und auf Timer Callback warten.
588 : // An dieser Stelle wurde im CallParser gerade mal ein Zeichen
589 : // gelesen und ein SaveState(0) gerufen.
590 0 : eState = SVPAR_PENDING;
591 0 : bViewCreated = true;
592 0 : pDoc->SetInLoadAsynchron( true );
593 :
594 : #ifdef DBG_UTIL
595 : m_nContinue--;
596 : #endif
597 :
598 16 : return;
599 : }
600 :
601 16 : bSetModEnabled = false;
602 32 : if( pDoc->GetDocShell() &&
603 16 : (bSetModEnabled = pDoc->GetDocShell()->IsEnableSetModified()) )
604 : {
605 0 : pDoc->GetDocShell()->EnableSetModified( false );
606 : }
607 :
608 : // waehrend des einlesens kein OLE-Modified rufen
609 16 : Link<> aOLELink( pDoc->GetOle2Link() );
610 16 : pDoc->SetOle2Link( Link<>() );
611 :
612 16 : bool bModified = pDoc->getIDocumentState().IsModified();
613 16 : bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
614 16 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
615 :
616 : // Wenn der Import abgebrochen wird, kein Continue mehr rufen.
617 : // Falls ein Pending-Stack existiert aber durch einen Aufruf
618 : // von NextToken dafuer sorgen, dass der Pending-Stack noch
619 : // beendet wird.
620 16 : if( SVPAR_ERROR == eState )
621 : {
622 : OSL_ENSURE( !pPendStack || pPendStack->nToken,
623 : "SwHTMLParser::Continue: Pending-Stack ohne Token" );
624 0 : if( pPendStack && pPendStack->nToken )
625 0 : NextToken( pPendStack->nToken );
626 : OSL_ENSURE( !pPendStack,
627 : "SwHTMLParser::Continue: Es gibt wieder einen Pend-Stack" );
628 : }
629 : else
630 : {
631 16 : HTMLParser::Continue( pPendStack ? pPendStack->nToken : nToken );
632 : }
633 :
634 : // Laufbalken wieder abschalten
635 16 : EndProgress( pDoc->GetDocShell() );
636 :
637 16 : bool bLFStripped = false;
638 16 : if( SVPAR_PENDING != GetStatus() )
639 : {
640 : // noch die letzten Attribute setzen
641 : {
642 16 : if( !aScriptSource.isEmpty() )
643 : {
644 : SwScriptFieldType *pType =
645 0 : static_cast<SwScriptFieldType*>(pDoc->getIDocumentFieldsAccess().GetSysFieldType( RES_SCRIPTFLD ));
646 :
647 : SwScriptField aField( pType, aScriptType, aScriptSource,
648 0 : false );
649 0 : InsertAttr( SwFormatField( aField ) );
650 : }
651 :
652 16 : if( pAppletImpl )
653 : {
654 0 : if( pAppletImpl->GetApplet().is() )
655 0 : EndApplet();
656 : else
657 0 : EndObject();
658 : }
659 :
660 : // ggf. ein noch vorhandes LF hinter dem letzen Absatz entfernen
661 16 : if( IsNewDoc() )
662 16 : bLFStripped = StripTrailingLF() > 0;
663 :
664 : // noch offene Nummerierungen beenden.
665 32 : while( GetNumInfo().GetNumRule() )
666 0 : EndNumBulList();
667 :
668 : OSL_ENSURE( !nContextStMin, "Es gibt geschuetzte Kontexte" );
669 16 : nContextStMin = 0;
670 33 : while( aContexts.size() )
671 : {
672 1 : _HTMLAttrContext *pCntxt = PopContext();
673 1 : if( pCntxt )
674 : {
675 1 : EndContext( pCntxt );
676 1 : delete pCntxt;
677 : }
678 : }
679 :
680 16 : if( !aParaAttrs.empty() )
681 0 : aParaAttrs.clear();
682 :
683 16 : SetAttr( false );
684 :
685 : // Noch die erst verzoegert gesetzten Styles setzen
686 16 : pCSS1Parser->SetDelayedStyles();
687 : }
688 :
689 : // den Start wieder korrigieren
690 16 : if( !IsNewDoc() && pSttNdIdx->GetIndex() )
691 : {
692 0 : SwTextNode* pTextNode = pSttNdIdx->GetNode().GetTextNode();
693 0 : SwNodeIndex aNxtIdx( *pSttNdIdx );
694 0 : if( pTextNode && pTextNode->CanJoinNext( &aNxtIdx ))
695 : {
696 0 : const sal_Int32 nStt = pTextNode->GetText().getLength();
697 : // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
698 0 : if( pPam->GetPoint()->nNode == aNxtIdx )
699 : {
700 0 : pPam->GetPoint()->nNode = *pSttNdIdx;
701 0 : pPam->GetPoint()->nContent.Assign( pTextNode, nStt );
702 : }
703 :
704 : #if OSL_DEBUG_LEVEL > 0
705 : // !!! sollte nicht moeglich sein, oder ??
706 : OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound( true ).nNode.GetIndex(),
707 : "Pam.Bound1 steht noch im Node" );
708 : OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound( false ).nNode.GetIndex(),
709 : "Pam.Bound2 steht noch im Node" );
710 :
711 : if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( true ).nNode.GetIndex() )
712 : {
713 : const sal_Int32 nCntPos = pPam->GetBound( true ).nContent.GetIndex();
714 : pPam->GetBound( true ).nContent.Assign( pTextNode,
715 : pTextNode->GetText().getLength() + nCntPos );
716 : }
717 : if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( false ).nNode.GetIndex() )
718 : {
719 : const sal_Int32 nCntPos = pPam->GetBound( false ).nContent.GetIndex();
720 : pPam->GetBound( false ).nContent.Assign( pTextNode,
721 : pTextNode->GetText().getLength() + nCntPos );
722 : }
723 : #endif
724 : // Zeichen Attribute beibehalten!
725 0 : SwTextNode* pDelNd = aNxtIdx.GetNode().GetTextNode();
726 0 : if (pTextNode->GetText().getLength())
727 0 : pDelNd->FormatToTextAttr( pTextNode );
728 : else
729 0 : pTextNode->ChgFormatColl( pDelNd->GetTextColl() );
730 0 : pTextNode->JoinNext();
731 0 : }
732 : }
733 : }
734 :
735 16 : if( SVPAR_ACCEPTED == eState )
736 : {
737 16 : if( nMissingImgMaps )
738 : {
739 : // es fehlen noch ein paar Image-Map zuordungen.
740 : // vielleicht sind die Image-Maps ja jetzt da?
741 0 : ConnectImageMaps();
742 : }
743 :
744 : // jetzt noch den letzten ueberfluessigen Absatz loeschen
745 16 : SwPosition* pPos = pPam->GetPoint();
746 16 : if( !pPos->nContent.GetIndex() && !bLFStripped )
747 : {
748 : SwTextNode* pAktNd;
749 13 : sal_uLong nNodeIdx = pPos->nNode.GetIndex();
750 :
751 : bool bHasFlysOrMarks =
752 13 : HasCurrentParaFlys() || HasCurrentParaBookmarks( true );
753 :
754 13 : if( IsNewDoc() )
755 : {
756 13 : const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1];
757 36 : if( !pPam->GetPoint()->nContent.GetIndex() &&
758 17 : ( pPrev->IsContentNode() ||
759 6 : (pPrev->IsEndNode() &&
760 2 : pPrev->StartOfSectionNode()->IsSectionNode()) ) )
761 : {
762 10 : SwContentNode* pCNd = pPam->GetContentNode();
763 30 : if( pCNd && pCNd->StartOfSectionIndex()+2 <
764 30 : pCNd->EndOfSectionIndex() && !bHasFlysOrMarks )
765 : {
766 10 : SwViewShell *pVSh = CheckActionViewShell();
767 1 : SwCrsrShell *pCrsrSh = pVSh && pVSh->ISA(SwCrsrShell)
768 : ? static_cast < SwCrsrShell * >( pVSh )
769 11 : : 0;
770 11 : if( pCrsrSh &&
771 1 : pCrsrSh->GetCrsr()->GetPoint()
772 1 : ->nNode.GetIndex() == nNodeIdx )
773 : {
774 0 : pCrsrSh->MovePara(fnParaPrev, fnParaEnd );
775 0 : pCrsrSh->SetMark();
776 0 : pCrsrSh->ClearMark();
777 : }
778 10 : pPam->GetBound(true).nContent.Assign( 0, 0 );
779 10 : pPam->GetBound(false).nContent.Assign( 0, 0 );
780 10 : pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
781 : }
782 : }
783 : }
784 0 : else if( 0 != ( pAktNd = pDoc->GetNodes()[ nNodeIdx ]->GetTextNode()) && !bHasFlysOrMarks )
785 : {
786 0 : if( pAktNd->CanJoinNext( &pPos->nNode ))
787 : {
788 0 : SwTextNode* pNextNd = pPos->nNode.GetNode().GetTextNode();
789 0 : pPos->nContent.Assign( pNextNd, 0 );
790 0 : pPam->SetMark(); pPam->DeleteMark();
791 0 : pNextNd->JoinPrev();
792 : }
793 0 : else if (pAktNd->GetText().isEmpty())
794 : {
795 0 : pPos->nContent.Assign( 0, 0 );
796 0 : pPam->SetMark(); pPam->DeleteMark();
797 0 : pDoc->GetNodes().Delete( pPos->nNode, 1 );
798 0 : pPam->Move( fnMoveBackward );
799 : }
800 : }
801 : }
802 :
803 : // nun noch das SplitNode vom Anfang aufheben
804 3 : else if( !IsNewDoc() )
805 : {
806 0 : if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein <P>,
807 0 : pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node
808 0 : SwTextNode* pTextNode = pPos->nNode.GetNode().GetTextNode();
809 0 : SwNodeIndex aPrvIdx( pPos->nNode );
810 0 : if( pTextNode && pTextNode->CanJoinPrev( &aPrvIdx ) &&
811 0 : *pSttNdIdx <= aPrvIdx )
812 : {
813 : // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
814 : // usw. sind im pTextNode angemeldet, so dass der bestehen
815 : // bleiben MUSS.
816 :
817 : // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
818 : // Absatzattribute und die Vorlage uebernehmen!
819 0 : SwTextNode* pPrev = aPrvIdx.GetNode().GetTextNode();
820 0 : pTextNode->ChgFormatColl( pPrev->GetTextColl() );
821 0 : pTextNode->FormatToTextAttr( pPrev );
822 0 : pTextNode->ResetAllAttr();
823 :
824 0 : if( pPrev->HasSwAttrSet() )
825 0 : pTextNode->SetAttr( *pPrev->GetpSwAttrSet() );
826 :
827 0 : if( &pPam->GetBound(true).nNode.GetNode() == pPrev )
828 0 : pPam->GetBound(true).nContent.Assign( pTextNode, 0 );
829 0 : if( &pPam->GetBound(false).nNode.GetNode() == pPrev )
830 0 : pPam->GetBound(false).nContent.Assign( pTextNode, 0 );
831 :
832 0 : pTextNode->JoinPrev();
833 0 : }
834 : }
835 :
836 : // adjust AutoLoad in DocumentProperties
837 16 : if( IsNewDoc() )
838 : {
839 16 : SwDocShell *pDocShell(pDoc->GetDocShell());
840 : OSL_ENSURE(pDocShell, "no SwDocShell");
841 16 : if (pDocShell) {
842 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
843 16 : pDocShell->GetModel(), uno::UNO_QUERY_THROW);
844 : uno::Reference<document::XDocumentProperties> xDocProps(
845 32 : xDPS->getDocumentProperties());
846 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
847 48 : if ( xDocProps.is() && (xDocProps->getAutoloadSecs() > 0) &&
848 16 : (xDocProps->getAutoloadURL().isEmpty()) )
849 : {
850 0 : xDocProps->setAutoloadURL(aPathToFile);
851 16 : }
852 : }
853 : }
854 :
855 16 : if( bUpdateDocStat )
856 : {
857 0 : pDoc->getIDocumentStatistics().UpdateDocStat( false, true );
858 : }
859 : }
860 :
861 16 : if( SVPAR_PENDING != GetStatus() )
862 16 : delete pSttNdIdx, pSttNdIdx = 0;
863 :
864 : // sollte der Parser der Letzte sein, der das Doc haelt, dann braucht
865 : // man hier auch nichts mehr tun, Doc wird gleich zerstoert!
866 16 : if( 1 < pDoc->getReferenceCount() )
867 : {
868 16 : if( bWasUndo )
869 : {
870 0 : pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
871 0 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
872 : }
873 16 : else if( !pInitVSh )
874 : {
875 : // Wenn zu Beginn des Continue keine Shell vorhanden war,
876 : // kann trotzdem mitlerweile eine angelegt worden sein.
877 : // In dieses Fall stimmt das bWasUndo-Flag nicht und
878 : // wir muessen das Undo noch anschalten.
879 16 : SwViewShell *pTmpVSh = CheckActionViewShell();
880 16 : if( pTmpVSh )
881 : {
882 1 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
883 : }
884 : }
885 :
886 16 : pDoc->SetOle2Link( aOLELink );
887 16 : if( !bModified )
888 0 : pDoc->getIDocumentState().ResetModified();
889 16 : if( bSetModEnabled && pDoc->GetDocShell() )
890 : {
891 0 : pDoc->GetDocShell()->EnableSetModified( true );
892 0 : bSetModEnabled = false; // this is unnecessary here
893 : }
894 : }
895 :
896 : // Wenn die Dokuemnt-SwViewShell noch existiert und eine Action
897 : // offen ist (muss bei Abbruch nicht sein), die Action beenden,
898 : // uns von der Shell abmelden und schliesslich die alte Shell
899 : // wieder rekonstruieren.
900 16 : CallEndAction( true );
901 :
902 : #ifdef DBG_UTIL
903 : m_nContinue--;
904 : #endif
905 : }
906 :
907 0 : void SwHTMLParser::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
908 : {
909 0 : switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
910 : {
911 : case RES_OBJECTDYING:
912 0 : if (pOld && static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject == GetRegisteredIn())
913 : {
914 : // dann uns selbst beenden
915 0 : GetRegisteredInNonConst()->Remove( this );
916 0 : ReleaseRef(); // ansonsten sind wir fertig!
917 : }
918 0 : break;
919 : }
920 0 : }
921 :
922 16 : void SwHTMLParser::DocumentDetected()
923 : {
924 : OSL_ENSURE( !bDocInitalized, "DocumentDetected mehrfach aufgerufen" );
925 16 : bDocInitalized = true;
926 16 : if( IsNewDoc() )
927 : {
928 16 : if( IsInHeader() )
929 16 : FinishHeader( true );
930 :
931 16 : CallEndAction( true, true );
932 :
933 16 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
934 : // Durch das DocumentDetected wurde im allgemeinen eine
935 : // SwViewShell angelegt. Es kann aber auch sein, dass sie
936 : // erst spaeter angelegt wird, naemlich dann, wenn die UI
937 : // gecaptured ist.
938 16 : CallStartAction();
939 : }
940 16 : }
941 :
942 : // is called for every token that is recognised in CallParser
943 2056 : void SwHTMLParser::NextToken( int nToken )
944 : {
945 6168 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
946 4112 : || 1 == pDoc->getReferenceCount() )
947 : {
948 : // Was the import cancelled by SFX? If a pending stack
949 : // exists, clean it.
950 0 : eState = SVPAR_ERROR;
951 : OSL_ENSURE( !pPendStack || pPendStack->nToken,
952 : "SwHTMLParser::NextToken: Pending-Stack without token" );
953 0 : if( 1 == pDoc->getReferenceCount() || !pPendStack )
954 0 : return ;
955 : }
956 :
957 : #if OSL_DEBUG_LEVEL > 0
958 : if( pPendStack )
959 : {
960 : switch( nToken )
961 : {
962 : // tables are read by recursive method calls
963 : case HTML_TABLE_ON:
964 : // For CSS declarations we might have to wait
965 : // for a file download to finish
966 : case HTML_LINK:
967 : // For controls we might have to set the size.
968 : case HTML_INPUT:
969 : case HTML_TEXTAREA_ON:
970 : case HTML_SELECT_ON:
971 : case HTML_SELECT_OFF:
972 : break;
973 : default:
974 : OSL_ENSURE( !pPendStack, "Unbekanntes Token fuer Pending-Stack" );
975 : break;
976 : }
977 : }
978 : #endif
979 :
980 : // The following special cases have to be treated before the
981 : // filter detection, because Netscape doesn't reference the content
982 : // of the title for filter detection either.
983 2056 : if( !pPendStack )
984 : {
985 2056 : if( bInTitle )
986 : {
987 9 : switch( nToken )
988 : {
989 : case HTML_TITLE_OFF:
990 8 : if( IsNewDoc() && !sTitle.isEmpty() )
991 : {
992 1 : if( pDoc->GetDocShell() ) {
993 : uno::Reference<document::XDocumentPropertiesSupplier>
994 1 : xDPS(pDoc->GetDocShell()->GetModel(),
995 1 : uno::UNO_QUERY_THROW);
996 : uno::Reference<document::XDocumentProperties> xDocProps(
997 2 : xDPS->getDocumentProperties());
998 : OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
999 1 : if (xDocProps.is()) {
1000 1 : xDocProps->setTitle(sTitle);
1001 : }
1002 :
1003 2 : pDoc->GetDocShell()->SetTitle( sTitle );
1004 : }
1005 : }
1006 8 : bInTitle = false;
1007 8 : sTitle.clear();
1008 8 : break;
1009 :
1010 : case HTML_NONBREAKSPACE:
1011 0 : sTitle += " ";
1012 0 : break;
1013 :
1014 : case HTML_SOFTHYPH:
1015 0 : sTitle += "-";
1016 0 : break;
1017 :
1018 : case HTML_TEXTTOKEN:
1019 1 : sTitle += aToken;
1020 1 : break;
1021 :
1022 : default:
1023 0 : sTitle += "<";
1024 0 : if( (HTML_TOKEN_ONOFF & nToken) && (1 & nToken) )
1025 0 : sTitle += "/";
1026 0 : sTitle += sSaveToken;
1027 0 : if( !aToken.isEmpty() )
1028 : {
1029 0 : sTitle += " ";
1030 0 : sTitle += aToken;
1031 : }
1032 0 : sTitle += ">";
1033 0 : break;
1034 : }
1035 :
1036 9 : return;
1037 : }
1038 : }
1039 :
1040 : // Find out what type of document it is if we don't know already.
1041 : // For Controls this has to be finished before the control is inserted
1042 : // because for inserting a View is needed.
1043 2047 : if( !bDocInitalized )
1044 16 : DocumentDetected();
1045 :
1046 2047 : bool bGetIDOption = false, bInsertUnknown = false;
1047 2047 : bool bUpperSpaceSave = bUpperSpace;
1048 2047 : bUpperSpace = false;
1049 :
1050 : // The following special cases may or have to be treated after the
1051 : // filter detection
1052 2047 : if( !pPendStack )
1053 : {
1054 2047 : if( bInFloatingFrame )
1055 : {
1056 : // <SCRIPT> is ignored here (from us), because it is ignored in
1057 : // Applets as well
1058 0 : if( HTML_IFRAME_OFF == nToken )
1059 : {
1060 0 : bCallNextToken = false;
1061 0 : EndFloatingFrame();
1062 : }
1063 :
1064 0 : return;
1065 : }
1066 2047 : else if( bInNoEmbed )
1067 : {
1068 0 : switch( nToken )
1069 : {
1070 : case HTML_NOEMBED_OFF:
1071 0 : aContents = convertLineEnd(aContents, GetSystemLineEnd());
1072 0 : InsertComment( aContents, OOO_STRING_SVTOOLS_HTML_noembed );
1073 0 : aContents.clear();
1074 0 : bCallNextToken = false;
1075 0 : bInNoEmbed = false;
1076 0 : break;
1077 :
1078 : case HTML_RAWDATA:
1079 0 : InsertCommentText( OOO_STRING_SVTOOLS_HTML_noembed );
1080 0 : break;
1081 :
1082 : default:
1083 : OSL_ENSURE( false, "SwHTMLParser::NextToken: invalid tag" );
1084 0 : break;
1085 : }
1086 :
1087 0 : return;
1088 : }
1089 2047 : else if( pAppletImpl )
1090 : {
1091 : // in an applet only <PARAM> tags and the </APPLET> tag
1092 : // are of interest for us (for the moment)
1093 : // <SCRIPT> is ignored here (from Netscape)!
1094 :
1095 0 : switch( nToken )
1096 : {
1097 : case HTML_APPLET_OFF:
1098 0 : bCallNextToken = false;
1099 0 : EndApplet();
1100 0 : break;
1101 : case HTML_OBJECT_OFF:
1102 0 : bCallNextToken = false;
1103 0 : EndObject();
1104 0 : break;
1105 :
1106 : case HTML_PARAM:
1107 0 : InsertParam();
1108 0 : break;
1109 : }
1110 :
1111 0 : return;
1112 : }
1113 2047 : else if( bTextArea )
1114 : {
1115 : // in a TextArea everything up to </TEXTAREA> is inserted as text.
1116 : // <SCRIPT> is ignored here (from Netscape)!
1117 :
1118 0 : switch( nToken )
1119 : {
1120 : case HTML_TEXTAREA_OFF:
1121 0 : bCallNextToken = false;
1122 0 : EndTextArea();
1123 0 : break;
1124 :
1125 : default:
1126 0 : InsertTextAreaText( static_cast< sal_uInt16 >(nToken) );
1127 0 : break;
1128 : }
1129 :
1130 0 : return;
1131 : }
1132 2047 : else if( bSelect )
1133 : {
1134 : // HAS to be treated after bNoScript!
1135 0 : switch( nToken )
1136 : {
1137 : case HTML_SELECT_OFF:
1138 0 : bCallNextToken = false;
1139 0 : EndSelect();
1140 0 : return;
1141 :
1142 : case HTML_OPTION:
1143 0 : InsertSelectOption();
1144 0 : return;
1145 :
1146 : case HTML_TEXTTOKEN:
1147 0 : InsertSelectText();
1148 0 : return;
1149 :
1150 : case HTML_INPUT:
1151 : case HTML_SCRIPT_ON:
1152 : case HTML_SCRIPT_OFF:
1153 : case HTML_NOSCRIPT_ON:
1154 : case HTML_NOSCRIPT_OFF:
1155 : case HTML_RAWDATA:
1156 : // treat in normal switch
1157 0 : break;
1158 :
1159 : default:
1160 : // ignore
1161 0 : return;
1162 : }
1163 : }
1164 2047 : else if( pMarquee )
1165 : {
1166 : // in a TextArea everything up to </TEXTAREA> is inserted as text.
1167 : // The <SCRIPT> tags are ignored from MS-IE, we ignore the whole
1168 : // script.
1169 0 : switch( nToken )
1170 : {
1171 : case HTML_MARQUEE_OFF:
1172 0 : bCallNextToken = false;
1173 0 : EndMarquee();
1174 0 : break;
1175 :
1176 : case HTML_TEXTTOKEN:
1177 0 : InsertMarqueeText();
1178 0 : break;
1179 : }
1180 :
1181 0 : return;
1182 : }
1183 2047 : else if( bInField )
1184 : {
1185 0 : switch( nToken )
1186 : {
1187 : case HTML_SDFIELD_OFF:
1188 0 : bCallNextToken = false;
1189 0 : EndField();
1190 0 : break;
1191 :
1192 : case HTML_TEXTTOKEN:
1193 0 : InsertFieldText();
1194 0 : break;
1195 : }
1196 :
1197 0 : return;
1198 : }
1199 2047 : else if( bInFootEndNoteAnchor || bInFootEndNoteSymbol )
1200 : {
1201 0 : switch( nToken )
1202 : {
1203 : case HTML_ANCHOR_OFF:
1204 0 : EndAnchor();
1205 0 : bCallNextToken = false;
1206 0 : break;
1207 :
1208 : case HTML_TEXTTOKEN:
1209 0 : InsertFootEndNoteText();
1210 0 : break;
1211 : }
1212 0 : return;
1213 : }
1214 2047 : else if( !aUnknownToken.isEmpty() )
1215 : {
1216 : // Paste content of unknown tags.
1217 : // (but surely if we are not in the header section) fdo#36080 fdo#34666
1218 15 : if (!aToken.isEmpty() && !IsInHeader() )
1219 : {
1220 0 : if( !bDocInitalized )
1221 0 : DocumentDetected();
1222 0 : pDoc->getIDocumentContentOperations().InsertString( *pPam, aToken );
1223 :
1224 : // if there are temporary paragraph attributes and the
1225 : // paragraph isn't empty then the paragraph attributes
1226 : // are final.
1227 0 : if( !aParaAttrs.empty() )
1228 0 : aParaAttrs.clear();
1229 :
1230 0 : SetAttr();
1231 : }
1232 :
1233 : // Unknown token in the header are only closed by a matching
1234 : // end-token, </HEAD> or <BODY>. Text inside is ignored.
1235 15 : switch( nToken )
1236 : {
1237 : case HTML_UNKNOWNCONTROL_OFF:
1238 5 : if( aUnknownToken != sSaveToken )
1239 3 : return;
1240 : //fall-through
1241 : case HTML_FRAMESET_ON:
1242 : case HTML_HEAD_OFF:
1243 : case HTML_BODY_ON:
1244 : case HTML_IMAGE: // Don't know why Netscape acts this way.
1245 3 : aUnknownToken.clear();
1246 3 : break;
1247 : case HTML_TEXTTOKEN:
1248 7 : return;
1249 : default:
1250 2 : aUnknownToken.clear();
1251 2 : break;
1252 : }
1253 : }
1254 : }
1255 :
1256 2037 : switch( nToken )
1257 : {
1258 : case HTML_BODY_ON:
1259 15 : if( !aStyleSource.isEmpty() )
1260 : {
1261 0 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1262 0 : aStyleSource.clear();
1263 : }
1264 15 : if( IsNewDoc() )
1265 : {
1266 15 : InsertBodyOptions();
1267 : // If there is a template for the first or the right page,
1268 : // it is set here.
1269 15 : const SwPageDesc *pPageDesc = 0;
1270 15 : if( pCSS1Parser->IsSetFirstPageDesc() )
1271 0 : pPageDesc = pCSS1Parser->GetFirstPageDesc();
1272 15 : else if( pCSS1Parser->IsSetRightPageDesc() )
1273 0 : pPageDesc = pCSS1Parser->GetRightPageDesc();
1274 :
1275 15 : if( pPageDesc )
1276 : {
1277 0 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pPam, SwFormatPageDesc( pPageDesc ) );
1278 : }
1279 : }
1280 15 : break;
1281 :
1282 : case HTML_LINK:
1283 0 : InsertLink();
1284 0 : break;
1285 :
1286 : case HTML_BASE:
1287 : {
1288 0 : const HTMLOptions& rHTMLOptions = GetOptions();
1289 0 : for (size_t i = rHTMLOptions.size(); i; )
1290 : {
1291 0 : const HTMLOption& rOption = rHTMLOptions[--i];
1292 0 : switch( rOption.GetToken() )
1293 : {
1294 : case HTML_O_HREF:
1295 0 : sBaseURL = rOption.GetString();
1296 0 : break;
1297 : case HTML_O_TARGET:
1298 0 : if( IsNewDoc() )
1299 : {
1300 0 : SwDocShell *pDocShell(pDoc->GetDocShell());
1301 : OSL_ENSURE(pDocShell, "no SwDocShell");
1302 0 : if (pDocShell) {
1303 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1304 0 : pDocShell->GetModel(), uno::UNO_QUERY_THROW);
1305 : uno::Reference<document::XDocumentProperties>
1306 0 : xDocProps(xDPS->getDocumentProperties());
1307 : OSL_ENSURE(xDocProps.is(),"no DocumentProperties");
1308 0 : if (xDocProps.is()) {
1309 0 : xDocProps->setDefaultTarget(
1310 0 : rOption.GetString());
1311 0 : }
1312 : }
1313 : }
1314 0 : break;
1315 : }
1316 : }
1317 : }
1318 0 : break;
1319 :
1320 : case HTML_META:
1321 : {
1322 42 : SvKeyValueIterator *pHTTPHeader = 0;
1323 42 : if( IsNewDoc() )
1324 : {
1325 42 : SwDocShell *pDocSh = pDoc->GetDocShell();
1326 42 : if( pDocSh )
1327 42 : pHTTPHeader = pDocSh->GetHeaderAttributes();
1328 : }
1329 42 : SwDocShell *pDocShell(pDoc->GetDocShell());
1330 : OSL_ENSURE(pDocShell, "no SwDocShell");
1331 42 : if (pDocShell)
1332 : {
1333 42 : uno::Reference<document::XDocumentProperties> xDocProps;
1334 42 : if (IsNewDoc())
1335 : {
1336 : const uno::Reference<document::XDocumentPropertiesSupplier>
1337 42 : xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
1338 42 : xDocProps = xDPS->getDocumentProperties();
1339 42 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
1340 : }
1341 42 : ParseMetaOptions( xDocProps, pHTTPHeader );
1342 : }
1343 : }
1344 42 : break;
1345 :
1346 : case HTML_TITLE_ON:
1347 8 : bInTitle = true;
1348 8 : break;
1349 :
1350 : case HTML_SCRIPT_ON:
1351 0 : NewScript();
1352 0 : break;
1353 :
1354 : case HTML_SCRIPT_OFF:
1355 0 : EndScript();
1356 0 : break;
1357 :
1358 : case HTML_NOSCRIPT_ON:
1359 : case HTML_NOSCRIPT_OFF:
1360 2 : bInsertUnknown = true;
1361 2 : break;
1362 :
1363 : case HTML_STYLE_ON:
1364 12 : NewStyle();
1365 12 : break;
1366 :
1367 : case HTML_STYLE_OFF:
1368 12 : EndStyle();
1369 12 : break;
1370 :
1371 : case HTML_RAWDATA:
1372 106 : if( !bIgnoreRawData )
1373 : {
1374 106 : if( IsReadScript() )
1375 : {
1376 0 : AddScriptSource();
1377 : }
1378 106 : else if( IsReadStyle() )
1379 : {
1380 106 : if( !aStyleSource.isEmpty() )
1381 80 : aStyleSource += "\n";
1382 106 : aStyleSource += aToken;
1383 : }
1384 : }
1385 106 : break;
1386 :
1387 : case HTML_OBJECT_ON:
1388 : #if HAVE_FEATURE_JAVA
1389 0 : NewObject();
1390 0 : bCallNextToken = pAppletImpl!=0 && pTable!=0;
1391 : #endif
1392 0 : break;
1393 :
1394 : case HTML_APPLET_ON:
1395 : #if HAVE_FEATURE_JAVA
1396 0 : InsertApplet();
1397 0 : bCallNextToken = pAppletImpl!=0 && pTable!=0;
1398 : #endif
1399 0 : break;
1400 :
1401 : case HTML_IFRAME_ON:
1402 1 : InsertFloatingFrame();
1403 1 : bCallNextToken = bInFloatingFrame && pTable!=0;
1404 1 : break;
1405 :
1406 : case HTML_LINEBREAK:
1407 273 : if( !IsReadPRE() )
1408 : {
1409 273 : InsertLineBreak();
1410 273 : break;
1411 : }
1412 : else
1413 0 : bGetIDOption = true;
1414 : // <BR>s in <PRE> resemble true LFs, hence no break
1415 :
1416 : case HTML_NEWPARA:
1417 : // CR in PRE/LISTING/XMP
1418 : {
1419 0 : if( HTML_NEWPARA==nToken ||
1420 0 : pPam->GetPoint()->nContent.GetIndex() )
1421 : {
1422 0 : AppendTextNode(); // there is no LF at this place
1423 : // therefore it will cause no problems
1424 0 : SetTextCollAttrs();
1425 : }
1426 : // progress bar
1427 0 : if( !GetMedium() || !GetMedium()->IsRemote() )
1428 0 : ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
1429 : }
1430 0 : break;
1431 :
1432 : case HTML_NONBREAKSPACE:
1433 0 : pDoc->getIDocumentContentOperations().InsertString( *pPam, OUString(CHAR_HARDBLANK) );
1434 0 : break;
1435 :
1436 : case HTML_SOFTHYPH:
1437 0 : pDoc->getIDocumentContentOperations().InsertString( *pPam, OUString(CHAR_SOFTHYPHEN) );
1438 0 : break;
1439 :
1440 : case HTML_LINEFEEDCHAR:
1441 0 : if( pPam->GetPoint()->nContent.GetIndex() )
1442 0 : AppendTextNode();
1443 0 : if( !pTable && !pDoc->IsInHeaderFooter( pPam->GetPoint()->nNode ) )
1444 : {
1445 0 : NewAttr( &aAttrTab.pBreak, SvxFormatBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK) );
1446 0 : EndAttr( aAttrTab.pBreak, 0, false );
1447 : }
1448 0 : break;
1449 :
1450 : case HTML_TEXTTOKEN:
1451 : // insert string without spanning attributes at the end.
1452 816 : if( !aToken.isEmpty() && ' '==aToken[0] && !IsReadPRE() )
1453 : {
1454 783 : sal_Int32 nPos = pPam->GetPoint()->nContent.GetIndex();
1455 783 : if( nPos )
1456 : {
1457 : const OUString& rText =
1458 297 : pPam->GetPoint()->nNode.GetNode().GetTextNode()->GetText();
1459 297 : sal_Unicode cLast = rText[--nPos];
1460 297 : if( ' ' == cLast || '\x0a' == cLast)
1461 289 : aToken = aToken.copy(1);
1462 : }
1463 : else
1464 486 : aToken = aToken.copy(1);
1465 :
1466 783 : if( aToken.isEmpty() )
1467 : {
1468 773 : bUpperSpace = bUpperSpaceSave;
1469 773 : break;
1470 : }
1471 : }
1472 :
1473 43 : if( !aToken.isEmpty() )
1474 : {
1475 43 : if( !bDocInitalized )
1476 0 : DocumentDetected();
1477 43 : pDoc->getIDocumentContentOperations().InsertString( *pPam, aToken );
1478 :
1479 : // if there are temporary paragraph attributes and the
1480 : // paragraph isn't empty then the paragraph attributes
1481 : // are final.
1482 43 : if( !aParaAttrs.empty() )
1483 0 : aParaAttrs.clear();
1484 :
1485 43 : SetAttr();
1486 : }
1487 43 : break;
1488 :
1489 : case HTML_HORZRULE:
1490 0 : InsertHorzRule();
1491 0 : break;
1492 :
1493 : case HTML_IMAGE:
1494 4 : InsertImage();
1495 : // if only the parser references the doc, we can break and set
1496 : // an error code
1497 4 : if( 1 == pDoc->getReferenceCount() )
1498 : {
1499 0 : eState = SVPAR_ERROR;
1500 : }
1501 4 : break;
1502 :
1503 : case HTML_SPACER:
1504 0 : InsertSpacer();
1505 0 : break;
1506 :
1507 : case HTML_EMBED:
1508 0 : InsertEmbed();
1509 0 : break;
1510 :
1511 : case HTML_NOEMBED_ON:
1512 0 : bInNoEmbed = true;
1513 0 : bCallNextToken = pTable!=0;
1514 0 : ReadRawData( OOO_STRING_SVTOOLS_HTML_noembed );
1515 0 : break;
1516 :
1517 : case HTML_DEFLIST_ON:
1518 0 : if( nOpenParaToken )
1519 0 : EndPara();
1520 0 : NewDefList();
1521 0 : break;
1522 : case HTML_DEFLIST_OFF:
1523 0 : if( nOpenParaToken )
1524 0 : EndPara();
1525 0 : EndDefListItem( 0, false, 1==nDefListDeep );
1526 0 : EndDefList();
1527 0 : break;
1528 :
1529 : case HTML_DD_ON:
1530 : case HTML_DT_ON:
1531 0 : if( nOpenParaToken )
1532 0 : EndPara();
1533 0 : EndDefListItem( 0, false );// close <DD>/<DT> and set no template
1534 0 : NewDefListItem( nToken );
1535 0 : break;
1536 :
1537 : case HTML_DD_OFF:
1538 : case HTML_DT_OFF:
1539 : // c.f. HTML_LI_OFF
1540 : // Actually we should close a DD/DT now.
1541 : // But neither Netscape nor Microsoft do this and so don't we.
1542 0 : EndDefListItem( nToken, false );
1543 0 : break;
1544 :
1545 : // divisions
1546 : case HTML_DIVISION_ON:
1547 : case HTML_CENTER_ON:
1548 16 : if( nOpenParaToken )
1549 : {
1550 0 : if( IsReadPRE() )
1551 0 : nOpenParaToken = 0;
1552 : else
1553 0 : EndPara();
1554 : }
1555 16 : NewDivision( nToken );
1556 16 : break;
1557 :
1558 : case HTML_DIVISION_OFF:
1559 : case HTML_CENTER_OFF:
1560 15 : if( nOpenParaToken )
1561 : {
1562 0 : if( IsReadPRE() )
1563 0 : nOpenParaToken = 0;
1564 : else
1565 0 : EndPara();
1566 : }
1567 15 : EndDivision( nToken );
1568 15 : break;
1569 :
1570 : case HTML_MULTICOL_ON:
1571 0 : if( nOpenParaToken )
1572 0 : EndPara();
1573 0 : NewMultiCol();
1574 0 : break;
1575 :
1576 : case HTML_MULTICOL_OFF:
1577 0 : if( nOpenParaToken )
1578 0 : EndPara();
1579 0 : EndTag( HTML_MULTICOL_ON );
1580 0 : break;
1581 :
1582 : case HTML_MARQUEE_ON:
1583 0 : NewMarquee();
1584 0 : bCallNextToken = pMarquee!=0 && pTable!=0;
1585 0 : break;
1586 :
1587 : case HTML_FORM_ON:
1588 2 : NewForm();
1589 2 : break;
1590 : case HTML_FORM_OFF:
1591 2 : EndForm();
1592 2 : break;
1593 :
1594 : // templates
1595 : case HTML_PARABREAK_ON:
1596 280 : if( nOpenParaToken )
1597 0 : EndPara( true );
1598 280 : NewPara();
1599 280 : break;
1600 :
1601 : case HTML_PARABREAK_OFF:
1602 280 : EndPara( true );
1603 280 : break;
1604 :
1605 : case HTML_ADDRESS_ON:
1606 0 : if( nOpenParaToken )
1607 0 : EndPara();
1608 0 : NewTextFormatColl( HTML_ADDRESS_ON, RES_POOLCOLL_SENDADRESS );
1609 0 : break;
1610 :
1611 : case HTML_ADDRESS_OFF:
1612 0 : if( nOpenParaToken )
1613 0 : EndPara();
1614 0 : EndTextFormatColl( HTML_ADDRESS_OFF );
1615 0 : break;
1616 :
1617 : case HTML_BLOCKQUOTE_ON:
1618 : case HTML_BLOCKQUOTE30_ON:
1619 0 : if( nOpenParaToken )
1620 0 : EndPara();
1621 0 : NewTextFormatColl( HTML_BLOCKQUOTE_ON, RES_POOLCOLL_HTML_BLOCKQUOTE );
1622 0 : break;
1623 :
1624 : case HTML_BLOCKQUOTE_OFF:
1625 : case HTML_BLOCKQUOTE30_OFF:
1626 0 : if( nOpenParaToken )
1627 0 : EndPara();
1628 0 : EndTextFormatColl( HTML_BLOCKQUOTE_ON );
1629 0 : break;
1630 :
1631 : case HTML_PREFORMTXT_ON:
1632 : case HTML_LISTING_ON:
1633 : case HTML_XMP_ON:
1634 0 : if( nOpenParaToken )
1635 0 : EndPara();
1636 0 : NewTextFormatColl( nToken, RES_POOLCOLL_HTML_PRE );
1637 0 : break;
1638 :
1639 : case HTML_PREFORMTXT_OFF:
1640 0 : bNoParSpace = true; // the last PRE-paragraph gets a spacing
1641 0 : EndTextFormatColl( HTML_PREFORMTXT_OFF );
1642 0 : break;
1643 :
1644 : case HTML_LISTING_OFF:
1645 : case HTML_XMP_OFF:
1646 0 : EndTextFormatColl( nToken );
1647 0 : break;
1648 :
1649 : case HTML_HEAD1_ON:
1650 : case HTML_HEAD2_ON:
1651 : case HTML_HEAD3_ON:
1652 : case HTML_HEAD4_ON:
1653 : case HTML_HEAD5_ON:
1654 : case HTML_HEAD6_ON:
1655 1 : if( nOpenParaToken )
1656 : {
1657 0 : if( IsReadPRE() )
1658 0 : nOpenParaToken = 0;
1659 : else
1660 0 : EndPara();
1661 : }
1662 1 : NewHeading( nToken );
1663 1 : break;
1664 :
1665 : case HTML_HEAD1_OFF:
1666 : case HTML_HEAD2_OFF:
1667 : case HTML_HEAD3_OFF:
1668 : case HTML_HEAD4_OFF:
1669 : case HTML_HEAD5_OFF:
1670 : case HTML_HEAD6_OFF:
1671 1 : EndHeading();
1672 1 : break;
1673 :
1674 : case HTML_TABLE_ON:
1675 6 : if( pPendStack )
1676 0 : BuildTable( SVX_ADJUST_END );
1677 : else
1678 : {
1679 6 : if( nOpenParaToken )
1680 0 : EndPara();
1681 : OSL_ENSURE( !pTable, "table in table not allowed here" );
1682 18 : if( !pTable && (IsNewDoc() || !pPam->GetNode().FindTableNode()) &&
1683 6 : (pPam->GetPoint()->nNode.GetIndex() >
1684 6 : pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
1685 0 : !pPam->GetNode().FindFootnoteStartNode() ) )
1686 : {
1687 6 : if ( nParaCnt < 5 )
1688 2 : Show(); // show what we have up to here
1689 :
1690 : SvxAdjust eAdjust = aAttrTab.pAdjust
1691 0 : ? static_cast<const SvxAdjustItem&>(aAttrTab.pAdjust->GetItem()).
1692 : GetAdjust()
1693 6 : : SVX_ADJUST_END;
1694 6 : BuildTable( eAdjust );
1695 : }
1696 : else
1697 0 : bInsertUnknown = bKeepUnknown;
1698 : }
1699 6 : break;
1700 :
1701 : // lists
1702 : case HTML_DIRLIST_ON:
1703 : case HTML_MENULIST_ON:
1704 : case HTML_ORDERLIST_ON:
1705 : case HTML_UNORDERLIST_ON:
1706 0 : if( nOpenParaToken )
1707 0 : EndPara();
1708 0 : NewNumBulList( nToken );
1709 0 : break;
1710 :
1711 : case HTML_DIRLIST_OFF:
1712 : case HTML_MENULIST_OFF:
1713 : case HTML_ORDERLIST_OFF:
1714 : case HTML_UNORDERLIST_OFF:
1715 0 : if( nOpenParaToken )
1716 0 : EndPara();
1717 0 : EndNumBulListItem( 0, true, GetNumInfo().GetDepth()==1 );
1718 0 : EndNumBulList( nToken );
1719 0 : break;
1720 :
1721 : case HTML_LI_ON:
1722 : case HTML_LISTHEADER_ON:
1723 0 : if( nOpenParaToken &&
1724 0 : (pPam->GetPoint()->nContent.GetIndex()
1725 0 : || HTML_PARABREAK_ON==nOpenParaToken) )
1726 : {
1727 : // only finish paragraph for <P><LI>, not for <DD><LI>
1728 0 : EndPara();
1729 : }
1730 :
1731 0 : EndNumBulListItem( 0, false );// close <LI>/<LH> and don't set a template
1732 0 : NewNumBulListItem( nToken );
1733 0 : break;
1734 :
1735 : case HTML_LI_OFF:
1736 : case HTML_LISTHEADER_OFF:
1737 0 : EndNumBulListItem( nToken, false );
1738 0 : break;
1739 :
1740 : // Attribute :
1741 : case HTML_ITALIC_ON:
1742 : {
1743 0 : SvxPostureItem aPosture( ITALIC_NORMAL, RES_CHRATR_POSTURE );
1744 0 : SvxPostureItem aPostureCJK( ITALIC_NORMAL, RES_CHRATR_CJK_POSTURE );
1745 0 : SvxPostureItem aPostureCTL( ITALIC_NORMAL, RES_CHRATR_CTL_POSTURE );
1746 : NewStdAttr( HTML_ITALIC_ON,
1747 : &aAttrTab.pItalic, aPosture,
1748 : &aAttrTab.pItalicCJK, &aPostureCJK,
1749 0 : &aAttrTab.pItalicCTL, &aPostureCTL );
1750 : }
1751 0 : break;
1752 :
1753 : case HTML_BOLD_ON:
1754 : {
1755 5 : SvxWeightItem aWeight( WEIGHT_BOLD, RES_CHRATR_WEIGHT );
1756 10 : SvxWeightItem aWeightCJK( WEIGHT_BOLD, RES_CHRATR_CJK_WEIGHT );
1757 10 : SvxWeightItem aWeightCTL( WEIGHT_BOLD, RES_CHRATR_CTL_WEIGHT );
1758 : NewStdAttr( HTML_BOLD_ON,
1759 : &aAttrTab.pBold, aWeight,
1760 : &aAttrTab.pBoldCJK, &aWeightCJK,
1761 10 : &aAttrTab.pBoldCTL, &aWeightCTL );
1762 : }
1763 5 : break;
1764 :
1765 : case HTML_STRIKE_ON:
1766 : case HTML_STRIKETHROUGH_ON:
1767 : {
1768 : NewStdAttr( HTML_STRIKE_ON, &aAttrTab.pStrike,
1769 0 : SvxCrossedOutItem(STRIKEOUT_SINGLE, RES_CHRATR_CROSSEDOUT) );
1770 : }
1771 0 : break;
1772 :
1773 : case HTML_UNDERLINE_ON:
1774 : {
1775 : NewStdAttr( HTML_UNDERLINE_ON, &aAttrTab.pUnderline,
1776 0 : SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE) );
1777 : }
1778 0 : break;
1779 :
1780 : case HTML_SUPERSCRIPT_ON:
1781 : {
1782 : NewStdAttr( HTML_SUPERSCRIPT_ON, &aAttrTab.pEscapement,
1783 0 : SvxEscapementItem(HTML_ESC_SUPER,HTML_ESC_PROP, RES_CHRATR_ESCAPEMENT) );
1784 : }
1785 0 : break;
1786 :
1787 : case HTML_SUBSCRIPT_ON:
1788 : {
1789 : NewStdAttr( HTML_SUBSCRIPT_ON, &aAttrTab.pEscapement,
1790 0 : SvxEscapementItem(HTML_ESC_SUB,HTML_ESC_PROP, RES_CHRATR_ESCAPEMENT) );
1791 : }
1792 0 : break;
1793 :
1794 : case HTML_BLINK_ON:
1795 : {
1796 : NewStdAttr( HTML_BLINK_ON, &aAttrTab.pBlink,
1797 0 : SvxBlinkItem( true, RES_CHRATR_BLINK ) );
1798 : }
1799 0 : break;
1800 :
1801 : case HTML_SPAN_ON:
1802 6 : NewStdAttr( HTML_SPAN_ON );
1803 6 : break;
1804 :
1805 : case HTML_ITALIC_OFF:
1806 : case HTML_BOLD_OFF:
1807 : case HTML_STRIKE_OFF:
1808 : case HTML_UNDERLINE_OFF:
1809 : case HTML_SUPERSCRIPT_OFF:
1810 : case HTML_SUBSCRIPT_OFF:
1811 : case HTML_BLINK_OFF:
1812 : case HTML_SPAN_OFF:
1813 11 : EndTag( nToken );
1814 11 : break;
1815 :
1816 : case HTML_STRIKETHROUGH_OFF:
1817 0 : EndTag( HTML_STRIKE_OFF );
1818 0 : break;
1819 :
1820 : case HTML_BASEFONT_ON:
1821 0 : NewBasefontAttr();
1822 0 : break;
1823 : case HTML_BASEFONT_OFF:
1824 0 : EndBasefontAttr();
1825 0 : break;
1826 : case HTML_FONT_ON:
1827 : case HTML_BIGPRINT_ON:
1828 : case HTML_SMALLPRINT_ON:
1829 13 : NewFontAttr( nToken );
1830 13 : break;
1831 : case HTML_FONT_OFF:
1832 : case HTML_BIGPRINT_OFF:
1833 : case HTML_SMALLPRINT_OFF:
1834 13 : EndFontAttr( nToken );
1835 13 : break;
1836 :
1837 : case HTML_EMPHASIS_ON:
1838 : case HTML_CITIATION_ON:
1839 : case HTML_STRONG_ON:
1840 : case HTML_CODE_ON:
1841 : case HTML_SAMPLE_ON:
1842 : case HTML_KEYBOARD_ON:
1843 : case HTML_VARIABLE_ON:
1844 : case HTML_DEFINSTANCE_ON:
1845 : case HTML_SHORTQUOTE_ON:
1846 : case HTML_LANGUAGE_ON:
1847 : case HTML_AUTHOR_ON:
1848 : case HTML_PERSON_ON:
1849 : case HTML_ACRONYM_ON:
1850 : case HTML_ABBREVIATION_ON:
1851 : case HTML_INSERTEDTEXT_ON:
1852 : case HTML_DELETEDTEXT_ON:
1853 :
1854 : case HTML_TELETYPE_ON:
1855 0 : NewCharFormat( nToken );
1856 0 : break;
1857 :
1858 : case HTML_SDFIELD_ON:
1859 0 : NewField();
1860 0 : bCallNextToken = bInField && pTable!=0;
1861 0 : break;
1862 :
1863 : case HTML_EMPHASIS_OFF:
1864 : case HTML_CITIATION_OFF:
1865 : case HTML_STRONG_OFF:
1866 : case HTML_CODE_OFF:
1867 : case HTML_SAMPLE_OFF:
1868 : case HTML_KEYBOARD_OFF:
1869 : case HTML_VARIABLE_OFF:
1870 : case HTML_DEFINSTANCE_OFF:
1871 : case HTML_SHORTQUOTE_OFF:
1872 : case HTML_LANGUAGE_OFF:
1873 : case HTML_AUTHOR_OFF:
1874 : case HTML_PERSON_OFF:
1875 : case HTML_ACRONYM_OFF:
1876 : case HTML_ABBREVIATION_OFF:
1877 : case HTML_INSERTEDTEXT_OFF:
1878 : case HTML_DELETEDTEXT_OFF:
1879 :
1880 : case HTML_TELETYPE_OFF:
1881 0 : EndTag( nToken );
1882 0 : break;
1883 :
1884 : case HTML_HEAD_OFF:
1885 13 : if( !aStyleSource.isEmpty() )
1886 : {
1887 0 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1888 0 : aStyleSource.clear();
1889 : }
1890 13 : break;
1891 :
1892 : case HTML_DOCTYPE:
1893 : case HTML_BODY_OFF:
1894 : case HTML_HTML_OFF:
1895 : case HTML_HEAD_ON:
1896 : case HTML_TITLE_OFF:
1897 28 : break; // don't evaluate further???
1898 : case HTML_HTML_ON:
1899 : {
1900 14 : const HTMLOptions& rHTMLOptions = GetOptions();
1901 39 : for (size_t i = rHTMLOptions.size(); i; )
1902 : {
1903 11 : const HTMLOption& rOption = rHTMLOptions[--i];
1904 11 : if( HTML_O_DIR == rOption.GetToken() )
1905 : {
1906 0 : const OUString& rDir = rOption.GetString();
1907 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(),
1908 0 : pCSS1Parser->GetWhichMap() );
1909 0 : SvxCSS1PropertyInfo aPropInfo;
1910 0 : OUString aDummy;
1911 : ParseStyleOptions( aDummy, aDummy, aDummy, aItemSet,
1912 0 : aPropInfo, 0, &rDir );
1913 :
1914 0 : pCSS1Parser->SetPageDescAttrs( 0, &aItemSet );
1915 0 : break;
1916 : }
1917 : }
1918 : }
1919 14 : break;
1920 :
1921 : case HTML_INPUT:
1922 4 : InsertInput();
1923 4 : break;
1924 :
1925 : case HTML_TEXTAREA_ON:
1926 0 : NewTextArea();
1927 0 : bCallNextToken = bTextArea && pTable!=0;
1928 0 : break;
1929 :
1930 : case HTML_SELECT_ON:
1931 0 : NewSelect();
1932 0 : bCallNextToken = bSelect && pTable!=0;
1933 0 : break;
1934 :
1935 : case HTML_ANCHOR_ON:
1936 5 : NewAnchor();
1937 5 : break;
1938 :
1939 : case HTML_ANCHOR_OFF:
1940 5 : EndAnchor();
1941 5 : break;
1942 :
1943 : case HTML_COMMENT:
1944 1 : if( ( aToken.getLength() > 5 ) && ( ! bIgnoreHTMLComments ) )
1945 : {
1946 : // insert as Post-It
1947 : // If there are no space characters right behind
1948 : // the <!-- and on front of the -->, leave the comment untouched.
1949 2 : if( ' ' == aToken[ 3 ] &&
1950 1 : ' ' == aToken[ aToken.getLength()-3 ] )
1951 : {
1952 0 : OUString aComment( aToken.copy( 3, aToken.getLength()-5 ) );
1953 0 : InsertComment(comphelper::string::strip(aComment, ' '));
1954 : }
1955 : else
1956 : {
1957 1 : OUStringBuffer aComment;
1958 1 : aComment.append('<').append(aToken).append('>');
1959 1 : InsertComment( aComment.makeStringAndClear() );
1960 : }
1961 : }
1962 1 : break;
1963 :
1964 : case HTML_MAP_ON:
1965 : // Image Maps are read asynchronously: At first only an image map is created
1966 : // Areas are processed later. Nevertheless the
1967 : // ImageMap is inserted into the IMap-Array, because it might be used
1968 : // already.
1969 0 : pImageMap = new ImageMap;
1970 0 : if( ParseMapOptions( pImageMap) )
1971 : {
1972 0 : if( !pImageMaps )
1973 0 : pImageMaps = new ImageMaps;
1974 0 : pImageMaps->push_back( pImageMap );
1975 : }
1976 : else
1977 : {
1978 0 : delete pImageMap;
1979 0 : pImageMap = 0;
1980 : }
1981 0 : break;
1982 :
1983 : case HTML_MAP_OFF:
1984 : // there is no ImageMap anymore (don't delete IMap, because it's
1985 : // already contained in the array!)
1986 0 : pImageMap = 0;
1987 0 : break;
1988 :
1989 : case HTML_AREA:
1990 0 : if( pImageMap )
1991 : ParseAreaOptions( pImageMap, sBaseURL, SFX_EVENT_MOUSEOVER_OBJECT,
1992 0 : SFX_EVENT_MOUSEOUT_OBJECT );
1993 0 : break;
1994 :
1995 : case HTML_FRAMESET_ON:
1996 0 : bInsertUnknown = bKeepUnknown;
1997 0 : break;
1998 :
1999 : case HTML_NOFRAMES_ON:
2000 0 : if( IsInHeader() )
2001 0 : FinishHeader( true );
2002 0 : bInsertUnknown = bKeepUnknown;
2003 0 : break;
2004 :
2005 : case HTML_UNKNOWNCONTROL_ON:
2006 : // Ignore content of unknown token in the header, if the token
2007 : // does not start with a '!'.
2008 : // (but judging from the code, also if does not start with a '%')
2009 : // (and also if we're not somewhere we consider PRE)
2010 50 : if( IsInHeader() && !IsReadPRE() && aUnknownToken.isEmpty() &&
2011 35 : !sSaveToken.isEmpty() && '!' != sSaveToken[0] &&
2012 5 : '%' != sSaveToken[0] )
2013 5 : aUnknownToken = sSaveToken;
2014 : // no break
2015 :
2016 : default:
2017 25 : bInsertUnknown = bKeepUnknown;
2018 25 : break;
2019 : }
2020 :
2021 2037 : if( bGetIDOption )
2022 0 : InsertIDOption();
2023 :
2024 2037 : if( bInsertUnknown )
2025 : {
2026 2 : OUString aComment("HTML: <");
2027 2 : if( (HTML_TOKEN_ONOFF & nToken) != 0 && (1 & nToken) != 0 )
2028 1 : aComment += "/";
2029 2 : aComment += sSaveToken;
2030 2 : if( !aToken.isEmpty() )
2031 : {
2032 0 : UnescapeToken();
2033 0 : (aComment += " ") += aToken;
2034 : }
2035 2 : aComment += ">";
2036 2 : InsertComment( aComment );
2037 : }
2038 :
2039 : // if there are temporary paragraph attributes and the
2040 : // paragraph isn't empty then the paragraph attributes are final.
2041 2037 : if( !aParaAttrs.empty() && pPam->GetPoint()->nContent.GetIndex() )
2042 1 : aParaAttrs.clear();
2043 : }
2044 :
2045 132 : static void lcl_swhtml_getItemInfo( const _HTMLAttr& rAttr,
2046 : bool& rScriptDependent, bool& rFont,
2047 : sal_uInt16& rScriptType )
2048 : {
2049 132 : switch( rAttr.GetItem().Which() )
2050 : {
2051 : case RES_CHRATR_FONT:
2052 3 : rFont = true;
2053 : //fall-through
2054 : case RES_CHRATR_FONTSIZE:
2055 : case RES_CHRATR_LANGUAGE:
2056 : case RES_CHRATR_POSTURE:
2057 : case RES_CHRATR_WEIGHT:
2058 33 : rScriptType = i18n::ScriptType::LATIN;
2059 33 : rScriptDependent = true;
2060 33 : break;
2061 : case RES_CHRATR_CJK_FONT:
2062 2 : rFont = true;
2063 : //fall-through
2064 : case RES_CHRATR_CJK_FONTSIZE:
2065 : case RES_CHRATR_CJK_LANGUAGE:
2066 : case RES_CHRATR_CJK_POSTURE:
2067 : case RES_CHRATR_CJK_WEIGHT:
2068 32 : rScriptType = i18n::ScriptType::ASIAN;
2069 32 : rScriptDependent = true;
2070 32 : break;
2071 : case RES_CHRATR_CTL_FONT:
2072 2 : rFont = true;
2073 : //fall-through
2074 : case RES_CHRATR_CTL_FONTSIZE:
2075 : case RES_CHRATR_CTL_LANGUAGE:
2076 : case RES_CHRATR_CTL_POSTURE:
2077 : case RES_CHRATR_CTL_WEIGHT:
2078 32 : rScriptType = i18n::ScriptType::COMPLEX;
2079 32 : rScriptDependent = true;
2080 32 : break;
2081 : default:
2082 35 : rScriptDependent = false;
2083 35 : rFont = false;
2084 35 : break;
2085 : }
2086 132 : }
2087 :
2088 290 : bool SwHTMLParser::AppendTextNode( SwHTMLAppendMode eMode, bool bUpdateNum )
2089 : {
2090 : // Ein harter Zeilen-Umbruch am Ende muss immer entfernt werden.
2091 : // Einen zweiten ersetzen wir durch einen Absatz-Abstand.
2092 290 : sal_Int32 nLFStripped = StripTrailingLF();
2093 290 : if( (AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode) && nLFStripped > 1 )
2094 0 : eMode = AM_SPACE;
2095 :
2096 : // die harten Attribute an diesem Absatz werden nie mehr ungueltig
2097 290 : if( !aParaAttrs.empty() )
2098 0 : aParaAttrs.clear();
2099 :
2100 290 : if( AM_SPACE==eMode || AM_NOSPACE==eMode )
2101 : {
2102 : SwTextNode *pTextNode =
2103 286 : pPam->GetPoint()->nNode.GetNode().GetTextNode();
2104 :
2105 : const SvxULSpaceItem& rULSpace =
2106 286 : static_cast<const SvxULSpaceItem&>(pTextNode->SwContentNode::GetAttr( RES_UL_SPACE ));
2107 :
2108 4 : bool bChange = AM_NOSPACE==eMode ? rULSpace.GetLower() > 0
2109 290 : : rULSpace.GetLower() == 0;
2110 :
2111 286 : if( bChange )
2112 : {
2113 : const SvxULSpaceItem& rCollULSpace =
2114 268 : pTextNode->GetAnyFormatColl().GetULSpace();
2115 :
2116 3 : bool bMayReset = AM_NOSPACE==eMode ? rCollULSpace.GetLower() == 0
2117 271 : : rCollULSpace.GetLower() > 0;
2118 :
2119 269 : if( bMayReset &&
2120 1 : rCollULSpace.GetUpper() == rULSpace.GetUpper() )
2121 : {
2122 1 : pTextNode->ResetAttr( RES_UL_SPACE );
2123 : }
2124 : else
2125 : {
2126 : pTextNode->SetAttr(
2127 267 : SvxULSpaceItem( rULSpace.GetUpper(),
2128 534 : AM_NOSPACE==eMode ? 0 : HTML_PARSPACE, RES_UL_SPACE ) );
2129 : }
2130 : }
2131 : }
2132 290 : bNoParSpace = AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode;
2133 :
2134 290 : SwPosition aOldPos( *pPam->GetPoint() );
2135 :
2136 290 : bool bRet = pDoc->getIDocumentContentOperations().AppendTextNode( *pPam->GetPoint() );
2137 :
2138 : // Zeichen-Attribute aufspalten und ggf keine setzen, die ueber den
2139 : // ganzen Absatz gesetzt sind
2140 290 : const SwNodeIndex& rEndIdx = aOldPos.nNode;
2141 290 : const sal_Int32 nEndCnt = aOldPos.nContent.GetIndex();
2142 290 : const SwPosition& rPos = *pPam->GetPoint();
2143 :
2144 290 : _HTMLAttr** pHTMLAttributes = reinterpret_cast<_HTMLAttr**>(&aAttrTab);
2145 11890 : for (auto nCnt = sizeof(_HTMLAttrTable) / sizeof(_HTMLAttr*); nCnt--; ++pHTMLAttributes)
2146 : {
2147 11600 : _HTMLAttr *pAttr = *pHTMLAttributes;
2148 11600 : if( pAttr && pAttr->GetItem().Which() < RES_PARATR_BEGIN )
2149 : {
2150 779 : bool bWholePara = false;
2151 :
2152 2337 : while( pAttr )
2153 : {
2154 779 : _HTMLAttr *pNext = pAttr->GetNext();
2155 1583 : if( pAttr->GetSttParaIdx() < rEndIdx.GetIndex() ||
2156 1558 : (!bWholePara &&
2157 1558 : pAttr->GetSttPara() == rEndIdx &&
2158 779 : pAttr->GetSttCnt() != nEndCnt) )
2159 : {
2160 : bWholePara =
2161 50 : pAttr->GetSttPara() == rEndIdx &&
2162 50 : pAttr->GetSttCnt() == 0;
2163 :
2164 25 : sal_Int32 nStt = pAttr->nSttContent;
2165 25 : bool bScript = false, bFont = false;
2166 : sal_uInt16 nScriptItem;
2167 25 : bool bInsert = true;
2168 : lcl_swhtml_getItemInfo( *pAttr, bScript, bFont,
2169 25 : nScriptItem );
2170 : // den besehrigen Teil setzen
2171 25 : if( bInsert && bScript )
2172 : {
2173 : const SwTextNode *pTextNd =
2174 24 : pAttr->GetSttPara().GetNode().GetTextNode();
2175 : OSL_ENSURE( pTextNd, "No text node" );
2176 24 : if( pTextNd )
2177 : {
2178 24 : const OUString& rText = pTextNd->GetText();
2179 : sal_uInt16 nScriptText =
2180 48 : g_pBreakIt->GetBreakIter()->getScriptType(
2181 24 : rText, pAttr->GetSttCnt() );
2182 : sal_Int32 nScriptEnd = g_pBreakIt->GetBreakIter()
2183 24 : ->endOfScript( rText, nStt, nScriptText );
2184 48 : while( nScriptEnd < nEndCnt )
2185 : {
2186 0 : if( nScriptItem == nScriptText )
2187 : {
2188 : _HTMLAttr *pSetAttr =
2189 0 : pAttr->Clone( rEndIdx, nScriptEnd );
2190 0 : pSetAttr->nSttContent = nStt;
2191 0 : pSetAttr->ClearPrev();
2192 0 : if( !pNext || bWholePara )
2193 : {
2194 0 : if (pSetAttr->bInsAtStart)
2195 0 : aSetAttrTab.push_front( pSetAttr );
2196 : else
2197 0 : aSetAttrTab.push_back( pSetAttr );
2198 : }
2199 : else
2200 0 : pNext->InsertPrev( pSetAttr );
2201 : }
2202 0 : nStt = nScriptEnd;
2203 0 : nScriptText = g_pBreakIt->GetBreakIter()->getScriptType(
2204 0 : rText, nStt );
2205 : nScriptEnd = g_pBreakIt->GetBreakIter()
2206 0 : ->endOfScript( rText, nStt, nScriptText );
2207 : }
2208 24 : bInsert = nScriptItem == nScriptText;
2209 : }
2210 : }
2211 25 : if( bInsert )
2212 : {
2213 : _HTMLAttr *pSetAttr =
2214 9 : pAttr->Clone( rEndIdx, nEndCnt );
2215 9 : pSetAttr->nSttContent = nStt;
2216 :
2217 : // Wenn das Attribut den gesamten Absatz umspannt, werden
2218 : // alle auesseren Attribute nicht mehr beachtet. Deshalb
2219 : // darf es auch nicht in die Prev-Liste eines ausseren
2220 : // Attributs eingetragen werden, denn dieses wird ja
2221 : // erstmal nicht gesetzt. Das fuehrt zu verschiebenungen,
2222 : // wenn Felder ins Rennen kommen
2223 9 : if( !pNext || bWholePara )
2224 : {
2225 18 : if (pSetAttr->bInsAtStart)
2226 9 : aSetAttrTab.push_front( pSetAttr );
2227 : else
2228 0 : aSetAttrTab.push_back( pSetAttr );
2229 : }
2230 : else
2231 0 : pNext->InsertPrev( pSetAttr );
2232 : }
2233 : else
2234 : {
2235 16 : _HTMLAttr *pPrev = pAttr->GetPrev();
2236 16 : if( pPrev )
2237 : {
2238 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
2239 0 : if( !pNext || bWholePara )
2240 : {
2241 0 : if (pPrev->bInsAtStart)
2242 0 : aSetAttrTab.push_front( pPrev );
2243 : else
2244 0 : aSetAttrTab.push_back( pPrev );
2245 : }
2246 : else
2247 0 : pNext->InsertPrev( pPrev );
2248 : }
2249 : }
2250 25 : pAttr->ClearPrev();
2251 : }
2252 :
2253 779 : pAttr->SetStart( rPos );
2254 779 : pAttr = pNext;
2255 : }
2256 : }
2257 : }
2258 :
2259 290 : if( bUpdateNum )
2260 : {
2261 290 : if( GetNumInfo().GetDepth() )
2262 : {
2263 0 : sal_uInt8 nLvl = GetNumInfo().GetLevel();
2264 0 : SetNodeNum( nLvl, false );
2265 : }
2266 : else
2267 290 : pPam->GetNode().GetTextNode()->ResetAttr( RES_PARATR_NUMRULE );
2268 : }
2269 :
2270 : // Attrubute im Absatz davor sollte man jetzt setzen (wegen JavaScript)
2271 290 : SetAttr();
2272 :
2273 : // Now it is time to get rid of all script dependent hints that are
2274 : // equal to the settings in the style
2275 290 : SwTextNode *pTextNd = rEndIdx.GetNode().GetTextNode();
2276 : OSL_ENSURE( pTextNd, "There is the txt node" );
2277 290 : size_t nCntAttr = (pTextNd && pTextNd->GetpSwpHints())
2278 303 : ? pTextNd->GetSwpHints().Count() : 0;
2279 290 : if( nCntAttr )
2280 : {
2281 : // These are the end position of all script depenent hints.
2282 : // If we find a hint that starts before the current end position,
2283 : // we have to set it. If we find a hint that start behind or at
2284 : // that position, we have to take the hint's value into account.
2285 : // If it is equal to the style, or in fact the paragarph's value
2286 : // for that hint, the hint is removed. Otherwise it's end position
2287 : // is remembered.
2288 : sal_Int32 aEndPos[15] =
2289 13 : { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2290 13 : SwpHints& rHints = pTextNd->GetSwpHints();
2291 36 : for( size_t i=0; i < nCntAttr; i++ )
2292 : {
2293 23 : SwTextAttr *pHt = rHints.GetTextHint( i );
2294 23 : sal_uInt16 nWhich = pHt->Which();
2295 23 : sal_Int16 nIdx = -1;
2296 : //In 'hintids.hxx', the following five attributes don't follow
2297 : //each other in the Latin attributes as they do among CJK and
2298 : //CTL attributes, so the old code just made a mess, IMHO.
2299 : //E.g. 29-22=7, which should be LANGUAGE, but it's FONT.
2300 : //Moreover, it should occur between 0 and 4.
2301 : //Since it would be too risky to change the attribute codes,
2302 : //I repaired the following source code the 'brute force' way.
2303 :
2304 : //Old code:
2305 : /*
2306 : if( RES_CHRATR_CJK_FONT <= nWhich &&
2307 : nWhich <= RES_CHRATR_CTL_WEIGHT )
2308 : {
2309 : nIdx = static_cast< sal_uInt16 >(nWhich - RES_CHRATR_CJK_FONT + 5);
2310 : }
2311 : else switch...
2312 : */
2313 :
2314 23 : if( RES_CHRATR_CJK_FONT == nWhich || RES_CHRATR_CTL_FONT == nWhich )
2315 : {
2316 0 : nIdx = 0;
2317 : }
2318 23 : else if( RES_CHRATR_CJK_FONTSIZE == nWhich || RES_CHRATR_CTL_FONTSIZE == nWhich )
2319 : {
2320 0 : nIdx = 1;
2321 : }
2322 23 : else if( RES_CHRATR_CJK_LANGUAGE == nWhich || RES_CHRATR_CTL_LANGUAGE == nWhich )
2323 : {
2324 0 : nIdx = 2;
2325 : }
2326 23 : else if( RES_CHRATR_CJK_POSTURE == nWhich || RES_CHRATR_CTL_POSTURE == nWhich )
2327 : {
2328 0 : nIdx = 3;
2329 : }
2330 23 : else if( RES_CHRATR_CJK_WEIGHT == nWhich || RES_CHRATR_CTL_WEIGHT == nWhich )
2331 : {
2332 0 : nIdx = 4;
2333 : }
2334 23 : else switch( nWhich )
2335 : {
2336 0 : case RES_CHRATR_FONT: nIdx = 0; break;
2337 0 : case RES_CHRATR_FONTSIZE: nIdx = 1; break;
2338 0 : case RES_CHRATR_LANGUAGE: nIdx = 2; break;
2339 0 : case RES_CHRATR_POSTURE: nIdx = 3; break;
2340 0 : case RES_CHRATR_WEIGHT: nIdx = 4; break;
2341 : }
2342 23 : if( nIdx != -1 )
2343 : {
2344 0 : sal_Int32 nStt = pHt->GetStart();
2345 0 : if( nStt >= aEndPos[nIdx] )
2346 : {
2347 0 : bool bFont = (nIdx % 5) == 0;
2348 : const SfxPoolItem& rItem =
2349 0 : static_cast<const SwContentNode *>(pTextNd)->GetAttr( nWhich );
2350 0 : if( bFont ? swhtml_css1atr_equalFontItems(rItem,pHt->GetAttr())
2351 0 : : rItem == pHt->GetAttr() )
2352 : {
2353 : // The hint is the same as set in the paragraph and
2354 : // therefore, it can be deleted
2355 : // CAUTION!!! This WILL delete the hint and it MAY
2356 : // also delete the SwpHints!!! To avoid any trouble
2357 : // we leave the loop immediately if this is the last
2358 : // hint.
2359 0 : pTextNd->DeleteAttribute( pHt );
2360 0 : if( 1 == nCntAttr )
2361 0 : break;
2362 0 : i--;
2363 0 : nCntAttr--;
2364 : }
2365 : else
2366 : {
2367 : // The hint is different. Therefore all hints within that
2368 : // hint have to be ignored.
2369 0 : aEndPos[nIdx] = pHt->GetEnd() ? *pHt->GetEnd() : nStt;
2370 : }
2371 : }
2372 : else
2373 : {
2374 : // The hint starts before another one ends.
2375 : // The hint in this case is not deleted
2376 : OSL_ENSURE( pHt->GetEnd() && *pHt->GetEnd() <= aEndPos[nIdx],
2377 : "hints aren't nested properly!" );
2378 : }
2379 : }
2380 : }
2381 : }
2382 :
2383 290 : if( !pTable && !--nParaCnt )
2384 1 : Show();
2385 :
2386 290 : return bRet;
2387 : }
2388 :
2389 284 : void SwHTMLParser::AddParSpace()
2390 : {
2391 : //If it already has ParSpace, return
2392 284 : if( !bNoParSpace )
2393 568 : return;
2394 :
2395 0 : bNoParSpace = false;
2396 :
2397 0 : sal_uLong nNdIdx = pPam->GetPoint()->nNode.GetIndex() - 1;
2398 :
2399 0 : SwTextNode *pTextNode = pDoc->GetNodes()[nNdIdx]->GetTextNode();
2400 0 : if( !pTextNode )
2401 0 : return;
2402 :
2403 : SvxULSpaceItem rULSpace =
2404 0 : static_cast<const SvxULSpaceItem&>(pTextNode->SwContentNode::GetAttr( RES_UL_SPACE ));
2405 0 : if( !rULSpace.GetLower() )
2406 : {
2407 : const SvxULSpaceItem& rCollULSpace =
2408 0 : pTextNode->GetAnyFormatColl().GetULSpace();
2409 0 : if( rCollULSpace.GetLower() &&
2410 0 : rCollULSpace.GetUpper() == rULSpace.GetUpper() )
2411 : {
2412 0 : pTextNode->ResetAttr( RES_UL_SPACE );
2413 : }
2414 : else
2415 : {
2416 : //What I do here, is that I examine the attributes, and if
2417 : //I find out, that it's CJK/CTL, then I set the paragraph space
2418 : //to the value set in HTML_CJK_PARSPACE/HTML_CTL_PARSPACE.
2419 :
2420 0 : bool bIsCJK = false;
2421 0 : bool bIsCTL = false;
2422 :
2423 0 : const size_t nCntAttr = (pTextNode && pTextNode->GetpSwpHints())
2424 0 : ? pTextNode->GetSwpHints().Count() : 0;
2425 :
2426 0 : for(size_t i = 0; i < nCntAttr; ++i)
2427 : {
2428 0 : SwTextAttr *const pHt = pTextNode->GetSwpHints().GetTextHint(i);
2429 0 : sal_uInt16 const nWhich = pHt->Which();
2430 0 : if (RES_CHRATR_CJK_FONT == nWhich ||
2431 0 : RES_CHRATR_CJK_FONTSIZE == nWhich ||
2432 0 : RES_CHRATR_CJK_LANGUAGE == nWhich ||
2433 0 : RES_CHRATR_CJK_POSTURE == nWhich ||
2434 : RES_CHRATR_CJK_WEIGHT == nWhich)
2435 : {
2436 0 : bIsCJK = true;
2437 0 : break;
2438 : }
2439 0 : if (RES_CHRATR_CTL_FONT == nWhich ||
2440 0 : RES_CHRATR_CTL_FONTSIZE == nWhich ||
2441 0 : RES_CHRATR_CTL_LANGUAGE == nWhich ||
2442 0 : RES_CHRATR_CTL_POSTURE == nWhich ||
2443 : RES_CHRATR_CTL_WEIGHT == nWhich)
2444 : {
2445 0 : bIsCTL = true;
2446 0 : break;
2447 : }
2448 : }
2449 :
2450 0 : if( bIsCTL )
2451 : {
2452 : pTextNode->SetAttr(
2453 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_CTL_PARSPACE, RES_UL_SPACE ) );
2454 : }
2455 0 : else if( bIsCJK )
2456 : {
2457 : pTextNode->SetAttr(
2458 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_CJK_PARSPACE, RES_UL_SPACE ) );
2459 : } else {
2460 : pTextNode->SetAttr(
2461 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_PARSPACE, RES_UL_SPACE ) );
2462 : }
2463 : }
2464 0 : }
2465 : }
2466 :
2467 6 : void SwHTMLParser::Show()
2468 : {
2469 : // Hier wird
2470 : // - ein EndAction gerufen, damit formatiert wird
2471 : // - ein Reschedule gerufen,
2472 : // - die eiegen View-Shell wieder gesetzt
2473 : // - und Start-Action gerufen
2474 :
2475 : OSL_ENSURE( SVPAR_WORKING==eState, "Show nicht im Working-State - Das kann ins Auge gehen" );
2476 6 : SwViewShell *pOldVSh = CallEndAction();
2477 :
2478 6 : Application::Reschedule();
2479 :
2480 18 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
2481 12 : || 1 == pDoc->getReferenceCount() )
2482 : {
2483 : // wurde der Import vom SFX abgebrochen?
2484 0 : eState = SVPAR_ERROR;
2485 : }
2486 :
2487 : // Die SwViewShell nochmal holen, denn sie koennte im Reschedule
2488 : // zerstoert wirden sein.
2489 6 : SwViewShell *pVSh = CallStartAction( pOldVSh );
2490 :
2491 : // ist der aktuelle Node nicht mehr sichtbar, dann benutzen wir
2492 : // eine groessere Schrittweite
2493 6 : if( pVSh )
2494 : {
2495 0 : nParaCnt = (pPam->GetPoint()->nNode.GetNode().IsInVisibleArea(pVSh))
2496 0 : ? 5 : 50;
2497 : }
2498 6 : }
2499 :
2500 281 : void SwHTMLParser::ShowStatline()
2501 : {
2502 : // Hier wird
2503 : // - ein Reschedule gerufen, damit gescrollt werden kann
2504 : // - die eiegen View-Shell wieder gesetzt
2505 : // - ein Start/End-Action gerufen, wenn gescrollt wurde.
2506 :
2507 : OSL_ENSURE( SVPAR_WORKING==eState, "ShowStatLine nicht im Working-State - Das kann ins Auge gehen" );
2508 :
2509 : // Laufbalkenanzeige
2510 281 : if( !GetMedium() || !GetMedium()->IsRemote() )
2511 : {
2512 281 : ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2513 281 : CheckActionViewShell();
2514 : }
2515 : else
2516 : {
2517 0 : Application::Reschedule();
2518 :
2519 0 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
2520 0 : || 1 == pDoc->getReferenceCount() )
2521 : // wurde der Import vom SFX abgebrochen?
2522 0 : eState = SVPAR_ERROR;
2523 :
2524 0 : SwViewShell *pVSh = CheckActionViewShell();
2525 0 : if( pVSh && pVSh->HasInvalidRect() )
2526 : {
2527 0 : CallEndAction( false, false );
2528 0 : CallStartAction( pVSh, false );
2529 : }
2530 : }
2531 281 : }
2532 :
2533 39 : SwViewShell *SwHTMLParser::CallStartAction( SwViewShell *pVSh, bool bChkPtr )
2534 : {
2535 : OSL_ENSURE( !pActionViewShell, "CallStartAction: SwViewShell schon gesetzt" );
2536 :
2537 39 : if( !pVSh || bChkPtr )
2538 : {
2539 : #if OSL_DEBUG_LEVEL > 0
2540 : SwViewShell *pOldVSh = pVSh;
2541 : #endif
2542 39 : pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2543 : #if OSL_DEBUG_LEVEL > 0
2544 : OSL_ENSURE( !pVSh || !pOldVSh || pOldVSh == pVSh, "CallStartAction: Wer hat die SwViewShell ausgetauscht?" );
2545 : if( pOldVSh && !pVSh )
2546 : pVSh = 0;
2547 : #endif
2548 : }
2549 39 : pActionViewShell = pVSh;
2550 :
2551 39 : if( pActionViewShell )
2552 : {
2553 1 : if( pActionViewShell->ISA( SwEditShell ) )
2554 1 : static_cast<SwEditShell*>(pActionViewShell)->StartAction();
2555 : else
2556 0 : pActionViewShell->StartAction();
2557 : }
2558 :
2559 39 : return pActionViewShell;
2560 : }
2561 :
2562 38 : SwViewShell *SwHTMLParser::CallEndAction( bool bChkAction, bool bChkPtr )
2563 : {
2564 38 : if( bChkPtr )
2565 : {
2566 38 : SwViewShell *pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2567 : OSL_ENSURE( !pVSh || pActionViewShell == pVSh,
2568 : "CallEndAction: Wer hat die SwViewShell ausgetauscht?" );
2569 : #if OSL_DEBUG_LEVEL > 0
2570 : if( pActionViewShell && !pVSh )
2571 : pVSh = 0;
2572 : #endif
2573 38 : if( pVSh != pActionViewShell )
2574 0 : pActionViewShell = 0;
2575 : }
2576 :
2577 38 : if( !pActionViewShell || (bChkAction && !pActionViewShell->ActionPend()) )
2578 37 : return pActionViewShell;
2579 :
2580 1 : if( bSetCrsr )
2581 : {
2582 : // set the cursor to the doc begin in all CrsrEditShells
2583 0 : for(SwViewShell& rSh : pActionViewShell->GetRingContainer())
2584 : {
2585 0 : if( rSh.IsA( TYPE( SwCrsrShell ) ) )
2586 0 : static_cast<SwCrsrShell*>(&rSh)->SttEndDoc(true);
2587 : }
2588 :
2589 0 : bSetCrsr = false;
2590 : }
2591 1 : if( pActionViewShell->ISA( SwEditShell ) )
2592 : {
2593 : //Schon gescrollt?, dann dafuer sorgen, dass die View sich nicht bewegt!
2594 1 : const bool bOldLock = pActionViewShell->IsViewLocked();
2595 1 : pActionViewShell->LockView( true );
2596 1 : const bool bOldEndActionByVirDev = pActionViewShell->IsEndActionByVirDev();
2597 1 : pActionViewShell->SetEndActionByVirDev( true );
2598 1 : static_cast<SwEditShell*>(pActionViewShell)->EndAction();
2599 1 : pActionViewShell->SetEndActionByVirDev( bOldEndActionByVirDev );
2600 1 : pActionViewShell->LockView( bOldLock );
2601 :
2602 : // bChkJumpMark ist nur gesetzt, wenn das Object auch gefunden wurde
2603 1 : if( bChkJumpMark )
2604 : {
2605 0 : const Point aVisSttPos( DOCUMENTBORDER, DOCUMENTBORDER );
2606 0 : if( GetMedium() && aVisSttPos == pActionViewShell->VisArea().Pos() )
2607 : ::JumpToSwMark( pActionViewShell,
2608 0 : GetMedium()->GetURLObject().GetMark() );
2609 0 : bChkJumpMark = false;
2610 : }
2611 : }
2612 : else
2613 0 : pActionViewShell->EndAction();
2614 :
2615 : // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
2616 : // man hier abbrechen und einen Fehler setzen.
2617 1 : if( 1 == pDoc->getReferenceCount() )
2618 : {
2619 0 : eState = SVPAR_ERROR;
2620 : }
2621 :
2622 1 : SwViewShell *pVSh = pActionViewShell;
2623 1 : pActionViewShell = 0;
2624 :
2625 1 : return pVSh;
2626 : }
2627 :
2628 307 : SwViewShell *SwHTMLParser::CheckActionViewShell()
2629 : {
2630 307 : SwViewShell *pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2631 : OSL_ENSURE( !pVSh || pActionViewShell == pVSh,
2632 : "CheckActionViewShell: Wer hat die SwViewShell ausgetauscht?" );
2633 : #if OSL_DEBUG_LEVEL > 0
2634 : if( pActionViewShell && !pVSh )
2635 : pVSh = 0;
2636 : #endif
2637 307 : if( pVSh != pActionViewShell )
2638 0 : pActionViewShell = 0;
2639 :
2640 307 : return pActionViewShell;
2641 : }
2642 :
2643 53 : void SwHTMLParser::_SetAttr( bool bChkEnd, bool bBeforeTable,
2644 : _HTMLAttrs *pPostIts )
2645 : {
2646 53 : SwPaM* pAttrPam = new SwPaM( *pPam->GetPoint() );
2647 53 : const SwNodeIndex& rEndIdx = pPam->GetPoint()->nNode;
2648 53 : const sal_Int32 nEndCnt = pPam->GetPoint()->nContent.GetIndex();
2649 : _HTMLAttr* pAttr;
2650 : SwContentNode* pCNd;
2651 :
2652 53 : _HTMLAttrs aFields;
2653 :
2654 213 : for( auto n = aSetAttrTab.size(); n; )
2655 : {
2656 107 : pAttr = aSetAttrTab[ --n ];
2657 107 : sal_uInt16 nWhich = pAttr->pItem->Which();
2658 :
2659 107 : sal_uLong nEndParaIdx = pAttr->GetEndParaIdx();
2660 : bool bSetAttr;
2661 107 : if( bChkEnd )
2662 : {
2663 : // Zechen-Attribute mit Ende moeglich frueh,
2664 : // also noch im aktuellen Absatz setzen (wegen JavaScript
2665 : // und diversen Chats). das darf man aber nicht fuer Attribute,
2666 : // die ueber den ganzen Absatz aufgspannt werden sollen, weil
2667 : // sie aus Absatzvorlgen stammen, die nicht gesetzt werden
2668 : // koennen. Weil die Attribute mit SETATTR_DONTREPLACE
2669 : // eingefuegt werden, sollte man sie auch anchtraeglich
2670 : // noch setzen koennen.
2671 152 : bSetAttr = ( nEndParaIdx < rEndIdx.GetIndex() &&
2672 26 : (RES_LR_SPACE != nWhich || !GetNumInfo().GetNumRule()) ) ||
2673 48 : ( !pAttr->IsLikePara() &&
2674 48 : nEndParaIdx == rEndIdx.GetIndex() &&
2675 43 : pAttr->GetEndCnt() < nEndCnt &&
2676 196 : (isCHRATR(nWhich) || isTXTATR_WITHEND(nWhich)) ) ||
2677 5 : ( bBeforeTable &&
2678 10 : nEndParaIdx == rEndIdx.GetIndex() &&
2679 93 : !pAttr->GetEndCnt() );
2680 : }
2681 : else
2682 : {
2683 : // Attribiute im Content-Bereich duerfen nicht gesetzt
2684 : // werden, wenn wir in einem Sonderbereich stehen, aber
2685 : // umgekekehrt schon.
2686 19 : sal_uLong nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
2687 38 : bSetAttr = nEndParaIdx < rEndIdx.GetIndex() ||
2688 19 : rEndIdx.GetIndex() > nEndOfIcons ||
2689 19 : nEndParaIdx <= nEndOfIcons;
2690 : }
2691 :
2692 107 : if( bSetAttr )
2693 : {
2694 : // Das Attribute darf nicht in der liste der vorlaeufigen
2695 : // Absatz-Attribute stehen, weil es sonst geloescht wurde.
2696 180 : while( !aParaAttrs.empty() )
2697 : {
2698 : OSL_ENSURE( pAttr != aParaAttrs.back(),
2699 : "SetAttr: Attribut duerfte noch nicht gesetzt werden" );
2700 0 : aParaAttrs.pop_back();
2701 : }
2702 :
2703 : // dann also setzen
2704 90 : aSetAttrTab.erase( aSetAttrTab.begin() + n );
2705 :
2706 271 : while( pAttr )
2707 : {
2708 91 : _HTMLAttr *pPrev = pAttr->GetPrev();
2709 91 : if( !pAttr->bValid )
2710 : {
2711 : // ungueltige Attribute koennen gloescht werden
2712 0 : delete pAttr;
2713 0 : pAttr = pPrev;
2714 0 : continue;
2715 : }
2716 :
2717 91 : pCNd = pAttr->nSttPara.GetNode().GetContentNode();
2718 91 : if( !pCNd )
2719 : {
2720 : // durch die elende Loescherei von Nodes kann auch mal
2721 : // ein Index auf einen End-Node zeigen :-(
2722 0 : if ( (pAttr->GetSttPara() == pAttr->GetEndPara()) &&
2723 0 : !isTXTATR_NOEND(nWhich) )
2724 : {
2725 : // wenn der End-Index auch auf den Node zeigt
2726 : // brauchen wir auch kein Attribut mehr zu setzen,
2727 : // es sei denn, es ist ein Text-Attribut.
2728 0 : delete pAttr;
2729 0 : pAttr = pPrev;
2730 0 : continue;
2731 : }
2732 0 : pCNd = pDoc->GetNodes().GoNext( &(pAttr->nSttPara) );
2733 0 : if( pCNd )
2734 0 : pAttr->nSttContent = 0;
2735 : else
2736 : {
2737 : OSL_ENSURE( false, "SetAttr: GoNext() failed!" );
2738 0 : delete pAttr;
2739 0 : pAttr = pPrev;
2740 0 : continue;
2741 : }
2742 : }
2743 91 : pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
2744 :
2745 : // durch das Loeschen von BRs kann der Start-Index
2746 : // auch mal hinter das Ende des Textes zeigen
2747 91 : if( pAttr->nSttContent > pCNd->Len() )
2748 0 : pAttr->nSttContent = pCNd->Len();
2749 91 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttContent );
2750 :
2751 91 : pAttrPam->SetMark();
2752 91 : if ( (pAttr->GetSttPara() != pAttr->GetEndPara()) &&
2753 0 : !isTXTATR_NOEND(nWhich) )
2754 : {
2755 0 : pCNd = pAttr->nEndPara.GetNode().GetContentNode();
2756 0 : if( !pCNd )
2757 : {
2758 0 : pCNd = SwNodes::GoPrevious( &(pAttr->nEndPara) );
2759 0 : if( pCNd )
2760 0 : pAttr->nEndContent = pCNd->Len();
2761 : else
2762 : {
2763 : OSL_ENSURE( false, "SetAttr: GoPrevious() failed!" );
2764 0 : pAttrPam->DeleteMark();
2765 0 : delete pAttr;
2766 0 : pAttr = pPrev;
2767 0 : continue;
2768 : }
2769 : }
2770 :
2771 0 : pAttrPam->GetPoint()->nNode = pAttr->nEndPara;
2772 : }
2773 91 : else if( pAttr->IsLikePara() )
2774 : {
2775 1 : pAttr->nEndContent = pCNd->Len();
2776 : }
2777 :
2778 : // durch das Loeschen von BRs kann der End-Index
2779 : // auch mal hinter das Ende des Textes zeigen
2780 91 : if( pAttr->nEndContent > pCNd->Len() )
2781 0 : pAttr->nEndContent = pCNd->Len();
2782 :
2783 91 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nEndContent );
2784 96 : if( bBeforeTable &&
2785 5 : pAttrPam->GetPoint()->nNode.GetIndex() ==
2786 5 : rEndIdx.GetIndex() )
2787 : {
2788 : // wenn wir vor dem Einfuegen einer Tabelle stehen
2789 : // und das Attribut im aktuellen Node beendet wird,
2790 : // muessen wir es im Node davor beenden oder wegschmeissen,
2791 : // wenn es erst in dem Node beginnt
2792 10 : if( nWhich != RES_BREAK && nWhich != RES_PAGEDESC &&
2793 5 : !isTXTATR_NOEND(nWhich) )
2794 : {
2795 0 : if( pAttrPam->GetMark()->nNode.GetIndex() !=
2796 0 : rEndIdx.GetIndex() )
2797 : {
2798 : OSL_ENSURE( !pAttrPam->GetPoint()->nContent.GetIndex(),
2799 : "Content-Position vor Tabelle nicht 0???" );
2800 0 : pAttrPam->Move( fnMoveBackward );
2801 : }
2802 : else
2803 : {
2804 0 : pAttrPam->DeleteMark();
2805 0 : delete pAttr;
2806 0 : pAttr = pPrev;
2807 0 : continue;
2808 : }
2809 : }
2810 : }
2811 :
2812 91 : switch( nWhich )
2813 : {
2814 : case RES_FLTR_BOOKMARK: // insert bookmark
2815 : {
2816 5 : const OUString sName( static_cast<SfxStringItem*>(pAttr->pItem)->GetValue() );
2817 5 : IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
2818 5 : IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark( sName );
2819 5 : if( ppBkmk != pMarkAccess->getAllMarksEnd() &&
2820 0 : ppBkmk->get()->GetMarkStart() == *pAttrPam->GetPoint() )
2821 0 : break; // do not generate duplicates on this position
2822 5 : pAttrPam->DeleteMark();
2823 : const ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
2824 : *pAttrPam,
2825 : sName,
2826 5 : IDocumentMarkAccess::MarkType::BOOKMARK );
2827 :
2828 : // jump to bookmark
2829 5 : if( JUMPTO_MARK == eJumpTo && pNewMark->GetName() == sJmpMark )
2830 : {
2831 0 : bChkJumpMark = true;
2832 0 : eJumpTo = JUMPTO_NONE;
2833 5 : }
2834 : }
2835 5 : break;
2836 : case RES_TXTATR_FIELD:
2837 : case RES_TXTATR_ANNOTATION:
2838 : case RES_TXTATR_INPUTFIELD:
2839 : {
2840 : sal_uInt16 nFieldWhich =
2841 : pPostIts
2842 5 : ? static_cast<const SwFormatField *>(pAttr->pItem)->GetField()->GetTyp()->Which()
2843 26 : : 0;
2844 21 : if( pPostIts && (RES_POSTITFLD == nFieldWhich ||
2845 : RES_SCRIPTFLD == nFieldWhich) )
2846 : {
2847 5 : pPostIts->push_front( pAttr );
2848 : }
2849 : else
2850 : {
2851 16 : aFields.push_back( pAttr);
2852 : }
2853 : }
2854 21 : pAttrPam->DeleteMark();
2855 21 : pAttr = pPrev;
2856 21 : continue;
2857 :
2858 : case RES_LR_SPACE:
2859 4 : if( pAttrPam->GetPoint()->nNode.GetIndex() ==
2860 2 : pAttrPam->GetMark()->nNode.GetIndex() &&
2861 : pCNd )
2862 : {
2863 : // wegen Numerierungen dieses Attribut direkt
2864 : // am Node setzen
2865 2 : pCNd->SetAttr( *pAttr->pItem );
2866 2 : break;
2867 : }
2868 : OSL_ENSURE( false,
2869 : "LRSpace ueber mehrere Absaetze gesetzt!" );
2870 : // no break (shouldn't reach this point anyway)
2871 : default:
2872 :
2873 : // ggfs. ein Bookmark anspringen
2874 66 : if( RES_TXTATR_INETFMT == nWhich &&
2875 63 : JUMPTO_MARK == eJumpTo &&
2876 0 : sJmpMark == static_cast<SwFormatINetFormat*>(pAttr->pItem)->GetName() )
2877 : {
2878 0 : bChkJumpMark = true;
2879 0 : eJumpTo = JUMPTO_NONE;
2880 : }
2881 :
2882 63 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pAttrPam, *pAttr->pItem, SetAttrMode::DONTREPLACE );
2883 : }
2884 70 : pAttrPam->DeleteMark();
2885 :
2886 70 : delete pAttr;
2887 70 : pAttr = pPrev;
2888 : }
2889 : }
2890 : }
2891 :
2892 106 : for( auto n = aMoveFlyFrms.size(); n; )
2893 : {
2894 0 : SwFrameFormat *pFrameFormat = aMoveFlyFrms[ --n ];
2895 :
2896 0 : const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
2897 : OSL_ENSURE( FLY_AT_PARA == rAnchor.GetAnchorId(),
2898 : "Nur Auto-Rahmen brauchen eine Spezialbehandlung" );
2899 0 : const SwPosition *pFlyPos = rAnchor.GetContentAnchor();
2900 0 : sal_uLong nFlyParaIdx = pFlyPos->nNode.GetIndex();
2901 : bool bMoveFly;
2902 0 : if( bChkEnd )
2903 : {
2904 0 : bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
2905 0 : ( nFlyParaIdx == rEndIdx.GetIndex() &&
2906 0 : aMoveFlyCnts[n] < nEndCnt );
2907 : }
2908 : else
2909 : {
2910 0 : sal_uLong nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
2911 0 : bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
2912 0 : rEndIdx.GetIndex() > nEndOfIcons ||
2913 0 : nFlyParaIdx <= nEndOfIcons;
2914 : }
2915 0 : if( bMoveFly )
2916 : {
2917 0 : pFrameFormat->DelFrms();
2918 0 : *pAttrPam->GetPoint() = *pFlyPos;
2919 0 : pAttrPam->GetPoint()->nContent.Assign( pAttrPam->GetContentNode(),
2920 0 : aMoveFlyCnts[n] );
2921 0 : SwFormatAnchor aAnchor( rAnchor );
2922 0 : aAnchor.SetType( FLY_AT_CHAR );
2923 0 : aAnchor.SetAnchor( pAttrPam->GetPoint() );
2924 0 : pFrameFormat->SetFormatAttr( aAnchor );
2925 :
2926 0 : const SwFormatHoriOrient& rHoriOri = pFrameFormat->GetHoriOrient();
2927 0 : if( text::HoriOrientation::LEFT == rHoriOri.GetHoriOrient() )
2928 : {
2929 0 : SwFormatHoriOrient aHoriOri( rHoriOri );
2930 0 : aHoriOri.SetRelationOrient( text::RelOrientation::CHAR );
2931 0 : pFrameFormat->SetFormatAttr( aHoriOri );
2932 : }
2933 0 : const SwFormatVertOrient& rVertOri = pFrameFormat->GetVertOrient();
2934 0 : if( text::VertOrientation::TOP == rVertOri.GetVertOrient() )
2935 : {
2936 0 : SwFormatVertOrient aVertOri( rVertOri );
2937 0 : aVertOri.SetRelationOrient( text::RelOrientation::CHAR );
2938 0 : pFrameFormat->SetFormatAttr( aVertOri );
2939 : }
2940 :
2941 0 : pFrameFormat->MakeFrms();
2942 0 : aMoveFlyFrms.erase( aMoveFlyFrms.begin() + n );
2943 0 : aMoveFlyCnts.erase( aMoveFlyCnts.begin() + n );
2944 : }
2945 : }
2946 122 : while( !aFields.empty() )
2947 : {
2948 16 : pAttr = aFields[0];
2949 :
2950 16 : pCNd = pAttr->nSttPara.GetNode().GetContentNode();
2951 16 : pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
2952 16 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttContent );
2953 :
2954 16 : if( bBeforeTable &&
2955 0 : pAttrPam->GetPoint()->nNode.GetIndex() == rEndIdx.GetIndex() )
2956 : {
2957 : OSL_ENSURE( !bBeforeTable, "Aha, der Fall tritt also doch ein" );
2958 : OSL_ENSURE( !pAttrPam->GetPoint()->nContent.GetIndex(),
2959 : "Content-Position vor Tabelle nicht 0???" );
2960 : // !!!
2961 0 : pAttrPam->Move( fnMoveBackward );
2962 : }
2963 :
2964 16 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pAttrPam, *pAttr->pItem );
2965 :
2966 16 : aFields.pop_front();
2967 16 : delete pAttr;
2968 : }
2969 :
2970 53 : delete pAttrPam;
2971 53 : }
2972 :
2973 890 : void SwHTMLParser::NewAttr( _HTMLAttr **ppAttr, const SfxPoolItem& rItem )
2974 : {
2975 : // Font-Hoehen und -Farben- sowie Escapement-Attribute duerfen nicht
2976 : // zusammengefasst werden. Sie werden deshalb in einer Liste gespeichert,
2977 : // in der das zuletzt aufgespannte Attribut vorne steht und der Count
2978 : // immer 1 ist. Fuer alle anderen Attribute wird der Count einfach
2979 : // hochgezaehlt.
2980 890 : if( *ppAttr )
2981 : {
2982 10 : _HTMLAttr *pAttr = new _HTMLAttr( *pPam->GetPoint(), rItem,
2983 10 : ppAttr );
2984 10 : pAttr->InsertNext( *ppAttr );
2985 10 : (*ppAttr) = pAttr;
2986 : }
2987 : else
2988 880 : (*ppAttr) = new _HTMLAttr( *pPam->GetPoint(), rItem, ppAttr );
2989 890 : }
2990 :
2991 890 : bool SwHTMLParser::EndAttr( _HTMLAttr* pAttr, _HTMLAttr **ppDepAttr,
2992 : bool bChkEmpty )
2993 : {
2994 890 : bool bRet = true;
2995 :
2996 : OSL_ENSURE( !ppDepAttr, "SwHTMLParser::EndAttr: ppDepAttr-Feature ungetestet?" );
2997 : // Der Listenkopf ist im Attribut gespeichert
2998 890 : _HTMLAttr **ppHead = pAttr->ppHead;
2999 :
3000 : OSL_ENSURE( ppHead, "keinen Attributs-Listenkopf gefunden!" );
3001 :
3002 : // die aktuelle Position als Ende-Position merken
3003 890 : const SwNodeIndex* pEndIdx = &pPam->GetPoint()->nNode;
3004 890 : sal_Int32 nEndCnt = pPam->GetPoint()->nContent.GetIndex();
3005 :
3006 : // WIrd das zueltzt gestartete oder ein frueher gestartetes Attribut
3007 : // beendet?
3008 890 : _HTMLAttr *pLast = 0;
3009 890 : if( ppHead && pAttr != *ppHead )
3010 : {
3011 : // Es wird nicht das zuletzt gestartete Attribut beendet
3012 :
3013 : // Dann suche wir das unmittelbar danach gestartete Attribut, das
3014 : // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
3015 : // mehr in der Liste
3016 2 : pLast = *ppHead;
3017 5 : while( pLast && pLast->GetNext() != pAttr )
3018 1 : pLast = pLast->GetNext();
3019 :
3020 : OSL_ENSURE( pLast, "Attribut nicht in eigener Liste gefunden!" );
3021 : }
3022 :
3023 890 : bool bMoveBack = false;
3024 890 : sal_uInt16 nWhich = pAttr->pItem->Which();
3025 902 : if( !nEndCnt && RES_PARATR_BEGIN <= nWhich &&
3026 12 : *pEndIdx != pAttr->GetSttPara() )
3027 : {
3028 : // dann eine Contentnt Position zurueck!
3029 10 : bMoveBack = pPam->Move( fnMoveBackward );
3030 10 : nEndCnt = pPam->GetPoint()->nContent.GetIndex();
3031 : }
3032 :
3033 : // nun das Attrubut beenden
3034 890 : _HTMLAttr *pNext = pAttr->GetNext();
3035 :
3036 : bool bInsert;
3037 890 : sal_uInt16 nScriptItem = 0;
3038 890 : bool bScript = false, bFont = false;
3039 : // ein Bereich ??
3040 2661 : if( !bChkEmpty || (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
3041 1742 : RES_PAGEDESC == nWhich || RES_BREAK == nWhich ||
3042 2632 : *pEndIdx != pAttr->GetSttPara() ||
3043 871 : nEndCnt != pAttr->GetSttCnt() )
3044 : {
3045 107 : bInsert = true;
3046 : // We do some optimization for script depenedent attribtes here.
3047 107 : if( *pEndIdx == pAttr->GetSttPara() )
3048 : {
3049 107 : lcl_swhtml_getItemInfo( *pAttr, bScript, bFont, nScriptItem );
3050 : }
3051 : }
3052 : else
3053 : {
3054 783 : bInsert = false;
3055 : }
3056 :
3057 890 : if( bInsert && bScript )
3058 : {
3059 73 : const SwTextNode *pTextNd = pAttr->GetSttPara().GetNode()
3060 73 : .GetTextNode();
3061 : OSL_ENSURE( pTextNd, "No text node" );
3062 73 : const OUString& rText = pTextNd->GetText();
3063 146 : sal_uInt16 nScriptText = g_pBreakIt->GetBreakIter()->getScriptType(
3064 73 : rText, pAttr->GetSttCnt() );
3065 : sal_Int32 nScriptEnd = g_pBreakIt->GetBreakIter()
3066 73 : ->endOfScript( rText, pAttr->GetSttCnt(), nScriptText );
3067 146 : while (nScriptEnd < nEndCnt && nScriptEnd != -1)
3068 : {
3069 0 : if( nScriptItem == nScriptText )
3070 : {
3071 0 : _HTMLAttr *pSetAttr = pAttr->Clone( *pEndIdx, nScriptEnd );
3072 0 : pSetAttr->ClearPrev();
3073 0 : if( pNext )
3074 0 : pNext->InsertPrev( pSetAttr );
3075 : else
3076 : {
3077 0 : if (pSetAttr->bInsAtStart)
3078 0 : aSetAttrTab.push_front( pSetAttr );
3079 : else
3080 0 : aSetAttrTab.push_back( pSetAttr );
3081 : }
3082 : }
3083 0 : pAttr->nSttContent = nScriptEnd;
3084 0 : nScriptText = g_pBreakIt->GetBreakIter()->getScriptType(
3085 0 : rText, nScriptEnd );
3086 : nScriptEnd = g_pBreakIt->GetBreakIter()
3087 0 : ->endOfScript( rText, nScriptEnd, nScriptText );
3088 : }
3089 73 : bInsert = nScriptItem == nScriptText;
3090 : }
3091 890 : if( bInsert )
3092 : {
3093 56 : pAttr->nEndPara = *pEndIdx;
3094 56 : pAttr->nEndContent = nEndCnt;
3095 56 : pAttr->bInsAtStart = RES_TXTATR_INETFMT != nWhich &&
3096 112 : RES_TXTATR_CHARFMT != nWhich;
3097 :
3098 56 : if( !pNext )
3099 : {
3100 : // keine offenen Attribute dieses Typs mehr da,
3101 : // dann koennen alle gesetzt werden, es sei denn
3102 : // sie haengen noch von einem anderen Attribut ab,
3103 : // dann werden sie dort angehaengt
3104 55 : if( ppDepAttr && *ppDepAttr )
3105 0 : (*ppDepAttr)->InsertPrev( pAttr );
3106 : else
3107 : {
3108 55 : if (pAttr->bInsAtStart)
3109 52 : aSetAttrTab.push_front( pAttr );
3110 : else
3111 3 : aSetAttrTab.push_back( pAttr );
3112 : }
3113 : }
3114 : else
3115 : {
3116 : // es gibt noch andere offene Attribute des Typs,
3117 : // daher muss das Setzen zurueckgestellt werden.
3118 : // das aktuelle Attribut wird deshalb hinten an die
3119 : // Previous-Liste des Nachfolgers angehaengt
3120 1 : pNext->InsertPrev( pAttr );
3121 : }
3122 : }
3123 : else
3124 : {
3125 : // dann nicht einfuegen, sondern Loeschen. Durch das "tuerken" von
3126 : // Vorlagen durch harte Attributierung koennen sich auch mal andere
3127 : // leere Attribute in der Prev-Liste befinden, die dann trotzdem
3128 : // gesetzt werden muessen
3129 834 : _HTMLAttr *pPrev = pAttr->GetPrev();
3130 834 : bRet = false;
3131 834 : delete pAttr;
3132 :
3133 834 : if( pPrev )
3134 : {
3135 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
3136 0 : if( pNext )
3137 0 : pNext->InsertPrev( pPrev );
3138 : else
3139 : {
3140 0 : if (pPrev->bInsAtStart)
3141 0 : aSetAttrTab.push_front( pPrev );
3142 : else
3143 0 : aSetAttrTab.push_back( pPrev );
3144 : }
3145 : }
3146 :
3147 : }
3148 :
3149 : // wenn das erste Attribut der Liste gesetzt wurde muss noch der
3150 : // Listenkopf korrigiert werden.
3151 890 : if( pLast )
3152 2 : pLast->pNext = pNext;
3153 888 : else if( ppHead )
3154 888 : *ppHead = pNext;
3155 :
3156 890 : if( bMoveBack )
3157 10 : pPam->Move( fnMoveForward );
3158 :
3159 890 : return bRet;
3160 : }
3161 :
3162 0 : void SwHTMLParser::DeleteAttr( _HTMLAttr* pAttr )
3163 : {
3164 : // preliminary paragraph attributes are not allowed here, they could
3165 : // be set here and then the pointers become invalid!
3166 : OSL_ENSURE(aParaAttrs.empty(),
3167 : "Danger: there are non-final paragraph attributes");
3168 0 : if( !aParaAttrs.empty() )
3169 0 : aParaAttrs.clear();
3170 :
3171 : // Der Listenkopf ist im Attribut gespeichert
3172 0 : _HTMLAttr **ppHead = pAttr->ppHead;
3173 :
3174 : OSL_ENSURE( ppHead, "keinen Attributs-Listenkopf gefunden!" );
3175 :
3176 : // Wird das zueltzt gestartete oder ein frueher gestartetes Attribut
3177 : // entfernt?
3178 0 : _HTMLAttr *pLast = 0;
3179 0 : if( ppHead && pAttr != *ppHead )
3180 : {
3181 : // Es wird nicht das zuletzt gestartete Attribut beendet
3182 :
3183 : // Dann suche wir das unmittelbar danach gestartete Attribut, das
3184 : // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
3185 : // mehr in der Liste
3186 0 : pLast = *ppHead;
3187 0 : while( pLast && pLast->GetNext() != pAttr )
3188 0 : pLast = pLast->GetNext();
3189 :
3190 : OSL_ENSURE( pLast, "Attribut nicht in eigener Liste gefunden!" );
3191 : }
3192 :
3193 : // nun das Attrubut entfernen
3194 0 : _HTMLAttr *pNext = pAttr->GetNext();
3195 0 : _HTMLAttr *pPrev = pAttr->GetPrev();
3196 0 : delete pAttr;
3197 :
3198 0 : if( pPrev )
3199 : {
3200 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
3201 0 : if( pNext )
3202 0 : pNext->InsertPrev( pPrev );
3203 : else
3204 : {
3205 0 : if (pPrev->bInsAtStart)
3206 0 : aSetAttrTab.push_front( pPrev );
3207 : else
3208 0 : aSetAttrTab.push_back( pPrev );
3209 : }
3210 : }
3211 :
3212 : // wenn das erste Attribut der Liste entfernt wurde muss noch der
3213 : // Listenkopf korrigiert werden.
3214 0 : if( pLast )
3215 0 : pLast->pNext = pNext;
3216 0 : else if( ppHead )
3217 0 : *ppHead = pNext;
3218 0 : }
3219 :
3220 1 : void SwHTMLParser::SaveAttrTab( _HTMLAttrTable& rNewAttrTab )
3221 : {
3222 : // preliminary paragraph attributes are not allowed here, they could
3223 : // be set here and then the pointers become invalid!
3224 : OSL_ENSURE(aParaAttrs.empty(),
3225 : "Danger: there are non-final paragraph attributes");
3226 1 : if( !aParaAttrs.empty() )
3227 0 : aParaAttrs.clear();
3228 :
3229 1 : _HTMLAttr** pHTMLAttributes = reinterpret_cast<_HTMLAttr**>(&aAttrTab);
3230 1 : _HTMLAttr** pSaveAttributes = reinterpret_cast<_HTMLAttr**>(&rNewAttrTab);
3231 :
3232 41 : for (auto nCnt = sizeof(_HTMLAttrTable) / sizeof(_HTMLAttr*); nCnt--; ++pHTMLAttributes, ++pSaveAttributes)
3233 : {
3234 40 : *pSaveAttributes = *pHTMLAttributes;
3235 :
3236 40 : _HTMLAttr *pAttr = *pSaveAttributes;
3237 80 : while (pAttr)
3238 : {
3239 0 : pAttr->SetHead(pSaveAttributes);
3240 0 : pAttr = pAttr->GetNext();
3241 : }
3242 :
3243 40 : *pHTMLAttributes = 0;
3244 : }
3245 1 : }
3246 :
3247 6 : void SwHTMLParser::SplitAttrTab( _HTMLAttrTable& rNewAttrTab,
3248 : bool bMoveEndBack )
3249 : {
3250 : // preliminary paragraph attributes are not allowed here, they could
3251 : // be set here and then the pointers become invalid!
3252 : OSL_ENSURE(aParaAttrs.empty(),
3253 : "Danger: there are non-final paragraph attributes");
3254 6 : if( !aParaAttrs.empty() )
3255 0 : aParaAttrs.clear();
3256 :
3257 6 : const SwNodeIndex& nSttIdx = pPam->GetPoint()->nNode;
3258 6 : SwNodeIndex nEndIdx( nSttIdx );
3259 :
3260 : // alle noch offenen Attribute beenden und hinter der Tabelle
3261 : // neu aufspannen
3262 6 : _HTMLAttr** pHTMLAttributes = reinterpret_cast<_HTMLAttr**>(&aAttrTab);
3263 6 : _HTMLAttr** pSaveAttributes = reinterpret_cast<_HTMLAttr**>(&rNewAttrTab);
3264 6 : bool bSetAttr = true;
3265 6 : const sal_Int32 nSttCnt = pPam->GetPoint()->nContent.GetIndex();
3266 6 : sal_Int32 nEndCnt = nSttCnt;
3267 :
3268 6 : if( bMoveEndBack )
3269 : {
3270 6 : sal_uLong nOldEnd = nEndIdx.GetIndex();
3271 : sal_uLong nTmpIdx;
3272 12 : if( ( nTmpIdx = pDoc->GetNodes().GetEndOfExtras().GetIndex()) >= nOldEnd ||
3273 6 : ( nTmpIdx = pDoc->GetNodes().GetEndOfAutotext().GetIndex()) >= nOldEnd )
3274 : {
3275 0 : nTmpIdx = pDoc->GetNodes().GetEndOfInserts().GetIndex();
3276 : }
3277 6 : SwContentNode* pCNd = SwNodes::GoPrevious(&nEndIdx);
3278 :
3279 : // keine Attribute setzen, wenn der PaM aus dem Content-Bereich
3280 : // herausgeschoben wurde.
3281 6 : bSetAttr = pCNd && nTmpIdx < nEndIdx.GetIndex();
3282 :
3283 6 : nEndCnt = (bSetAttr ? pCNd->Len() : 0);
3284 : }
3285 246 : for (auto nCnt = sizeof(_HTMLAttrTable) / sizeof(_HTMLAttr*); nCnt--; (++pHTMLAttributes, ++pSaveAttributes))
3286 : {
3287 240 : _HTMLAttr *pAttr = *pHTMLAttributes;
3288 240 : *pSaveAttributes = 0;
3289 480 : while( pAttr )
3290 : {
3291 0 : _HTMLAttr *pNext = pAttr->GetNext();
3292 0 : _HTMLAttr *pPrev = pAttr->GetPrev();
3293 :
3294 0 : if( bSetAttr &&
3295 0 : ( pAttr->GetSttParaIdx() < nEndIdx.GetIndex() ||
3296 0 : (pAttr->GetSttPara() == nEndIdx &&
3297 0 : pAttr->GetSttCnt() != nEndCnt) ) )
3298 : {
3299 : // das Attribut muss vor der Liste gesetzt werden. Da wir
3300 : // das Original noch brauchen, weil Zeiger auf das Attribut
3301 : // noch in den Kontexten existieren, muessen wir es clonen.
3302 : // Die Next-Liste geht dabei verloren, aber die
3303 : // Previous-Liste bleibt erhalten
3304 0 : _HTMLAttr *pSetAttr = pAttr->Clone( nEndIdx, nEndCnt );
3305 :
3306 0 : if( pNext )
3307 0 : pNext->InsertPrev( pSetAttr );
3308 : else
3309 : {
3310 0 : if (pSetAttr->bInsAtStart)
3311 0 : aSetAttrTab.push_front( pSetAttr );
3312 : else
3313 0 : aSetAttrTab.push_back( pSetAttr );
3314 : }
3315 : }
3316 0 : else if( pPrev )
3317 : {
3318 : // Wenn das Attribut nicht gesetzt vor der Tabelle
3319 : // gesetzt werden muss, muessen der Previous-Attribute
3320 : // trotzdem gesetzt werden.
3321 0 : if( pNext )
3322 0 : pNext->InsertPrev( pPrev );
3323 : else
3324 : {
3325 0 : if (pPrev->bInsAtStart)
3326 0 : aSetAttrTab.push_front( pPrev );
3327 : else
3328 0 : aSetAttrTab.push_back( pPrev );
3329 : }
3330 : }
3331 :
3332 : // den Start des Attributs neu setzen und die Verkettungen
3333 : // aufbrechen
3334 0 : pAttr->Reset(nSttIdx, nSttCnt, pSaveAttributes);
3335 :
3336 0 : if (*pSaveAttributes)
3337 : {
3338 0 : _HTMLAttr *pSAttr = *pSaveAttributes;
3339 0 : while( pSAttr->GetNext() )
3340 0 : pSAttr = pSAttr->GetNext();
3341 0 : pSAttr->InsertNext( pAttr );
3342 : }
3343 : else
3344 0 : *pSaveAttributes = pAttr;
3345 :
3346 0 : pAttr = pNext;
3347 : }
3348 :
3349 240 : *pHTMLAttributes = 0;
3350 6 : }
3351 6 : }
3352 :
3353 7 : void SwHTMLParser::RestoreAttrTab( _HTMLAttrTable& rNewAttrTab,
3354 : bool bSetNewStart )
3355 : {
3356 : // preliminary paragraph attributes are not allowed here, they could
3357 : // be set here and then the pointers become invalid!
3358 : OSL_ENSURE(aParaAttrs.empty(),
3359 : "Danger: there are non-final paragraph attributes");
3360 7 : if( !aParaAttrs.empty() )
3361 0 : aParaAttrs.clear();
3362 :
3363 7 : _HTMLAttr** pHTMLAttributes = reinterpret_cast<_HTMLAttr**>(&aAttrTab);
3364 7 : _HTMLAttr** pSaveAttributes = reinterpret_cast<_HTMLAttr**>(&rNewAttrTab);
3365 :
3366 287 : for (auto nCnt = sizeof(_HTMLAttrTable) / sizeof(_HTMLAttr*); nCnt--; ++pHTMLAttributes, ++pSaveAttributes)
3367 : {
3368 : OSL_ENSURE(!*pHTMLAttributes, "Die Attribut-Tabelle ist nicht leer!");
3369 :
3370 280 : const SwPosition *pPos = pPam->GetPoint();
3371 280 : const SwNodeIndex& rSttPara = pPos->nNode;
3372 280 : const sal_Int32 nSttCnt = pPos->nContent.GetIndex();
3373 :
3374 280 : *pHTMLAttributes = *pSaveAttributes;
3375 :
3376 280 : _HTMLAttr *pAttr = *pHTMLAttributes;
3377 560 : while (pAttr)
3378 : {
3379 : OSL_ENSURE( !pAttr->GetPrev() || !pAttr->GetPrev()->ppHead,
3380 : "Previous-Attribut hat noch einen Header" );
3381 0 : pAttr->SetHead(pHTMLAttributes);
3382 0 : if( bSetNewStart )
3383 : {
3384 0 : pAttr->nSttPara = rSttPara;
3385 0 : pAttr->nEndPara = rSttPara;
3386 0 : pAttr->nSttContent = nSttCnt;
3387 0 : pAttr->nEndContent = nSttCnt;
3388 : }
3389 0 : pAttr = pAttr->GetNext();
3390 : }
3391 :
3392 280 : *pSaveAttributes = 0;
3393 : }
3394 7 : }
3395 :
3396 21 : void SwHTMLParser::InsertAttr( const SfxPoolItem& rItem, bool bLikePara,
3397 : bool bInsAtStart )
3398 : {
3399 21 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
3400 21 : rItem );
3401 21 : if( bLikePara )
3402 0 : pTmp->SetLikePara();
3403 21 : if (bInsAtStart)
3404 0 : aSetAttrTab.push_front( pTmp );
3405 : else
3406 21 : aSetAttrTab.push_back( pTmp );
3407 21 : }
3408 :
3409 9 : void SwHTMLParser::InsertAttrs( _HTMLAttrs& rAttrs )
3410 : {
3411 23 : while( !rAttrs.empty() )
3412 : {
3413 5 : _HTMLAttr *pAttr = rAttrs.front();
3414 5 : InsertAttr( pAttr->GetItem() );
3415 5 : rAttrs.pop_front();
3416 5 : delete pAttr;
3417 : }
3418 9 : }
3419 :
3420 6 : void SwHTMLParser::NewStdAttr( int nToken )
3421 : {
3422 12 : OUString aId, aStyle, aLang, aDir;
3423 12 : OUString aClass;
3424 :
3425 6 : const HTMLOptions& rHTMLOptions = GetOptions();
3426 18 : for (size_t i = rHTMLOptions.size(); i; )
3427 : {
3428 6 : const HTMLOption& rOption = rHTMLOptions[--i];
3429 6 : switch( rOption.GetToken() )
3430 : {
3431 : case HTML_O_ID:
3432 0 : aId = rOption.GetString();
3433 0 : break;
3434 : case HTML_O_STYLE:
3435 6 : aStyle = rOption.GetString();
3436 6 : break;
3437 : case HTML_O_CLASS:
3438 0 : aClass = rOption.GetString();
3439 0 : break;
3440 : case HTML_O_LANG:
3441 0 : aLang = rOption.GetString();
3442 0 : break;
3443 : case HTML_O_DIR:
3444 0 : aDir = rOption.GetString();
3445 0 : break;
3446 : }
3447 : }
3448 :
3449 : // einen neuen Kontext anlegen
3450 6 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3451 :
3452 : // Styles parsen
3453 6 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3454 : {
3455 6 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3456 12 : SvxCSS1PropertyInfo aPropInfo;
3457 :
3458 6 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3459 : {
3460 6 : if( HTML_SPAN_ON != nToken || aClass.isEmpty() ||
3461 0 : !CreateContainer( aClass, aItemSet, aPropInfo, pCntxt ) )
3462 6 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3463 6 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3464 6 : }
3465 : }
3466 :
3467 : // den Kontext merken
3468 12 : PushContext( pCntxt );
3469 6 : }
3470 :
3471 5 : void SwHTMLParser::NewStdAttr( int nToken,
3472 : _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
3473 : _HTMLAttr **ppAttr2, const SfxPoolItem *pItem2,
3474 : _HTMLAttr **ppAttr3, const SfxPoolItem *pItem3 )
3475 : {
3476 10 : OUString aId, aStyle, aClass, aLang, aDir;
3477 :
3478 5 : const HTMLOptions& rHTMLOptions = GetOptions();
3479 10 : for (size_t i = rHTMLOptions.size(); i; )
3480 : {
3481 0 : const HTMLOption& rOption = rHTMLOptions[--i];
3482 0 : switch( rOption.GetToken() )
3483 : {
3484 : case HTML_O_ID:
3485 0 : aId = rOption.GetString();
3486 0 : break;
3487 : case HTML_O_STYLE:
3488 0 : aStyle = rOption.GetString();
3489 0 : break;
3490 : case HTML_O_CLASS:
3491 0 : aClass = rOption.GetString();
3492 0 : break;
3493 : case HTML_O_LANG:
3494 0 : aLang = rOption.GetString();
3495 0 : break;
3496 : case HTML_O_DIR:
3497 0 : aDir = rOption.GetString();
3498 0 : break;
3499 : }
3500 : }
3501 :
3502 : // einen neuen Kontext anlegen
3503 5 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3504 :
3505 : // Styles parsen
3506 5 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3507 : {
3508 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3509 0 : SvxCSS1PropertyInfo aPropInfo;
3510 :
3511 0 : aItemSet.Put( rItem );
3512 0 : if( pItem2 )
3513 0 : aItemSet.Put( *pItem2 );
3514 0 : if( pItem3 )
3515 0 : aItemSet.Put( *pItem3 );
3516 :
3517 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3518 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3519 :
3520 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3521 : }
3522 : else
3523 : {
3524 5 : InsertAttr( ppAttr ,rItem, pCntxt );
3525 5 : if( pItem2 )
3526 : {
3527 : OSL_ENSURE( ppAttr2, "missing table entry for item2" );
3528 5 : InsertAttr( ppAttr2, *pItem2, pCntxt );
3529 : }
3530 5 : if( pItem3 )
3531 : {
3532 : OSL_ENSURE( ppAttr3, "missing table entry for item3" );
3533 5 : InsertAttr( ppAttr3, *pItem3, pCntxt );
3534 : }
3535 : }
3536 :
3537 : // den Kontext merken
3538 10 : PushContext( pCntxt );
3539 5 : }
3540 :
3541 29 : void SwHTMLParser::EndTag( int nToken )
3542 : {
3543 : // den Kontext holen
3544 29 : _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
3545 29 : if( pCntxt )
3546 : {
3547 : // und ggf. die Attribute beenden
3548 29 : EndContext( pCntxt );
3549 29 : delete pCntxt;
3550 : }
3551 29 : }
3552 :
3553 0 : void SwHTMLParser::NewBasefontAttr()
3554 : {
3555 0 : OUString aId, aStyle, aClass, aLang, aDir;
3556 0 : sal_uInt16 nSize = 3;
3557 :
3558 0 : const HTMLOptions& rHTMLOptions = GetOptions();
3559 0 : for (size_t i = rHTMLOptions.size(); i; )
3560 : {
3561 0 : const HTMLOption& rOption = rHTMLOptions[--i];
3562 0 : switch( rOption.GetToken() )
3563 : {
3564 : case HTML_O_SIZE:
3565 0 : nSize = (sal_uInt16)rOption.GetNumber();
3566 0 : break;
3567 : case HTML_O_ID:
3568 0 : aId = rOption.GetString();
3569 0 : break;
3570 : case HTML_O_STYLE:
3571 0 : aStyle = rOption.GetString();
3572 0 : break;
3573 : case HTML_O_CLASS:
3574 0 : aClass = rOption.GetString();
3575 0 : break;
3576 : case HTML_O_LANG:
3577 0 : aLang = rOption.GetString();
3578 0 : break;
3579 : case HTML_O_DIR:
3580 0 : aDir = rOption.GetString();
3581 0 : break;
3582 : }
3583 : }
3584 :
3585 0 : if( nSize < 1 )
3586 0 : nSize = 1;
3587 :
3588 0 : if( nSize > 7 )
3589 0 : nSize = 7;
3590 :
3591 : // einen neuen Kontext anlegen
3592 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_BASEFONT_ON );
3593 :
3594 : // Styles parsen
3595 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3596 : {
3597 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3598 0 : SvxCSS1PropertyInfo aPropInfo;
3599 :
3600 : //CJK has different defaults
3601 0 : SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
3602 0 : aItemSet.Put( aFontHeight );
3603 0 : SvxFontHeightItem aFontHeightCJK( aFontHeights[nSize-1], 100, RES_CHRATR_CJK_FONTSIZE );
3604 0 : aItemSet.Put( aFontHeightCJK );
3605 : //Complex type can contain so many types of letters,
3606 : //that it's not really worthy to bother, IMO.
3607 : //Still, I have set a default.
3608 0 : SvxFontHeightItem aFontHeightCTL( aFontHeights[nSize-1], 100, RES_CHRATR_CTL_FONTSIZE );
3609 0 : aItemSet.Put( aFontHeightCTL );
3610 :
3611 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3612 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3613 :
3614 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3615 : }
3616 : else
3617 : {
3618 0 : SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
3619 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
3620 0 : SvxFontHeightItem aFontHeightCJK( aFontHeights[nSize-1], 100, RES_CHRATR_CJK_FONTSIZE );
3621 0 : InsertAttr( &aAttrTab.pFontHeightCJK, aFontHeightCJK, pCntxt );
3622 0 : SvxFontHeightItem aFontHeightCTL( aFontHeights[nSize-1], 100, RES_CHRATR_CTL_FONTSIZE );
3623 0 : InsertAttr( &aAttrTab.pFontHeightCTL, aFontHeightCTL, pCntxt );
3624 : }
3625 :
3626 : // den Kontext merken
3627 0 : PushContext( pCntxt );
3628 :
3629 : // die Font-Size merken
3630 0 : aBaseFontStack.push_back( nSize );
3631 0 : }
3632 :
3633 0 : void SwHTMLParser::EndBasefontAttr()
3634 : {
3635 0 : EndTag( HTML_BASEFONT_ON );
3636 :
3637 : // Stack-Unterlauf in Tabellen vermeiden
3638 0 : if( aBaseFontStack.size() > nBaseFontStMin )
3639 0 : aBaseFontStack.erase( aBaseFontStack.begin() + aBaseFontStack.size() - 1 );
3640 0 : }
3641 :
3642 13 : void SwHTMLParser::NewFontAttr( int nToken )
3643 : {
3644 : sal_uInt16 nBaseSize =
3645 13 : ( aBaseFontStack.size() > nBaseFontStMin
3646 0 : ? (aBaseFontStack[aBaseFontStack.size()-1] & FONTSIZE_MASK)
3647 13 : : 3 );
3648 : sal_uInt16 nFontSize =
3649 13 : ( aFontStack.size() > nFontStMin
3650 7 : ? (aFontStack[aFontStack.size()-1] & FONTSIZE_MASK)
3651 20 : : nBaseSize );
3652 :
3653 26 : OUString aFace, aId, aStyle, aClass, aLang, aDir;
3654 13 : Color aColor;
3655 13 : sal_uLong nFontHeight = 0; // tatsaechlich einzustellende Font-Hoehe
3656 13 : sal_uInt16 nSize = 0; // Fontgroesse in Netscape-Notation (1-7)
3657 13 : bool bColor = false;
3658 :
3659 13 : const HTMLOptions& rHTMLOptions = GetOptions();
3660 44 : for (size_t i = rHTMLOptions.size(); i; )
3661 : {
3662 18 : const HTMLOption& rOption = rHTMLOptions[--i];
3663 18 : switch( rOption.GetToken() )
3664 : {
3665 : case HTML_O_SIZE:
3666 5 : if( HTML_FONT_ON==nToken && !rOption.GetString().isEmpty() )
3667 : {
3668 : sal_Int32 nSSize;
3669 10 : if( '+' == rOption.GetString()[0] ||
3670 5 : '-' == rOption.GetString()[0] )
3671 0 : nSSize = nBaseSize + rOption.GetSNumber();
3672 : else
3673 5 : nSSize = (sal_Int32)rOption.GetNumber();
3674 :
3675 5 : if( nSSize < 1 )
3676 0 : nSSize = 1;
3677 5 : else if( nSSize > 7 )
3678 0 : nSSize = 7;
3679 :
3680 5 : nSize = (sal_uInt16)nSSize;
3681 5 : nFontHeight = aFontHeights[nSize-1];
3682 : }
3683 5 : break;
3684 : case HTML_O_COLOR:
3685 7 : if( HTML_FONT_ON==nToken )
3686 : {
3687 7 : rOption.GetColor( aColor );
3688 7 : bColor = true;
3689 : }
3690 7 : break;
3691 : case HTML_O_FACE:
3692 1 : if( HTML_FONT_ON==nToken )
3693 1 : aFace = rOption.GetString();
3694 1 : break;
3695 : case HTML_O_ID:
3696 0 : aId = rOption.GetString();
3697 0 : break;
3698 : case HTML_O_STYLE:
3699 5 : aStyle = rOption.GetString();
3700 5 : break;
3701 : case HTML_O_CLASS:
3702 0 : aClass = rOption.GetString();
3703 0 : break;
3704 : case HTML_O_LANG:
3705 0 : aLang = rOption.GetString();
3706 0 : break;
3707 : case HTML_O_DIR:
3708 0 : aDir = rOption.GetString();
3709 0 : break;
3710 : }
3711 : }
3712 :
3713 13 : if( HTML_FONT_ON != nToken )
3714 : {
3715 : // HTML_BIGPRINT_ON oder HTML_SMALLPRINT_ON
3716 :
3717 : // in Ueberschriften bestimmt die aktuelle Ueberschrift
3718 : // die Font-Hoehe und nicht BASEFONT
3719 0 : sal_uInt16 nPoolId = GetCurrFormatColl()->GetPoolFormatId();
3720 0 : if( (nPoolId>=RES_POOLCOLL_HEADLINE1 &&
3721 : nPoolId<=RES_POOLCOLL_HEADLINE6) )
3722 : {
3723 : // wenn die Schriftgroesse in der Ueberschrift noch
3724 : // nicht veraendert ist, die aus der Vorlage nehmen
3725 0 : if( nFontStHeadStart==aFontStack.size() )
3726 0 : nFontSize = static_cast< sal_uInt16 >(6 - (nPoolId - RES_POOLCOLL_HEADLINE1));
3727 : }
3728 : else
3729 0 : nPoolId = 0;
3730 :
3731 0 : if( HTML_BIGPRINT_ON == nToken )
3732 0 : nSize = ( nFontSize<7 ? nFontSize+1 : 7 );
3733 : else
3734 0 : nSize = ( nFontSize>1 ? nFontSize-1 : 1 );
3735 :
3736 : // in Ueberschriften wird die neue Fonthoehe wenn moeglich aus
3737 : // den Vorlagen geholt.
3738 0 : if( nPoolId && nSize>=1 && nSize <=6 )
3739 : nFontHeight =
3740 : pCSS1Parser->GetTextCollFromPool(
3741 0 : RES_POOLCOLL_HEADLINE1+6-nSize )->GetSize().GetHeight();
3742 : else
3743 0 : nFontHeight = aFontHeights[nSize-1];
3744 : }
3745 :
3746 : OSL_ENSURE( !nSize == !nFontHeight, "HTML-Font-Size != Font-Height" );
3747 :
3748 26 : OUString aFontName, aStyleName;
3749 13 : FontFamily eFamily = FAMILY_DONTKNOW; // Family und Pitch,
3750 13 : FontPitch ePitch = PITCH_DONTKNOW; // falls nicht gefunden
3751 13 : rtl_TextEncoding eEnc = osl_getThreadTextEncoding();
3752 :
3753 13 : if( !aFace.isEmpty() && !pCSS1Parser->IsIgnoreFontFamily() )
3754 : {
3755 1 : const FontList *pFList = 0;
3756 1 : SwDocShell *pDocSh = pDoc->GetDocShell();
3757 1 : if( pDocSh )
3758 : {
3759 : const SvxFontListItem *pFListItem =
3760 1 : static_cast<const SvxFontListItem *>(pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST));
3761 1 : if( pFListItem )
3762 1 : pFList = pFListItem->GetFontList();
3763 : }
3764 :
3765 1 : bool bFound = false;
3766 1 : sal_Int32 nStrPos = 0;
3767 4 : while( nStrPos!= -1 )
3768 : {
3769 2 : OUString aFName = aFace.getToken( 0, ',', nStrPos );
3770 2 : aFName = comphelper::string::strip(aFName, ' ');
3771 2 : if( !aFName.isEmpty() )
3772 : {
3773 2 : if( !bFound && pFList )
3774 : {
3775 2 : sal_Handle hFont = pFList->GetFirstFontInfo( aFName );
3776 2 : if( 0 != hFont )
3777 : {
3778 0 : const vcl::FontInfo& rFInfo = FontList::GetFontInfo( hFont );
3779 0 : if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
3780 : {
3781 0 : bFound = true;
3782 0 : if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
3783 0 : eEnc = RTL_TEXTENCODING_SYMBOL;
3784 : }
3785 : }
3786 : }
3787 2 : if( !aFontName.isEmpty() )
3788 1 : aFontName += ";";
3789 2 : aFontName += aFName;
3790 : }
3791 2 : }
3792 : }
3793 :
3794 : // einen neuen Kontext anlegen
3795 13 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3796 :
3797 : // Styles parsen
3798 13 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3799 : {
3800 5 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3801 10 : SvxCSS1PropertyInfo aPropInfo;
3802 :
3803 5 : if( nFontHeight )
3804 : {
3805 5 : SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
3806 5 : aItemSet.Put( aFontHeight );
3807 10 : SvxFontHeightItem aFontHeightCJK( nFontHeight, 100, RES_CHRATR_CJK_FONTSIZE );
3808 5 : aItemSet.Put( aFontHeightCJK );
3809 10 : SvxFontHeightItem aFontHeightCTL( nFontHeight, 100, RES_CHRATR_CTL_FONTSIZE );
3810 10 : aItemSet.Put( aFontHeightCTL );
3811 : }
3812 5 : if( bColor )
3813 0 : aItemSet.Put( SvxColorItem(aColor, RES_CHRATR_COLOR) );
3814 5 : if( !aFontName.isEmpty() )
3815 : {
3816 0 : SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
3817 0 : aItemSet.Put( aFont );
3818 0 : SvxFontItem aFontCJK( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CJK_FONT );
3819 0 : aItemSet.Put( aFontCJK );
3820 0 : SvxFontItem aFontCTL( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CTL_FONT );
3821 0 : aItemSet.Put( aFontCTL );
3822 : }
3823 :
3824 5 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3825 5 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3826 :
3827 10 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3828 : }
3829 : else
3830 : {
3831 8 : if( nFontHeight )
3832 : {
3833 0 : SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
3834 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
3835 0 : SvxFontHeightItem aFontHeightCJK( nFontHeight, 100, RES_CHRATR_CJK_FONTSIZE );
3836 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeightCJK, pCntxt );
3837 0 : SvxFontHeightItem aFontHeightCTL( nFontHeight, 100, RES_CHRATR_CTL_FONTSIZE );
3838 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeightCTL, pCntxt );
3839 : }
3840 8 : if( bColor )
3841 7 : InsertAttr( &aAttrTab.pFontColor, SvxColorItem(aColor, RES_CHRATR_COLOR), pCntxt );
3842 8 : if( !aFontName.isEmpty() )
3843 : {
3844 1 : SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
3845 1 : InsertAttr( &aAttrTab.pFont, aFont, pCntxt );
3846 2 : SvxFontItem aFontCJK( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CJK_FONT );
3847 1 : InsertAttr( &aAttrTab.pFont, aFontCJK, pCntxt );
3848 2 : SvxFontItem aFontCTL( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CTL_FONT );
3849 2 : InsertAttr( &aAttrTab.pFont, aFontCTL, pCntxt );
3850 : }
3851 : }
3852 :
3853 : // den Kontext merken
3854 13 : PushContext( pCntxt );
3855 :
3856 39 : aFontStack.push_back( nSize );
3857 13 : }
3858 :
3859 13 : void SwHTMLParser::EndFontAttr( int nToken )
3860 : {
3861 13 : EndTag( nToken );
3862 :
3863 : // Stack-Unterlauf in Tabellen vermeiden
3864 13 : if( aFontStack.size() > nFontStMin )
3865 13 : aFontStack.erase( aFontStack.begin() + aFontStack.size() - 1 );
3866 13 : }
3867 :
3868 280 : void SwHTMLParser::NewPara()
3869 : {
3870 280 : if( pPam->GetPoint()->nContent.GetIndex() )
3871 1 : AppendTextNode( AM_SPACE );
3872 : else
3873 279 : AddParSpace();
3874 :
3875 280 : eParaAdjust = SVX_ADJUST_END;
3876 560 : OUString aId, aStyle, aClass, aLang, aDir;
3877 :
3878 280 : const HTMLOptions& rHTMLOptions = GetOptions();
3879 878 : for (size_t i = rHTMLOptions.size(); i; )
3880 : {
3881 318 : const HTMLOption& rOption = rHTMLOptions[--i];
3882 318 : switch( rOption.GetToken() )
3883 : {
3884 : case HTML_O_ID:
3885 0 : aId = rOption.GetString();
3886 0 : break;
3887 : case HTML_O_ALIGN:
3888 0 : eParaAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
3889 0 : break;
3890 : case HTML_O_STYLE:
3891 7 : aStyle = rOption.GetString();
3892 7 : break;
3893 : case HTML_O_CLASS:
3894 55 : aClass = rOption.GetString();
3895 55 : break;
3896 : case HTML_O_LANG:
3897 256 : aLang = rOption.GetString();
3898 256 : break;
3899 : case HTML_O_DIR:
3900 0 : aDir = rOption.GetString();
3901 0 : break;
3902 : }
3903 : }
3904 :
3905 : // einen neuen Kontext anlegen
3906 : _HTMLAttrContext *pCntxt =
3907 280 : !aClass.isEmpty() ? new _HTMLAttrContext( HTML_PARABREAK_ON,
3908 55 : RES_POOLCOLL_TEXT, aClass )
3909 335 : : new _HTMLAttrContext( HTML_PARABREAK_ON );
3910 :
3911 : // Styles parsen (Class nicht beruecksichtigen. Das geht nur, solange
3912 : // keine der CSS1-Properties der Klasse hart formatiert werden muss!!!)
3913 280 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
3914 : {
3915 260 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3916 520 : SvxCSS1PropertyInfo aPropInfo;
3917 :
3918 260 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
3919 : {
3920 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
3921 : "Class wird nicht beruecksichtigt" );
3922 260 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3923 260 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
3924 260 : }
3925 : }
3926 :
3927 280 : if( SVX_ADJUST_END != eParaAdjust )
3928 0 : InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
3929 :
3930 : // und auf den Stack packen
3931 280 : PushContext( pCntxt );
3932 :
3933 : // die aktuelle Vorlage oder deren Attribute setzen
3934 280 : SetTextCollAttrs( !aClass.isEmpty() ? pCntxt : 0 );
3935 :
3936 : // Laufbalkenanzeige
3937 280 : ShowStatline();
3938 :
3939 : OSL_ENSURE( !nOpenParaToken, "Jetzt geht ein offenes Absatz-Element verloren" );
3940 560 : nOpenParaToken = HTML_PARABREAK_ON;
3941 280 : }
3942 :
3943 280 : void SwHTMLParser::EndPara( bool bReal )
3944 : {
3945 280 : if( HTML_LI_ON==nOpenParaToken && pTable )
3946 : {
3947 : #if OSL_DEBUG_LEVEL > 0
3948 : const SwNumRule *pNumRule = pPam->GetNode().GetTextNode()->GetNumRule();
3949 : OSL_ENSURE( pNumRule, "Wo ist die Numrule geblieben" );
3950 : #endif
3951 : }
3952 :
3953 : // leere Absaetze werden von Netscape uebersprungen, von uns jetzt auch
3954 280 : if( bReal )
3955 : {
3956 280 : if( pPam->GetPoint()->nContent.GetIndex() )
3957 280 : AppendTextNode( AM_SPACE );
3958 : else
3959 0 : AddParSpace();
3960 : }
3961 :
3962 : // wenn ein DD oder DT offen war, handelt es sich um eine
3963 : // implizite Def-Liste, die jetzt beendet werden muss
3964 280 : if( (nOpenParaToken==HTML_DT_ON || nOpenParaToken==HTML_DD_ON) &&
3965 : nDefListDeep)
3966 : {
3967 0 : nDefListDeep--;
3968 : }
3969 :
3970 : // den Kontext vom Stack holen. Er kann auch von einer implizit
3971 : // geoeffneten Definitionsliste kommen
3972 : _HTMLAttrContext *pCntxt =
3973 : PopContext( static_cast< sal_uInt16 >(nOpenParaToken ? (nOpenParaToken & ~1)
3974 280 : : HTML_PARABREAK_ON) );
3975 :
3976 : // Attribute beenden
3977 280 : if( pCntxt )
3978 : {
3979 280 : EndContext( pCntxt );
3980 280 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
3981 280 : delete pCntxt;
3982 : }
3983 :
3984 : // und die bisherige Vorlage neu setzen
3985 280 : if( bReal )
3986 280 : SetTextCollAttrs();
3987 :
3988 280 : nOpenParaToken = 0;
3989 280 : }
3990 :
3991 1 : void SwHTMLParser::NewHeading( int nToken )
3992 : {
3993 1 : eParaAdjust = SVX_ADJUST_END;
3994 :
3995 2 : OUString aId, aStyle, aClass, aLang, aDir;
3996 :
3997 1 : const HTMLOptions& rHTMLOptions = GetOptions();
3998 4 : for (size_t i = rHTMLOptions.size(); i; )
3999 : {
4000 2 : const HTMLOption& rOption = rHTMLOptions[--i];
4001 2 : switch( rOption.GetToken() )
4002 : {
4003 : case HTML_O_ID:
4004 1 : aId = rOption.GetString();
4005 1 : break;
4006 : case HTML_O_ALIGN:
4007 0 : eParaAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
4008 0 : break;
4009 : case HTML_O_STYLE:
4010 1 : aStyle = rOption.GetString();
4011 1 : break;
4012 : case HTML_O_CLASS:
4013 0 : aClass = rOption.GetString();
4014 0 : break;
4015 : case HTML_O_LANG:
4016 0 : aLang = rOption.GetString();
4017 0 : break;
4018 : case HTML_O_DIR:
4019 0 : aDir = rOption.GetString();
4020 0 : break;
4021 : }
4022 : }
4023 :
4024 : // einen neuen Absatz aufmachen
4025 1 : if( pPam->GetPoint()->nContent.GetIndex() )
4026 1 : AppendTextNode( AM_SPACE );
4027 : else
4028 0 : AddParSpace();
4029 :
4030 : // die passende Vorlage suchen
4031 : sal_uInt16 nTextColl;
4032 1 : switch( nToken )
4033 : {
4034 1 : case HTML_HEAD1_ON: nTextColl = RES_POOLCOLL_HEADLINE1; break;
4035 0 : case HTML_HEAD2_ON: nTextColl = RES_POOLCOLL_HEADLINE2; break;
4036 0 : case HTML_HEAD3_ON: nTextColl = RES_POOLCOLL_HEADLINE3; break;
4037 0 : case HTML_HEAD4_ON: nTextColl = RES_POOLCOLL_HEADLINE4; break;
4038 0 : case HTML_HEAD5_ON: nTextColl = RES_POOLCOLL_HEADLINE5; break;
4039 0 : case HTML_HEAD6_ON: nTextColl = RES_POOLCOLL_HEADLINE6; break;
4040 0 : default: nTextColl = RES_POOLCOLL_STANDARD; break;
4041 : }
4042 :
4043 : // den Kontext anlegen
4044 1 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nTextColl, aClass );
4045 :
4046 : // Styles parsen (zu Class siehe auch NewPara)
4047 1 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4048 : {
4049 1 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4050 2 : SvxCSS1PropertyInfo aPropInfo;
4051 :
4052 1 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4053 : {
4054 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4055 : "Class wird nicht beruecksichtigt" );
4056 1 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4057 1 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4058 1 : }
4059 : }
4060 :
4061 1 : if( SVX_ADJUST_END != eParaAdjust )
4062 0 : InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
4063 :
4064 : // udn auf den Stack packen
4065 1 : PushContext( pCntxt );
4066 :
4067 : // und die Vorlage oder deren Attribute setzen
4068 1 : SetTextCollAttrs( pCntxt );
4069 :
4070 1 : nFontStHeadStart = aFontStack.size();
4071 :
4072 : // Laufbalkenanzeige
4073 2 : ShowStatline();
4074 1 : }
4075 :
4076 1 : void SwHTMLParser::EndHeading()
4077 : {
4078 : // einen neuen Absatz aufmachen
4079 1 : if( pPam->GetPoint()->nContent.GetIndex() )
4080 0 : AppendTextNode( AM_SPACE );
4081 : else
4082 1 : AddParSpace();
4083 :
4084 : // Kontext zu dem Token suchen und vom Stack holen
4085 1 : _HTMLAttrContext *pCntxt = 0;
4086 1 : auto nPos = aContexts.size();
4087 3 : while( !pCntxt && nPos>nContextStMin )
4088 : {
4089 1 : switch( aContexts[--nPos]->GetToken() )
4090 : {
4091 : case HTML_HEAD1_ON:
4092 : case HTML_HEAD2_ON:
4093 : case HTML_HEAD3_ON:
4094 : case HTML_HEAD4_ON:
4095 : case HTML_HEAD5_ON:
4096 : case HTML_HEAD6_ON:
4097 1 : pCntxt = aContexts[nPos];
4098 1 : aContexts.erase( aContexts.begin() + nPos );
4099 1 : break;
4100 : }
4101 : }
4102 :
4103 : // und noch Attribute beenden
4104 1 : if( pCntxt )
4105 : {
4106 1 : EndContext( pCntxt );
4107 1 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4108 1 : delete pCntxt;
4109 : }
4110 :
4111 : // die bisherige Vorlage neu setzen
4112 1 : SetTextCollAttrs();
4113 :
4114 1 : nFontStHeadStart = nFontStMin;
4115 1 : }
4116 :
4117 0 : void SwHTMLParser::NewTextFormatColl( int nToken, sal_uInt16 nColl )
4118 : {
4119 0 : OUString aId, aStyle, aClass, aLang, aDir;
4120 :
4121 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4122 0 : for (size_t i = rHTMLOptions.size(); i; )
4123 : {
4124 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4125 0 : switch( rOption.GetToken() )
4126 : {
4127 : case HTML_O_ID:
4128 0 : aId = rOption.GetString();
4129 0 : break;
4130 : case HTML_O_STYLE:
4131 0 : aStyle = rOption.GetString();
4132 0 : break;
4133 : case HTML_O_CLASS:
4134 0 : aClass = rOption.GetString();
4135 0 : break;
4136 : case HTML_O_LANG:
4137 0 : aLang = rOption.GetString();
4138 0 : break;
4139 : case HTML_O_DIR:
4140 0 : aDir = rOption.GetString();
4141 0 : break;
4142 : }
4143 : }
4144 :
4145 : // einen neuen Absatz aufmachen
4146 0 : SwHTMLAppendMode eMode = AM_NORMAL;
4147 0 : switch( nToken )
4148 : {
4149 : case HTML_LISTING_ON:
4150 : case HTML_XMP_ON:
4151 : // Diese beiden Tags werden jetzt auf die PRE-Vorlage gemappt.
4152 : // Fuer dem Fall, dass ein CLASS angegeben ist, loeschen wir
4153 : // es damit wir nicht die CLASS der PRE-Vorlage bekommen.
4154 0 : aClass = aEmptyOUStr;
4155 : // fall-through
4156 : case HTML_BLOCKQUOTE_ON:
4157 : case HTML_BLOCKQUOTE30_ON:
4158 : case HTML_PREFORMTXT_ON:
4159 0 : eMode = AM_SPACE;
4160 0 : break;
4161 : case HTML_ADDRESS_ON:
4162 0 : eMode = AM_NOSPACE; // ADDRESS kann auf einen <P> ohne </P> folgen
4163 0 : break;
4164 : case HTML_DT_ON:
4165 : case HTML_DD_ON:
4166 0 : eMode = AM_SOFTNOSPACE;
4167 0 : break;
4168 : default:
4169 : OSL_ENSURE( false, "unbekannte Vorlage" );
4170 0 : break;
4171 : }
4172 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4173 0 : AppendTextNode( eMode );
4174 0 : else if( AM_SPACE==eMode )
4175 0 : AddParSpace();
4176 :
4177 : // ... und in einem Kontext merken
4178 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nColl, aClass );
4179 :
4180 : // Styles parsen (zu Class siehe auch NewPara)
4181 0 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4182 : {
4183 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4184 0 : SvxCSS1PropertyInfo aPropInfo;
4185 :
4186 0 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4187 : {
4188 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4189 : "Class wird nicht beruecksichtigt" );
4190 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4191 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4192 0 : }
4193 : }
4194 :
4195 0 : PushContext( pCntxt );
4196 :
4197 : // die neue Vorlage setzen
4198 0 : SetTextCollAttrs( pCntxt );
4199 :
4200 : // Laufbalkenanzeige aktualisieren
4201 0 : ShowStatline();
4202 0 : }
4203 :
4204 0 : void SwHTMLParser::EndTextFormatColl( int nToken )
4205 : {
4206 0 : SwHTMLAppendMode eMode = AM_NORMAL;
4207 0 : switch( nToken & ~1 )
4208 : {
4209 : case HTML_BLOCKQUOTE_ON:
4210 : case HTML_BLOCKQUOTE30_ON:
4211 : case HTML_PREFORMTXT_ON:
4212 : case HTML_LISTING_ON:
4213 : case HTML_XMP_ON:
4214 0 : eMode = AM_SPACE;
4215 0 : break;
4216 : case HTML_ADDRESS_ON:
4217 : case HTML_DT_ON:
4218 : case HTML_DD_ON:
4219 0 : eMode = AM_SOFTNOSPACE;
4220 0 : break;
4221 : default:
4222 : OSL_ENSURE( false, "unbekannte Vorlage" );
4223 0 : break;
4224 : }
4225 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4226 0 : AppendTextNode( eMode );
4227 0 : else if( AM_SPACE==eMode )
4228 0 : AddParSpace();
4229 :
4230 : // den aktuellen Kontext vom Stack holen
4231 0 : _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
4232 :
4233 : // und noch Attribute beenden
4234 0 : if( pCntxt )
4235 : {
4236 0 : EndContext( pCntxt );
4237 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4238 0 : delete pCntxt;
4239 : }
4240 :
4241 : // und die bisherige Vorlage setzen
4242 0 : SetTextCollAttrs();
4243 0 : }
4244 :
4245 0 : void SwHTMLParser::NewDefList()
4246 : {
4247 0 : OUString aId, aStyle, aClass, aLang, aDir;
4248 :
4249 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4250 0 : for (size_t i = rHTMLOptions.size(); i; )
4251 : {
4252 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4253 0 : switch( rOption.GetToken() )
4254 : {
4255 : case HTML_O_ID:
4256 0 : aId = rOption.GetString();
4257 0 : break;
4258 : case HTML_O_STYLE:
4259 0 : aStyle = rOption.GetString();
4260 0 : break;
4261 : case HTML_O_CLASS:
4262 0 : aClass = rOption.GetString();
4263 0 : break;
4264 : case HTML_O_LANG:
4265 0 : aLang = rOption.GetString();
4266 0 : break;
4267 : case HTML_O_DIR:
4268 0 : aDir = rOption.GetString();
4269 0 : break;
4270 : }
4271 : }
4272 :
4273 : // einen neuen Absatz aufmachen
4274 0 : bool bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 0;
4275 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4276 0 : AppendTextNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
4277 0 : else if( bSpace )
4278 0 : AddParSpace();
4279 :
4280 : // ein Level mehr
4281 0 : nDefListDeep++;
4282 :
4283 0 : bool bInDD = false, bNotInDD = false;
4284 0 : auto nPos = aContexts.size();
4285 0 : while( !bInDD && !bNotInDD && nPos>nContextStMin )
4286 : {
4287 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4288 0 : switch( nCntxtToken )
4289 : {
4290 : case HTML_DEFLIST_ON:
4291 : case HTML_DIRLIST_ON:
4292 : case HTML_MENULIST_ON:
4293 : case HTML_ORDERLIST_ON:
4294 : case HTML_UNORDERLIST_ON:
4295 0 : bNotInDD = true;
4296 0 : break;
4297 : case HTML_DD_ON:
4298 0 : bInDD = true;
4299 0 : break;
4300 : }
4301 : }
4302 :
4303 : // ... und in einem Kontext merken
4304 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_DEFLIST_ON );
4305 :
4306 : // darin auch die Raender merken
4307 0 : sal_uInt16 nLeft=0, nRight=0;
4308 0 : short nIndent=0;
4309 0 : GetMarginsFromContext( nLeft, nRight, nIndent );
4310 :
4311 : // Die Einrueckung, die sich schon aus einem DL-ergibt, entspricht der
4312 : // eines DT auf dem aktuellen Level, und die entspricht der eines
4313 : // DD auf dem Level davor. Fue einen Level >=2 muss also ein DD-Abstand
4314 : // hinzugefuegt werden
4315 0 : if( !bInDD && nDefListDeep > 1 )
4316 : {
4317 :
4318 : // und den der DT-Vorlage des aktuellen Levels
4319 : SvxLRSpaceItem rLRSpace =
4320 0 : pCSS1Parser->GetTextFormatColl( RES_POOLCOLL_HTML_DD, aEmptyOUStr )
4321 0 : ->GetLRSpace();
4322 0 : nLeft = nLeft + static_cast< sal_uInt16 >(rLRSpace.GetTextLeft());
4323 : }
4324 :
4325 0 : pCntxt->SetMargins( nLeft, nRight, nIndent );
4326 :
4327 : // Styles parsen
4328 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
4329 : {
4330 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4331 0 : SvxCSS1PropertyInfo aPropInfo;
4332 :
4333 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
4334 : {
4335 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4336 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4337 0 : }
4338 : }
4339 :
4340 0 : PushContext( pCntxt );
4341 :
4342 : // die Attribute der neuen Vorlage setzen
4343 0 : if( nDefListDeep > 1 )
4344 0 : SetTextCollAttrs( pCntxt );
4345 0 : }
4346 :
4347 0 : void SwHTMLParser::EndDefList()
4348 : {
4349 0 : bool bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 1;
4350 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4351 0 : AppendTextNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
4352 0 : else if( bSpace )
4353 0 : AddParSpace();
4354 :
4355 : // ein Level weniger
4356 0 : if( nDefListDeep > 0 )
4357 0 : nDefListDeep--;
4358 :
4359 : // den aktuellen Kontext vom Stack holen
4360 0 : _HTMLAttrContext *pCntxt = PopContext( HTML_DEFLIST_ON );
4361 :
4362 : // und noch Attribute beenden
4363 0 : if( pCntxt )
4364 : {
4365 0 : EndContext( pCntxt );
4366 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4367 0 : delete pCntxt;
4368 : }
4369 :
4370 : // und Vorlage setzen
4371 0 : SetTextCollAttrs();
4372 0 : }
4373 :
4374 0 : void SwHTMLParser::NewDefListItem( int nToken )
4375 : {
4376 : // festellen, ob das DD/DT in einer DL vorkommt
4377 0 : bool bInDefList = false, bNotInDefList = false;
4378 0 : auto nPos = aContexts.size();
4379 0 : while( !bInDefList && !bNotInDefList && nPos>nContextStMin )
4380 : {
4381 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4382 0 : switch( nCntxtToken )
4383 : {
4384 : case HTML_DEFLIST_ON:
4385 0 : bInDefList = true;
4386 0 : break;
4387 : case HTML_DIRLIST_ON:
4388 : case HTML_MENULIST_ON:
4389 : case HTML_ORDERLIST_ON:
4390 : case HTML_UNORDERLIST_ON:
4391 0 : bNotInDefList = true;
4392 0 : break;
4393 : }
4394 : }
4395 :
4396 : // wenn nicht, implizit eine neue DL aufmachen
4397 0 : if( !bInDefList )
4398 : {
4399 0 : nDefListDeep++;
4400 : OSL_ENSURE( !nOpenParaToken,
4401 : "Jetzt geht ein offenes Absatz-Element verloren" );
4402 0 : nOpenParaToken = static_cast< sal_uInt16 >(nToken);
4403 : }
4404 :
4405 : NewTextFormatColl( nToken, static_cast< sal_uInt16 >(nToken==HTML_DD_ON ? RES_POOLCOLL_HTML_DD
4406 0 : : RES_POOLCOLL_HTML_DT) );
4407 0 : }
4408 :
4409 0 : void SwHTMLParser::EndDefListItem( int nToken, bool bSetColl,
4410 : bool /*bLastPara*/ )
4411 : {
4412 : // einen neuen Absatz aufmachen
4413 0 : if( !nToken && pPam->GetPoint()->nContent.GetIndex() )
4414 0 : AppendTextNode( AM_SOFTNOSPACE );
4415 :
4416 : // Kontext zu dem Token suchen und vom Stack holen
4417 0 : nToken &= ~1;
4418 0 : _HTMLAttrContext *pCntxt = 0;
4419 0 : auto nPos = aContexts.size();
4420 0 : while( !pCntxt && nPos>nContextStMin )
4421 : {
4422 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4423 0 : switch( nCntxtToken )
4424 : {
4425 : case HTML_DD_ON:
4426 : case HTML_DT_ON:
4427 0 : if( !nToken || nToken == nCntxtToken )
4428 : {
4429 0 : pCntxt = aContexts[nPos];
4430 0 : aContexts.erase( aContexts.begin() + nPos );
4431 : }
4432 0 : break;
4433 : case HTML_DEFLIST_ON:
4434 : // keine DD/DT ausserhalb der aktuelen DefListe betrachten
4435 : case HTML_DIRLIST_ON:
4436 : case HTML_MENULIST_ON:
4437 : case HTML_ORDERLIST_ON:
4438 : case HTML_UNORDERLIST_ON:
4439 : // und auch nicht ausserhalb einer anderen Liste
4440 0 : nPos = nContextStMin;
4441 0 : break;
4442 : }
4443 : }
4444 :
4445 : // und noch Attribute beenden
4446 0 : if( pCntxt )
4447 : {
4448 0 : EndContext( pCntxt );
4449 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4450 0 : delete pCntxt;
4451 : }
4452 :
4453 : // und die bisherige Vorlage setzen
4454 0 : if( bSetColl )
4455 0 : SetTextCollAttrs();
4456 0 : }
4457 :
4458 17 : bool SwHTMLParser::HasCurrentParaFlys( bool bNoSurroundOnly,
4459 : bool bSurroundOnly ) const
4460 : {
4461 : // bNoSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4462 : // ohne Umlauf
4463 : // bSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4464 : // mit Umlauf aber keinen ohne Umlauf
4465 : // sonst: Der Absatz enthaelt irgendeinen Rahmen
4466 17 : SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
4467 :
4468 17 : const SwFrameFormats& rFrameFormatTable = *pDoc->GetSpzFrameFormats();
4469 :
4470 17 : bool bFound = false;
4471 23 : for ( size_t i=0; i<rFrameFormatTable.size(); i++ )
4472 : {
4473 6 : const SwFrameFormat *const pFormat = rFrameFormatTable[i];
4474 6 : SwFormatAnchor const*const pAnchor = &pFormat->GetAnchor();
4475 : // Ein Rahmen wurde gefunden, wenn
4476 : // - er absatzgebunden ist, und
4477 : // - im aktuellen Absatz verankert ist, und
4478 : // - jeder absatzgebunene Rahmen zaehlt, oder
4479 : // - (nur Rahmen oder umlauf zaehlen und ) der Rahmen keinen
4480 : // Umlauf besitzt
4481 6 : SwPosition const*const pAPos = pAnchor->GetContentAnchor();
4482 11 : if (pAPos &&
4483 10 : ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
4484 11 : (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
4485 0 : pAPos->nNode == rNodeIdx )
4486 : {
4487 0 : if( !(bNoSurroundOnly || bSurroundOnly) )
4488 : {
4489 0 : bFound = true;
4490 0 : break;
4491 : }
4492 : else
4493 : {
4494 : // Wenn Rahmen mit Umlauf gesucht sind,
4495 : // auch keine mit Durchlauf beachten. Dabei handelt es
4496 : // sich (noch) um HIDDEN-Controls, und denen weicht man
4497 : // besser auch nicht aus.
4498 0 : SwSurround eSurround = pFormat->GetSurround().GetSurround();
4499 0 : if( bNoSurroundOnly )
4500 : {
4501 0 : if( SURROUND_NONE==eSurround )
4502 : {
4503 0 : bFound = true;
4504 0 : break;
4505 : }
4506 : }
4507 0 : if( bSurroundOnly )
4508 : {
4509 0 : if( SURROUND_NONE==eSurround )
4510 : {
4511 0 : bFound = false;
4512 0 : break;
4513 : }
4514 0 : else if( SURROUND_THROUGHT!=eSurround )
4515 : {
4516 0 : bFound = true;
4517 : // weitersuchen: Es koennten ja noch welche ohne
4518 : // Umlauf kommen ...
4519 : }
4520 : }
4521 : }
4522 : }
4523 : }
4524 :
4525 17 : return bFound;
4526 : }
4527 :
4528 : // die speziellen Methoden zum Einfuegen von Objecten
4529 :
4530 0 : const SwFormatColl *SwHTMLParser::GetCurrFormatColl() const
4531 : {
4532 0 : const SwContentNode* pCNd = pPam->GetContentNode();
4533 0 : return &pCNd->GetAnyFormatColl();
4534 : }
4535 :
4536 568 : void SwHTMLParser::SetTextCollAttrs( _HTMLAttrContext *pContext )
4537 : {
4538 568 : SwTextFormatColl *pCollToSet = 0; // die zu setzende Vorlage
4539 568 : SfxItemSet *pItemSet = 0; // der Set fuer harte Attrs
4540 568 : sal_uInt16 nTopColl = pContext ? pContext->GetTextFormatColl() : 0;
4541 568 : const OUString& rTopClass = pContext ? pContext->GetClass() : aEmptyOUStr;
4542 568 : sal_uInt16 nDfltColl = RES_POOLCOLL_TEXT;
4543 :
4544 568 : bool bInPRE=false; // etwas Kontext Info
4545 :
4546 568 : sal_uInt16 nLeftMargin = 0, nRightMargin = 0; // die Einzuege und
4547 568 : short nFirstLineIndent = 0; // Abstaende
4548 :
4549 1405 : for( auto i = nContextStAttrMin; i < aContexts.size(); ++i )
4550 : {
4551 837 : const _HTMLAttrContext *pCntxt = aContexts[i];
4552 :
4553 837 : sal_uInt16 nColl = pCntxt->GetTextFormatColl();
4554 837 : if( nColl )
4555 : {
4556 : // Es gibt eine Vorlage, die zu setzen ist. Dann
4557 : // muss zunaechst einmal entschieden werden,
4558 : // ob die Vorlage auch gesetzt werden kann
4559 58 : bool bSetThis = true;
4560 58 : switch( nColl )
4561 : {
4562 : case RES_POOLCOLL_HTML_PRE:
4563 0 : bInPRE = true;
4564 0 : break;
4565 : case RES_POOLCOLL_TEXT:
4566 : // <TD><P CLASS=xxx> muss TD.xxx werden
4567 55 : if( nDfltColl==RES_POOLCOLL_TABLE ||
4568 : nDfltColl==RES_POOLCOLL_TABLE_HDLN )
4569 51 : nColl = nDfltColl;
4570 55 : break;
4571 : case RES_POOLCOLL_HTML_HR:
4572 : // <HR> auch in <PRE> als Vorlage setzen, sonst kann man sie
4573 : // nicht mehr exportieren
4574 0 : break;
4575 : default:
4576 3 : if( bInPRE )
4577 0 : bSetThis = false;
4578 3 : break;
4579 : }
4580 :
4581 : SwTextFormatColl *pNewColl =
4582 58 : pCSS1Parser->GetTextFormatColl( nColl, pCntxt->GetClass() );
4583 :
4584 58 : if( bSetThis )
4585 : {
4586 : // wenn jetzt eine andere Vorlage gesetzt werden soll als
4587 : // bisher, muss die bishere Vorlage durch harte Attributierung
4588 : // ersetzt werden
4589 :
4590 58 : if( pCollToSet )
4591 : {
4592 : // die Attribute, die bisherige Vorlage setzt
4593 : // hart einfuegen
4594 1 : if( !pItemSet )
4595 1 : pItemSet = new SfxItemSet( pCollToSet->GetAttrSet() );
4596 : else
4597 : {
4598 0 : const SfxItemSet& rCollSet = pCollToSet->GetAttrSet();
4599 0 : SfxItemSet aItemSet( *rCollSet.GetPool(),
4600 0 : rCollSet.GetRanges() );
4601 0 : aItemSet.Set( rCollSet );
4602 0 : pItemSet->Put( aItemSet );
4603 : }
4604 : // aber die Attribute, die aktuelle Vorlage setzt
4605 : // entfernen, weil sie sonst spaeter ueberschrieben
4606 : // werden
4607 1 : pItemSet->Differentiate( pNewColl->GetAttrSet() );
4608 : }
4609 :
4610 58 : pCollToSet = pNewColl;
4611 : }
4612 : else
4613 : {
4614 : // hart Attributieren
4615 0 : if( !pItemSet )
4616 0 : pItemSet = new SfxItemSet( pNewColl->GetAttrSet() );
4617 : else
4618 : {
4619 0 : const SfxItemSet& rCollSet = pNewColl->GetAttrSet();
4620 0 : SfxItemSet aItemSet( *rCollSet.GetPool(),
4621 0 : rCollSet.GetRanges() );
4622 0 : aItemSet.Set( rCollSet );
4623 0 : pItemSet->Put( aItemSet );
4624 : }
4625 : }
4626 : }
4627 : else
4628 : {
4629 : // vielliecht gibt es ja eine Default-Vorlage?
4630 779 : nColl = pCntxt->GetDfltTextFormatColl();
4631 779 : if( nColl )
4632 528 : nDfltColl = nColl;
4633 : }
4634 :
4635 : // ggf. neue Absatz-Einzuege holen
4636 837 : if( pCntxt->IsLRSpaceChanged() )
4637 : {
4638 1 : sal_uInt16 nLeft=0, nRight=0;
4639 :
4640 1 : pCntxt->GetMargins( nLeft, nRight, nFirstLineIndent );
4641 1 : nLeftMargin = nLeft;
4642 1 : nRightMargin = nRight;
4643 : }
4644 : }
4645 :
4646 : // wenn im aktuellen Kontext eine neue Vorlage gesetzt werden soll,
4647 : // muessen deren Absatz-Abstaende noch in den Kontext eingetragen werden
4648 568 : if( pContext && nTopColl )
4649 : {
4650 : // <TD><P CLASS=xxx> muss TD.xxx werden
4651 56 : if( nTopColl==RES_POOLCOLL_TEXT &&
4652 4 : (nDfltColl==RES_POOLCOLL_TABLE ||
4653 : nDfltColl==RES_POOLCOLL_TABLE_HDLN) )
4654 51 : nTopColl = nDfltColl;
4655 :
4656 : const SwTextFormatColl *pTopColl =
4657 56 : pCSS1Parser->GetTextFormatColl( nTopColl, rTopClass );
4658 56 : const SfxItemSet& rItemSet = pTopColl->GetAttrSet();
4659 : const SfxPoolItem *pItem;
4660 56 : if( SfxItemState::SET == rItemSet.GetItemState(RES_LR_SPACE,true, &pItem) )
4661 : {
4662 : const SvxLRSpaceItem *pLRItem =
4663 0 : static_cast<const SvxLRSpaceItem *>(pItem);
4664 :
4665 0 : sal_Int32 nLeft = pLRItem->GetTextLeft();
4666 0 : sal_Int32 nRight = pLRItem->GetRight();
4667 0 : nFirstLineIndent = pLRItem->GetTextFirstLineOfst();
4668 :
4669 : // In Definitions-Listen enthalten die Abstaende auch die der
4670 : // vorhergehenden Level
4671 0 : if( RES_POOLCOLL_HTML_DD == nTopColl )
4672 : {
4673 : const SvxLRSpaceItem& rDTLRSpace = pCSS1Parser
4674 0 : ->GetTextFormatColl( RES_POOLCOLL_HTML_DT, aEmptyOUStr )
4675 0 : ->GetLRSpace();
4676 0 : nLeft -= rDTLRSpace.GetTextLeft();
4677 0 : nRight -= rDTLRSpace.GetRight();
4678 : }
4679 0 : else if( RES_POOLCOLL_HTML_DT == nTopColl )
4680 : {
4681 0 : nLeft = 0;
4682 0 : nRight = 0;
4683 : }
4684 :
4685 : // die Absatz-Abstaende addieren sich
4686 0 : nLeftMargin = nLeftMargin + static_cast< sal_uInt16 >(nLeft);
4687 0 : nRightMargin = nRightMargin + static_cast< sal_uInt16 >(nRight);
4688 :
4689 : pContext->SetMargins( nLeftMargin, nRightMargin,
4690 0 : nFirstLineIndent );
4691 : }
4692 56 : if( SfxItemState::SET == rItemSet.GetItemState(RES_UL_SPACE,true, &pItem) )
4693 : {
4694 : const SvxULSpaceItem *pULItem =
4695 5 : static_cast<const SvxULSpaceItem *>(pItem);
4696 5 : pContext->SetULSpace( pULItem->GetUpper(), pULItem->GetLower() );
4697 : }
4698 : }
4699 :
4700 : // wenn gar keine Vorlage im Kontext gesetzt ist, Textkoerper nehmen
4701 568 : if( !pCollToSet )
4702 : {
4703 511 : pCollToSet = pCSS1Parser->GetTextCollFromPool( nDfltColl );
4704 511 : const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
4705 511 : if( !nLeftMargin )
4706 511 : nLeftMargin = static_cast< sal_uInt16 >(rLRItem.GetTextLeft());
4707 511 : if( !nRightMargin )
4708 511 : nRightMargin = static_cast< sal_uInt16 >(rLRItem.GetRight());
4709 511 : if( !nFirstLineIndent )
4710 511 : nFirstLineIndent = rLRItem.GetTextFirstLineOfst();
4711 : }
4712 :
4713 : // bisherige harte Attributierung des Absatzes entfernen
4714 568 : if( !aParaAttrs.empty() )
4715 : {
4716 0 : for( auto pParaAttr : aParaAttrs )
4717 0 : pParaAttr->Invalidate();
4718 :
4719 0 : aParaAttrs.clear();
4720 : }
4721 :
4722 : // Die Vorlage setzen
4723 568 : pDoc->SetTextFormatColl( *pPam, pCollToSet );
4724 :
4725 : // ggf. noch den Absatz-Einzug korrigieren
4726 568 : const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
4727 : bool bSetLRSpace;
4728 :
4729 1135 : bSetLRSpace = nLeftMargin != rLRItem.GetTextLeft() ||
4730 1135 : nFirstLineIndent != rLRItem.GetTextFirstLineOfst() ||
4731 1135 : nRightMargin != rLRItem.GetRight();
4732 :
4733 568 : if( bSetLRSpace )
4734 : {
4735 1 : SvxLRSpaceItem aLRItem( rLRItem );
4736 1 : aLRItem.SetTextLeft( nLeftMargin );
4737 1 : aLRItem.SetRight( nRightMargin );
4738 1 : aLRItem.SetTextFirstLineOfst( nFirstLineIndent );
4739 1 : if( pItemSet )
4740 0 : pItemSet->Put( aLRItem );
4741 : else
4742 : {
4743 1 : NewAttr( &aAttrTab.pLRSpace, aLRItem );
4744 1 : aAttrTab.pLRSpace->SetLikePara();
4745 1 : aParaAttrs.push_back( aAttrTab.pLRSpace );
4746 1 : EndAttr( aAttrTab.pLRSpace, 0, false );
4747 1 : }
4748 : }
4749 :
4750 : // und nun noch die Attribute setzen
4751 568 : if( pItemSet )
4752 : {
4753 1 : InsertParaAttrs( *pItemSet );
4754 1 : delete pItemSet;
4755 : }
4756 568 : }
4757 :
4758 0 : void SwHTMLParser::NewCharFormat( int nToken )
4759 : {
4760 0 : OUString aId, aStyle, aLang, aDir;
4761 0 : OUString aClass;
4762 :
4763 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4764 0 : for (size_t i = rHTMLOptions.size(); i; )
4765 : {
4766 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4767 0 : switch( rOption.GetToken() )
4768 : {
4769 : case HTML_O_ID:
4770 0 : aId = rOption.GetString();
4771 0 : break;
4772 : case HTML_O_STYLE:
4773 0 : aStyle = rOption.GetString();
4774 0 : break;
4775 : case HTML_O_CLASS:
4776 0 : aClass = rOption.GetString();
4777 0 : break;
4778 : case HTML_O_LANG:
4779 0 : aLang = rOption.GetString();
4780 0 : break;
4781 : case HTML_O_DIR:
4782 0 : aDir = rOption.GetString();
4783 0 : break;
4784 : }
4785 : }
4786 :
4787 : // einen neuen Kontext anlegen
4788 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
4789 :
4790 : // die Vorlage setzen und im Kontext merken
4791 0 : SwCharFormat* pCFormat = pCSS1Parser->GetChrFormat( static_cast< sal_uInt16 >(nToken), aClass );
4792 : OSL_ENSURE( pCFormat, "keine Zeichenvorlage zu Token gefunden" );
4793 :
4794 : // Styles parsen (zu Class siehe auch NewPara)
4795 0 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4796 : {
4797 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4798 0 : SvxCSS1PropertyInfo aPropInfo;
4799 :
4800 0 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4801 : {
4802 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4803 : "Class wird nicht beruecksichtigt" );
4804 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4805 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
4806 0 : }
4807 : }
4808 :
4809 : // Zeichen-Vorlagen werden in einem eigenen Stack gehalten und
4810 : // koennen nie durch Styles eingefuegt werden. Das Attribut ist deshalb
4811 : // auch gar nicht im CSS1-Which-Range enthalten
4812 0 : if( pCFormat )
4813 0 : InsertAttr( &aAttrTab.pCharFormats, SwFormatCharFormat( pCFormat ), pCntxt );
4814 :
4815 : // den Kontext merken
4816 0 : PushContext( pCntxt );
4817 0 : }
4818 :
4819 0 : void SwHTMLParser::InsertSpacer()
4820 : {
4821 : // und es ggf. durch die Optionen veraendern
4822 0 : OUString aId;
4823 0 : sal_Int16 eVertOri = text::VertOrientation::TOP;
4824 0 : sal_Int16 eHoriOri = text::HoriOrientation::NONE;
4825 0 : Size aSize( 0, 0);
4826 0 : long nSize = 0;
4827 0 : bool bPrcWidth = false;
4828 0 : bool bPrcHeight = false;
4829 0 : sal_uInt16 nType = HTML_SPTYPE_HORI;
4830 :
4831 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4832 0 : for (size_t i = rHTMLOptions.size(); i; )
4833 : {
4834 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4835 0 : switch( rOption.GetToken() )
4836 : {
4837 : case HTML_O_ID:
4838 0 : aId = rOption.GetString();
4839 0 : break;
4840 : case HTML_O_TYPE:
4841 0 : rOption.GetEnum( nType, aHTMLSpacerTypeTable );
4842 0 : break;
4843 : case HTML_O_ALIGN:
4844 : eVertOri =
4845 : rOption.GetEnum( aHTMLImgVAlignTable,
4846 0 : eVertOri );
4847 : eHoriOri =
4848 : rOption.GetEnum( aHTMLImgHAlignTable,
4849 0 : eHoriOri );
4850 0 : break;
4851 : case HTML_O_WIDTH:
4852 : // erstmal nur als Pixelwerte merken!
4853 0 : bPrcWidth = (rOption.GetString().indexOf('%') != -1);
4854 0 : aSize.Width() = (long)rOption.GetNumber();
4855 0 : break;
4856 : case HTML_O_HEIGHT:
4857 : // erstmal nur als Pixelwerte merken!
4858 0 : bPrcHeight = (rOption.GetString().indexOf('%') != -1);
4859 0 : aSize.Height() = (long)rOption.GetNumber();
4860 0 : break;
4861 : case HTML_O_SIZE:
4862 : // erstmal nur als Pixelwerte merken!
4863 0 : nSize = rOption.GetNumber();
4864 0 : break;
4865 : }
4866 : }
4867 :
4868 0 : switch( nType )
4869 : {
4870 : case HTML_SPTYPE_BLOCK:
4871 : {
4872 : // einen leeren Textrahmen anlegen
4873 :
4874 : // den Itemset holen
4875 0 : SfxItemSet aFrmSet( pDoc->GetAttrPool(),
4876 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
4877 0 : if( !IsNewDoc() )
4878 0 : Reader::ResetFrameFormatAttrs( aFrmSet );
4879 :
4880 : // den Anker und die Ausrichtung setzen
4881 0 : SetAnchorAndAdjustment( eVertOri, eHoriOri, aFrmSet );
4882 :
4883 : // und noch die Groesse des Rahmens
4884 0 : Size aDfltSz( MINFLY, MINFLY );
4885 0 : Size aSpace( 0, 0 );
4886 0 : SfxItemSet aDummyItemSet( pDoc->GetAttrPool(),
4887 0 : pCSS1Parser->GetWhichMap() );
4888 0 : SvxCSS1PropertyInfo aDummyPropInfo;
4889 :
4890 : SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight,
4891 0 : aDummyItemSet, aDummyPropInfo, aFrmSet );
4892 0 : SetSpace( aSpace, aDummyItemSet, aDummyPropInfo, aFrmSet );
4893 :
4894 : // den Inhalt schuetzen
4895 0 : SvxProtectItem aProtectItem( RES_PROTECT) ;
4896 0 : aProtectItem.SetContentProtect( true );
4897 0 : aFrmSet.Put( aProtectItem );
4898 :
4899 : // der Rahmen anlegen
4900 : RndStdIds eAnchorId =
4901 0 : static_cast<const SwFormatAnchor &>(aFrmSet.Get(RES_ANCHOR)).GetAnchorId();
4902 : SwFrameFormat *pFlyFormat = pDoc->MakeFlySection( eAnchorId,
4903 0 : pPam->GetPoint(), &aFrmSet );
4904 : // Ggf Frames anlegen und auto-geb. Rahmen registrieren
4905 0 : RegisterFlyFrm( pFlyFormat );
4906 : }
4907 0 : break;
4908 : case HTML_SPTYPE_VERT:
4909 0 : if( nSize > 0 )
4910 : {
4911 0 : if( nSize && Application::GetDefaultDevice() )
4912 : {
4913 : nSize = Application::GetDefaultDevice()
4914 : ->PixelToLogic( Size(0,nSize),
4915 0 : MapMode(MAP_TWIP) ).Height();
4916 : }
4917 :
4918 : // einen Absatz-Abstand setzen
4919 0 : SwTextNode *pTextNode = 0;
4920 0 : if( !pPam->GetPoint()->nContent.GetIndex() )
4921 : {
4922 : // den unteren Absatz-Abstand des vorherigen Nodes aendern,
4923 : // wenn moeglich
4924 :
4925 0 : SetAttr(); // noch offene Absatz-Attribute setzen
4926 :
4927 0 : pTextNode = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()-1]
4928 0 : ->GetTextNode();
4929 :
4930 : // Wenn der Abstz davor kein Textenode ist, dann wird jetzt
4931 : // ein leere Absatz angelegt, der eh schon eine Zeilenhoehe
4932 : // Abstand erzeugt.
4933 0 : if( !pTextNode )
4934 0 : nSize = nSize>HTML_PARSPACE ? nSize-HTML_PARSPACE : 0;
4935 : }
4936 :
4937 0 : if( pTextNode )
4938 : {
4939 : SvxULSpaceItem aULSpace( static_cast<const SvxULSpaceItem&>(pTextNode
4940 0 : ->SwContentNode::GetAttr( RES_UL_SPACE )) );
4941 0 : aULSpace.SetLower( aULSpace.GetLower() + (sal_uInt16)nSize );
4942 0 : pTextNode->SetAttr( aULSpace );
4943 : }
4944 : else
4945 : {
4946 0 : NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, (sal_uInt16)nSize, RES_UL_SPACE ) );
4947 0 : EndAttr( aAttrTab.pULSpace, 0, false );
4948 :
4949 0 : AppendTextNode(); // nicht am Abstand drehen!
4950 : }
4951 : }
4952 0 : break;
4953 : case HTML_SPTYPE_HORI:
4954 0 : if( nSize > 0 )
4955 : {
4956 : // wenn der Absatz noch leer ist, einen Erstzeilen-Einzug
4957 : // setzen, sondern Sperrschrift ueber einem Space aufspannen
4958 :
4959 0 : if( nSize && Application::GetDefaultDevice() )
4960 : {
4961 : nSize = Application::GetDefaultDevice()
4962 : ->PixelToLogic( Size(nSize,0),
4963 0 : MapMode(MAP_TWIP) ).Width();
4964 : }
4965 :
4966 0 : if( !pPam->GetPoint()->nContent.GetIndex() )
4967 : {
4968 0 : sal_uInt16 nLeft=0, nRight=0;
4969 0 : short nIndent = 0;
4970 :
4971 0 : GetMarginsFromContextWithNumBul( nLeft, nRight, nIndent );
4972 0 : nIndent = nIndent + (short)nSize;
4973 :
4974 0 : SvxLRSpaceItem aLRItem( RES_LR_SPACE );
4975 0 : aLRItem.SetTextLeft( nLeft );
4976 0 : aLRItem.SetRight( nRight );
4977 0 : aLRItem.SetTextFirstLineOfst( nIndent );
4978 :
4979 0 : NewAttr( &aAttrTab.pLRSpace, aLRItem );
4980 0 : EndAttr( aAttrTab.pLRSpace, 0, false );
4981 : }
4982 : else
4983 : {
4984 0 : NewAttr( &aAttrTab.pKerning, SvxKerningItem( (short)nSize, RES_CHRATR_KERNING ) );
4985 0 : OUString aTmp( ' ' );
4986 0 : pDoc->getIDocumentContentOperations().InsertString( *pPam, aTmp );
4987 0 : EndAttr( aAttrTab.pKerning );
4988 : }
4989 : }
4990 0 : }
4991 0 : }
4992 :
4993 10 : sal_uInt16 SwHTMLParser::ToTwips( sal_uInt16 nPixel )
4994 : {
4995 10 : if( nPixel && Application::GetDefaultDevice() )
4996 : {
4997 : long nTwips = Application::GetDefaultDevice()->PixelToLogic(
4998 10 : Size( nPixel, nPixel ), MapMode( MAP_TWIP ) ).Width();
4999 10 : return nTwips <= USHRT_MAX ? (sal_uInt16)nTwips : USHRT_MAX;
5000 : }
5001 : else
5002 0 : return nPixel;
5003 : }
5004 :
5005 6 : SwTwips SwHTMLParser::GetCurrentBrowseWidth()
5006 : {
5007 6 : const SwTwips nWidth = SwHTMLTableLayout::GetBrowseWidth( *pDoc );
5008 6 : if( nWidth )
5009 0 : return nWidth;
5010 :
5011 6 : if( !aHTMLPageSize.Width() )
5012 : {
5013 5 : const SwFrameFormat& rPgFormat = pCSS1Parser->GetMasterPageDesc()->GetMaster();
5014 :
5015 5 : const SwFormatFrmSize& rSz = rPgFormat.GetFrmSize();
5016 5 : const SvxLRSpaceItem& rLR = rPgFormat.GetLRSpace();
5017 5 : const SvxULSpaceItem& rUL = rPgFormat.GetULSpace();
5018 5 : const SwFormatCol& rCol = rPgFormat.GetCol();
5019 :
5020 5 : aHTMLPageSize.Width() = rSz.GetWidth() - rLR.GetLeft() - rLR.GetRight();
5021 5 : aHTMLPageSize.Height() = rSz.GetHeight() - rUL.GetUpper() - rUL.GetLower();
5022 :
5023 5 : if( 1 < rCol.GetNumCols() )
5024 0 : aHTMLPageSize.Width() /= rCol.GetNumCols();
5025 : }
5026 :
5027 6 : return aHTMLPageSize.Width();
5028 : }
5029 :
5030 0 : void SwHTMLParser::InsertIDOption()
5031 : {
5032 0 : OUString aId;
5033 0 : const HTMLOptions& rHTMLOptions = GetOptions();
5034 0 : for (size_t i = rHTMLOptions.size(); i; )
5035 : {
5036 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5037 0 : if( HTML_O_ID==rOption.GetToken() )
5038 : {
5039 0 : aId = rOption.GetString();
5040 0 : break;
5041 : }
5042 : }
5043 :
5044 0 : if( !aId.isEmpty() )
5045 0 : InsertBookmark( aId );
5046 0 : }
5047 :
5048 273 : void SwHTMLParser::InsertLineBreak()
5049 : {
5050 : // <BR CLEAR=xxx> wird wie folgt behandelt:
5051 : // 1.) Es werden nur nur absatzgebundene Rahmen betrachtet, die
5052 : // im aktuellen Absatz verankert sind.
5053 : // 2.) Fuer linksbuendig ausgerichtete Rahmen wird bei CLEAR=LEFT
5054 : // oder ALL und auf rechtsbuendige ausgerichtete Rahmen bei
5055 : // CLEAR=RIGHT oder ALL der Durchlauf wie folgt geaendert:
5056 : // 3.) Wenn der Absatz keinen Text enthaelt, bekommt der Rahmen keinen
5057 : // Umlauf
5058 : // 4.) sonst erhaelt ein links ausgerichteter Rahmen eine rechten
5059 : // "nur Anker" Umlauf und recht rechst ausg. Rahmen einen linken
5060 : // "nur Anker" Umlauf.
5061 : // 5.) wenn in einem nicht-leeren Absatz der Umlauf eines Rahmens
5062 : // geaendert wird, wird ein neuer Absatz aufgemacht
5063 : // 6.) Wenn von keinem Rahmen der Umlauf geaendert wird, wird ein
5064 : // harter Zeilenumbruch eingefuegt
5065 :
5066 546 : OUString aId, aStyle, aClass; // die ID der Bookmark
5067 273 : bool bClearLeft = false, bClearRight = false;
5068 273 : bool bCleared = false; // wurde ein CLEAR ausgefuehrt?
5069 :
5070 : // dann holen wir mal die Optionen
5071 273 : const HTMLOptions& rHTMLOptions = GetOptions();
5072 546 : for (size_t i = rHTMLOptions.size(); i; )
5073 : {
5074 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5075 0 : switch( rOption.GetToken() )
5076 : {
5077 : case HTML_O_CLEAR:
5078 : {
5079 0 : const OUString &rClear = rOption.GetString();
5080 0 : if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_all ) )
5081 : {
5082 0 : bClearLeft = true;
5083 0 : bClearRight = true;
5084 : }
5085 0 : else if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_left ) )
5086 0 : bClearLeft = true;
5087 0 : else if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_right ) )
5088 0 : bClearRight = true;
5089 : }
5090 0 : break;
5091 : case HTML_O_ID:
5092 0 : aId = rOption.GetString();
5093 0 : break;
5094 : case HTML_O_STYLE:
5095 0 : aStyle = rOption.GetString();
5096 0 : break;
5097 : case HTML_O_CLASS:
5098 0 : aClass = rOption.GetString();
5099 0 : break;
5100 : }
5101 : }
5102 :
5103 : // CLEAR wird nur fuer den aktuellen Absaetz unterstuetzt
5104 273 : if( bClearLeft || bClearRight )
5105 : {
5106 0 : SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
5107 0 : SwTextNode* pTextNd = rNodeIdx.GetNode().GetTextNode();
5108 0 : if( pTextNd )
5109 : {
5110 0 : const SwFrameFormats& rFrameFormatTable = *pDoc->GetSpzFrameFormats();
5111 :
5112 0 : for( size_t i=0; i<rFrameFormatTable.size(); i++ )
5113 : {
5114 0 : SwFrameFormat *const pFormat = rFrameFormatTable[i];
5115 0 : SwFormatAnchor const*const pAnchor = &pFormat->GetAnchor();
5116 0 : SwPosition const*const pAPos = pAnchor->GetContentAnchor();
5117 0 : if (pAPos &&
5118 0 : ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
5119 0 : (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
5120 0 : pAPos->nNode == rNodeIdx &&
5121 0 : pFormat->GetSurround().GetSurround() != SURROUND_NONE )
5122 : {
5123 0 : sal_Int16 eHori = RES_DRAWFRMFMT == pFormat->Which()
5124 : ? text::HoriOrientation::LEFT
5125 0 : : pFormat->GetHoriOrient().GetHoriOrient();
5126 :
5127 0 : SwSurround eSurround = SURROUND_PARALLEL;
5128 0 : if( pPam->GetPoint()->nContent.GetIndex() )
5129 : {
5130 0 : if( bClearLeft && text::HoriOrientation::LEFT==eHori )
5131 0 : eSurround = SURROUND_RIGHT;
5132 0 : else if( bClearRight && text::HoriOrientation::RIGHT==eHori )
5133 0 : eSurround = SURROUND_LEFT;
5134 : }
5135 0 : else if( (bClearLeft && text::HoriOrientation::LEFT==eHori) ||
5136 0 : (bClearRight && text::HoriOrientation::RIGHT==eHori) )
5137 : {
5138 0 : eSurround = SURROUND_NONE;
5139 : }
5140 :
5141 0 : if( SURROUND_PARALLEL != eSurround )
5142 : {
5143 0 : SwFormatSurround aSurround( eSurround );
5144 0 : if( SURROUND_NONE != eSurround )
5145 0 : aSurround.SetAnchorOnly( true );
5146 0 : pFormat->SetFormatAttr( aSurround );
5147 0 : bCleared = true;
5148 : }
5149 : } // Anker ist nicht im Node
5150 : } // Schleife ueber Fly-Frames
5151 : } // kein Text-Node
5152 : } // kein CLEAR
5153 :
5154 : // Styles parsen
5155 273 : SvxFormatBreakItem aBreakItem( SVX_BREAK_NONE, RES_BREAK );
5156 273 : bool bBreakItem = false;
5157 273 : if( HasStyleOptions( aStyle, aId, aClass ) )
5158 : {
5159 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
5160 0 : SvxCSS1PropertyInfo aPropInfo;
5161 :
5162 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo ) )
5163 : {
5164 0 : if( pCSS1Parser->SetFormatBreak( aItemSet, aPropInfo ) )
5165 : {
5166 0 : aBreakItem = static_cast<const SvxFormatBreakItem &>(aItemSet.Get( RES_BREAK ));
5167 0 : bBreakItem = true;
5168 : }
5169 0 : if( !aPropInfo.aId.isEmpty() )
5170 0 : InsertBookmark( aPropInfo.aId );
5171 0 : }
5172 : }
5173 :
5174 273 : if( bBreakItem && SVX_BREAK_PAGE_AFTER==aBreakItem.GetBreak() )
5175 : {
5176 0 : NewAttr( &aAttrTab.pBreak, aBreakItem );
5177 0 : EndAttr( aAttrTab.pBreak, 0, false );
5178 : }
5179 :
5180 273 : if( !bCleared && !bBreakItem )
5181 : {
5182 : // wenn kein CLEAR ausgefuehrt werden sollte oder konnte, wird
5183 : // ein Zeilenumbruch eingef?gt
5184 273 : OUString sTmp( (sal_Unicode)0x0a ); // make the Mac happy :-)
5185 273 : pDoc->getIDocumentContentOperations().InsertString( *pPam, sTmp );
5186 : }
5187 0 : else if( pPam->GetPoint()->nContent.GetIndex() )
5188 : {
5189 : // wenn ein clear in einem nicht-leeren Absatz ausgefuehrt wurde,
5190 : // muss anschliessen ein neuer Absatz aufgemacht werden
5191 : // MIB 21.02.97: Eigentlich muesste man hier den unteren Absatz-
5192 : // Absatnd auf 0 drehen. Das geht aber bei sowas wie <BR ..><P>
5193 : // schief (>Netacpe). Deshalb lassen wir das erstmal.
5194 0 : AppendTextNode( AM_NOSPACE );
5195 : }
5196 273 : if( bBreakItem && SVX_BREAK_PAGE_BEFORE==aBreakItem.GetBreak() )
5197 : {
5198 0 : NewAttr( &aAttrTab.pBreak, aBreakItem );
5199 0 : EndAttr( aAttrTab.pBreak, 0, false );
5200 546 : }
5201 273 : }
5202 :
5203 0 : void SwHTMLParser::InsertHorzRule()
5204 : {
5205 0 : sal_uInt16 nSize = 0;
5206 0 : sal_uInt16 nWidth = 0;
5207 :
5208 0 : SvxAdjust eAdjust = SVX_ADJUST_END;
5209 :
5210 0 : bool bPrcWidth = false;
5211 0 : bool bNoShade = false;
5212 0 : bool bColor = false;
5213 :
5214 0 : Color aColor;
5215 0 : OUString aId;
5216 :
5217 : // dann holen wir mal die Optionen
5218 0 : const HTMLOptions& rHTMLOptions = GetOptions();
5219 0 : for (size_t i = rHTMLOptions.size(); i; )
5220 : {
5221 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5222 0 : switch( rOption.GetToken() )
5223 : {
5224 : case HTML_O_ID:
5225 0 : aId = rOption.GetString();
5226 0 : break;
5227 : case HTML_O_SIZE:
5228 0 : nSize = (sal_uInt16)rOption.GetNumber();
5229 0 : break;
5230 : case HTML_O_WIDTH:
5231 0 : bPrcWidth = (rOption.GetString().indexOf('%') != -1);
5232 0 : nWidth = (sal_uInt16)rOption.GetNumber();
5233 0 : if( bPrcWidth && nWidth>=100 )
5234 : {
5235 : // 100%-Linien sind der default-Fall (keine Attrs neotig)
5236 0 : nWidth = 0;
5237 0 : bPrcWidth = false;
5238 : }
5239 0 : break;
5240 : case HTML_O_ALIGN:
5241 : eAdjust =
5242 0 : (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
5243 0 : break;
5244 : case HTML_O_NOSHADE:
5245 0 : bNoShade = true;
5246 0 : break;
5247 : case HTML_O_COLOR:
5248 0 : rOption.GetColor( aColor );
5249 0 : bColor = true;
5250 0 : break;
5251 : }
5252 : }
5253 :
5254 0 : if( pPam->GetPoint()->nContent.GetIndex() )
5255 0 : AppendTextNode( AM_NOSPACE );
5256 0 : if( nOpenParaToken )
5257 0 : EndPara();
5258 0 : AppendTextNode();
5259 0 : pPam->Move( fnMoveBackward );
5260 :
5261 : // ... und in einem Kontext merken
5262 : _HTMLAttrContext *pCntxt =
5263 0 : new _HTMLAttrContext( HTML_HORZRULE, RES_POOLCOLL_HTML_HR, aEmptyOUStr );
5264 :
5265 0 : PushContext( pCntxt );
5266 :
5267 : // die neue Vorlage setzen
5268 0 : SetTextCollAttrs( pCntxt );
5269 :
5270 : // die harten Attribute an diesem Absatz werden nie mehr ungueltig
5271 0 : if( !aParaAttrs.empty() )
5272 0 : aParaAttrs.clear();
5273 :
5274 0 : if( nSize>0 || bColor || bNoShade )
5275 : {
5276 : // Farbe und/oder Breite der Linie setzen
5277 0 : if( !bColor )
5278 0 : aColor.SetColor( COL_GRAY );
5279 :
5280 0 : SvxBorderLine aBorderLine( &aColor );
5281 0 : if( nSize )
5282 : {
5283 0 : long nPWidth = 0;
5284 0 : long nPHeight = (long)nSize;
5285 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
5286 0 : if ( !bNoShade )
5287 : {
5288 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
5289 : }
5290 0 : aBorderLine.SetWidth( nPHeight );
5291 : }
5292 0 : else if( bNoShade )
5293 : {
5294 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_2 );
5295 : }
5296 : else
5297 : {
5298 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
5299 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
5300 : }
5301 :
5302 0 : SvxBoxItem aBoxItem(RES_BOX);
5303 0 : aBoxItem.SetLine( &aBorderLine, SvxBoxItemLine::BOTTOM );
5304 0 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aBoxItem );
5305 0 : aSetAttrTab.push_back( pTmp );
5306 : }
5307 0 : if( nWidth )
5308 : {
5309 : // Wenn wir in keiner Tabelle sind, wird die Breitenangabe durch
5310 : // Absatz-Einzuege "getuerkt". In einer Tabelle macht das wenig
5311 : // Sinn. Um zu Vermeiden, dass die Linie bei der Breitenberechnung
5312 : // beruecksichtigt wird, bekommt sie aber trotzdem entsprechendes
5313 : // LRSpace-Item verpasst.
5314 0 : if( !pTable )
5315 : {
5316 : // Laenge und Ausrichtung der Linie ueber Absatz-Einzuege "tuerken"
5317 0 : long nBrowseWidth = GetCurrentBrowseWidth();
5318 0 : nWidth = bPrcWidth ? (sal_uInt16)((nWidth*nBrowseWidth) / 100)
5319 0 : : ToTwips( (sal_uInt16)nBrowseWidth );
5320 0 : if( nWidth < MINLAY )
5321 0 : nWidth = MINLAY;
5322 :
5323 0 : if( (long)nWidth < nBrowseWidth )
5324 : {
5325 0 : const SwFormatColl *pColl = GetCurrFormatColl();
5326 0 : SvxLRSpaceItem aLRItem( pColl->GetLRSpace() );
5327 0 : long nDist = nBrowseWidth - nWidth;
5328 :
5329 0 : switch( eAdjust )
5330 : {
5331 : case SVX_ADJUST_RIGHT:
5332 0 : aLRItem.SetTextLeft( (sal_uInt16)nDist );
5333 0 : break;
5334 : case SVX_ADJUST_LEFT:
5335 0 : aLRItem.SetRight( (sal_uInt16)nDist );
5336 0 : break;
5337 : case SVX_ADJUST_CENTER:
5338 : default:
5339 0 : nDist /= 2;
5340 0 : aLRItem.SetTextLeft( (sal_uInt16)nDist );
5341 0 : aLRItem.SetRight( (sal_uInt16)nDist );
5342 0 : break;
5343 : }
5344 :
5345 0 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aLRItem );
5346 0 : aSetAttrTab.push_back( pTmp );
5347 : }
5348 : }
5349 : }
5350 :
5351 : // Bookmarks koennen nicht in Hyperlinks eingefueht werden
5352 0 : if( !aId.isEmpty() )
5353 0 : InsertBookmark( aId );
5354 :
5355 : // den aktuellen Kontext vom Stack holen
5356 0 : _HTMLAttrContext *pPoppedContext = PopContext( HTML_HORZRULE );
5357 : OSL_ENSURE( pPoppedContext==pCntxt, "wo kommt denn da ein HR-Kontext her?" );
5358 0 : delete pPoppedContext;
5359 :
5360 0 : pPam->Move( fnMoveForward );
5361 :
5362 : // und im Absatz danach die dort aktuelle Vorlage setzen
5363 0 : SetTextCollAttrs();
5364 0 : }
5365 :
5366 32 : void SwHTMLParser::ParseMoreMetaOptions()
5367 : {
5368 45 : OUString aName, aContent;
5369 32 : bool bHTTPEquiv = false;
5370 :
5371 32 : const HTMLOptions& rHTMLOptions = GetOptions();
5372 128 : for (size_t i = rHTMLOptions.size(); i; )
5373 : {
5374 64 : const HTMLOption& rOption = rHTMLOptions[--i];
5375 64 : switch( rOption.GetToken() )
5376 : {
5377 : case HTML_O_NAME:
5378 21 : aName = rOption.GetString();
5379 21 : bHTTPEquiv = false;
5380 21 : break;
5381 : case HTML_O_HTTPEQUIV:
5382 11 : aName = rOption.GetString();
5383 11 : bHTTPEquiv = true;
5384 11 : break;
5385 : case HTML_O_CONTENT:
5386 32 : aContent = rOption.GetString();
5387 32 : break;
5388 : }
5389 : }
5390 :
5391 : // Hier wird es etwas tricky: Wir wissen genau, da? die Dok-Info
5392 : // nicht geaendert wurde. Deshalb genuegt es, auf Generator und
5393 : // auf refresh abzufragen, um noch nicht verarbeitete Token zu finden,
5394 : // denn das sind die einzigen, die die Dok-Info nicht modifizieren.
5395 88 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_generator ) ||
5396 48 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_refresh ) ||
5397 69 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_content_type ) ||
5398 13 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
5399 19 : return;
5400 :
5401 13 : aContent = comphelper::string::remove(aContent, '\r');
5402 13 : aContent = comphelper::string::remove(aContent, '\n');
5403 :
5404 13 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_sdendnote ) )
5405 : {
5406 0 : FillEndNoteInfo( aContent );
5407 0 : return;
5408 : }
5409 :
5410 13 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_sdfootnote ) )
5411 : {
5412 0 : FillFootNoteInfo( aContent );
5413 0 : return;
5414 : }
5415 :
5416 13 : OUStringBuffer sText;
5417 13 : sText.append("HTML: <");
5418 13 : sText.append(OOO_STRING_SVTOOLS_HTML_meta);
5419 13 : sText.append(' ');
5420 13 : if( bHTTPEquiv )
5421 0 : sText.append(OOO_STRING_SVTOOLS_HTML_O_httpequiv);
5422 : else
5423 13 : sText.append(OOO_STRING_SVTOOLS_HTML_O_name);
5424 13 : sText.append("=\"");
5425 13 : sText.append(aName);
5426 13 : sText.append("\" ");
5427 13 : sText.append(OOO_STRING_SVTOOLS_HTML_O_content);
5428 13 : sText.append("=\"");
5429 13 : sText.append(aContent);
5430 13 : sText.append("\">");
5431 :
5432 : SwPostItField aPostItField(
5433 13 : static_cast<SwPostItFieldType*>(pDoc->getIDocumentFieldsAccess().GetSysFieldType( RES_POSTITFLD )),
5434 39 : aEmptyOUStr, sText.makeStringAndClear(), aEmptyOUStr, aEmptyOUStr, DateTime( DateTime::SYSTEM ) );
5435 26 : SwFormatField aFormatField( aPostItField );
5436 39 : InsertAttr( aFormatField );
5437 : }
5438 :
5439 916 : _HTMLAttr::_HTMLAttr( const SwPosition& rPos, const SfxPoolItem& rItem,
5440 : _HTMLAttr **ppHd ) :
5441 : nSttPara( rPos.nNode ),
5442 : nEndPara( rPos.nNode ),
5443 916 : nSttContent( rPos.nContent.GetIndex() ),
5444 916 : nEndContent(rPos.nContent.GetIndex() ),
5445 : bInsAtStart( true ),
5446 : bLikePara( false ),
5447 : bValid( true ),
5448 : nCount( 1 ),
5449 : pNext( 0 ),
5450 : pPrev( 0 ),
5451 2748 : ppHead( ppHd )
5452 : {
5453 916 : pItem = rItem.Clone();
5454 916 : }
5455 :
5456 9 : _HTMLAttr::_HTMLAttr( const _HTMLAttr &rAttr, const SwNodeIndex &rEndPara,
5457 : sal_Int32 nEndCnt, _HTMLAttr **ppHd ) :
5458 : nSttPara( rAttr.nSttPara ),
5459 : nEndPara( rEndPara ),
5460 : nSttContent( rAttr.nSttContent ),
5461 : nEndContent( nEndCnt ),
5462 : bInsAtStart( rAttr.bInsAtStart ),
5463 : bLikePara( rAttr.bLikePara ),
5464 : bValid( rAttr.bValid ),
5465 : nCount( rAttr.nCount ),
5466 : pNext( 0 ),
5467 : pPrev( 0 ),
5468 9 : ppHead( ppHd )
5469 : {
5470 9 : pItem = rAttr.pItem->Clone();
5471 9 : }
5472 :
5473 1850 : _HTMLAttr::~_HTMLAttr()
5474 : {
5475 925 : delete pItem;
5476 925 : }
5477 :
5478 9 : _HTMLAttr *_HTMLAttr::Clone(const SwNodeIndex& rEndPara, sal_Int32 nEndCnt) const
5479 : {
5480 : // das Attribut mit der alten Start-Position neu anlegen
5481 9 : _HTMLAttr *pNew = new _HTMLAttr( *this, rEndPara, nEndCnt, ppHead );
5482 :
5483 : // die Previous-Liste muss uebernommen werden, die Next-Liste nicht!
5484 9 : pNew->pPrev = pPrev;
5485 :
5486 9 : return pNew;
5487 : }
5488 :
5489 0 : void _HTMLAttr::Reset(const SwNodeIndex& rSttPara, sal_Int32 nSttCnt,
5490 : _HTMLAttr **ppHd)
5491 : {
5492 : // den Anfang (und das Ende) neu setzen
5493 0 : nSttPara = rSttPara;
5494 0 : nSttContent = nSttCnt;
5495 0 : nEndPara = rSttPara;
5496 0 : nEndContent = nSttCnt;
5497 :
5498 : // den Head korrigieren und die Verkettungen aufheben
5499 0 : pNext = 0;
5500 0 : pPrev = 0;
5501 0 : ppHead = ppHd;
5502 0 : }
5503 :
5504 1 : void _HTMLAttr::InsertPrev( _HTMLAttr *pPrv )
5505 : {
5506 : OSL_ENSURE( !pPrv->pNext || pPrv->pNext == this,
5507 : "_HTMLAttr::InsertPrev: pNext falsch" );
5508 1 : pPrv->pNext = 0;
5509 :
5510 : OSL_ENSURE( 0 == pPrv->ppHead || ppHead == pPrv->ppHead,
5511 : "_HTMLAttr::InsertPrev: ppHead falsch" );
5512 1 : pPrv->ppHead = 0;
5513 :
5514 1 : _HTMLAttr *pAttr = this;
5515 2 : while( pAttr->GetPrev() )
5516 0 : pAttr = pAttr->GetPrev();
5517 :
5518 1 : pAttr->pPrev = pPrv;
5519 1 : }
5520 :
5521 42 : bool SwHTMLParser::ParseMetaOptions(
5522 : const uno::Reference<document::XDocumentProperties> & i_xDocProps,
5523 : SvKeyValueIterator *i_pHeader )
5524 : {
5525 : // always call base ParseMetaOptions, it sets the encoding (#i96700#)
5526 42 : bool ret( HTMLParser::ParseMetaOptions(i_xDocProps, i_pHeader) );
5527 42 : if (!ret && IsNewDoc())
5528 : {
5529 32 : ParseMoreMetaOptions();
5530 : }
5531 42 : return ret;
5532 : }
5533 :
5534 : // override so we can parse DOCINFO field subtypes INFO[1-4]
5535 9 : void SwHTMLParser::AddMetaUserDefined( OUString const & i_rMetaName )
5536 : {
5537 : // unless we already have 4 names, append the argument to m_InfoNames
5538 : OUString* pName // the first empty string in m_InfoNames
5539 9 : (m_InfoNames[0].isEmpty() ? &m_InfoNames[0] :
5540 5 : (m_InfoNames[1].isEmpty() ? &m_InfoNames[1] :
5541 4 : (m_InfoNames[2].isEmpty() ? &m_InfoNames[2] :
5542 18 : (m_InfoNames[3].isEmpty() ? &m_InfoNames[3] : 0 ))));
5543 9 : if (pName)
5544 : {
5545 7 : (*pName) = i_rMetaName;
5546 : }
5547 186 : }
5548 :
5549 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|