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 90 : HTMLReader::HTMLReader()
150 : {
151 90 : bTmplBrowseMode = true;
152 90 : }
153 :
154 8 : OUString HTMLReader::GetTemplateName() const
155 : {
156 8 : const OUString sTemplateWithoutExt("internal/html");
157 16 : SvtPathOptions aPathOpt;
158 :
159 : // first search for OpenDocument Writer/Web template
160 : // OpenDocument Writer/Web template (extension .oth)
161 16 : OUString sTemplate( sTemplateWithoutExt + ".oth" );
162 8 : 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 8 : sTemplate = sTemplateWithoutExt + ".stw";
168 8 : if (aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ))
169 8 : return sTemplate;
170 :
171 : OSL_ENSURE( false, "The default HTML template cannot be found in the defined template directories!");
172 :
173 8 : return OUString();
174 : }
175 :
176 22 : int HTMLReader::SetStrmStgPtr()
177 : {
178 : OSL_ENSURE( pMedium, "Wo ist das Medium??" );
179 :
180 22 : if( pMedium->IsRemote() || !pMedium->IsStorage() )
181 : {
182 22 : pStrm = pMedium->GetInStream();
183 22 : return sal_True;
184 : }
185 0 : return sal_False;
186 :
187 : }
188 :
189 : // Aufruf fuer die allg. Reader-Schnittstelle
190 22 : sal_uLong HTMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPam, const OUString & rName )
191 : {
192 22 : if( !pStrm )
193 : {
194 : OSL_ENSURE( pStrm, "HTML-Read ohne Stream" );
195 0 : return ERR_SWG_READ_ERROR;
196 : }
197 :
198 22 : if( !bInsertMode )
199 : {
200 22 : Reader::ResetFrmFmts( rDoc );
201 :
202 : // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist,
203 : // sonst ist sie schon gesetzt.
204 22 : if( !rDoc.getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE) )
205 : {
206 20 : rDoc.getIDocumentContentOperations().InsertPoolItem( rPam, SwFmtPageDesc(
207 20 : rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false )), 0 );
208 : }
209 : }
210 :
211 : // damit keiner das Doc klaut!
212 22 : rDoc.acquire();
213 22 : sal_uLong nRet = 0;
214 : SvParserRef xParser = new SwHTMLParser( &rDoc, rPam, *pStrm,
215 22 : rName, rBaseURL, !bInsertMode, pMedium,
216 22 : IsReadUTF8(),
217 44 : bIgnoreHTMLComments );
218 :
219 22 : SvParserState eState = xParser->CallParser();
220 :
221 22 : if( SVPAR_PENDING == eState )
222 0 : pStrm->ResetError();
223 22 : 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 22 : return nRet;
234 : }
235 :
236 22 : 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 22 : 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 44 : pTempViewFrame(0)
301 : {
302 22 : nEventId = 0;
303 : bUpperSpace = bViewCreated = bChkJumpMark =
304 22 : bSetCrsr = false;
305 :
306 22 : eScriptLang = HTML_SL_UNKNOWN;
307 22 : bAnyStarBasic = true;
308 :
309 22 : rCrsr.DeleteMark();
310 22 : pPam = &rCrsr; // re-use existing cursor: avoids spurious ~SwIndexReg assert
311 22 : memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
312 :
313 : // Die Font-Groessen 1-7 aus der INI-Datei lesen
314 22 : SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
315 22 : aFontHeights[0] = rHtmlOptions.GetFontSize( 0 ) * 20;
316 22 : aFontHeights[1] = rHtmlOptions.GetFontSize( 1 ) * 20;
317 22 : aFontHeights[2] = rHtmlOptions.GetFontSize( 2 ) * 20;
318 22 : aFontHeights[3] = rHtmlOptions.GetFontSize( 3 ) * 20;
319 22 : aFontHeights[4] = rHtmlOptions.GetFontSize( 4 ) * 20;
320 22 : aFontHeights[5] = rHtmlOptions.GetFontSize( 5 ) * 20;
321 22 : aFontHeights[6] = rHtmlOptions.GetFontSize( 6 ) * 20;
322 :
323 22 : bKeepUnknown = rHtmlOptions.IsImportUnknown();
324 :
325 22 : 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 22 : SvxFontHeightItem aFontHeight(aFontHeights[2], 100, RES_CHRATR_FONTSIZE);
330 22 : pDoc->SetDefault( aFontHeight );
331 44 : SvxFontHeightItem aFontHeightCJK(aFontHeights[2], 100, RES_CHRATR_CJK_FONTSIZE);
332 22 : pDoc->SetDefault( aFontHeightCJK );
333 44 : SvxFontHeightItem aFontHeightCTL(aFontHeights[2], 100, RES_CHRATR_CTL_FONTSIZE);
334 22 : pDoc->SetDefault( aFontHeightCTL );
335 :
336 : // #i18732# - adjust default of option 'FollowTextFlow'
337 : // TODO: not sure what the appropriate default for HTML should be?
338 44 : pDoc->SetDefault( SwFmtFollowTextFlow(true) );
339 : }
340 :
341 : // Waehrend des Imports in den HTML-Modus schalten, damit die
342 : // richrigen Vorlagen angelegt werden
343 22 : bOldIsHTMLMode = pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE);
344 22 : pDoc->getIDocumentSettingAccess().set(IDocumentSettingAccess::HTML_MODE, true);
345 :
346 22 : pCSS1Parser = new SwCSS1Parser( pDoc, aFontHeights, sBaseURL, IsNewDoc() );
347 22 : pCSS1Parser->SetIgnoreFontFamily( rHtmlOptions.IsIgnoreFontFamily() );
348 :
349 22 : if( bReadUTF8 )
350 : {
351 0 : SetSrcEncoding( RTL_TEXTENCODING_UTF8 );
352 : }
353 : else
354 : {
355 22 : SwDocShell *pDocSh = pDoc->GetDocShell();
356 : SvKeyValueIterator *pHeaderAttrs =
357 22 : pDocSh->GetHeaderAttributes();
358 22 : if( pHeaderAttrs )
359 22 : SetEncodingByHTTPHeader( pHeaderAttrs );
360 : }
361 22 : pCSS1Parser->SetDfltEncoding( osl_getThreadTextEncoding() );
362 :
363 : // Timer nur bei ganz normalen Dokumenten aufsetzen!
364 22 : SwDocShell* pDocSh = pDoc->GetDocShell();
365 22 : if( pDocSh )
366 : {
367 22 : bViewCreated = true; // nicht, synchron laden
368 :
369 : // es ist ein Sprungziel vorgegeben.
370 :
371 22 : if( pMed )
372 : {
373 22 : sJmpMark = pMed->GetURLObject().GetMark();
374 22 : 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 22 : }
415 :
416 66 : SwHTMLParser::~SwHTMLParser()
417 : {
418 : #ifdef DBG_UTIL
419 : OSL_ENSURE( !m_nContinue, "DTOR im Continue!" );
420 : #endif
421 22 : bool bAsync = pDoc->IsInLoadAsynchron();
422 22 : pDoc->SetInLoadAsynchron( false );
423 22 : pDoc->getIDocumentSettingAccess().set(IDocumentSettingAccess::HTML_MODE, bOldIsHTMLMode);
424 :
425 22 : if( pDoc->GetDocShell() && nEventId )
426 0 : Application::RemoveUserEvent( nEventId );
427 :
428 : // das DocumentDetected kann ggfs. die DocShells loeschen, darum nochmals
429 : // abfragen
430 22 : if( pDoc->GetDocShell() )
431 : {
432 : // Gelinkte Bereiche updaten
433 22 : sal_uInt16 nLinkMode = pDoc->getIDocumentSettingAccess().getLinkUpdateMode( true );
434 22 : if( nLinkMode != NEVER && bAsync &&
435 0 : SFX_CREATE_MODE_INTERNAL!=pDoc->GetDocShell()->GetCreateMode() )
436 0 : pDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks( nLinkMode == MANUAL,
437 0 : true, false );
438 :
439 22 : if ( pDoc->GetDocShell()->IsLoading() )
440 : {
441 : // #i59688#
442 22 : pDoc->GetDocShell()->LoadingFinished();
443 : }
444 : }
445 :
446 22 : delete pSttNdIdx;
447 :
448 22 : 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 22 : delete pCSS1Parser;
458 22 : delete pNumRuleInfo;
459 22 : DeleteFormImpl();
460 22 : DeleteFootEndNoteImpl();
461 :
462 : OSL_ENSURE( !pTable, "Es existiert noch eine offene Tabelle" );
463 22 : delete pImageMaps;
464 :
465 : OSL_ENSURE( !pPendStack,
466 : "SwHTMLParser::~SwHTMLParser: Hier sollte es keinen Pending-Stack mehr geben" );
467 44 : 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 22 : 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 22 : if ( pTempViewFrame )
483 : {
484 2 : pTempViewFrame->DoClose();
485 :
486 : // the temporary view frame is hidden, so the hidden flag might need to be removed
487 2 : if ( bRemoveHidden && pDoc && pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() )
488 2 : pDoc->GetDocShell()->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN );
489 : }
490 44 : }
491 :
492 0 : IMPL_LINK( SwHTMLParser, AsyncCallback, void*, /*pVoid*/ )
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 22 : SvParserState SwHTMLParser::CallParser()
510 : {
511 : // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
512 22 : pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
513 22 : 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->SetTxtFmtColl( *pPam,
533 0 : pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
534 : }
535 :
536 22 : if( GetMedium() )
537 : {
538 22 : if( !bViewCreated )
539 : {
540 0 : nEventId = Application::PostUserEvent( LINK( this, SwHTMLParser, AsyncCallback ), 0 );
541 : }
542 : else
543 : {
544 22 : bViewCreated = true;
545 22 : 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 22 : pDoc->GetPageDesc( 0 ).Add( this );
561 :
562 22 : SvParserState eRet = HTMLParser::CallParser();
563 22 : return eRet;
564 : }
565 :
566 22 : 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 22 : if( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
579 0 : eState = SVPAR_ERROR;
580 :
581 : // Die SwViewShell vom Dokument holen, merken und als aktuelle setzen.
582 22 : SwViewShell *pInitVSh = CallStartAction();
583 :
584 22 : 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 22 : return;
599 : }
600 :
601 22 : bSetModEnabled = false;
602 44 : if( pDoc->GetDocShell() &&
603 22 : (bSetModEnabled = pDoc->GetDocShell()->IsEnableSetModified()) )
604 : {
605 0 : pDoc->GetDocShell()->EnableSetModified( false );
606 : }
607 :
608 : // waehrend des einlesens kein OLE-Modified rufen
609 22 : Link aOLELink( pDoc->GetOle2Link() );
610 22 : pDoc->SetOle2Link( Link() );
611 :
612 22 : bool bModified = pDoc->getIDocumentState().IsModified();
613 22 : bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
614 22 : 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 22 : 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 22 : HTMLParser::Continue( pPendStack ? pPendStack->nToken : nToken );
632 : }
633 :
634 : // Laufbalken wieder abschalten
635 22 : EndProgress( pDoc->GetDocShell() );
636 :
637 22 : bool bLFStripped = false;
638 22 : if( SVPAR_PENDING != GetStatus() )
639 : {
640 : // noch die letzten Attribute setzen
641 : {
642 22 : if( !aScriptSource.isEmpty() )
643 : {
644 : SwScriptFieldType *pType =
645 0 : (SwScriptFieldType*)pDoc->getIDocumentFieldsAccess().GetSysFldType( RES_SCRIPTFLD );
646 :
647 : SwScriptField aFld( pType, aScriptType, aScriptSource,
648 0 : false );
649 0 : InsertAttr( SwFmtFld( aFld ) );
650 : }
651 :
652 22 : 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 22 : if( IsNewDoc() )
662 22 : bLFStripped = StripTrailingLF() > 0;
663 :
664 : // noch offene Nummerierungen beenden.
665 44 : while( GetNumInfo().GetNumRule() )
666 0 : EndNumBulList();
667 :
668 : OSL_ENSURE( !nContextStMin, "Es gibt geschuetzte Kontexte" );
669 22 : nContextStMin = 0;
670 46 : while( aContexts.size() )
671 : {
672 2 : _HTMLAttrContext *pCntxt = PopContext();
673 2 : if( pCntxt )
674 : {
675 2 : EndContext( pCntxt );
676 2 : delete pCntxt;
677 : }
678 : }
679 :
680 22 : if( !aParaAttrs.empty() )
681 0 : aParaAttrs.clear();
682 :
683 22 : SetAttr( false );
684 :
685 : // Noch die erst verzoegert gesetzten Styles setzen
686 22 : pCSS1Parser->SetDelayedStyles();
687 : }
688 :
689 : // den Start wieder korrigieren
690 22 : if( !IsNewDoc() && pSttNdIdx->GetIndex() )
691 : {
692 0 : SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
693 0 : SwNodeIndex aNxtIdx( *pSttNdIdx );
694 0 : if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
695 : {
696 0 : const sal_Int32 nStt = pTxtNode->GetTxt().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( pTxtNode, 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( pTxtNode,
715 : pTxtNode->GetTxt().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( pTxtNode,
721 : pTxtNode->GetTxt().getLength() + nCntPos );
722 : }
723 : #endif
724 : // Zeichen Attribute beibehalten!
725 0 : SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
726 0 : if (pTxtNode->GetTxt().getLength())
727 0 : pDelNd->FmtToTxtAttr( pTxtNode );
728 : else
729 0 : pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
730 0 : pTxtNode->JoinNext();
731 0 : }
732 : }
733 : }
734 :
735 22 : if( SVPAR_ACCEPTED == eState )
736 : {
737 22 : 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 22 : SwPosition* pPos = pPam->GetPoint();
746 22 : if( !pPos->nContent.GetIndex() && !bLFStripped )
747 : {
748 : SwTxtNode* pAktNd;
749 18 : sal_uLong nNodeIdx = pPos->nNode.GetIndex();
750 :
751 : bool bHasFlysOrMarks =
752 18 : HasCurrentParaFlys() || HasCurrentParaBookmarks( true );
753 :
754 18 : if( IsNewDoc() )
755 : {
756 18 : const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1];
757 50 : if( !pPam->GetPoint()->nContent.GetIndex() &&
758 24 : ( pPrev->IsCntntNode() ||
759 8 : (pPrev->IsEndNode() &&
760 2 : pPrev->StartOfSectionNode()->IsSectionNode()) ) )
761 : {
762 14 : SwCntntNode* pCNd = pPam->GetCntntNode();
763 42 : if( pCNd && pCNd->StartOfSectionIndex()+2 <
764 42 : pCNd->EndOfSectionIndex() && !bHasFlysOrMarks )
765 : {
766 14 : SwViewShell *pVSh = CheckActionViewShell();
767 2 : SwCrsrShell *pCrsrSh = pVSh && pVSh->ISA(SwCrsrShell)
768 : ? static_cast < SwCrsrShell * >( pVSh )
769 16 : : 0;
770 16 : if( pCrsrSh &&
771 2 : pCrsrSh->GetCrsr()->GetPoint()
772 2 : ->nNode.GetIndex() == nNodeIdx )
773 : {
774 0 : pCrsrSh->MovePara(fnParaPrev, fnParaEnd );
775 0 : pCrsrSh->SetMark();
776 0 : pCrsrSh->ClearMark();
777 : }
778 14 : pPam->GetBound(true).nContent.Assign( 0, 0 );
779 14 : pPam->GetBound(false).nContent.Assign( 0, 0 );
780 14 : pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
781 : }
782 : }
783 : }
784 0 : else if( 0 != ( pAktNd = pDoc->GetNodes()[ nNodeIdx ]->GetTxtNode()) && !bHasFlysOrMarks )
785 : {
786 0 : if( pAktNd->CanJoinNext( &pPos->nNode ))
787 : {
788 0 : SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
789 0 : pPos->nContent.Assign( pNextNd, 0 );
790 0 : pPam->SetMark(); pPam->DeleteMark();
791 0 : pNextNd->JoinPrev();
792 : }
793 0 : else if (pAktNd->GetTxt().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 4 : 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 : SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
809 0 : SwNodeIndex aPrvIdx( pPos->nNode );
810 0 : if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
811 0 : *pSttNdIdx <= aPrvIdx )
812 : {
813 : // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
814 : // usw. sind im pTxtNode 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 : SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
820 0 : pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
821 0 : pTxtNode->FmtToTxtAttr( pPrev );
822 0 : pTxtNode->ResetAllAttr();
823 :
824 0 : if( pPrev->HasSwAttrSet() )
825 0 : pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
826 :
827 0 : if( &pPam->GetBound(true).nNode.GetNode() == pPrev )
828 0 : pPam->GetBound(true).nContent.Assign( pTxtNode, 0 );
829 0 : if( &pPam->GetBound(false).nNode.GetNode() == pPrev )
830 0 : pPam->GetBound(false).nContent.Assign( pTxtNode, 0 );
831 :
832 0 : pTxtNode->JoinPrev();
833 0 : }
834 : }
835 :
836 : // adjust AutoLoad in DocumentProperties
837 22 : if( IsNewDoc() )
838 : {
839 22 : SwDocShell *pDocShell(pDoc->GetDocShell());
840 : OSL_ENSURE(pDocShell, "no SwDocShell");
841 22 : if (pDocShell) {
842 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
843 22 : pDocShell->GetModel(), uno::UNO_QUERY_THROW);
844 : uno::Reference<document::XDocumentProperties> xDocProps(
845 44 : xDPS->getDocumentProperties());
846 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
847 66 : if ( xDocProps.is() && (xDocProps->getAutoloadSecs() > 0) &&
848 22 : (xDocProps->getAutoloadURL().isEmpty()) )
849 : {
850 0 : xDocProps->setAutoloadURL(aPathToFile);
851 22 : }
852 : }
853 : }
854 :
855 22 : if( bUpdateDocStat )
856 : {
857 0 : pDoc->getIDocumentStatistics().UpdateDocStat( false, true );
858 : }
859 : }
860 :
861 22 : if( SVPAR_PENDING != GetStatus() )
862 22 : 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 22 : if( 1 < pDoc->getReferenceCount() )
867 : {
868 22 : if( bWasUndo )
869 : {
870 0 : pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
871 0 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
872 : }
873 22 : 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 22 : SwViewShell *pTmpVSh = CheckActionViewShell();
880 22 : if( pTmpVSh )
881 : {
882 2 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
883 : }
884 : }
885 :
886 22 : pDoc->SetOle2Link( aOLELink );
887 22 : if( !bModified )
888 0 : pDoc->getIDocumentState().ResetModified();
889 22 : 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 22 : 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 && ((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 22 : void SwHTMLParser::DocumentDetected()
923 : {
924 : OSL_ENSURE( !bDocInitalized, "DocumentDetected mehrfach aufgerufen" );
925 22 : bDocInitalized = true;
926 22 : if( IsNewDoc() )
927 : {
928 22 : if( IsInHeader() )
929 22 : FinishHeader( true );
930 :
931 22 : CallEndAction( true, true );
932 :
933 22 : 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 22 : CallStartAction();
939 : }
940 22 : }
941 :
942 : // is called for every token that is recognised in CallParser
943 3536 : void SwHTMLParser::NextToken( int nToken )
944 : {
945 10608 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
946 7072 : || 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 3536 : if( !pPendStack )
984 : {
985 3536 : if( bInTitle )
986 : {
987 12 : switch( nToken )
988 : {
989 : case HTML_TITLE_OFF:
990 10 : if( IsNewDoc() && !sTitle.isEmpty() )
991 : {
992 2 : if( pDoc->GetDocShell() ) {
993 : uno::Reference<document::XDocumentPropertiesSupplier>
994 2 : xDPS(pDoc->GetDocShell()->GetModel(),
995 2 : uno::UNO_QUERY_THROW);
996 : uno::Reference<document::XDocumentProperties> xDocProps(
997 4 : xDPS->getDocumentProperties());
998 : OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
999 2 : if (xDocProps.is()) {
1000 2 : xDocProps->setTitle(sTitle);
1001 : }
1002 :
1003 4 : pDoc->GetDocShell()->SetTitle( sTitle );
1004 : }
1005 : }
1006 10 : bInTitle = false;
1007 10 : sTitle = "";
1008 10 : 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 2 : sTitle += aToken;
1020 2 : 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 12 : 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 3524 : if( !bDocInitalized )
1044 22 : DocumentDetected();
1045 :
1046 3524 : bool bGetIDOption = false, bInsertUnknown = false;
1047 3524 : bool bUpperSpaceSave = bUpperSpace;
1048 3524 : bUpperSpace = false;
1049 :
1050 : // The following special cases may or have to be treated after the
1051 : // filter detection
1052 3524 : if( !pPendStack )
1053 : {
1054 3524 : 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 3524 : 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 = "";
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 3524 : 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 3524 : 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 3524 : 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 3524 : 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 3524 : 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 3524 : 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 3524 : 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 0 : 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 0 : switch( nToken )
1236 : {
1237 : case HTML_UNKNOWNCONTROL_OFF:
1238 0 : if( aUnknownToken != sSaveToken )
1239 0 : 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 0 : aUnknownToken = "";
1246 0 : break;
1247 : case HTML_TEXTTOKEN:
1248 0 : return;
1249 : default:
1250 0 : aUnknownToken = "";
1251 0 : break;
1252 : }
1253 : }
1254 : }
1255 :
1256 3524 : switch( nToken )
1257 : {
1258 : case HTML_BODY_ON:
1259 20 : if( !aStyleSource.isEmpty() )
1260 : {
1261 0 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1262 0 : aStyleSource = "";
1263 : }
1264 20 : if( IsNewDoc() )
1265 : {
1266 20 : InsertBodyOptions();
1267 : // If there is a template for the first or the right page,
1268 : // it is set here.
1269 20 : const SwPageDesc *pPageDesc = 0;
1270 20 : if( pCSS1Parser->IsSetFirstPageDesc() )
1271 0 : pPageDesc = pCSS1Parser->GetFirstPageDesc();
1272 20 : else if( pCSS1Parser->IsSetRightPageDesc() )
1273 0 : pPageDesc = pCSS1Parser->GetRightPageDesc();
1274 :
1275 20 : if( pPageDesc )
1276 : {
1277 0 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pPam, SwFmtPageDesc( pPageDesc ), 0 );
1278 : }
1279 : }
1280 20 : 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 66 : SvKeyValueIterator *pHTTPHeader = 0;
1323 66 : if( IsNewDoc() )
1324 : {
1325 66 : SwDocShell *pDocSh = pDoc->GetDocShell();
1326 66 : if( pDocSh )
1327 66 : pHTTPHeader = pDocSh->GetHeaderAttributes();
1328 : }
1329 66 : SwDocShell *pDocShell(pDoc->GetDocShell());
1330 : OSL_ENSURE(pDocShell, "no SwDocShell");
1331 66 : if (pDocShell)
1332 : {
1333 66 : uno::Reference<document::XDocumentProperties> xDocProps;
1334 66 : if (IsNewDoc())
1335 : {
1336 : const uno::Reference<document::XDocumentPropertiesSupplier>
1337 66 : xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
1338 66 : xDocProps = xDPS->getDocumentProperties();
1339 66 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
1340 : }
1341 66 : ParseMetaOptions( xDocProps, pHTTPHeader );
1342 : }
1343 : }
1344 66 : break;
1345 :
1346 : case HTML_TITLE_ON:
1347 10 : bInTitle = true;
1348 10 : 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 4 : bInsertUnknown = true;
1361 4 : 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 82 : if( !bIgnoreRawData )
1373 : {
1374 82 : if( IsReadScript() )
1375 : {
1376 0 : AddScriptSource();
1377 : }
1378 82 : else if( IsReadStyle() )
1379 : {
1380 82 : if( !aStyleSource.isEmpty() )
1381 54 : aStyleSource += "\n";
1382 82 : aStyleSource += aToken;
1383 : }
1384 : }
1385 82 : 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 2 : InsertFloatingFrame();
1403 2 : bCallNextToken = bInFloatingFrame && pTable!=0;
1404 2 : break;
1405 :
1406 : case HTML_LINEBREAK:
1407 526 : if( !IsReadPRE() )
1408 : {
1409 526 : InsertLineBreak();
1410 526 : 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 : AppendTxtNode(); // there is no LF at this place
1423 : // therefore it will cause no problems
1424 0 : SetTxtCollAttrs();
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 : AppendTxtNode();
1443 0 : if( !pTable && !pDoc->IsInHeaderFooter( pPam->GetPoint()->nNode ) )
1444 : {
1445 0 : NewAttr( &aAttrTab.pBreak, SvxFmtBreakItem(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 1406 : if( !aToken.isEmpty() && ' '==aToken[0] && !IsReadPRE() )
1453 : {
1454 1382 : sal_Int32 nPos = pPam->GetPoint()->nContent.GetIndex();
1455 1382 : if( nPos )
1456 : {
1457 : const OUString& rText =
1458 548 : pPam->GetPoint()->nNode.GetNode().GetTxtNode()->GetTxt();
1459 548 : sal_Unicode cLast = rText[--nPos];
1460 548 : if( ' ' == cLast || '\x0a' == cLast)
1461 532 : aToken = aToken.copy(1);
1462 : }
1463 : else
1464 834 : aToken = aToken.copy(1);
1465 :
1466 1382 : if( aToken.isEmpty() )
1467 : {
1468 1364 : bUpperSpace = bUpperSpaceSave;
1469 1364 : break;
1470 : }
1471 : }
1472 :
1473 42 : if( !aToken.isEmpty() )
1474 : {
1475 42 : if( !bDocInitalized )
1476 0 : DocumentDetected();
1477 42 : 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 42 : if( !aParaAttrs.empty() )
1483 0 : aParaAttrs.clear();
1484 :
1485 42 : SetAttr();
1486 : }
1487 42 : break;
1488 :
1489 : case HTML_HORZRULE:
1490 0 : InsertHorzRule();
1491 0 : break;
1492 :
1493 : case HTML_IMAGE:
1494 8 : InsertImage();
1495 : // if only the parser references the doc, we can break and set
1496 : // an error code
1497 8 : if( 1 == pDoc->getReferenceCount() )
1498 : {
1499 0 : eState = SVPAR_ERROR;
1500 : }
1501 8 : 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 30 : if( nOpenParaToken )
1549 : {
1550 0 : if( IsReadPRE() )
1551 0 : nOpenParaToken = 0;
1552 : else
1553 0 : EndPara();
1554 : }
1555 30 : NewDivision( nToken );
1556 30 : break;
1557 :
1558 : case HTML_DIVISION_OFF:
1559 : case HTML_CENTER_OFF:
1560 28 : if( nOpenParaToken )
1561 : {
1562 0 : if( IsReadPRE() )
1563 0 : nOpenParaToken = 0;
1564 : else
1565 0 : EndPara();
1566 : }
1567 28 : EndDivision( nToken );
1568 28 : 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 4 : NewForm();
1589 4 : break;
1590 : case HTML_FORM_OFF:
1591 4 : EndForm();
1592 4 : break;
1593 :
1594 : // templates
1595 : case HTML_PARABREAK_ON:
1596 546 : if( nOpenParaToken )
1597 0 : EndPara( true );
1598 546 : NewPara();
1599 546 : break;
1600 :
1601 : case HTML_PARABREAK_OFF:
1602 546 : EndPara( true );
1603 546 : break;
1604 :
1605 : case HTML_ADDRESS_ON:
1606 0 : if( nOpenParaToken )
1607 0 : EndPara();
1608 0 : NewTxtFmtColl( HTML_ADDRESS_ON, RES_POOLCOLL_SENDADRESS );
1609 0 : break;
1610 :
1611 : case HTML_ADDRESS_OFF:
1612 0 : if( nOpenParaToken )
1613 0 : EndPara();
1614 0 : EndTxtFmtColl( 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 : NewTxtFmtColl( 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 : EndTxtFmtColl( 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 : NewTxtFmtColl( 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 : EndTxtFmtColl( HTML_PREFORMTXT_OFF );
1642 0 : break;
1643 :
1644 : case HTML_LISTING_OFF:
1645 : case HTML_XMP_OFF:
1646 0 : EndTxtFmtColl( 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 0 : if( nOpenParaToken )
1656 : {
1657 0 : if( IsReadPRE() )
1658 0 : nOpenParaToken = 0;
1659 : else
1660 0 : EndPara();
1661 : }
1662 0 : NewHeading( nToken );
1663 0 : 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 0 : EndHeading();
1672 0 : break;
1673 :
1674 : case HTML_TABLE_ON:
1675 2 : if( pPendStack )
1676 0 : BuildTable( SVX_ADJUST_END );
1677 : else
1678 : {
1679 2 : if( nOpenParaToken )
1680 0 : EndPara();
1681 : OSL_ENSURE( !pTable, "table in table not allowed here" );
1682 6 : if( !pTable && (IsNewDoc() || !pPam->GetNode().FindTableNode()) &&
1683 2 : (pPam->GetPoint()->nNode.GetIndex() >
1684 2 : pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
1685 0 : !pPam->GetNode().FindFootnoteStartNode() ) )
1686 : {
1687 2 : if ( nParaCnt < 5 )
1688 0 : Show(); // show what we have up to here
1689 :
1690 : SvxAdjust eAdjust = aAttrTab.pAdjust
1691 0 : ? ((const SvxAdjustItem&)aAttrTab.pAdjust->GetItem()).
1692 : GetAdjust()
1693 2 : : SVX_ADJUST_END;
1694 2 : BuildTable( eAdjust );
1695 : }
1696 : else
1697 0 : bInsertUnknown = bKeepUnknown;
1698 : }
1699 2 : 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 10 : SvxWeightItem aWeight( WEIGHT_BOLD, RES_CHRATR_WEIGHT );
1756 20 : SvxWeightItem aWeightCJK( WEIGHT_BOLD, RES_CHRATR_CJK_WEIGHT );
1757 20 : SvxWeightItem aWeightCTL( WEIGHT_BOLD, RES_CHRATR_CTL_WEIGHT );
1758 : NewStdAttr( HTML_BOLD_ON,
1759 : &aAttrTab.pBold, aWeight,
1760 : &aAttrTab.pBoldCJK, &aWeightCJK,
1761 20 : &aAttrTab.pBoldCTL, &aWeightCTL );
1762 : }
1763 10 : 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 12 : NewStdAttr( HTML_SPAN_ON );
1803 12 : 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 22 : EndTag( nToken );
1814 22 : 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 26 : NewFontAttr( nToken );
1830 26 : break;
1831 : case HTML_FONT_OFF:
1832 : case HTML_BIGPRINT_OFF:
1833 : case HTML_SMALLPRINT_OFF:
1834 26 : EndFontAttr( nToken );
1835 26 : 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 : NewCharFmt( 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 16 : if( !aStyleSource.isEmpty() )
1886 : {
1887 0 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1888 0 : aStyleSource = "";
1889 : }
1890 16 : 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 36 : break; // don't evaluate further???
1898 : case HTML_HTML_ON:
1899 : {
1900 20 : const HTMLOptions& rHTMLOptions = GetOptions();
1901 52 : for (size_t i = rHTMLOptions.size(); i; )
1902 : {
1903 12 : const HTMLOption& rOption = rHTMLOptions[--i];
1904 12 : 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 20 : break;
1920 :
1921 : case HTML_INPUT:
1922 8 : InsertInput();
1923 8 : 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 10 : NewAnchor();
1937 10 : break;
1938 :
1939 : case HTML_ANCHOR_OFF:
1940 10 : EndAnchor();
1941 10 : break;
1942 :
1943 : case HTML_COMMENT:
1944 0 : 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 0 : if( ' ' == aToken[ 3 ] &&
1950 0 : ' ' == 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 0 : OUStringBuffer aComment;
1958 0 : aComment.append('<').append(aToken).append('>');
1959 0 : InsertComment( aComment.makeStringAndClear() );
1960 : }
1961 : }
1962 0 : 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 36 : if( IsInHeader() && !IsReadPRE() && aUnknownToken.isEmpty() &&
2011 18 : !sSaveToken.isEmpty() && '!' != sSaveToken[0] &&
2012 0 : '%' != sSaveToken[0] )
2013 0 : aUnknownToken = sSaveToken;
2014 : // no break
2015 :
2016 : default:
2017 20 : bInsertUnknown = bKeepUnknown;
2018 20 : break;
2019 : }
2020 :
2021 3524 : if( bGetIDOption )
2022 0 : InsertIDOption();
2023 :
2024 3524 : if( bInsertUnknown )
2025 : {
2026 4 : OUString aComment("HTML: <");
2027 4 : if( (HTML_TOKEN_ONOFF & nToken) != 0 && (1 & nToken) != 0 )
2028 2 : aComment += "/";
2029 4 : aComment += sSaveToken;
2030 4 : if( !aToken.isEmpty() )
2031 : {
2032 0 : UnescapeToken();
2033 0 : (aComment += " ") += aToken;
2034 : }
2035 4 : aComment += ">";
2036 4 : 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 3524 : if( !aParaAttrs.empty() && pPam->GetPoint()->nContent.GetIndex() )
2042 2 : aParaAttrs.clear();
2043 : }
2044 :
2045 140 : static void lcl_swhtml_getItemInfo( const _HTMLAttr& rAttr,
2046 : bool& rScriptDependent, bool& rFont,
2047 : sal_uInt16& rScriptType )
2048 : {
2049 140 : sal_uInt16 nWhich = rAttr.GetItem().Which();
2050 140 : switch( nWhich )
2051 : {
2052 : case RES_CHRATR_FONT:
2053 2 : rFont = true;
2054 : //fall-through
2055 : case RES_CHRATR_FONTSIZE:
2056 : case RES_CHRATR_LANGUAGE:
2057 : case RES_CHRATR_POSTURE:
2058 : case RES_CHRATR_WEIGHT:
2059 32 : rScriptType = i18n::ScriptType::LATIN;
2060 32 : rScriptDependent = true;
2061 32 : break;
2062 : case RES_CHRATR_CJK_FONT:
2063 2 : rFont = true;
2064 : //fall-through
2065 : case RES_CHRATR_CJK_FONTSIZE:
2066 : case RES_CHRATR_CJK_LANGUAGE:
2067 : case RES_CHRATR_CJK_POSTURE:
2068 : case RES_CHRATR_CJK_WEIGHT:
2069 32 : rScriptType = i18n::ScriptType::ASIAN;
2070 32 : rScriptDependent = true;
2071 32 : break;
2072 : case RES_CHRATR_CTL_FONT:
2073 2 : rFont = true;
2074 : //fall-through
2075 : case RES_CHRATR_CTL_FONTSIZE:
2076 : case RES_CHRATR_CTL_LANGUAGE:
2077 : case RES_CHRATR_CTL_POSTURE:
2078 : case RES_CHRATR_CTL_WEIGHT:
2079 32 : rScriptType = i18n::ScriptType::COMPLEX;
2080 32 : rScriptDependent = true;
2081 32 : break;
2082 : default:
2083 44 : rScriptDependent = false;
2084 44 : rFont = false;
2085 44 : break;
2086 : }
2087 140 : }
2088 :
2089 560 : bool SwHTMLParser::AppendTxtNode( SwHTMLAppendMode eMode, bool bUpdateNum )
2090 : {
2091 : // Ein harter Zeilen-Umbruch am Ende muss immer entfernt werden.
2092 : // Einen zweiten ersetzen wir durch einen Absatz-Abstand.
2093 560 : sal_Int32 nLFStripped = StripTrailingLF();
2094 560 : if( (AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode) && nLFStripped > 1 )
2095 0 : eMode = AM_SPACE;
2096 :
2097 : // die harten Attribute an diesem Absatz werden nie mehr ungueltig
2098 560 : if( !aParaAttrs.empty() )
2099 0 : aParaAttrs.clear();
2100 :
2101 560 : if( AM_SPACE==eMode || AM_NOSPACE==eMode )
2102 : {
2103 : SwTxtNode *pTxtNode =
2104 552 : pPam->GetPoint()->nNode.GetNode().GetTxtNode();
2105 :
2106 : const SvxULSpaceItem& rULSpace =
2107 552 : (const SvxULSpaceItem&)pTxtNode->SwCntntNode::GetAttr( RES_UL_SPACE );
2108 :
2109 4 : bool bChange = AM_NOSPACE==eMode ? rULSpace.GetLower() > 0
2110 556 : : rULSpace.GetLower() == 0;
2111 :
2112 552 : if( bChange )
2113 : {
2114 : const SvxULSpaceItem& rCollULSpace =
2115 526 : pTxtNode->GetAnyFmtColl().GetULSpace();
2116 :
2117 2 : bool bMayReset = AM_NOSPACE==eMode ? rCollULSpace.GetLower() == 0
2118 528 : : rCollULSpace.GetLower() > 0;
2119 :
2120 528 : if( bMayReset &&
2121 2 : rCollULSpace.GetUpper() == rULSpace.GetUpper() )
2122 : {
2123 2 : pTxtNode->ResetAttr( RES_UL_SPACE );
2124 : }
2125 : else
2126 : {
2127 : pTxtNode->SetAttr(
2128 524 : SvxULSpaceItem( rULSpace.GetUpper(),
2129 1048 : AM_NOSPACE==eMode ? 0 : HTML_PARSPACE, RES_UL_SPACE ) );
2130 : }
2131 : }
2132 : }
2133 560 : bNoParSpace = AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode;
2134 :
2135 560 : SwPosition aOldPos( *pPam->GetPoint() );
2136 :
2137 560 : bool bRet = pDoc->getIDocumentContentOperations().AppendTxtNode( *pPam->GetPoint() );
2138 :
2139 : // Zeichen-Attribute aufspalten und ggf keine setzen, die ueber den
2140 : // ganzen Absatz gesetzt sind
2141 560 : const SwNodeIndex& rEndIdx = aOldPos.nNode;
2142 560 : const sal_Int32 nEndCnt = aOldPos.nContent.GetIndex();
2143 560 : const SwPosition& rPos = *pPam->GetPoint();
2144 :
2145 560 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
2146 22960 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
2147 : nCnt--; ++pTbl )
2148 : {
2149 22400 : _HTMLAttr *pAttr = *pTbl;
2150 22400 : if( pAttr && pAttr->GetItem().Which() < RES_PARATR_BEGIN )
2151 : {
2152 1538 : bool bWholePara = false;
2153 :
2154 4614 : while( pAttr )
2155 : {
2156 1538 : _HTMLAttr *pNext = pAttr->GetNext();
2157 3106 : if( pAttr->GetSttParaIdx() < rEndIdx.GetIndex() ||
2158 3076 : (!bWholePara &&
2159 3076 : pAttr->GetSttPara() == rEndIdx &&
2160 1538 : pAttr->GetSttCnt() != nEndCnt) )
2161 : {
2162 : bWholePara =
2163 60 : pAttr->GetSttPara() == rEndIdx &&
2164 60 : pAttr->GetSttCnt() == 0;
2165 :
2166 30 : sal_Int32 nStt = pAttr->nSttCntnt;
2167 30 : bool bScript = false, bFont = false;
2168 : sal_uInt16 nScriptItem;
2169 30 : bool bInsert = true;
2170 : lcl_swhtml_getItemInfo( *pAttr, bScript, bFont,
2171 30 : nScriptItem );
2172 : // den besehrigen Teil setzen
2173 30 : if( bInsert && bScript )
2174 : {
2175 : const SwTxtNode *pTxtNd =
2176 30 : pAttr->GetSttPara().GetNode().GetTxtNode();
2177 : OSL_ENSURE( pTxtNd, "No text node" );
2178 30 : if( pTxtNd )
2179 : {
2180 30 : const OUString& rText = pTxtNd->GetTxt();
2181 : sal_uInt16 nScriptTxt =
2182 60 : g_pBreakIt->GetBreakIter()->getScriptType(
2183 30 : rText, pAttr->GetSttCnt() );
2184 : sal_Int32 nScriptEnd = g_pBreakIt->GetBreakIter()
2185 30 : ->endOfScript( rText, nStt, nScriptTxt );
2186 60 : while( nScriptEnd < nEndCnt )
2187 : {
2188 0 : if( nScriptItem == nScriptTxt )
2189 : {
2190 : _HTMLAttr *pSetAttr =
2191 0 : pAttr->Clone( rEndIdx, nScriptEnd );
2192 0 : pSetAttr->nSttCntnt = nStt;
2193 0 : pSetAttr->ClearPrev();
2194 0 : if( !pNext || bWholePara )
2195 : {
2196 0 : if (pSetAttr->bInsAtStart)
2197 0 : aSetAttrTab.push_front( pSetAttr );
2198 : else
2199 0 : aSetAttrTab.push_back( pSetAttr );
2200 : }
2201 : else
2202 0 : pNext->InsertPrev( pSetAttr );
2203 : }
2204 0 : nStt = nScriptEnd;
2205 0 : nScriptTxt = g_pBreakIt->GetBreakIter()->getScriptType(
2206 0 : rText, nStt );
2207 : nScriptEnd = g_pBreakIt->GetBreakIter()
2208 0 : ->endOfScript( rText, nStt, nScriptTxt );
2209 : }
2210 30 : bInsert = nScriptItem == nScriptTxt;
2211 : }
2212 : }
2213 30 : if( bInsert )
2214 : {
2215 : _HTMLAttr *pSetAttr =
2216 10 : pAttr->Clone( rEndIdx, nEndCnt );
2217 10 : pSetAttr->nSttCntnt = nStt;
2218 :
2219 : // Wenn das Attribut den gesamten Absatz umspannt, werden
2220 : // alle auesseren Attribute nicht mehr beachtet. Deshalb
2221 : // darf es auch nicht in die Prev-Liste eines ausseren
2222 : // Attributs eingetragen werden, denn dieses wird ja
2223 : // erstmal nicht gesetzt. Das fuehrt zu verschiebenungen,
2224 : // wenn Felder ins Rennen kommen
2225 10 : if( !pNext || bWholePara )
2226 : {
2227 20 : if (pSetAttr->bInsAtStart)
2228 10 : aSetAttrTab.push_front( pSetAttr );
2229 : else
2230 0 : aSetAttrTab.push_back( pSetAttr );
2231 : }
2232 : else
2233 0 : pNext->InsertPrev( pSetAttr );
2234 : }
2235 : else
2236 : {
2237 20 : _HTMLAttr *pPrev = pAttr->GetPrev();
2238 20 : if( pPrev )
2239 : {
2240 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
2241 0 : if( !pNext || bWholePara )
2242 : {
2243 0 : if (pPrev->bInsAtStart)
2244 0 : aSetAttrTab.push_front( pPrev );
2245 : else
2246 0 : aSetAttrTab.push_back( pPrev );
2247 : }
2248 : else
2249 0 : pNext->InsertPrev( pPrev );
2250 : }
2251 : }
2252 30 : pAttr->ClearPrev();
2253 : }
2254 :
2255 1538 : pAttr->SetStart( rPos );
2256 1538 : pAttr = pNext;
2257 : }
2258 : }
2259 : }
2260 :
2261 560 : if( bUpdateNum )
2262 : {
2263 560 : if( GetNumInfo().GetDepth() )
2264 : {
2265 0 : sal_uInt8 nLvl = GetNumInfo().GetLevel();
2266 0 : SetNodeNum( nLvl, false );
2267 : }
2268 : else
2269 560 : pPam->GetNode().GetTxtNode()->ResetAttr( RES_PARATR_NUMRULE );
2270 : }
2271 :
2272 : // Attrubute im Absatz davor sollte man jetzt setzen (wegen JavaScript)
2273 560 : SetAttr();
2274 :
2275 : // Now it is time to get rid of all script dependent hints that are
2276 : // equal to the settings in the style
2277 560 : SwTxtNode *pTxtNd = rEndIdx.GetNode().GetTxtNode();
2278 : OSL_ENSURE( pTxtNd, "There is the txt node" );
2279 560 : size_t nCntAttr = (pTxtNd && pTxtNd->GetpSwpHints())
2280 584 : ? pTxtNd->GetSwpHints().Count() : 0;
2281 560 : if( nCntAttr )
2282 : {
2283 : // These are the end position of all script depenent hints.
2284 : // If we find a hint that starts before the current end position,
2285 : // we have to set it. If we find a hint that start behind or at
2286 : // that position, we have to take the hint's value into account.
2287 : // If it is equal to the style, or in fact the paragarph's value
2288 : // for that hint, the hint is removed. Otherwise it's end position
2289 : // is remembered.
2290 : sal_Int32 aEndPos[15] =
2291 24 : { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2292 24 : SwpHints& rHints = pTxtNd->GetSwpHints();
2293 66 : for( size_t i=0; i < nCntAttr; i++ )
2294 : {
2295 42 : SwTxtAttr *pHt = rHints.GetTextHint( i );
2296 42 : sal_uInt16 nWhich = pHt->Which();
2297 42 : sal_Int16 nIdx = -1;
2298 : //In 'hintids.hxx', the following five attributes don't follow
2299 : //each other in the Latin attributes as they do among CJK and
2300 : //CTL attributes, so the old code just made a mess, IMHO.
2301 : //E.g. 29-22=7, which should be LANGUAGE, but it's FONT.
2302 : //Moreover, it should occur between 0 and 4.
2303 : //Since it would be too risky to change the attribute codes,
2304 : //I repaired the following source code the 'brute force' way.
2305 :
2306 : //Old code:
2307 : /*
2308 : if( RES_CHRATR_CJK_FONT <= nWhich &&
2309 : nWhich <= RES_CHRATR_CTL_WEIGHT )
2310 : {
2311 : nIdx = static_cast< sal_uInt16 >(nWhich - RES_CHRATR_CJK_FONT + 5);
2312 : }
2313 : else switch...
2314 : */
2315 :
2316 42 : if( RES_CHRATR_CJK_FONT == nWhich || RES_CHRATR_CTL_FONT == nWhich )
2317 : {
2318 0 : nIdx = static_cast< sal_uInt16 >(0);
2319 : }
2320 42 : else if( RES_CHRATR_CJK_FONTSIZE == nWhich || RES_CHRATR_CTL_FONTSIZE == nWhich )
2321 : {
2322 0 : nIdx = static_cast< sal_uInt16 >(1);
2323 : }
2324 42 : else if( RES_CHRATR_CJK_LANGUAGE == nWhich || RES_CHRATR_CTL_LANGUAGE == nWhich )
2325 : {
2326 0 : nIdx = static_cast< sal_uInt16 >(2);
2327 : }
2328 42 : else if( RES_CHRATR_CJK_POSTURE == nWhich || RES_CHRATR_CTL_POSTURE == nWhich )
2329 : {
2330 0 : nIdx = static_cast< sal_uInt16 >(3);
2331 : }
2332 42 : else if( RES_CHRATR_CJK_WEIGHT == nWhich || RES_CHRATR_CTL_WEIGHT == nWhich )
2333 : {
2334 0 : nIdx = static_cast< sal_uInt16 >(4);
2335 : }
2336 42 : else switch( nWhich )
2337 : {
2338 0 : case RES_CHRATR_FONT: nIdx = 0; break;
2339 0 : case RES_CHRATR_FONTSIZE: nIdx = 1; break;
2340 0 : case RES_CHRATR_LANGUAGE: nIdx = 2; break;
2341 0 : case RES_CHRATR_POSTURE: nIdx = 3; break;
2342 0 : case RES_CHRATR_WEIGHT: nIdx = 4; break;
2343 : }
2344 42 : if( nIdx != -1 )
2345 : {
2346 0 : sal_Int32 nStt = pHt->GetStart();
2347 0 : if( nStt >= aEndPos[nIdx] )
2348 : {
2349 0 : bool bFont = (nIdx % 5) == 0;
2350 : const SfxPoolItem& rItem =
2351 0 : ((const SwCntntNode *)pTxtNd)->GetAttr( nWhich );
2352 0 : if( bFont ? swhtml_css1atr_equalFontItems(rItem,pHt->GetAttr())
2353 0 : : rItem == pHt->GetAttr() )
2354 : {
2355 : // The hint is the same as set in the paragraph and
2356 : // therefore, it can be deleted
2357 : // CAUTION!!! This WILL delete the hint and it MAY
2358 : // also delete the SwpHints!!! To avoid any trouble
2359 : // we leave the loop immediately if this is the last
2360 : // hint.
2361 0 : pTxtNd->DeleteAttribute( pHt );
2362 0 : if( 1 == nCntAttr )
2363 0 : break;
2364 0 : i--;
2365 0 : nCntAttr--;
2366 : }
2367 : else
2368 : {
2369 : // The hint is different. Therefore all hints within that
2370 : // hint have to be ignored.
2371 0 : aEndPos[nIdx] = pHt->GetEnd() ? *pHt->GetEnd() : nStt;
2372 : }
2373 : }
2374 : else
2375 : {
2376 : // The hint starts before another one ends.
2377 : // The hint in this case is not deleted
2378 : OSL_ENSURE( pHt->GetEnd() && *pHt->GetEnd() <= aEndPos[nIdx],
2379 : "hints aren't nested properly!" );
2380 : }
2381 : }
2382 : }
2383 : }
2384 :
2385 560 : if( !pTable && !--nParaCnt )
2386 2 : Show();
2387 :
2388 560 : return bRet;
2389 : }
2390 :
2391 552 : void SwHTMLParser::AddParSpace()
2392 : {
2393 : //If it already has ParSpace, return
2394 552 : if( !bNoParSpace )
2395 1104 : return;
2396 :
2397 0 : bNoParSpace = false;
2398 :
2399 0 : sal_uLong nNdIdx = pPam->GetPoint()->nNode.GetIndex() - 1;
2400 :
2401 0 : SwTxtNode *pTxtNode = pDoc->GetNodes()[nNdIdx]->GetTxtNode();
2402 0 : if( !pTxtNode )
2403 0 : return;
2404 :
2405 : SvxULSpaceItem rULSpace =
2406 0 : (const SvxULSpaceItem&)pTxtNode->SwCntntNode::GetAttr( RES_UL_SPACE );
2407 0 : if( !rULSpace.GetLower() )
2408 : {
2409 : const SvxULSpaceItem& rCollULSpace =
2410 0 : pTxtNode->GetAnyFmtColl().GetULSpace();
2411 0 : if( rCollULSpace.GetLower() &&
2412 0 : rCollULSpace.GetUpper() == rULSpace.GetUpper() )
2413 : {
2414 0 : pTxtNode->ResetAttr( RES_UL_SPACE );
2415 : }
2416 : else
2417 : {
2418 0 : if (!pTxtNode->HasHints())
2419 : {
2420 : pTxtNode->SetAttr(
2421 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_PARSPACE, RES_UL_SPACE ) );
2422 0 : return;
2423 : }
2424 : //What I do here, is that I examine the attributes, and if
2425 : //I find out, that it's CJK/CTL, then I set the paragraph space
2426 : //to the value set in HTML_CJK_PARSPACE/HTML_CTL_PARSPACE.
2427 :
2428 0 : bool bIsCJK = false;
2429 0 : bool bIsCTL = false;
2430 0 : SwpHints& rHints = pTxtNode->GetSwpHints();
2431 : sal_uInt16 nWhich;
2432 : SwTxtAttr *pHt;
2433 :
2434 0 : const size_t nCntAttr = (pTxtNode && pTxtNode->GetpSwpHints())
2435 0 : ? pTxtNode->GetSwpHints().Count() : 0;
2436 :
2437 0 : for(size_t i = 0; i < nCntAttr; ++i)
2438 : {
2439 0 : pHt = rHints.GetTextHint(i);
2440 0 : nWhich = pHt->Which();
2441 0 : if (RES_CHRATR_CJK_FONT == nWhich ||
2442 0 : RES_CHRATR_CJK_FONTSIZE == nWhich ||
2443 0 : RES_CHRATR_CJK_LANGUAGE == nWhich ||
2444 0 : RES_CHRATR_CJK_POSTURE == nWhich ||
2445 : RES_CHRATR_CJK_WEIGHT == nWhich)
2446 : {
2447 0 : bIsCJK = true;
2448 0 : break;
2449 : }
2450 0 : if (RES_CHRATR_CTL_FONT == nWhich ||
2451 0 : RES_CHRATR_CTL_FONTSIZE == nWhich ||
2452 0 : RES_CHRATR_CTL_LANGUAGE == nWhich ||
2453 0 : RES_CHRATR_CTL_POSTURE == nWhich ||
2454 : RES_CHRATR_CTL_WEIGHT == nWhich)
2455 : {
2456 0 : bIsCTL = true;
2457 0 : break;
2458 : }
2459 : }
2460 :
2461 0 : if( bIsCTL )
2462 : {
2463 : pTxtNode->SetAttr(
2464 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_CTL_PARSPACE, RES_UL_SPACE ) );
2465 : }
2466 0 : else if( bIsCJK )
2467 : {
2468 : pTxtNode->SetAttr(
2469 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_CJK_PARSPACE, RES_UL_SPACE ) );
2470 : } else {
2471 : pTxtNode->SetAttr(
2472 0 : SvxULSpaceItem( rULSpace.GetUpper(), HTML_PARSPACE, RES_UL_SPACE ) );
2473 : }
2474 : }
2475 0 : }
2476 : }
2477 :
2478 4 : void SwHTMLParser::Show()
2479 : {
2480 : // Hier wird
2481 : // - ein EndAction gerufen, damit formatiert wird
2482 : // - ein Reschedule gerufen,
2483 : // - die eiegen View-Shell wieder gesetzt
2484 : // - und Start-Action gerufen
2485 :
2486 : OSL_ENSURE( SVPAR_WORKING==eState, "Show nicht im Working-State - Das kann ins Auge gehen" );
2487 4 : SwViewShell *pOldVSh = CallEndAction();
2488 :
2489 4 : Application::Reschedule();
2490 :
2491 12 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
2492 8 : || 1 == pDoc->getReferenceCount() )
2493 : {
2494 : // wurde der Import vom SFX abgebrochen?
2495 0 : eState = SVPAR_ERROR;
2496 : }
2497 :
2498 : // Die SwViewShell nochmal holen, denn sie koennte im Reschedule
2499 : // zerstoert wirden sein.
2500 4 : SwViewShell *pVSh = CallStartAction( pOldVSh );
2501 :
2502 : // ist der aktuelle Node nicht mehr sichtbar, dann benutzen wir
2503 : // eine groessere Schrittweite
2504 4 : if( pVSh )
2505 : {
2506 0 : nParaCnt = (pPam->GetPoint()->nNode.GetNode().IsInVisibleArea(pVSh))
2507 0 : ? 5 : 50;
2508 : }
2509 4 : }
2510 :
2511 546 : void SwHTMLParser::ShowStatline()
2512 : {
2513 : // Hier wird
2514 : // - ein Reschedule gerufen, damit gescrollt werden kann
2515 : // - die eiegen View-Shell wieder gesetzt
2516 : // - ein Start/End-Action gerufen, wenn gescrollt wurde.
2517 :
2518 : OSL_ENSURE( SVPAR_WORKING==eState, "ShowStatLine nicht im Working-State - Das kann ins Auge gehen" );
2519 :
2520 : // Laufbalkenanzeige
2521 546 : if( !GetMedium() || !GetMedium()->IsRemote() )
2522 : {
2523 546 : ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2524 546 : CheckActionViewShell();
2525 : }
2526 : else
2527 : {
2528 0 : Application::Reschedule();
2529 :
2530 0 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
2531 0 : || 1 == pDoc->getReferenceCount() )
2532 : // wurde der Import vom SFX abgebrochen?
2533 0 : eState = SVPAR_ERROR;
2534 :
2535 0 : SwViewShell *pVSh = CheckActionViewShell();
2536 0 : if( pVSh && pVSh->HasInvalidRect() )
2537 : {
2538 0 : CallEndAction( false, false );
2539 0 : CallStartAction( pVSh, false );
2540 : }
2541 : }
2542 546 : }
2543 :
2544 50 : SwViewShell *SwHTMLParser::CallStartAction( SwViewShell *pVSh, bool bChkPtr )
2545 : {
2546 : OSL_ENSURE( !pActionViewShell, "CallStartAction: SwViewShell schon gesetzt" );
2547 :
2548 50 : if( !pVSh || bChkPtr )
2549 : {
2550 : #if OSL_DEBUG_LEVEL > 0
2551 : SwViewShell *pOldVSh = pVSh;
2552 : #endif
2553 50 : pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2554 : #if OSL_DEBUG_LEVEL > 0
2555 : OSL_ENSURE( !pVSh || !pOldVSh || pOldVSh == pVSh, "CallStartAction: Wer hat die SwViewShell ausgetauscht?" );
2556 : if( pOldVSh && !pVSh )
2557 : pVSh = 0;
2558 : #endif
2559 : }
2560 50 : pActionViewShell = pVSh;
2561 :
2562 50 : if( pActionViewShell )
2563 : {
2564 2 : if( pActionViewShell->ISA( SwEditShell ) )
2565 2 : ((SwEditShell*)pActionViewShell)->StartAction();
2566 : else
2567 0 : pActionViewShell->StartAction();
2568 : }
2569 :
2570 50 : return pActionViewShell;
2571 : }
2572 :
2573 48 : SwViewShell *SwHTMLParser::CallEndAction( bool bChkAction, bool bChkPtr )
2574 : {
2575 48 : if( bChkPtr )
2576 : {
2577 48 : SwViewShell *pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2578 : OSL_ENSURE( !pVSh || pActionViewShell == pVSh,
2579 : "CallEndAction: Wer hat die SwViewShell ausgetauscht?" );
2580 : #if OSL_DEBUG_LEVEL > 0
2581 : if( pActionViewShell && !pVSh )
2582 : pVSh = 0;
2583 : #endif
2584 48 : if( pVSh != pActionViewShell )
2585 0 : pActionViewShell = 0;
2586 : }
2587 :
2588 48 : if( !pActionViewShell || (bChkAction && !pActionViewShell->ActionPend()) )
2589 46 : return pActionViewShell;
2590 :
2591 2 : if( bSetCrsr )
2592 : {
2593 : // an allen CrsrEditShells die Cursor auf den Doc-Anfang setzen
2594 0 : SwViewShell *pSh = pActionViewShell;
2595 0 : do {
2596 0 : if( pSh->IsA( TYPE( SwCrsrShell ) ) )
2597 0 : ((SwCrsrShell*)pSh)->SttEndDoc(true);
2598 0 : pSh = (SwViewShell *)pSh->GetNext();
2599 0 : } while( pSh != pActionViewShell );
2600 :
2601 0 : bSetCrsr = false;
2602 : }
2603 2 : if( pActionViewShell->ISA( SwEditShell ) )
2604 : {
2605 : //Schon gescrollt?, dann dafuer sorgen, dass die View sich nicht bewegt!
2606 2 : const bool bOldLock = pActionViewShell->IsViewLocked();
2607 2 : pActionViewShell->LockView( true );
2608 2 : const bool bOldEndActionByVirDev = pActionViewShell->IsEndActionByVirDev();
2609 2 : pActionViewShell->SetEndActionByVirDev( true );
2610 2 : ((SwEditShell*)pActionViewShell)->EndAction();
2611 2 : pActionViewShell->SetEndActionByVirDev( bOldEndActionByVirDev );
2612 2 : pActionViewShell->LockView( bOldLock );
2613 :
2614 : // bChkJumpMark ist nur gesetzt, wenn das Object auch gefunden wurde
2615 2 : if( bChkJumpMark )
2616 : {
2617 0 : const Point aVisSttPos( DOCUMENTBORDER, DOCUMENTBORDER );
2618 0 : if( GetMedium() && aVisSttPos == pActionViewShell->VisArea().Pos() )
2619 : ::JumpToSwMark( pActionViewShell,
2620 0 : GetMedium()->GetURLObject().GetMark() );
2621 0 : bChkJumpMark = false;
2622 : }
2623 : }
2624 : else
2625 0 : pActionViewShell->EndAction();
2626 :
2627 : // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
2628 : // man hier abbrechen und einen Fehler setzen.
2629 2 : if( 1 == pDoc->getReferenceCount() )
2630 : {
2631 0 : eState = SVPAR_ERROR;
2632 : }
2633 :
2634 2 : SwViewShell *pVSh = pActionViewShell;
2635 2 : pActionViewShell = 0;
2636 :
2637 2 : return pVSh;
2638 : }
2639 :
2640 582 : SwViewShell *SwHTMLParser::CheckActionViewShell()
2641 : {
2642 582 : SwViewShell *pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2643 : OSL_ENSURE( !pVSh || pActionViewShell == pVSh,
2644 : "CheckActionViewShell: Wer hat die SwViewShell ausgetauscht?" );
2645 : #if OSL_DEBUG_LEVEL > 0
2646 : if( pActionViewShell && !pVSh )
2647 : pVSh = 0;
2648 : #endif
2649 582 : if( pVSh != pActionViewShell )
2650 0 : pActionViewShell = 0;
2651 :
2652 582 : return pActionViewShell;
2653 : }
2654 :
2655 68 : void SwHTMLParser::_SetAttr( bool bChkEnd, bool bBeforeTable,
2656 : _HTMLAttrs *pPostIts )
2657 : {
2658 68 : SwPaM* pAttrPam = new SwPaM( *pPam->GetPoint() );
2659 68 : const SwNodeIndex& rEndIdx = pPam->GetPoint()->nNode;
2660 68 : const sal_Int32 nEndCnt = pPam->GetPoint()->nContent.GetIndex();
2661 : _HTMLAttr* pAttr;
2662 : SwCntntNode* pCNd;
2663 : sal_uInt16 n;
2664 :
2665 68 : _HTMLAttrs aFields;
2666 :
2667 282 : for( n = aSetAttrTab.size(); n; )
2668 : {
2669 146 : pAttr = aSetAttrTab[ --n ];
2670 146 : sal_uInt16 nWhich = pAttr->pItem->Which();
2671 :
2672 146 : sal_uLong nEndParaIdx = pAttr->GetEndParaIdx();
2673 : bool bSetAttr;
2674 146 : if( bChkEnd )
2675 : {
2676 : // Zechen-Attribute mit Ende moeglich frueh,
2677 : // also noch im aktuellen Absatz setzen (wegen JavaScript
2678 : // und diversen Chats). das darf man aber nicht fuer Attribute,
2679 : // die ueber den ganzen Absatz aufgspannt werden sollen, weil
2680 : // sie aus Absatzvorlgen stammen, die nicht gesetzt werden
2681 : // koennen. Weil die Attribute mit SETATTR_DONTREPLACE
2682 : // eingefuegt werden, sollte man sie auch anchtraeglich
2683 : // noch setzen koennen.
2684 246 : bSetAttr = ( nEndParaIdx < rEndIdx.GetIndex() &&
2685 46 : (RES_LR_SPACE != nWhich || !GetNumInfo().GetNumRule()) ) ||
2686 84 : ( !pAttr->IsLikePara() &&
2687 84 : nEndParaIdx == rEndIdx.GetIndex() &&
2688 78 : pAttr->GetEndCnt() < nEndCnt &&
2689 326 : (isCHRATR(nWhich) || isTXTATR_WITHEND(nWhich)) ) ||
2690 6 : ( bBeforeTable &&
2691 12 : nEndParaIdx == rEndIdx.GetIndex() &&
2692 150 : !pAttr->GetEndCnt() );
2693 : }
2694 : else
2695 : {
2696 : // Attribiute im Content-Bereich duerfen nicht gesetzt
2697 : // werden, wenn wir in einem Sonderbereich stehen, aber
2698 : // umgekekehrt schon.
2699 2 : sal_uLong nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
2700 4 : bSetAttr = nEndParaIdx < rEndIdx.GetIndex() ||
2701 2 : rEndIdx.GetIndex() > nEndOfIcons ||
2702 2 : nEndParaIdx <= nEndOfIcons;
2703 : }
2704 :
2705 146 : if( bSetAttr )
2706 : {
2707 : // Das Attribute darf nicht in der liste der vorlaeufigen
2708 : // Absatz-Attribute stehen, weil es sonst geloescht wurde.
2709 228 : while( !aParaAttrs.empty() )
2710 : {
2711 : OSL_ENSURE( pAttr != aParaAttrs.back(),
2712 : "SetAttr: Attribut duerfte noch nicht gesetzt werden" );
2713 0 : aParaAttrs.pop_back();
2714 : }
2715 :
2716 : // dann also setzen
2717 114 : aSetAttrTab.erase( aSetAttrTab.begin() + n );
2718 :
2719 344 : while( pAttr )
2720 : {
2721 116 : _HTMLAttr *pPrev = pAttr->GetPrev();
2722 116 : if( !pAttr->bValid )
2723 : {
2724 : // ungueltige Attribute koennen gloescht werden
2725 0 : delete pAttr;
2726 0 : pAttr = pPrev;
2727 0 : continue; //break;
2728 : }
2729 :
2730 116 : pCNd = pAttr->nSttPara.GetNode().GetCntntNode();
2731 116 : if( !pCNd )
2732 : {
2733 : // durch die elende Loescherei von Nodes kann auch mal
2734 : // ein Index auf einen End-Node zeigen :-(
2735 0 : if ( (pAttr->GetSttPara() == pAttr->GetEndPara()) &&
2736 0 : !isTXTATR_NOEND(nWhich) )
2737 : {
2738 : // wenn der End-Index auch auf den Node zeigt
2739 : // brauchen wir auch kein Attribut mehr zu setzen,
2740 : // es sei denn, es ist ein Text-Attribut.
2741 0 : delete pAttr;
2742 0 : pAttr = pPrev;
2743 0 : continue; //break;
2744 : }
2745 0 : pCNd = pDoc->GetNodes().GoNext( &(pAttr->nSttPara) );
2746 0 : if( pCNd )
2747 0 : pAttr->nSttCntnt = 0;
2748 : else
2749 : {
2750 : OSL_ENSURE( false, "SetAttr: GoNext() failed!" );
2751 0 : delete pAttr;
2752 0 : pAttr = pPrev;
2753 0 : continue; // break;
2754 : }
2755 : }
2756 116 : pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
2757 :
2758 : // durch das Loeschen von BRs kann der Start-Index
2759 : // auch mal hinter das Ende des Textes zeigen
2760 116 : if( pAttr->nSttCntnt > pCNd->Len() )
2761 0 : pAttr->nSttCntnt = pCNd->Len();
2762 116 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttCntnt );
2763 :
2764 116 : pAttrPam->SetMark();
2765 116 : if ( (pAttr->GetSttPara() != pAttr->GetEndPara()) &&
2766 0 : !isTXTATR_NOEND(nWhich) )
2767 : {
2768 0 : pCNd = pAttr->nEndPara.GetNode().GetCntntNode();
2769 0 : if( !pCNd )
2770 : {
2771 0 : pCNd = pDoc->GetNodes().GoPrevious( &(pAttr->nEndPara) );
2772 0 : if( pCNd )
2773 0 : pAttr->nEndCntnt = pCNd->Len();
2774 : else
2775 : {
2776 : OSL_ENSURE( false, "SetAttr: GoPrevious() failed!" );
2777 0 : pAttrPam->DeleteMark();
2778 0 : delete pAttr;
2779 0 : pAttr = pPrev;
2780 0 : continue; // break;
2781 : }
2782 : }
2783 :
2784 0 : pAttrPam->GetPoint()->nNode = pAttr->nEndPara;
2785 : }
2786 116 : else if( pAttr->IsLikePara() )
2787 : {
2788 2 : pAttr->nEndCntnt = pCNd->Len();
2789 : }
2790 :
2791 : // durch das Loeschen von BRs kann der End-Index
2792 : // auch mal hinter das Ende des Textes zeigen
2793 116 : if( pAttr->nEndCntnt > pCNd->Len() )
2794 0 : pAttr->nEndCntnt = pCNd->Len();
2795 :
2796 116 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nEndCntnt );
2797 122 : if( bBeforeTable &&
2798 6 : pAttrPam->GetPoint()->nNode.GetIndex() ==
2799 6 : rEndIdx.GetIndex() )
2800 : {
2801 : // wenn wir vor dem Einfuegen einer Tabelle stehen
2802 : // und das Attribut im aktuellen Node beendet wird,
2803 : // muessen wir es im Node davor beenden oder wegschmeissen,
2804 : // wenn es erst in dem Node beginnt
2805 12 : if( nWhich != RES_BREAK && nWhich != RES_PAGEDESC &&
2806 6 : !isTXTATR_NOEND(nWhich) )
2807 : {
2808 0 : if( pAttrPam->GetMark()->nNode.GetIndex() !=
2809 0 : rEndIdx.GetIndex() )
2810 : {
2811 : OSL_ENSURE( !pAttrPam->GetPoint()->nContent.GetIndex(),
2812 : "Content-Position vor Tabelle nicht 0???" );
2813 0 : pAttrPam->Move( fnMoveBackward );
2814 : }
2815 : else
2816 : {
2817 0 : pAttrPam->DeleteMark();
2818 0 : delete pAttr;
2819 0 : pAttr = pPrev;
2820 0 : continue;
2821 : }
2822 : }
2823 : }
2824 :
2825 116 : switch( nWhich )
2826 : {
2827 : case RES_FLTR_BOOKMARK: // insert bookmark
2828 : {
2829 8 : const OUString sName( ((SfxStringItem*)pAttr->pItem)->GetValue() );
2830 8 : IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
2831 8 : IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark( sName );
2832 8 : if( ppBkmk != pMarkAccess->getAllMarksEnd() &&
2833 0 : ppBkmk->get()->GetMarkStart() == *pAttrPam->GetPoint() )
2834 0 : break; // do not generate duplicates on this position
2835 8 : pAttrPam->DeleteMark();
2836 : const ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
2837 : *pAttrPam,
2838 : sName,
2839 8 : IDocumentMarkAccess::BOOKMARK );
2840 :
2841 : // jump to bookmark
2842 8 : if( JUMPTO_MARK == eJumpTo && pNewMark->GetName() == sJmpMark )
2843 : {
2844 0 : bChkJumpMark = true;
2845 0 : eJumpTo = JUMPTO_NONE;
2846 8 : }
2847 : }
2848 8 : break;
2849 : case RES_TXTATR_FIELD:
2850 : case RES_TXTATR_ANNOTATION:
2851 : case RES_TXTATR_INPUTFIELD:
2852 : {
2853 : sal_uInt16 nFldWhich =
2854 : pPostIts
2855 6 : ? ((const SwFmtFld *)pAttr->pItem)->GetField()->GetTyp()->Which()
2856 38 : : 0;
2857 32 : if( pPostIts && (RES_POSTITFLD == nFldWhich ||
2858 : RES_SCRIPTFLD == nFldWhich) )
2859 : {
2860 6 : pPostIts->push_front( pAttr );
2861 : }
2862 : else
2863 : {
2864 26 : aFields.push_back( pAttr);
2865 : }
2866 : }
2867 32 : pAttrPam->DeleteMark();
2868 32 : pAttr = pPrev;
2869 32 : continue;
2870 :
2871 : case RES_LR_SPACE:
2872 8 : if( pAttrPam->GetPoint()->nNode.GetIndex() ==
2873 4 : pAttrPam->GetMark()->nNode.GetIndex() &&
2874 : pCNd )
2875 : {
2876 : // wegen Numerierungen dieses Attribut direkt
2877 : // am Node setzen
2878 4 : pCNd->SetAttr( *pAttr->pItem );
2879 4 : break;
2880 : }
2881 : OSL_ENSURE( false,
2882 : "LRSpace ueber mehrere Absaetze gesetzt!" );
2883 : // no break (shouldn't reach this point anyway)
2884 : default:
2885 :
2886 : // ggfs. ein Bookmark anspringen
2887 78 : if( RES_TXTATR_INETFMT == nWhich &&
2888 72 : JUMPTO_MARK == eJumpTo &&
2889 0 : sJmpMark == ((SwFmtINetFmt*)pAttr->pItem)->GetName() )
2890 : {
2891 0 : bChkJumpMark = true;
2892 0 : eJumpTo = JUMPTO_NONE;
2893 : }
2894 :
2895 72 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pAttrPam, *pAttr->pItem, nsSetAttrMode::SETATTR_DONTREPLACE );
2896 : }
2897 84 : pAttrPam->DeleteMark();
2898 :
2899 84 : delete pAttr;
2900 84 : pAttr = pPrev;
2901 : }
2902 : }
2903 : }
2904 :
2905 136 : for( n = aMoveFlyFrms.size(); n; )
2906 : {
2907 0 : SwFrmFmt *pFrmFmt = aMoveFlyFrms[ --n ];
2908 :
2909 0 : const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
2910 : OSL_ENSURE( FLY_AT_PARA == rAnchor.GetAnchorId(),
2911 : "Nur Auto-Rahmen brauchen eine Spezialbehandlung" );
2912 0 : const SwPosition *pFlyPos = rAnchor.GetCntntAnchor();
2913 0 : sal_uLong nFlyParaIdx = pFlyPos->nNode.GetIndex();
2914 : bool bMoveFly;
2915 0 : if( bChkEnd )
2916 : {
2917 0 : bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
2918 0 : ( nFlyParaIdx == rEndIdx.GetIndex() &&
2919 0 : aMoveFlyCnts[n] < nEndCnt );
2920 : }
2921 : else
2922 : {
2923 0 : sal_uLong nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
2924 0 : bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
2925 0 : rEndIdx.GetIndex() > nEndOfIcons ||
2926 0 : nFlyParaIdx <= nEndOfIcons;
2927 : }
2928 0 : if( bMoveFly )
2929 : {
2930 0 : pFrmFmt->DelFrms();
2931 0 : *pAttrPam->GetPoint() = *pFlyPos;
2932 0 : pAttrPam->GetPoint()->nContent.Assign( pAttrPam->GetCntntNode(),
2933 0 : aMoveFlyCnts[n] );
2934 0 : SwFmtAnchor aAnchor( rAnchor );
2935 0 : aAnchor.SetType( FLY_AT_CHAR );
2936 0 : aAnchor.SetAnchor( pAttrPam->GetPoint() );
2937 0 : pFrmFmt->SetFmtAttr( aAnchor );
2938 :
2939 0 : const SwFmtHoriOrient& rHoriOri = pFrmFmt->GetHoriOrient();
2940 0 : if( text::HoriOrientation::LEFT == rHoriOri.GetHoriOrient() )
2941 : {
2942 0 : SwFmtHoriOrient aHoriOri( rHoriOri );
2943 0 : aHoriOri.SetRelationOrient( text::RelOrientation::CHAR );
2944 0 : pFrmFmt->SetFmtAttr( aHoriOri );
2945 : }
2946 0 : const SwFmtVertOrient& rVertOri = pFrmFmt->GetVertOrient();
2947 0 : if( text::VertOrientation::TOP == rVertOri.GetVertOrient() )
2948 : {
2949 0 : SwFmtVertOrient aVertOri( rVertOri );
2950 0 : aVertOri.SetRelationOrient( text::RelOrientation::CHAR );
2951 0 : pFrmFmt->SetFmtAttr( aVertOri );
2952 : }
2953 :
2954 0 : pFrmFmt->MakeFrms();
2955 0 : aMoveFlyFrms.erase( aMoveFlyFrms.begin() + n );
2956 0 : aMoveFlyCnts.erase( aMoveFlyCnts.begin() + n );
2957 : }
2958 : }
2959 162 : while( !aFields.empty() )
2960 : {
2961 26 : pAttr = aFields[0];
2962 :
2963 26 : pCNd = pAttr->nSttPara.GetNode().GetCntntNode();
2964 26 : pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
2965 26 : pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttCntnt );
2966 :
2967 26 : if( bBeforeTable &&
2968 0 : pAttrPam->GetPoint()->nNode.GetIndex() == rEndIdx.GetIndex() )
2969 : {
2970 : OSL_ENSURE( !bBeforeTable, "Aha, der Fall tritt also doch ein" );
2971 : OSL_ENSURE( !pAttrPam->GetPoint()->nContent.GetIndex(),
2972 : "Content-Position vor Tabelle nicht 0???" );
2973 : // !!!
2974 0 : pAttrPam->Move( fnMoveBackward );
2975 : }
2976 :
2977 26 : pDoc->getIDocumentContentOperations().InsertPoolItem( *pAttrPam, *pAttr->pItem, 0 );
2978 :
2979 26 : aFields.pop_front();
2980 26 : delete pAttr;
2981 : }
2982 :
2983 68 : delete pAttrPam;
2984 68 : }
2985 :
2986 1656 : void SwHTMLParser::NewAttr( _HTMLAttr **ppAttr, const SfxPoolItem& rItem )
2987 : {
2988 : // Font-Hoehen und -Farben- sowie Escapement-Attribute duerfen nicht
2989 : // zusammengefasst werden. Sie werden deshalb in einer Liste gespeichert,
2990 : // in der das zuletzt aufgespannte Attribut vorne steht und der Count
2991 : // immer 1 ist. Fuer alle anderen Attribute wird der Count einfach
2992 : // hochgezaehlt.
2993 1656 : if( *ppAttr )
2994 : {
2995 6 : _HTMLAttr *pAttr = new _HTMLAttr( *pPam->GetPoint(), rItem,
2996 6 : ppAttr );
2997 6 : pAttr->InsertNext( *ppAttr );
2998 6 : (*ppAttr) = pAttr;
2999 : }
3000 : else
3001 1650 : (*ppAttr) = new _HTMLAttr( *pPam->GetPoint(), rItem, ppAttr );
3002 1656 : }
3003 :
3004 1656 : void SwHTMLParser::EndAttr( _HTMLAttr* pAttr, _HTMLAttr **ppDepAttr,
3005 : bool bChkEmpty )
3006 : {
3007 : OSL_ENSURE( !ppDepAttr, "SwHTMLParser::EndAttr: ppDepAttr-Feature ungetestet?" );
3008 : // Der Listenkopf ist im Attribut gespeichert
3009 1656 : _HTMLAttr **ppHead = pAttr->ppHead;
3010 :
3011 : OSL_ENSURE( ppHead, "keinen Attributs-Listenkopf gefunden!" );
3012 :
3013 : // die aktuelle Position als Ende-Position merken
3014 1656 : const SwNodeIndex* pEndIdx = &pPam->GetPoint()->nNode;
3015 1656 : sal_Int32 nEndCnt = pPam->GetPoint()->nContent.GetIndex();
3016 :
3017 : // WIrd das zueltzt gestartete oder ein frueher gestartetes Attribut
3018 : // beendet?
3019 1656 : _HTMLAttr *pLast = 0;
3020 1656 : if( ppHead && pAttr != *ppHead )
3021 : {
3022 : // Es wird nicht das zuletzt gestartete Attribut beendet
3023 :
3024 : // Dann suche wir das unmittelbar danach gestartete Attribut, das
3025 : // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
3026 : // mehr in der Liste
3027 4 : pLast = *ppHead;
3028 10 : while( pLast && pLast->GetNext() != pAttr )
3029 2 : pLast = pLast->GetNext();
3030 :
3031 : OSL_ENSURE( pLast, "Attribut nicht in eigener Liste gefunden!" );
3032 : }
3033 :
3034 1656 : bool bMoveBack = false;
3035 1656 : sal_uInt16 nWhich = pAttr->pItem->Which();
3036 1668 : if( !nEndCnt && RES_PARATR_BEGIN <= nWhich &&
3037 12 : *pEndIdx != pAttr->GetSttPara() )
3038 : {
3039 : // dann eine Cntntnt Position zurueck!
3040 8 : bMoveBack = pPam->Move( fnMoveBackward );
3041 8 : nEndCnt = pPam->GetPoint()->nContent.GetIndex();
3042 : }
3043 :
3044 : // nun das Attrubut beenden
3045 1656 : _HTMLAttr *pNext = pAttr->GetNext();
3046 :
3047 : bool bInsert;
3048 1656 : sal_uInt16 nScriptItem = 0;
3049 1656 : bool bScript = false, bFont = false;
3050 : // ein Bereich ??
3051 4964 : if( !bChkEmpty || (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
3052 3288 : RES_PAGEDESC == nWhich || RES_BREAK == nWhich ||
3053 4944 : *pEndIdx != pAttr->GetSttPara() ||
3054 1644 : nEndCnt != pAttr->GetSttCnt() )
3055 : {
3056 110 : bInsert = true;
3057 : // We do some optimization for script depenedent attribtes here.
3058 110 : if( *pEndIdx == pAttr->GetSttPara() )
3059 : {
3060 110 : lcl_swhtml_getItemInfo( *pAttr, bScript, bFont, nScriptItem );
3061 : }
3062 : }
3063 : else
3064 : {
3065 1546 : bInsert = false;
3066 : }
3067 :
3068 1656 : if( bInsert && bScript )
3069 : {
3070 66 : const SwTxtNode *pTxtNd = pAttr->GetSttPara().GetNode()
3071 66 : .GetTxtNode();
3072 : OSL_ENSURE( pTxtNd, "No text node" );
3073 66 : const OUString& rText = pTxtNd->GetTxt();
3074 132 : sal_uInt16 nScriptTxt = g_pBreakIt->GetBreakIter()->getScriptType(
3075 66 : rText, pAttr->GetSttCnt() );
3076 : sal_Int32 nScriptEnd = g_pBreakIt->GetBreakIter()
3077 66 : ->endOfScript( rText, pAttr->GetSttCnt(), nScriptTxt );
3078 132 : while( nScriptEnd < nEndCnt )
3079 : {
3080 0 : if( nScriptItem == nScriptTxt )
3081 : {
3082 0 : _HTMLAttr *pSetAttr = pAttr->Clone( *pEndIdx, nScriptEnd );
3083 0 : pSetAttr->ClearPrev();
3084 0 : if( pNext )
3085 0 : pNext->InsertPrev( pSetAttr );
3086 : else
3087 : {
3088 0 : if (pSetAttr->bInsAtStart)
3089 0 : aSetAttrTab.push_front( pSetAttr );
3090 : else
3091 0 : aSetAttrTab.push_back( pSetAttr );
3092 : }
3093 : }
3094 0 : pAttr->nSttCntnt = nScriptEnd;
3095 0 : nScriptTxt = g_pBreakIt->GetBreakIter()->getScriptType(
3096 0 : rText, nScriptEnd );
3097 : nScriptEnd = g_pBreakIt->GetBreakIter()
3098 0 : ->endOfScript( rText, nScriptEnd, nScriptTxt );
3099 : }
3100 66 : bInsert = nScriptItem == nScriptTxt;
3101 : }
3102 1656 : if( bInsert )
3103 : {
3104 66 : pAttr->nEndPara = *pEndIdx;
3105 66 : pAttr->nEndCntnt = nEndCnt;
3106 66 : pAttr->bInsAtStart = RES_TXTATR_INETFMT != nWhich &&
3107 132 : RES_TXTATR_CHARFMT != nWhich;
3108 :
3109 66 : if( !pNext )
3110 : {
3111 : // keine offenen Attribute dieses Typs mehr da,
3112 : // dann koennen alle gesetzt werden, es sei denn
3113 : // sie haengen noch von einem anderen Attribut ab,
3114 : // dann werden sie dort angehaengt
3115 64 : if( ppDepAttr && *ppDepAttr )
3116 0 : (*ppDepAttr)->InsertPrev( pAttr );
3117 : else
3118 : {
3119 64 : if (pAttr->bInsAtStart)
3120 58 : aSetAttrTab.push_front( pAttr );
3121 : else
3122 6 : aSetAttrTab.push_back( pAttr );
3123 : }
3124 : }
3125 : else
3126 : {
3127 : // es gibt noch andere offene Attribute des Typs,
3128 : // daher muss das Setzen zurueckgestellt werden.
3129 : // das aktuelle Attribut wird deshalb hinten an die
3130 : // Previous-Liste des Nachfolgers angehaengt
3131 2 : pNext->InsertPrev( pAttr );
3132 : }
3133 : }
3134 : else
3135 : {
3136 : // dann nicht einfuegen, sondern Loeschen. Durch das "tuerken" von
3137 : // Vorlagen durch harte Attributierung koennen sich auch mal andere
3138 : // leere Attribute in der Prev-Liste befinden, die dann trotzdem
3139 : // gesetzt werden muessen
3140 1590 : _HTMLAttr *pPrev = pAttr->GetPrev();
3141 1590 : delete pAttr;
3142 :
3143 1590 : if( pPrev )
3144 : {
3145 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
3146 0 : if( pNext )
3147 0 : pNext->InsertPrev( pPrev );
3148 : else
3149 : {
3150 0 : if (pPrev->bInsAtStart)
3151 0 : aSetAttrTab.push_front( pPrev );
3152 : else
3153 0 : aSetAttrTab.push_back( pPrev );
3154 : }
3155 : }
3156 :
3157 : }
3158 :
3159 : // wenn das erste Attribut der Liste gesetzt wurde muss noch der
3160 : // Listenkopf korrigiert werden.
3161 1656 : if( pLast )
3162 4 : pLast->pNext = pNext;
3163 1652 : else if( ppHead )
3164 1652 : *ppHead = pNext;
3165 :
3166 1656 : if( bMoveBack )
3167 8 : pPam->Move( fnMoveForward );
3168 1656 : }
3169 :
3170 0 : void SwHTMLParser::DeleteAttr( _HTMLAttr* pAttr )
3171 : {
3172 : // preliminary paragraph attributes are not allowed here, they could
3173 : // be set here and then the pointers become invalid!
3174 : OSL_ENSURE(aParaAttrs.empty(),
3175 : "Danger: there are non-final paragraph attributes");
3176 0 : if( !aParaAttrs.empty() )
3177 0 : aParaAttrs.clear();
3178 :
3179 : // Der Listenkopf ist im Attribut gespeichert
3180 0 : _HTMLAttr **ppHead = pAttr->ppHead;
3181 :
3182 : OSL_ENSURE( ppHead, "keinen Attributs-Listenkopf gefunden!" );
3183 :
3184 : // Wird das zueltzt gestartete oder ein frueher gestartetes Attribut
3185 : // entfernt?
3186 0 : _HTMLAttr *pLast = 0;
3187 0 : if( ppHead && pAttr != *ppHead )
3188 : {
3189 : // Es wird nicht das zuletzt gestartete Attribut beendet
3190 :
3191 : // Dann suche wir das unmittelbar danach gestartete Attribut, das
3192 : // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
3193 : // mehr in der Liste
3194 0 : pLast = *ppHead;
3195 0 : while( pLast && pLast->GetNext() != pAttr )
3196 0 : pLast = pLast->GetNext();
3197 :
3198 : OSL_ENSURE( pLast, "Attribut nicht in eigener Liste gefunden!" );
3199 : }
3200 :
3201 : // nun das Attrubut entfernen
3202 0 : _HTMLAttr *pNext = pAttr->GetNext();
3203 0 : _HTMLAttr *pPrev = pAttr->GetPrev();
3204 0 : delete pAttr;
3205 :
3206 0 : if( pPrev )
3207 : {
3208 : // Die Previous-Attribute muessen trotzdem gesetzt werden.
3209 0 : if( pNext )
3210 0 : pNext->InsertPrev( pPrev );
3211 : else
3212 : {
3213 0 : if (pPrev->bInsAtStart)
3214 0 : aSetAttrTab.push_front( pPrev );
3215 : else
3216 0 : aSetAttrTab.push_back( pPrev );
3217 : }
3218 : }
3219 :
3220 : // wenn das erste Attribut der Liste entfernt wurde muss noch der
3221 : // Listenkopf korrigiert werden.
3222 0 : if( pLast )
3223 0 : pLast->pNext = pNext;
3224 0 : else if( ppHead )
3225 0 : *ppHead = pNext;
3226 0 : }
3227 :
3228 2 : void SwHTMLParser::SaveAttrTab( _HTMLAttrTable& rNewAttrTab )
3229 : {
3230 : // preliminary paragraph attributes are not allowed here, they could
3231 : // be set here and then the pointers become invalid!
3232 : OSL_ENSURE(aParaAttrs.empty(),
3233 : "Danger: there are non-final paragraph attributes");
3234 2 : if( !aParaAttrs.empty() )
3235 0 : aParaAttrs.clear();
3236 :
3237 2 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
3238 2 : _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
3239 :
3240 82 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
3241 : nCnt--; (++pTbl, ++pSaveTbl) )
3242 : {
3243 80 : *pSaveTbl = *pTbl;
3244 :
3245 80 : _HTMLAttr *pAttr = *pSaveTbl;
3246 160 : while( pAttr )
3247 : {
3248 0 : pAttr->SetHead( pSaveTbl );
3249 0 : pAttr = pAttr->GetNext();
3250 : }
3251 :
3252 80 : *pTbl = 0;
3253 : }
3254 2 : }
3255 :
3256 2 : void SwHTMLParser::SplitAttrTab( _HTMLAttrTable& rNewAttrTab,
3257 : bool bMoveEndBack )
3258 : {
3259 : // preliminary paragraph attributes are not allowed here, they could
3260 : // be set here and then the pointers become invalid!
3261 : OSL_ENSURE(aParaAttrs.empty(),
3262 : "Danger: there are non-final paragraph attributes");
3263 2 : if( !aParaAttrs.empty() )
3264 0 : aParaAttrs.clear();
3265 :
3266 2 : const SwNodeIndex& nSttIdx = pPam->GetPoint()->nNode;
3267 2 : SwNodeIndex nEndIdx( nSttIdx );
3268 :
3269 : // alle noch offenen Attribute beenden und hinter der Tabelle
3270 : // neu aufspannen
3271 2 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
3272 2 : _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
3273 2 : bool bSetAttr = true;
3274 2 : const sal_Int32 nSttCnt = pPam->GetPoint()->nContent.GetIndex();
3275 2 : sal_Int32 nEndCnt = nSttCnt;
3276 :
3277 2 : if( bMoveEndBack )
3278 : {
3279 2 : sal_uLong nOldEnd = nEndIdx.GetIndex();
3280 : sal_uLong nTmpIdx;
3281 4 : if( ( nTmpIdx = pDoc->GetNodes().GetEndOfExtras().GetIndex()) >= nOldEnd ||
3282 2 : ( nTmpIdx = pDoc->GetNodes().GetEndOfAutotext().GetIndex()) >= nOldEnd )
3283 : {
3284 0 : nTmpIdx = pDoc->GetNodes().GetEndOfInserts().GetIndex();
3285 : }
3286 2 : SwCntntNode* pCNd = pDoc->GetNodes().GoPrevious(&nEndIdx);
3287 :
3288 : // keine Attribute setzen, wenn der PaM aus dem Content-Bereich
3289 : // herausgeschoben wurde.
3290 2 : bSetAttr = pCNd && nTmpIdx < nEndIdx.GetIndex();
3291 :
3292 2 : nEndCnt = (bSetAttr ? pCNd->Len() : 0);
3293 : }
3294 82 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
3295 : nCnt--; (++pTbl, ++pSaveTbl) )
3296 : {
3297 80 : _HTMLAttr *pAttr = *pTbl;
3298 80 : *pSaveTbl = 0;
3299 160 : while( pAttr )
3300 : {
3301 0 : _HTMLAttr *pNext = pAttr->GetNext();
3302 0 : _HTMLAttr *pPrev = pAttr->GetPrev();
3303 :
3304 0 : if( bSetAttr &&
3305 0 : ( pAttr->GetSttParaIdx() < nEndIdx.GetIndex() ||
3306 0 : (pAttr->GetSttPara() == nEndIdx &&
3307 0 : pAttr->GetSttCnt() != nEndCnt) ) )
3308 : {
3309 : // das Attribut muss vor der Liste gesetzt werden. Da wir
3310 : // das Original noch brauchen, weil Zeiger auf das Attribut
3311 : // noch in den Kontexten existieren, muessen wir es clonen.
3312 : // Die Next-Liste geht dabei verloren, aber die
3313 : // Previous-Liste bleibt erhalten
3314 0 : _HTMLAttr *pSetAttr = pAttr->Clone( nEndIdx, nEndCnt );
3315 :
3316 0 : if( pNext )
3317 0 : pNext->InsertPrev( pSetAttr );
3318 : else
3319 : {
3320 0 : if (pSetAttr->bInsAtStart)
3321 0 : aSetAttrTab.push_front( pSetAttr );
3322 : else
3323 0 : aSetAttrTab.push_back( pSetAttr );
3324 : }
3325 : }
3326 0 : else if( pPrev )
3327 : {
3328 : // Wenn das Attribut nicht gesetzt vor der Tabelle
3329 : // gesetzt werden muss, muessen der Previous-Attribute
3330 : // trotzdem gesetzt werden.
3331 0 : if( pNext )
3332 0 : pNext->InsertPrev( pPrev );
3333 : else
3334 : {
3335 0 : if (pPrev->bInsAtStart)
3336 0 : aSetAttrTab.push_front( pPrev );
3337 : else
3338 0 : aSetAttrTab.push_back( pPrev );
3339 : }
3340 : }
3341 :
3342 : // den Start des Attributs neu setzen und die Verkettungen
3343 : // aufbrechen
3344 0 : pAttr->Reset( nSttIdx, nSttCnt, pSaveTbl );
3345 :
3346 0 : if( *pSaveTbl )
3347 : {
3348 0 : _HTMLAttr *pSAttr = *pSaveTbl;
3349 0 : while( pSAttr->GetNext() )
3350 0 : pSAttr = pSAttr->GetNext();
3351 0 : pSAttr->InsertNext( pAttr );
3352 : }
3353 : else
3354 0 : *pSaveTbl = pAttr;
3355 :
3356 0 : pAttr = pNext;
3357 : }
3358 :
3359 80 : *pTbl = 0;
3360 2 : }
3361 2 : }
3362 :
3363 4 : void SwHTMLParser::RestoreAttrTab( const _HTMLAttrTable& rNewAttrTab,
3364 : bool bSetNewStart )
3365 : {
3366 : // preliminary paragraph attributes are not allowed here, they could
3367 : // be set here and then the pointers become invalid!
3368 : OSL_ENSURE(aParaAttrs.empty(),
3369 : "Danger: there are non-final paragraph attributes");
3370 4 : if( !aParaAttrs.empty() )
3371 0 : aParaAttrs.clear();
3372 :
3373 4 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
3374 4 : _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
3375 :
3376 164 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
3377 : nCnt--; (++pTbl, ++pSaveTbl) )
3378 : {
3379 : OSL_ENSURE( !*pTbl, "Die Attribut-Tabelle ist nicht leer!" );
3380 :
3381 160 : const SwPosition *pPos = pPam->GetPoint();
3382 160 : const SwNodeIndex& rSttPara = pPos->nNode;
3383 160 : const sal_Int32 nSttCnt = pPos->nContent.GetIndex();
3384 :
3385 160 : *pTbl = *pSaveTbl;
3386 :
3387 160 : _HTMLAttr *pAttr = *pTbl;
3388 320 : while( pAttr )
3389 : {
3390 : OSL_ENSURE( !pAttr->GetPrev() || !pAttr->GetPrev()->ppHead,
3391 : "Previous-Attribut hat noch einen Header" );
3392 0 : pAttr->SetHead( pTbl );
3393 0 : if( bSetNewStart )
3394 : {
3395 0 : pAttr->nSttPara = rSttPara;
3396 0 : pAttr->nEndPara = rSttPara;
3397 0 : pAttr->nSttCntnt = nSttCnt;
3398 0 : pAttr->nEndCntnt = nSttCnt;
3399 : }
3400 0 : pAttr = pAttr->GetNext();
3401 : }
3402 :
3403 160 : *pSaveTbl = 0;
3404 : }
3405 4 : }
3406 :
3407 32 : void SwHTMLParser::InsertAttr( const SfxPoolItem& rItem, bool bLikePara,
3408 : bool bInsAtStart )
3409 : {
3410 32 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
3411 32 : rItem );
3412 32 : if( bLikePara )
3413 0 : pTmp->SetLikePara();
3414 32 : if (bInsAtStart)
3415 0 : aSetAttrTab.push_front( pTmp );
3416 : else
3417 32 : aSetAttrTab.push_back( pTmp );
3418 32 : }
3419 :
3420 12 : void SwHTMLParser::InsertAttrs( _HTMLAttrs& rAttrs )
3421 : {
3422 30 : while( !rAttrs.empty() )
3423 : {
3424 6 : _HTMLAttr *pAttr = rAttrs.front();
3425 6 : InsertAttr( pAttr->GetItem() );
3426 6 : rAttrs.pop_front();
3427 6 : delete pAttr;
3428 : }
3429 12 : }
3430 :
3431 12 : void SwHTMLParser::NewStdAttr( int nToken )
3432 : {
3433 24 : OUString aId, aStyle, aLang, aDir;
3434 24 : OUString aClass;
3435 :
3436 12 : const HTMLOptions& rHTMLOptions = GetOptions();
3437 36 : for (size_t i = rHTMLOptions.size(); i; )
3438 : {
3439 12 : const HTMLOption& rOption = rHTMLOptions[--i];
3440 12 : switch( rOption.GetToken() )
3441 : {
3442 : case HTML_O_ID:
3443 0 : aId = rOption.GetString();
3444 0 : break;
3445 : case HTML_O_STYLE:
3446 12 : aStyle = rOption.GetString();
3447 12 : break;
3448 : case HTML_O_CLASS:
3449 0 : aClass = rOption.GetString();
3450 0 : break;
3451 : case HTML_O_LANG:
3452 0 : aLang = rOption.GetString();
3453 0 : break;
3454 : case HTML_O_DIR:
3455 0 : aDir = rOption.GetString();
3456 0 : break;
3457 : }
3458 : }
3459 :
3460 : // einen neuen Kontext anlegen
3461 12 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3462 :
3463 : // Styles parsen
3464 12 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3465 : {
3466 12 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3467 24 : SvxCSS1PropertyInfo aPropInfo;
3468 :
3469 12 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3470 : {
3471 12 : if( HTML_SPAN_ON != nToken || aClass.isEmpty() ||
3472 0 : !CreateContainer( aClass, aItemSet, aPropInfo, pCntxt ) )
3473 12 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3474 12 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3475 12 : }
3476 : }
3477 :
3478 : // den Kontext merken
3479 24 : PushContext( pCntxt );
3480 12 : }
3481 :
3482 10 : void SwHTMLParser::NewStdAttr( int nToken,
3483 : _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
3484 : _HTMLAttr **ppAttr2, const SfxPoolItem *pItem2,
3485 : _HTMLAttr **ppAttr3, const SfxPoolItem *pItem3 )
3486 : {
3487 20 : OUString aId, aStyle, aClass, aLang, aDir;
3488 :
3489 10 : const HTMLOptions& rHTMLOptions = GetOptions();
3490 20 : for (size_t i = rHTMLOptions.size(); i; )
3491 : {
3492 0 : const HTMLOption& rOption = rHTMLOptions[--i];
3493 0 : switch( rOption.GetToken() )
3494 : {
3495 : case HTML_O_ID:
3496 0 : aId = rOption.GetString();
3497 0 : break;
3498 : case HTML_O_STYLE:
3499 0 : aStyle = rOption.GetString();
3500 0 : break;
3501 : case HTML_O_CLASS:
3502 0 : aClass = rOption.GetString();
3503 0 : break;
3504 : case HTML_O_LANG:
3505 0 : aLang = rOption.GetString();
3506 0 : break;
3507 : case HTML_O_DIR:
3508 0 : aDir = rOption.GetString();
3509 0 : break;
3510 : }
3511 : }
3512 :
3513 : // einen neuen Kontext anlegen
3514 10 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3515 :
3516 : // Styles parsen
3517 10 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3518 : {
3519 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3520 0 : SvxCSS1PropertyInfo aPropInfo;
3521 :
3522 0 : aItemSet.Put( rItem );
3523 0 : if( pItem2 )
3524 0 : aItemSet.Put( *pItem2 );
3525 0 : if( pItem3 )
3526 0 : aItemSet.Put( *pItem3 );
3527 :
3528 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3529 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3530 :
3531 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3532 : }
3533 : else
3534 : {
3535 10 : InsertAttr( ppAttr ,rItem, pCntxt );
3536 10 : if( pItem2 )
3537 : {
3538 : OSL_ENSURE( ppAttr2, "missing table entry for item2" );
3539 10 : InsertAttr( ppAttr2, *pItem2, pCntxt );
3540 : }
3541 10 : if( pItem3 )
3542 : {
3543 : OSL_ENSURE( ppAttr3, "missing table entry for item3" );
3544 10 : InsertAttr( ppAttr3, *pItem3, pCntxt );
3545 : }
3546 : }
3547 :
3548 : // den Kontext merken
3549 20 : PushContext( pCntxt );
3550 10 : }
3551 :
3552 58 : void SwHTMLParser::EndTag( int nToken )
3553 : {
3554 : // den Kontext holen
3555 58 : _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
3556 58 : if( pCntxt )
3557 : {
3558 : // und ggf. die Attribute beenden
3559 58 : EndContext( pCntxt );
3560 58 : delete pCntxt;
3561 : }
3562 58 : }
3563 :
3564 0 : void SwHTMLParser::NewBasefontAttr()
3565 : {
3566 0 : OUString aId, aStyle, aClass, aLang, aDir;
3567 0 : sal_uInt16 nSize = 3;
3568 :
3569 0 : const HTMLOptions& rHTMLOptions = GetOptions();
3570 0 : for (size_t i = rHTMLOptions.size(); i; )
3571 : {
3572 0 : const HTMLOption& rOption = rHTMLOptions[--i];
3573 0 : switch( rOption.GetToken() )
3574 : {
3575 : case HTML_O_SIZE:
3576 0 : nSize = (sal_uInt16)rOption.GetNumber();
3577 0 : break;
3578 : case HTML_O_ID:
3579 0 : aId = rOption.GetString();
3580 0 : break;
3581 : case HTML_O_STYLE:
3582 0 : aStyle = rOption.GetString();
3583 0 : break;
3584 : case HTML_O_CLASS:
3585 0 : aClass = rOption.GetString();
3586 0 : break;
3587 : case HTML_O_LANG:
3588 0 : aLang = rOption.GetString();
3589 0 : break;
3590 : case HTML_O_DIR:
3591 0 : aDir = rOption.GetString();
3592 0 : break;
3593 : }
3594 : }
3595 :
3596 0 : if( nSize < 1 )
3597 0 : nSize = 1;
3598 :
3599 0 : if( nSize > 7 )
3600 0 : nSize = 7;
3601 :
3602 : // einen neuen Kontext anlegen
3603 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_BASEFONT_ON );
3604 :
3605 : // Styles parsen
3606 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3607 : {
3608 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3609 0 : SvxCSS1PropertyInfo aPropInfo;
3610 :
3611 : //CJK has different defaults
3612 0 : SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
3613 0 : aItemSet.Put( aFontHeight );
3614 0 : SvxFontHeightItem aFontHeightCJK( aFontHeights[nSize-1], 100, RES_CHRATR_CJK_FONTSIZE );
3615 0 : aItemSet.Put( aFontHeightCJK );
3616 : //Complex type can contain so many types of letters,
3617 : //that it's not really worthy to bother, IMO.
3618 : //Still, I have set a default.
3619 0 : SvxFontHeightItem aFontHeightCTL( aFontHeights[nSize-1], 100, RES_CHRATR_CTL_FONTSIZE );
3620 0 : aItemSet.Put( aFontHeightCTL );
3621 :
3622 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3623 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3624 :
3625 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3626 : }
3627 : else
3628 : {
3629 0 : SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
3630 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
3631 0 : SvxFontHeightItem aFontHeightCJK( aFontHeights[nSize-1], 100, RES_CHRATR_CJK_FONTSIZE );
3632 0 : InsertAttr( &aAttrTab.pFontHeightCJK, aFontHeightCJK, pCntxt );
3633 0 : SvxFontHeightItem aFontHeightCTL( aFontHeights[nSize-1], 100, RES_CHRATR_CTL_FONTSIZE );
3634 0 : InsertAttr( &aAttrTab.pFontHeightCTL, aFontHeightCTL, pCntxt );
3635 : }
3636 :
3637 : // den Kontext merken
3638 0 : PushContext( pCntxt );
3639 :
3640 : // die Font-Size merken
3641 0 : aBaseFontStack.push_back( nSize );
3642 0 : }
3643 :
3644 0 : void SwHTMLParser::EndBasefontAttr()
3645 : {
3646 0 : EndTag( HTML_BASEFONT_ON );
3647 :
3648 : // Stack-Unterlauf in Tabellen vermeiden
3649 0 : if( aBaseFontStack.size() > nBaseFontStMin )
3650 0 : aBaseFontStack.erase( aBaseFontStack.begin() + aBaseFontStack.size() - 1 );
3651 0 : }
3652 :
3653 26 : void SwHTMLParser::NewFontAttr( int nToken )
3654 : {
3655 : sal_uInt16 nBaseSize =
3656 26 : ( aBaseFontStack.size() > nBaseFontStMin
3657 0 : ? (aBaseFontStack[aBaseFontStack.size()-1] & FONTSIZE_MASK)
3658 26 : : 3 );
3659 : sal_uInt16 nFontSize =
3660 26 : ( aFontStack.size() > nFontStMin
3661 14 : ? (aFontStack[aFontStack.size()-1] & FONTSIZE_MASK)
3662 40 : : nBaseSize );
3663 :
3664 52 : OUString aFace, aId, aStyle, aClass, aLang, aDir;
3665 26 : Color aColor;
3666 26 : sal_uLong nFontHeight = 0; // tatsaechlich einzustellende Font-Hoehe
3667 26 : sal_uInt16 nSize = 0; // Fontgroesse in Netscape-Notation (1-7)
3668 26 : bool bColor = false;
3669 :
3670 26 : const HTMLOptions& rHTMLOptions = GetOptions();
3671 88 : for (size_t i = rHTMLOptions.size(); i; )
3672 : {
3673 36 : const HTMLOption& rOption = rHTMLOptions[--i];
3674 36 : switch( rOption.GetToken() )
3675 : {
3676 : case HTML_O_SIZE:
3677 10 : if( HTML_FONT_ON==nToken && !rOption.GetString().isEmpty() )
3678 : {
3679 : sal_Int32 nSSize;
3680 20 : if( '+' == rOption.GetString()[0] ||
3681 10 : '-' == rOption.GetString()[0] )
3682 0 : nSSize = nBaseSize + rOption.GetSNumber();
3683 : else
3684 10 : nSSize = (sal_Int32)rOption.GetNumber();
3685 :
3686 10 : if( nSSize < 1 )
3687 0 : nSSize = 1;
3688 10 : else if( nSSize > 7 )
3689 0 : nSSize = 7;
3690 :
3691 10 : nSize = (sal_uInt16)nSSize;
3692 10 : nFontHeight = aFontHeights[nSize-1];
3693 : }
3694 10 : break;
3695 : case HTML_O_COLOR:
3696 14 : if( HTML_FONT_ON==nToken )
3697 : {
3698 14 : rOption.GetColor( aColor );
3699 14 : bColor = true;
3700 : }
3701 14 : break;
3702 : case HTML_O_FACE:
3703 2 : if( HTML_FONT_ON==nToken )
3704 2 : aFace = rOption.GetString();
3705 2 : break;
3706 : case HTML_O_ID:
3707 0 : aId = rOption.GetString();
3708 0 : break;
3709 : case HTML_O_STYLE:
3710 10 : aStyle = rOption.GetString();
3711 10 : break;
3712 : case HTML_O_CLASS:
3713 0 : aClass = rOption.GetString();
3714 0 : break;
3715 : case HTML_O_LANG:
3716 0 : aLang = rOption.GetString();
3717 0 : break;
3718 : case HTML_O_DIR:
3719 0 : aDir = rOption.GetString();
3720 0 : break;
3721 : }
3722 : }
3723 :
3724 26 : if( HTML_FONT_ON != nToken )
3725 : {
3726 : // HTML_BIGPRINT_ON oder HTML_SMALLPRINT_ON
3727 :
3728 : // in Ueberschriften bestimmt die aktuelle Ueberschrift
3729 : // die Font-Hoehe und nicht BASEFONT
3730 0 : sal_uInt16 nPoolId = GetCurrFmtColl()->GetPoolFmtId();
3731 0 : if( (nPoolId>=RES_POOLCOLL_HEADLINE1 &&
3732 : nPoolId<=RES_POOLCOLL_HEADLINE6) )
3733 : {
3734 : // wenn die Schriftgroesse in der Ueberschrift noch
3735 : // nicht veraendert ist, die aus der Vorlage nehmen
3736 0 : if( nFontStHeadStart==aFontStack.size() )
3737 0 : nFontSize = static_cast< sal_uInt16 >(6 - (nPoolId - RES_POOLCOLL_HEADLINE1));
3738 : }
3739 : else
3740 0 : nPoolId = 0;
3741 :
3742 0 : if( HTML_BIGPRINT_ON == nToken )
3743 0 : nSize = ( nFontSize<7 ? nFontSize+1 : 7 );
3744 : else
3745 0 : nSize = ( nFontSize>1 ? nFontSize-1 : 1 );
3746 :
3747 : // in Ueberschriften wird die neue Fonthoehe wenn moeglich aus
3748 : // den Vorlagen geholt.
3749 0 : if( nPoolId && nSize>=1 && nSize <=6 )
3750 : nFontHeight =
3751 : pCSS1Parser->GetTxtCollFromPool(
3752 0 : RES_POOLCOLL_HEADLINE1+6-nSize )->GetSize().GetHeight();
3753 : else
3754 0 : nFontHeight = aFontHeights[nSize-1];
3755 : }
3756 :
3757 : OSL_ENSURE( !nSize == !nFontHeight, "HTML-Font-Size != Font-Height" );
3758 :
3759 52 : OUString aFontName, aStyleName;
3760 26 : FontFamily eFamily = FAMILY_DONTKNOW; // Family und Pitch,
3761 26 : FontPitch ePitch = PITCH_DONTKNOW; // falls nicht gefunden
3762 26 : rtl_TextEncoding eEnc = osl_getThreadTextEncoding();
3763 :
3764 26 : if( !aFace.isEmpty() && !pCSS1Parser->IsIgnoreFontFamily() )
3765 : {
3766 2 : const FontList *pFList = 0;
3767 2 : SwDocShell *pDocSh = pDoc->GetDocShell();
3768 2 : if( pDocSh )
3769 : {
3770 : const SvxFontListItem *pFListItem =
3771 2 : (const SvxFontListItem *)pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST);
3772 2 : if( pFListItem )
3773 2 : pFList = pFListItem->GetFontList();
3774 : }
3775 :
3776 2 : bool bFound = false;
3777 2 : sal_Int32 nStrPos = 0;
3778 8 : while( nStrPos!= -1 )
3779 : {
3780 4 : OUString aFName = aFace.getToken( 0, ',', nStrPos );
3781 4 : aFName = comphelper::string::strip(aFName, ' ');
3782 4 : if( !aFName.isEmpty() )
3783 : {
3784 4 : if( !bFound && pFList )
3785 : {
3786 4 : sal_Handle hFont = pFList->GetFirstFontInfo( aFName );
3787 4 : if( 0 != hFont )
3788 : {
3789 0 : const vcl::FontInfo& rFInfo = pFList->GetFontInfo( hFont );
3790 0 : if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
3791 : {
3792 0 : bFound = true;
3793 0 : if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
3794 0 : eEnc = RTL_TEXTENCODING_SYMBOL;
3795 : }
3796 : }
3797 : }
3798 4 : if( !aFontName.isEmpty() )
3799 2 : aFontName += ";";
3800 4 : aFontName += aFName;
3801 : }
3802 4 : }
3803 : }
3804 :
3805 : // einen neuen Kontext anlegen
3806 26 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
3807 :
3808 : // Styles parsen
3809 26 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3810 : {
3811 10 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3812 20 : SvxCSS1PropertyInfo aPropInfo;
3813 :
3814 10 : if( nFontHeight )
3815 : {
3816 10 : SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
3817 10 : aItemSet.Put( aFontHeight );
3818 20 : SvxFontHeightItem aFontHeightCJK( nFontHeight, 100, RES_CHRATR_CJK_FONTSIZE );
3819 10 : aItemSet.Put( aFontHeightCJK );
3820 20 : SvxFontHeightItem aFontHeightCTL( nFontHeight, 100, RES_CHRATR_CTL_FONTSIZE );
3821 20 : aItemSet.Put( aFontHeightCTL );
3822 : }
3823 10 : if( bColor )
3824 0 : aItemSet.Put( SvxColorItem(aColor, RES_CHRATR_COLOR) );
3825 10 : if( !aFontName.isEmpty() )
3826 : {
3827 0 : SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
3828 0 : aItemSet.Put( aFont );
3829 0 : SvxFontItem aFontCJK( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CJK_FONT );
3830 0 : aItemSet.Put( aFontCJK );
3831 0 : SvxFontItem aFontCTL( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CTL_FONT );
3832 0 : aItemSet.Put( aFontCTL );
3833 : }
3834 :
3835 10 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
3836 10 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3837 :
3838 20 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
3839 : }
3840 : else
3841 : {
3842 16 : if( nFontHeight )
3843 : {
3844 0 : SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
3845 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
3846 0 : SvxFontHeightItem aFontHeightCJK( nFontHeight, 100, RES_CHRATR_CJK_FONTSIZE );
3847 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeightCJK, pCntxt );
3848 0 : SvxFontHeightItem aFontHeightCTL( nFontHeight, 100, RES_CHRATR_CTL_FONTSIZE );
3849 0 : InsertAttr( &aAttrTab.pFontHeight, aFontHeightCTL, pCntxt );
3850 : }
3851 16 : if( bColor )
3852 14 : InsertAttr( &aAttrTab.pFontColor, SvxColorItem(aColor, RES_CHRATR_COLOR), pCntxt );
3853 16 : if( !aFontName.isEmpty() )
3854 : {
3855 2 : SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
3856 2 : InsertAttr( &aAttrTab.pFont, aFont, pCntxt );
3857 4 : SvxFontItem aFontCJK( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CJK_FONT );
3858 2 : InsertAttr( &aAttrTab.pFont, aFontCJK, pCntxt );
3859 4 : SvxFontItem aFontCTL( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_CTL_FONT );
3860 4 : InsertAttr( &aAttrTab.pFont, aFontCTL, pCntxt );
3861 : }
3862 : }
3863 :
3864 : // den Kontext merken
3865 26 : PushContext( pCntxt );
3866 :
3867 78 : aFontStack.push_back( nSize );
3868 26 : }
3869 :
3870 26 : void SwHTMLParser::EndFontAttr( int nToken )
3871 : {
3872 26 : EndTag( nToken );
3873 :
3874 : // Stack-Unterlauf in Tabellen vermeiden
3875 26 : if( aFontStack.size() > nFontStMin )
3876 26 : aFontStack.erase( aFontStack.begin() + aFontStack.size() - 1 );
3877 26 : }
3878 :
3879 546 : void SwHTMLParser::NewPara()
3880 : {
3881 546 : if( pPam->GetPoint()->nContent.GetIndex() )
3882 2 : AppendTxtNode( AM_SPACE );
3883 : else
3884 544 : AddParSpace();
3885 :
3886 546 : eParaAdjust = SVX_ADJUST_END;
3887 1092 : OUString aId, aStyle, aClass, aLang, aDir;
3888 :
3889 546 : const HTMLOptions& rHTMLOptions = GetOptions();
3890 1720 : for (size_t i = rHTMLOptions.size(); i; )
3891 : {
3892 628 : const HTMLOption& rOption = rHTMLOptions[--i];
3893 628 : switch( rOption.GetToken() )
3894 : {
3895 : case HTML_O_ID:
3896 0 : aId = rOption.GetString();
3897 0 : break;
3898 : case HTML_O_ALIGN:
3899 0 : eParaAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
3900 0 : break;
3901 : case HTML_O_STYLE:
3902 8 : aStyle = rOption.GetString();
3903 8 : break;
3904 : case HTML_O_CLASS:
3905 108 : aClass = rOption.GetString();
3906 108 : break;
3907 : case HTML_O_LANG:
3908 512 : aLang = rOption.GetString();
3909 512 : break;
3910 : case HTML_O_DIR:
3911 0 : aDir = rOption.GetString();
3912 0 : break;
3913 : }
3914 : }
3915 :
3916 : // einen neuen Kontext anlegen
3917 : _HTMLAttrContext *pCntxt =
3918 546 : !aClass.isEmpty() ? new _HTMLAttrContext( HTML_PARABREAK_ON,
3919 108 : RES_POOLCOLL_TEXT, aClass )
3920 654 : : new _HTMLAttrContext( HTML_PARABREAK_ON );
3921 :
3922 : // Styles parsen (Class nicht beruecksichtigen. Das geht nur, solange
3923 : // keine der CSS1-Properties der Klasse hart formatiert werden muss!!!)
3924 546 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
3925 : {
3926 514 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
3927 1028 : SvxCSS1PropertyInfo aPropInfo;
3928 :
3929 514 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
3930 : {
3931 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
3932 : "Class wird nicht beruecksichtigt" );
3933 514 : DoPositioning( aItemSet, aPropInfo, pCntxt );
3934 514 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
3935 514 : }
3936 : }
3937 :
3938 546 : if( SVX_ADJUST_END != eParaAdjust )
3939 0 : InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
3940 :
3941 : // und auf den Stack packen
3942 546 : PushContext( pCntxt );
3943 :
3944 : // die aktuelle Vorlage oder deren Attribute setzen
3945 546 : SetTxtCollAttrs( !aClass.isEmpty() ? pCntxt : 0 );
3946 :
3947 : // Laufbalkenanzeige
3948 546 : ShowStatline();
3949 :
3950 : OSL_ENSURE( !nOpenParaToken, "Jetzt geht ein offenes Absatz-Element verloren" );
3951 1092 : nOpenParaToken = HTML_PARABREAK_ON;
3952 546 : }
3953 :
3954 546 : void SwHTMLParser::EndPara( bool bReal )
3955 : {
3956 546 : if( HTML_LI_ON==nOpenParaToken && pTable )
3957 : {
3958 : #if OSL_DEBUG_LEVEL > 0
3959 : const SwNumRule *pNumRule = pPam->GetNode().GetTxtNode()->GetNumRule();
3960 : OSL_ENSURE( pNumRule, "Wo ist die Numrule geblieben" );
3961 : #endif
3962 : }
3963 :
3964 : // leere Absaetze werden von Netscape uebersprungen, von uns jetzt auch
3965 546 : if( bReal )
3966 : {
3967 546 : if( pPam->GetPoint()->nContent.GetIndex() )
3968 546 : AppendTxtNode( AM_SPACE );
3969 : else
3970 0 : AddParSpace();
3971 : }
3972 :
3973 : // wenn ein DD oder DT offen war, handelt es sich um eine
3974 : // implizite Def-Liste, die jetzt beendet werden muss
3975 546 : if( (nOpenParaToken==HTML_DT_ON || nOpenParaToken==HTML_DD_ON) &&
3976 : nDefListDeep)
3977 : {
3978 0 : nDefListDeep--;
3979 : }
3980 :
3981 : // den Kontext vom Stack holen. Er kann auch von einer implizit
3982 : // geoeffneten Definitionsliste kommen
3983 : _HTMLAttrContext *pCntxt =
3984 : PopContext( static_cast< sal_uInt16 >(nOpenParaToken ? (nOpenParaToken & ~1)
3985 546 : : HTML_PARABREAK_ON) );
3986 :
3987 : // Attribute beenden
3988 546 : if( pCntxt )
3989 : {
3990 546 : EndContext( pCntxt );
3991 546 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
3992 546 : delete pCntxt;
3993 : }
3994 :
3995 : // und die bisherige Vorlage neu setzen
3996 546 : if( bReal )
3997 546 : SetTxtCollAttrs();
3998 :
3999 546 : nOpenParaToken = 0;
4000 546 : }
4001 :
4002 0 : void SwHTMLParser::NewHeading( int nToken )
4003 : {
4004 0 : eParaAdjust = SVX_ADJUST_END;
4005 :
4006 0 : OUString aId, aStyle, aClass, aLang, aDir;
4007 :
4008 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4009 0 : for (size_t i = rHTMLOptions.size(); i; )
4010 : {
4011 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4012 0 : switch( rOption.GetToken() )
4013 : {
4014 : case HTML_O_ID:
4015 0 : aId = rOption.GetString();
4016 0 : break;
4017 : case HTML_O_ALIGN:
4018 0 : eParaAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
4019 0 : break;
4020 : case HTML_O_STYLE:
4021 0 : aStyle = rOption.GetString();
4022 0 : break;
4023 : case HTML_O_CLASS:
4024 0 : aClass = rOption.GetString();
4025 0 : break;
4026 : case HTML_O_LANG:
4027 0 : aLang = rOption.GetString();
4028 0 : break;
4029 : case HTML_O_DIR:
4030 0 : aDir = rOption.GetString();
4031 0 : break;
4032 : }
4033 : }
4034 :
4035 : // einen neuen Absatz aufmachen
4036 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4037 0 : AppendTxtNode( AM_SPACE );
4038 : else
4039 0 : AddParSpace();
4040 :
4041 : // die passende Vorlage suchen
4042 : sal_uInt16 nTxtColl;
4043 0 : switch( nToken )
4044 : {
4045 0 : case HTML_HEAD1_ON: nTxtColl = RES_POOLCOLL_HEADLINE1; break;
4046 0 : case HTML_HEAD2_ON: nTxtColl = RES_POOLCOLL_HEADLINE2; break;
4047 0 : case HTML_HEAD3_ON: nTxtColl = RES_POOLCOLL_HEADLINE3; break;
4048 0 : case HTML_HEAD4_ON: nTxtColl = RES_POOLCOLL_HEADLINE4; break;
4049 0 : case HTML_HEAD5_ON: nTxtColl = RES_POOLCOLL_HEADLINE5; break;
4050 0 : case HTML_HEAD6_ON: nTxtColl = RES_POOLCOLL_HEADLINE6; break;
4051 0 : default: nTxtColl = RES_POOLCOLL_STANDARD; break;
4052 : }
4053 :
4054 : // den Kontext anlegen
4055 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nTxtColl, aClass );
4056 :
4057 : // Styles parsen (zu Class siehe auch NewPara)
4058 0 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4059 : {
4060 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4061 0 : SvxCSS1PropertyInfo aPropInfo;
4062 :
4063 0 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4064 : {
4065 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4066 : "Class wird nicht beruecksichtigt" );
4067 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4068 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4069 0 : }
4070 : }
4071 :
4072 0 : if( SVX_ADJUST_END != eParaAdjust )
4073 0 : InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
4074 :
4075 : // udn auf den Stack packen
4076 0 : PushContext( pCntxt );
4077 :
4078 : // und die Vorlage oder deren Attribute setzen
4079 0 : SetTxtCollAttrs( pCntxt );
4080 :
4081 0 : nFontStHeadStart = aFontStack.size();
4082 :
4083 : // Laufbalkenanzeige
4084 0 : ShowStatline();
4085 0 : }
4086 :
4087 0 : void SwHTMLParser::EndHeading()
4088 : {
4089 : // einen neuen Absatz aufmachen
4090 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4091 0 : AppendTxtNode( AM_SPACE );
4092 : else
4093 0 : AddParSpace();
4094 :
4095 : // Kontext zu dem Token suchen und vom Stack holen
4096 0 : _HTMLAttrContext *pCntxt = 0;
4097 0 : sal_uInt16 nPos = aContexts.size();
4098 0 : while( !pCntxt && nPos>nContextStMin )
4099 : {
4100 0 : switch( aContexts[--nPos]->GetToken() )
4101 : {
4102 : case HTML_HEAD1_ON:
4103 : case HTML_HEAD2_ON:
4104 : case HTML_HEAD3_ON:
4105 : case HTML_HEAD4_ON:
4106 : case HTML_HEAD5_ON:
4107 : case HTML_HEAD6_ON:
4108 0 : pCntxt = aContexts[nPos];
4109 0 : aContexts.erase( aContexts.begin() + nPos );
4110 0 : break;
4111 : }
4112 : }
4113 :
4114 : // und noch Attribute beenden
4115 0 : if( pCntxt )
4116 : {
4117 0 : EndContext( pCntxt );
4118 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4119 0 : delete pCntxt;
4120 : }
4121 :
4122 : // die bisherige Vorlage neu setzen
4123 0 : SetTxtCollAttrs();
4124 :
4125 0 : nFontStHeadStart = nFontStMin;
4126 0 : }
4127 :
4128 0 : void SwHTMLParser::NewTxtFmtColl( int nToken, sal_uInt16 nColl )
4129 : {
4130 0 : OUString aId, aStyle, aClass, aLang, aDir;
4131 :
4132 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4133 0 : for (size_t i = rHTMLOptions.size(); i; )
4134 : {
4135 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4136 0 : switch( rOption.GetToken() )
4137 : {
4138 : case HTML_O_ID:
4139 0 : aId = rOption.GetString();
4140 0 : break;
4141 : case HTML_O_STYLE:
4142 0 : aStyle = rOption.GetString();
4143 0 : break;
4144 : case HTML_O_CLASS:
4145 0 : aClass = rOption.GetString();
4146 0 : break;
4147 : case HTML_O_LANG:
4148 0 : aLang = rOption.GetString();
4149 0 : break;
4150 : case HTML_O_DIR:
4151 0 : aDir = rOption.GetString();
4152 0 : break;
4153 : }
4154 : }
4155 :
4156 : // einen neuen Absatz aufmachen
4157 0 : SwHTMLAppendMode eMode = AM_NORMAL;
4158 0 : switch( nToken )
4159 : {
4160 : case HTML_LISTING_ON:
4161 : case HTML_XMP_ON:
4162 : // Diese beiden Tags werden jetzt auf die PRE-Vorlage gemappt.
4163 : // Fuer dem Fall, dass ein CLASS angegeben ist, loeschen wir
4164 : // es damit wir nicht die CLASS der PRE-Vorlage bekommen.
4165 0 : aClass = aEmptyOUStr;
4166 : // fall-through
4167 : case HTML_BLOCKQUOTE_ON:
4168 : case HTML_BLOCKQUOTE30_ON:
4169 : case HTML_PREFORMTXT_ON:
4170 0 : eMode = AM_SPACE;
4171 0 : break;
4172 : case HTML_ADDRESS_ON:
4173 0 : eMode = AM_NOSPACE; // ADDRESS kann auf einen <P> ohne </P> folgen
4174 0 : break;
4175 : case HTML_DT_ON:
4176 : case HTML_DD_ON:
4177 0 : eMode = AM_SOFTNOSPACE;
4178 0 : break;
4179 : default:
4180 : OSL_ENSURE( false, "unbekannte Vorlage" );
4181 0 : break;
4182 : }
4183 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4184 0 : AppendTxtNode( eMode );
4185 0 : else if( AM_SPACE==eMode )
4186 0 : AddParSpace();
4187 :
4188 : // ... und in einem Kontext merken
4189 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nColl, aClass );
4190 :
4191 : // Styles parsen (zu Class siehe auch NewPara)
4192 0 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4193 : {
4194 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4195 0 : SvxCSS1PropertyInfo aPropInfo;
4196 :
4197 0 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4198 : {
4199 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4200 : "Class wird nicht beruecksichtigt" );
4201 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4202 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4203 0 : }
4204 : }
4205 :
4206 0 : PushContext( pCntxt );
4207 :
4208 : // die neue Vorlage setzen
4209 0 : SetTxtCollAttrs( pCntxt );
4210 :
4211 : // Laufbalkenanzeige aktualisieren
4212 0 : ShowStatline();
4213 0 : }
4214 :
4215 0 : void SwHTMLParser::EndTxtFmtColl( int nToken )
4216 : {
4217 0 : SwHTMLAppendMode eMode = AM_NORMAL;
4218 0 : switch( nToken & ~1 )
4219 : {
4220 : case HTML_BLOCKQUOTE_ON:
4221 : case HTML_BLOCKQUOTE30_ON:
4222 : case HTML_PREFORMTXT_ON:
4223 : case HTML_LISTING_ON:
4224 : case HTML_XMP_ON:
4225 0 : eMode = AM_SPACE;
4226 0 : break;
4227 : case HTML_ADDRESS_ON:
4228 : case HTML_DT_ON:
4229 : case HTML_DD_ON:
4230 0 : eMode = AM_SOFTNOSPACE;
4231 0 : break;
4232 : default:
4233 : OSL_ENSURE( false, "unbekannte Vorlage" );
4234 0 : break;
4235 : }
4236 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4237 0 : AppendTxtNode( eMode );
4238 0 : else if( AM_SPACE==eMode )
4239 0 : AddParSpace();
4240 :
4241 : // den aktuellen Kontext vom Stack holen
4242 0 : _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
4243 :
4244 : // und noch Attribute beenden
4245 0 : if( pCntxt )
4246 : {
4247 0 : EndContext( pCntxt );
4248 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4249 0 : delete pCntxt;
4250 : }
4251 :
4252 : // und die bisherige Vorlage setzen
4253 0 : SetTxtCollAttrs();
4254 0 : }
4255 :
4256 0 : void SwHTMLParser::NewDefList()
4257 : {
4258 0 : OUString aId, aStyle, aClass, aLang, aDir;
4259 :
4260 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4261 0 : for (size_t i = rHTMLOptions.size(); i; )
4262 : {
4263 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4264 0 : switch( rOption.GetToken() )
4265 : {
4266 : case HTML_O_ID:
4267 0 : aId = rOption.GetString();
4268 0 : break;
4269 : case HTML_O_STYLE:
4270 0 : aStyle = rOption.GetString();
4271 0 : break;
4272 : case HTML_O_CLASS:
4273 0 : aClass = rOption.GetString();
4274 0 : break;
4275 : case HTML_O_LANG:
4276 0 : aLang = rOption.GetString();
4277 0 : break;
4278 : case HTML_O_DIR:
4279 0 : aDir = rOption.GetString();
4280 0 : break;
4281 : }
4282 : }
4283 :
4284 : // einen neuen Absatz aufmachen
4285 0 : bool bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 0;
4286 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4287 0 : AppendTxtNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
4288 0 : else if( bSpace )
4289 0 : AddParSpace();
4290 :
4291 : // ein Level mehr
4292 0 : nDefListDeep++;
4293 :
4294 0 : bool bInDD = false, bNotInDD = false;
4295 0 : sal_uInt16 nPos = aContexts.size();
4296 0 : while( !bInDD && !bNotInDD && nPos>nContextStMin )
4297 : {
4298 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4299 0 : switch( nCntxtToken )
4300 : {
4301 : case HTML_DEFLIST_ON:
4302 : case HTML_DIRLIST_ON:
4303 : case HTML_MENULIST_ON:
4304 : case HTML_ORDERLIST_ON:
4305 : case HTML_UNORDERLIST_ON:
4306 0 : bNotInDD = true;
4307 0 : break;
4308 : case HTML_DD_ON:
4309 0 : bInDD = true;
4310 0 : break;
4311 : }
4312 : }
4313 :
4314 : // ... und in einem Kontext merken
4315 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_DEFLIST_ON );
4316 :
4317 : // darin auch die Raender merken
4318 0 : sal_uInt16 nLeft=0, nRight=0;
4319 0 : short nIndent=0;
4320 0 : GetMarginsFromContext( nLeft, nRight, nIndent );
4321 :
4322 : // Die Einrueckung, die sich schon aus einem DL-ergibt, entspricht der
4323 : // eines DT auf dem aktuellen Level, und die entspricht der eines
4324 : // DD auf dem Level davor. Fue einen Level >=2 muss also ein DD-Abstand
4325 : // hinzugefuegt werden
4326 0 : if( !bInDD && nDefListDeep > 1 )
4327 : {
4328 :
4329 : // und den der DT-Vorlage des aktuellen Levels
4330 : SvxLRSpaceItem rLRSpace =
4331 0 : pCSS1Parser->GetTxtFmtColl( RES_POOLCOLL_HTML_DD, aEmptyOUStr )
4332 0 : ->GetLRSpace();
4333 0 : nLeft = nLeft + static_cast< sal_uInt16 >(rLRSpace.GetTxtLeft());
4334 : }
4335 :
4336 0 : pCntxt->SetMargins( nLeft, nRight, nIndent );
4337 :
4338 : // Styles parsen
4339 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
4340 : {
4341 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4342 0 : SvxCSS1PropertyInfo aPropInfo;
4343 :
4344 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
4345 : {
4346 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4347 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt );
4348 0 : }
4349 : }
4350 :
4351 0 : PushContext( pCntxt );
4352 :
4353 : // die Attribute der neuen Vorlage setzen
4354 0 : if( nDefListDeep > 1 )
4355 0 : SetTxtCollAttrs( pCntxt );
4356 0 : }
4357 :
4358 0 : void SwHTMLParser::EndDefList()
4359 : {
4360 0 : bool bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 1;
4361 0 : if( pPam->GetPoint()->nContent.GetIndex() )
4362 0 : AppendTxtNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
4363 0 : else if( bSpace )
4364 0 : AddParSpace();
4365 :
4366 : // ein Level weniger
4367 0 : if( nDefListDeep > 0 )
4368 0 : nDefListDeep--;
4369 :
4370 : // den aktuellen Kontext vom Stack holen
4371 0 : _HTMLAttrContext *pCntxt = PopContext( HTML_DEFLIST_ON );
4372 :
4373 : // und noch Attribute beenden
4374 0 : if( pCntxt )
4375 : {
4376 0 : EndContext( pCntxt );
4377 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4378 0 : delete pCntxt;
4379 : }
4380 :
4381 : // und Vorlage setzen
4382 0 : SetTxtCollAttrs();
4383 0 : }
4384 :
4385 0 : void SwHTMLParser::NewDefListItem( int nToken )
4386 : {
4387 : // festellen, ob das DD/DT in einer DL vorkommt
4388 0 : bool bInDefList = false, bNotInDefList = false;
4389 0 : sal_uInt16 nPos = aContexts.size();
4390 0 : while( !bInDefList && !bNotInDefList && nPos>nContextStMin )
4391 : {
4392 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4393 0 : switch( nCntxtToken )
4394 : {
4395 : case HTML_DEFLIST_ON:
4396 0 : bInDefList = true;
4397 0 : break;
4398 : case HTML_DIRLIST_ON:
4399 : case HTML_MENULIST_ON:
4400 : case HTML_ORDERLIST_ON:
4401 : case HTML_UNORDERLIST_ON:
4402 0 : bNotInDefList = true;
4403 0 : break;
4404 : }
4405 : }
4406 :
4407 : // wenn nicht, implizit eine neue DL aufmachen
4408 0 : if( !bInDefList )
4409 : {
4410 0 : nDefListDeep++;
4411 : OSL_ENSURE( !nOpenParaToken,
4412 : "Jetzt geht ein offenes Absatz-Element verloren" );
4413 0 : nOpenParaToken = static_cast< sal_uInt16 >(nToken);
4414 : }
4415 :
4416 : NewTxtFmtColl( nToken, static_cast< sal_uInt16 >(nToken==HTML_DD_ON ? RES_POOLCOLL_HTML_DD
4417 0 : : RES_POOLCOLL_HTML_DT) );
4418 0 : }
4419 :
4420 0 : void SwHTMLParser::EndDefListItem( int nToken, bool bSetColl,
4421 : bool /*bLastPara*/ )
4422 : {
4423 : // einen neuen Absatz aufmachen
4424 0 : if( !nToken && pPam->GetPoint()->nContent.GetIndex() )
4425 0 : AppendTxtNode( AM_SOFTNOSPACE );
4426 :
4427 : // Kontext zu dem Token suchen und vom Stack holen
4428 0 : nToken &= ~1;
4429 0 : _HTMLAttrContext *pCntxt = 0;
4430 0 : sal_uInt16 nPos = aContexts.size();
4431 0 : while( !pCntxt && nPos>nContextStMin )
4432 : {
4433 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
4434 0 : switch( nCntxtToken )
4435 : {
4436 : case HTML_DD_ON:
4437 : case HTML_DT_ON:
4438 0 : if( !nToken || nToken == nCntxtToken )
4439 : {
4440 0 : pCntxt = aContexts[nPos];
4441 0 : aContexts.erase( aContexts.begin() + nPos );
4442 : }
4443 0 : break;
4444 : case HTML_DEFLIST_ON:
4445 : // keine DD/DT ausserhalb der aktuelen DefListe betrachten
4446 : case HTML_DIRLIST_ON:
4447 : case HTML_MENULIST_ON:
4448 : case HTML_ORDERLIST_ON:
4449 : case HTML_UNORDERLIST_ON:
4450 : // und auch nicht ausserhalb einer anderen Liste
4451 0 : nPos = nContextStMin;
4452 0 : break;
4453 : }
4454 : }
4455 :
4456 : // und noch Attribute beenden
4457 0 : if( pCntxt )
4458 : {
4459 0 : EndContext( pCntxt );
4460 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4461 0 : delete pCntxt;
4462 : }
4463 :
4464 : // und die bisherige Vorlage setzen
4465 0 : if( bSetColl )
4466 0 : SetTxtCollAttrs();
4467 0 : }
4468 :
4469 20 : bool SwHTMLParser::HasCurrentParaFlys( bool bNoSurroundOnly,
4470 : bool bSurroundOnly ) const
4471 : {
4472 : // bNoSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4473 : // ohne Umlauf
4474 : // bSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4475 : // mit Umlauf aber keinen ohne Umlauf
4476 : // sonst: Der Absatz enthaelt irgendeinen Rahmen
4477 20 : SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
4478 :
4479 20 : const SwFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
4480 :
4481 20 : bool bFound = false;
4482 32 : for ( sal_uInt16 i=0; i<rFrmFmtTbl.size(); i++ )
4483 : {
4484 12 : SwFrmFmt *const pFmt = rFrmFmtTbl[i];
4485 12 : SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
4486 : // Ein Rahmen wurde gefunden, wenn
4487 : // - er absatzgebunden ist, und
4488 : // - im aktuellen Absatz verankert ist, und
4489 : // - jeder absatzgebunene Rahmen zaehlt, oder
4490 : // - (nur Rahmen oder umlauf zaehlen und ) der Rahmen keinen
4491 : // Umlauf besitzt
4492 12 : SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
4493 22 : if (pAPos &&
4494 20 : ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
4495 22 : (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
4496 0 : pAPos->nNode == rNodeIdx )
4497 : {
4498 0 : if( !(bNoSurroundOnly || bSurroundOnly) )
4499 : {
4500 0 : bFound = true;
4501 0 : break;
4502 : }
4503 : else
4504 : {
4505 : // Wenn Rahmen mit Umlauf gesucht sind,
4506 : // auch keine mit Durchlauf beachten. Dabei handelt es
4507 : // sich (noch) um HIDDEN-Controls, und denen weicht man
4508 : // besser auch nicht aus.
4509 0 : SwSurround eSurround = pFmt->GetSurround().GetSurround();
4510 0 : if( bNoSurroundOnly )
4511 : {
4512 0 : if( SURROUND_NONE==eSurround )
4513 : {
4514 0 : bFound = true;
4515 0 : break;
4516 : }
4517 : }
4518 0 : if( bSurroundOnly )
4519 : {
4520 0 : if( SURROUND_NONE==eSurround )
4521 : {
4522 0 : bFound = false;
4523 0 : break;
4524 : }
4525 0 : else if( SURROUND_THROUGHT!=eSurround )
4526 : {
4527 0 : bFound = true;
4528 : // weitersuchen: Es koennten ja noch welche ohne
4529 : // Umlauf kommen ...
4530 : }
4531 : }
4532 : }
4533 : }
4534 : }
4535 :
4536 20 : return bFound;
4537 : }
4538 :
4539 : // die speziellen Methoden zum Einfuegen von Objecten
4540 :
4541 0 : const SwFmtColl *SwHTMLParser::GetCurrFmtColl() const
4542 : {
4543 0 : const SwCntntNode* pCNd = pPam->GetCntntNode();
4544 0 : return &pCNd->GetAnyFmtColl();
4545 : }
4546 :
4547 1094 : void SwHTMLParser::SetTxtCollAttrs( _HTMLAttrContext *pContext )
4548 : {
4549 1094 : SwTxtFmtColl *pCollToSet = 0; // die zu setzende Vorlage
4550 1094 : SfxItemSet *pItemSet = 0; // der Set fuer harte Attrs
4551 1094 : sal_uInt16 nTopColl = pContext ? pContext->GetTxtFmtColl() : 0;
4552 1094 : const OUString& rTopClass = pContext ? pContext->GetClass() : aEmptyOUStr;
4553 1094 : sal_uInt16 nDfltColl = RES_POOLCOLL_TEXT;
4554 :
4555 1094 : bool bInPRE=false; // etwas Kontext Info
4556 :
4557 1094 : sal_uInt16 nLeftMargin = 0, nRightMargin = 0; // die Einzuege und
4558 1094 : short nFirstLineIndent = 0; // Abstaende
4559 : sal_uInt16 i;
4560 :
4561 2724 : for( i = nContextStAttrMin; i < aContexts.size(); i++ )
4562 : {
4563 1630 : const _HTMLAttrContext *pCntxt = aContexts[i];
4564 :
4565 1630 : sal_uInt16 nColl = pCntxt->GetTxtFmtColl();
4566 1630 : if( nColl )
4567 : {
4568 : // Es gibt eine Vorlage, die zu setzen ist. Dann
4569 : // muss zunaechst einmal entschieden werden,
4570 : // ob die Vorlage auch gesetzt werden kann
4571 108 : bool bSetThis = true;
4572 108 : switch( nColl )
4573 : {
4574 : case sal_uInt16(RES_POOLCOLL_HTML_PRE):
4575 0 : bInPRE = true;
4576 0 : break;
4577 : case sal_uInt16(RES_POOLCOLL_TEXT):
4578 : // <TD><P CLASS=xxx> muss TD.xxx werden
4579 108 : if( nDfltColl==RES_POOLCOLL_TABLE ||
4580 : nDfltColl==RES_POOLCOLL_TABLE_HDLN )
4581 102 : nColl = nDfltColl;
4582 108 : break;
4583 : case sal_uInt16(RES_POOLCOLL_HTML_HR):
4584 : // <HR> auch in <PRE> als Vorlage setzen, sonst kann man sie
4585 : // nicht mehr exportieren
4586 0 : break;
4587 : default:
4588 0 : if( bInPRE )
4589 0 : bSetThis = false;
4590 0 : break;
4591 : }
4592 :
4593 : SwTxtFmtColl *pNewColl =
4594 108 : pCSS1Parser->GetTxtFmtColl( nColl, pCntxt->GetClass() );
4595 :
4596 108 : if( bSetThis )
4597 : {
4598 : // wenn jetzt eine andere Vorlage gesetzt werden soll als
4599 : // bisher, muss die bishere Vorlage durch harte Attributierung
4600 : // ersetzt werden
4601 :
4602 108 : if( pCollToSet )
4603 : {
4604 : // die Attribute, die die bisherige Vorlage setzt
4605 : // hart einfuegen
4606 0 : if( !pItemSet )
4607 0 : pItemSet = new SfxItemSet( pCollToSet->GetAttrSet() );
4608 : else
4609 : {
4610 0 : const SfxItemSet& rCollSet = pCollToSet->GetAttrSet();
4611 0 : SfxItemSet aItemSet( *rCollSet.GetPool(),
4612 0 : rCollSet.GetRanges() );
4613 0 : aItemSet.Set( rCollSet );
4614 0 : pItemSet->Put( aItemSet );
4615 : }
4616 : // aber die Attribute, die aktuelle Vorlage setzt
4617 : // entfernen, weil sie sonst spaeter ueberschrieben
4618 : // werden
4619 0 : pItemSet->Differentiate( pNewColl->GetAttrSet() );
4620 : }
4621 :
4622 108 : pCollToSet = pNewColl;
4623 : }
4624 : else
4625 : {
4626 : // hart Attributieren
4627 0 : if( !pItemSet )
4628 0 : pItemSet = new SfxItemSet( pNewColl->GetAttrSet() );
4629 : else
4630 : {
4631 0 : const SfxItemSet& rCollSet = pNewColl->GetAttrSet();
4632 0 : SfxItemSet aItemSet( *rCollSet.GetPool(),
4633 0 : rCollSet.GetRanges() );
4634 0 : aItemSet.Set( rCollSet );
4635 0 : pItemSet->Put( aItemSet );
4636 : }
4637 : }
4638 : }
4639 : else
4640 : {
4641 : // vielliecht gibt es ja eine Default-Vorlage?
4642 1522 : nColl = pCntxt->GetDfltTxtFmtColl();
4643 1522 : if( nColl )
4644 1044 : nDfltColl = nColl;
4645 : }
4646 :
4647 : // ggf. neue Absatz-Einzuege holen
4648 1630 : if( pCntxt->IsLRSpaceChanged() )
4649 : {
4650 2 : sal_uInt16 nLeft=0, nRight=0;
4651 :
4652 2 : pCntxt->GetMargins( nLeft, nRight, nFirstLineIndent );
4653 2 : nLeftMargin = nLeft;
4654 2 : nRightMargin = nRight;
4655 : }
4656 : }
4657 :
4658 : // wenn im aktuellen Kontext eine neue Vorlage gesetzt werden soll,
4659 : // muessen deren Absatz-Abstaende noch in den Kontext eingetragen werden
4660 1094 : if( pContext && nTopColl )
4661 : {
4662 : // <TD><P CLASS=xxx> muss TD.xxx werden
4663 108 : if( nTopColl==RES_POOLCOLL_TEXT &&
4664 6 : (nDfltColl==RES_POOLCOLL_TABLE ||
4665 : nDfltColl==RES_POOLCOLL_TABLE_HDLN) )
4666 102 : nTopColl = nDfltColl;
4667 :
4668 : const SwTxtFmtColl *pTopColl =
4669 108 : pCSS1Parser->GetTxtFmtColl( nTopColl, rTopClass );
4670 108 : const SfxItemSet& rItemSet = pTopColl->GetAttrSet();
4671 : const SfxPoolItem *pItem;
4672 108 : if( SfxItemState::SET == rItemSet.GetItemState(RES_LR_SPACE,true, &pItem) )
4673 : {
4674 : const SvxLRSpaceItem *pLRItem =
4675 0 : (const SvxLRSpaceItem *)pItem;
4676 :
4677 0 : sal_Int32 nLeft = pLRItem->GetTxtLeft();
4678 0 : sal_Int32 nRight = pLRItem->GetRight();
4679 0 : nFirstLineIndent = pLRItem->GetTxtFirstLineOfst();
4680 :
4681 : // In Definitions-Listen enthalten die Abstaende auch die der
4682 : // vorhergehenden Level
4683 0 : if( RES_POOLCOLL_HTML_DD == nTopColl )
4684 : {
4685 : const SvxLRSpaceItem& rDTLRSpace = pCSS1Parser
4686 0 : ->GetTxtFmtColl( RES_POOLCOLL_HTML_DT, aEmptyOUStr )
4687 0 : ->GetLRSpace();
4688 0 : nLeft -= rDTLRSpace.GetTxtLeft();
4689 0 : nRight -= rDTLRSpace.GetRight();
4690 : }
4691 0 : else if( RES_POOLCOLL_HTML_DT == nTopColl )
4692 : {
4693 0 : nLeft = 0;
4694 0 : nRight = 0;
4695 : }
4696 :
4697 : // die Absatz-Abstaende addieren sich
4698 0 : nLeftMargin = nLeftMargin + static_cast< sal_uInt16 >(nLeft);
4699 0 : nRightMargin = nRightMargin + static_cast< sal_uInt16 >(nRight);
4700 :
4701 : pContext->SetMargins( nLeftMargin, nRightMargin,
4702 0 : nFirstLineIndent );
4703 : }
4704 108 : if( SfxItemState::SET == rItemSet.GetItemState(RES_UL_SPACE,true, &pItem) )
4705 : {
4706 : const SvxULSpaceItem *pULItem =
4707 6 : (const SvxULSpaceItem *)pItem;
4708 6 : pContext->SetULSpace( pULItem->GetUpper(), pULItem->GetLower() );
4709 : }
4710 : }
4711 :
4712 : // wenn gar keine Vorlage im Kontext gesetzt ist, Textkoerper nehmen
4713 1094 : if( !pCollToSet )
4714 : {
4715 986 : pCollToSet = pCSS1Parser->GetTxtCollFromPool( nDfltColl );
4716 986 : const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
4717 986 : if( !nLeftMargin )
4718 986 : nLeftMargin = static_cast< sal_uInt16 >(rLRItem.GetTxtLeft());
4719 986 : if( !nRightMargin )
4720 986 : nRightMargin = static_cast< sal_uInt16 >(rLRItem.GetRight());
4721 986 : if( !nFirstLineIndent )
4722 986 : nFirstLineIndent = rLRItem.GetTxtFirstLineOfst();
4723 : }
4724 :
4725 : // bisherige harte Attributierung des Absatzes entfernen
4726 1094 : if( !aParaAttrs.empty() )
4727 : {
4728 0 : for( i=0; i<aParaAttrs.size(); i++ )
4729 0 : aParaAttrs[i]->Invalidate();
4730 :
4731 0 : aParaAttrs.clear();
4732 : }
4733 :
4734 : // Die Vorlage setzen
4735 1094 : pDoc->SetTxtFmtColl( *pPam, pCollToSet );
4736 :
4737 : // ggf. noch den Absatz-Einzug korrigieren
4738 1094 : const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
4739 : bool bSetLRSpace;
4740 :
4741 2186 : bSetLRSpace = nLeftMargin != rLRItem.GetTxtLeft() ||
4742 2186 : nFirstLineIndent != rLRItem.GetTxtFirstLineOfst() ||
4743 2186 : nRightMargin != rLRItem.GetRight();
4744 :
4745 1094 : if( bSetLRSpace )
4746 : {
4747 2 : SvxLRSpaceItem aLRItem( rLRItem );
4748 2 : aLRItem.SetTxtLeft( nLeftMargin );
4749 2 : aLRItem.SetRight( nRightMargin );
4750 2 : aLRItem.SetTxtFirstLineOfst( nFirstLineIndent );
4751 2 : if( pItemSet )
4752 0 : pItemSet->Put( aLRItem );
4753 : else
4754 : {
4755 2 : NewAttr( &aAttrTab.pLRSpace, aLRItem );
4756 2 : aAttrTab.pLRSpace->SetLikePara();
4757 2 : aParaAttrs.push_back( aAttrTab.pLRSpace );
4758 2 : EndAttr( aAttrTab.pLRSpace, 0, false );
4759 2 : }
4760 : }
4761 :
4762 : // und nun noch die Attribute setzen
4763 1094 : if( pItemSet )
4764 : {
4765 0 : InsertParaAttrs( *pItemSet );
4766 0 : delete pItemSet;
4767 : }
4768 1094 : }
4769 :
4770 0 : void SwHTMLParser::NewCharFmt( int nToken )
4771 : {
4772 0 : OUString aId, aStyle, aLang, aDir;
4773 0 : OUString aClass;
4774 :
4775 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4776 0 : for (size_t i = rHTMLOptions.size(); i; )
4777 : {
4778 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4779 0 : switch( rOption.GetToken() )
4780 : {
4781 : case HTML_O_ID:
4782 0 : aId = rOption.GetString();
4783 0 : break;
4784 : case HTML_O_STYLE:
4785 0 : aStyle = rOption.GetString();
4786 0 : break;
4787 : case HTML_O_CLASS:
4788 0 : aClass = rOption.GetString();
4789 0 : break;
4790 : case HTML_O_LANG:
4791 0 : aLang = rOption.GetString();
4792 0 : break;
4793 : case HTML_O_DIR:
4794 0 : aDir = rOption.GetString();
4795 0 : break;
4796 : }
4797 : }
4798 :
4799 : // einen neuen Kontext anlegen
4800 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
4801 :
4802 : // die Vorlage setzen und im Kontext merken
4803 0 : SwCharFmt* pCFmt = pCSS1Parser->GetChrFmt( static_cast< sal_uInt16 >(nToken), aClass );
4804 : OSL_ENSURE( pCFmt, "keine Zeichenvorlage zu Token gefunden" );
4805 :
4806 : // Styles parsen (zu Class siehe auch NewPara)
4807 0 : if( HasStyleOptions( aStyle, aId, aEmptyOUStr, &aLang, &aDir ) )
4808 : {
4809 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
4810 0 : SvxCSS1PropertyInfo aPropInfo;
4811 :
4812 0 : if( ParseStyleOptions( aStyle, aId, aEmptyOUStr, aItemSet, aPropInfo, &aLang, &aDir ) )
4813 : {
4814 : OSL_ENSURE( aClass.isEmpty() || !pCSS1Parser->GetClass( aClass ),
4815 : "Class wird nicht beruecksichtigt" );
4816 0 : DoPositioning( aItemSet, aPropInfo, pCntxt );
4817 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
4818 0 : }
4819 : }
4820 :
4821 : // Zeichen-Vorlagen werden in einem eigenen Stack gehalten und
4822 : // koennen nie durch Styles eingefuegt werden. Das Attribut ist deshalb
4823 : // auch gar nicht im CSS1-Which-Range enthalten
4824 0 : if( pCFmt )
4825 0 : InsertAttr( &aAttrTab.pCharFmts, SwFmtCharFmt( pCFmt ), pCntxt );
4826 :
4827 : // den Kontext merken
4828 0 : PushContext( pCntxt );
4829 0 : }
4830 :
4831 0 : void SwHTMLParser::InsertSpacer()
4832 : {
4833 : // und es ggf. durch die Optionen veraendern
4834 0 : OUString aId;
4835 0 : sal_Int16 eVertOri = text::VertOrientation::TOP;
4836 0 : sal_Int16 eHoriOri = text::HoriOrientation::NONE;
4837 0 : Size aSize( 0, 0);
4838 0 : long nSize = 0;
4839 0 : bool bPrcWidth = false;
4840 0 : bool bPrcHeight = false;
4841 0 : sal_uInt16 nType = HTML_SPTYPE_HORI;
4842 :
4843 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4844 0 : for (size_t i = rHTMLOptions.size(); i; )
4845 : {
4846 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4847 0 : switch( rOption.GetToken() )
4848 : {
4849 : case HTML_O_ID:
4850 0 : aId = rOption.GetString();
4851 0 : break;
4852 : case HTML_O_TYPE:
4853 0 : rOption.GetEnum( nType, aHTMLSpacerTypeTable );
4854 0 : break;
4855 : case HTML_O_ALIGN:
4856 : eVertOri =
4857 : rOption.GetEnum( aHTMLImgVAlignTable,
4858 0 : eVertOri );
4859 : eHoriOri =
4860 : rOption.GetEnum( aHTMLImgHAlignTable,
4861 0 : eHoriOri );
4862 0 : break;
4863 : case HTML_O_WIDTH:
4864 : // erstmal nur als Pixelwerte merken!
4865 0 : bPrcWidth = (rOption.GetString().indexOf('%') != -1);
4866 0 : aSize.Width() = (long)rOption.GetNumber();
4867 0 : break;
4868 : case HTML_O_HEIGHT:
4869 : // erstmal nur als Pixelwerte merken!
4870 0 : bPrcHeight = (rOption.GetString().indexOf('%') != -1);
4871 0 : aSize.Height() = (long)rOption.GetNumber();
4872 0 : break;
4873 : case HTML_O_SIZE:
4874 : // erstmal nur als Pixelwerte merken!
4875 0 : nSize = rOption.GetNumber();
4876 0 : break;
4877 : }
4878 : }
4879 :
4880 0 : switch( nType )
4881 : {
4882 : case HTML_SPTYPE_BLOCK:
4883 : {
4884 : // einen leeren Textrahmen anlegen
4885 :
4886 : // den Itemset holen
4887 0 : SfxItemSet aFrmSet( pDoc->GetAttrPool(),
4888 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
4889 0 : if( !IsNewDoc() )
4890 0 : Reader::ResetFrmFmtAttrs( aFrmSet );
4891 :
4892 : // den Anker und die Ausrichtung setzen
4893 0 : SetAnchorAndAdjustment( eVertOri, eHoriOri, aFrmSet );
4894 :
4895 : // und noch die Groesse des Rahmens
4896 0 : Size aDfltSz( MINFLY, MINFLY );
4897 0 : Size aSpace( 0, 0 );
4898 0 : SfxItemSet aDummyItemSet( pDoc->GetAttrPool(),
4899 0 : pCSS1Parser->GetWhichMap() );
4900 0 : SvxCSS1PropertyInfo aDummyPropInfo;
4901 :
4902 : SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight,
4903 0 : aDummyItemSet, aDummyPropInfo, aFrmSet );
4904 0 : SetSpace( aSpace, aDummyItemSet, aDummyPropInfo, aFrmSet );
4905 :
4906 : // den Inhalt schuetzen
4907 0 : SvxProtectItem aProtectItem( RES_PROTECT) ;
4908 0 : aProtectItem.SetCntntProtect( true );
4909 0 : aFrmSet.Put( aProtectItem );
4910 :
4911 : // der Rahmen anlegen
4912 : RndStdIds eAnchorId =
4913 0 : ((const SwFmtAnchor &)aFrmSet.Get(RES_ANCHOR)).GetAnchorId();
4914 : SwFrmFmt *pFlyFmt = pDoc->MakeFlySection( eAnchorId,
4915 0 : pPam->GetPoint(), &aFrmSet );
4916 : // Ggf Frames anlegen und auto-geb. Rahmen registrieren
4917 0 : RegisterFlyFrm( pFlyFmt );
4918 : }
4919 0 : break;
4920 : case HTML_SPTYPE_VERT:
4921 0 : if( nSize > 0 )
4922 : {
4923 0 : if( nSize && Application::GetDefaultDevice() )
4924 : {
4925 : nSize = Application::GetDefaultDevice()
4926 : ->PixelToLogic( Size(0,nSize),
4927 0 : MapMode(MAP_TWIP) ).Height();
4928 : }
4929 :
4930 : // einen Absatz-Abstand setzen
4931 0 : SwTxtNode *pTxtNode = 0;
4932 0 : if( !pPam->GetPoint()->nContent.GetIndex() )
4933 : {
4934 : // den unteren Absatz-Abstand des vorherigen Nodes aendern,
4935 : // wenn moeglich
4936 :
4937 0 : SetAttr(); // noch offene Absatz-Attribute setzen
4938 :
4939 0 : pTxtNode = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()-1]
4940 0 : ->GetTxtNode();
4941 :
4942 : // Wenn der Abstz davor kein Txtenode ist, dann wird jetzt
4943 : // ein leere Absatz angelegt, der eh schon eine Zeilenhoehe
4944 : // Abstand erzeugt.
4945 0 : if( !pTxtNode )
4946 0 : nSize = nSize>HTML_PARSPACE ? nSize-HTML_PARSPACE : 0;
4947 : }
4948 :
4949 0 : if( pTxtNode )
4950 : {
4951 : SvxULSpaceItem aULSpace( (const SvxULSpaceItem&)pTxtNode
4952 0 : ->SwCntntNode::GetAttr( RES_UL_SPACE ) );
4953 0 : aULSpace.SetLower( aULSpace.GetLower() + (sal_uInt16)nSize );
4954 0 : pTxtNode->SetAttr( aULSpace );
4955 : }
4956 : else
4957 : {
4958 0 : NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, (sal_uInt16)nSize, RES_UL_SPACE ) );
4959 0 : EndAttr( aAttrTab.pULSpace, 0, false );
4960 :
4961 0 : AppendTxtNode(); // nicht am Abstand drehen!
4962 : }
4963 : }
4964 0 : break;
4965 : case HTML_SPTYPE_HORI:
4966 0 : if( nSize > 0 )
4967 : {
4968 : // wenn der Absatz noch leer ist, einen Erstzeilen-Einzug
4969 : // setzen, sondern Sperrschrift ueber einem Space aufspannen
4970 :
4971 0 : if( nSize && Application::GetDefaultDevice() )
4972 : {
4973 : nSize = Application::GetDefaultDevice()
4974 : ->PixelToLogic( Size(nSize,0),
4975 0 : MapMode(MAP_TWIP) ).Width();
4976 : }
4977 :
4978 0 : if( !pPam->GetPoint()->nContent.GetIndex() )
4979 : {
4980 0 : sal_uInt16 nLeft=0, nRight=0;
4981 0 : short nIndent = 0;
4982 :
4983 0 : GetMarginsFromContextWithNumBul( nLeft, nRight, nIndent );
4984 0 : nIndent = nIndent + (short)nSize;
4985 :
4986 0 : SvxLRSpaceItem aLRItem( RES_LR_SPACE );
4987 0 : aLRItem.SetTxtLeft( nLeft );
4988 0 : aLRItem.SetRight( nRight );
4989 0 : aLRItem.SetTxtFirstLineOfst( nIndent );
4990 :
4991 0 : NewAttr( &aAttrTab.pLRSpace, aLRItem );
4992 0 : EndAttr( aAttrTab.pLRSpace, 0, false );
4993 : }
4994 : else
4995 : {
4996 0 : NewAttr( &aAttrTab.pKerning, SvxKerningItem( (short)nSize, RES_CHRATR_KERNING ) );
4997 0 : OUString aTmp( ' ' );
4998 0 : pDoc->getIDocumentContentOperations().InsertString( *pPam, aTmp );
4999 0 : EndAttr( aAttrTab.pKerning );
5000 : }
5001 : }
5002 0 : }
5003 0 : }
5004 :
5005 2 : sal_uInt16 SwHTMLParser::ToTwips( sal_uInt16 nPixel ) const
5006 : {
5007 2 : if( nPixel && Application::GetDefaultDevice() )
5008 : {
5009 : long nTwips = Application::GetDefaultDevice()->PixelToLogic(
5010 2 : Size( nPixel, nPixel ), MapMode( MAP_TWIP ) ).Width();
5011 2 : return nTwips <= USHRT_MAX ? (sal_uInt16)nTwips : USHRT_MAX;
5012 : }
5013 : else
5014 0 : return nPixel;
5015 : }
5016 :
5017 2 : SwTwips SwHTMLParser::GetCurrentBrowseWidth()
5018 : {
5019 2 : const SwTwips nWidth = SwHTMLTableLayout::GetBrowseWidth( *pDoc );
5020 2 : if( nWidth )
5021 0 : return nWidth;
5022 :
5023 2 : if( !aHTMLPageSize.Width() )
5024 : {
5025 2 : const SwFrmFmt& rPgFmt = pCSS1Parser->GetMasterPageDesc()->GetMaster();
5026 :
5027 2 : const SwFmtFrmSize& rSz = rPgFmt.GetFrmSize();
5028 2 : const SvxLRSpaceItem& rLR = rPgFmt.GetLRSpace();
5029 2 : const SvxULSpaceItem& rUL = rPgFmt.GetULSpace();
5030 2 : const SwFmtCol& rCol = rPgFmt.GetCol();
5031 :
5032 2 : aHTMLPageSize.Width() = rSz.GetWidth() - rLR.GetLeft() - rLR.GetRight();
5033 2 : aHTMLPageSize.Height() = rSz.GetHeight() - rUL.GetUpper() - rUL.GetLower();
5034 :
5035 2 : if( 1 < rCol.GetNumCols() )
5036 0 : aHTMLPageSize.Width() /= rCol.GetNumCols();
5037 : }
5038 :
5039 2 : return aHTMLPageSize.Width();
5040 : }
5041 :
5042 0 : void SwHTMLParser::InsertIDOption()
5043 : {
5044 0 : OUString aId;
5045 0 : const HTMLOptions& rHTMLOptions = GetOptions();
5046 0 : for (size_t i = rHTMLOptions.size(); i; )
5047 : {
5048 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5049 0 : if( HTML_O_ID==rOption.GetToken() )
5050 : {
5051 0 : aId = rOption.GetString();
5052 0 : break;
5053 : }
5054 : }
5055 :
5056 0 : if( !aId.isEmpty() )
5057 0 : InsertBookmark( aId );
5058 0 : }
5059 :
5060 526 : void SwHTMLParser::InsertLineBreak()
5061 : {
5062 : // <BR CLEAR=xxx> wird wie folgt behandelt:
5063 : // 1.) Es werden nur nur absatzgebundene Rahmen betrachtet, die
5064 : // im aktuellen Absatz verankert sind.
5065 : // 2.) Fuer linksbuendig ausgerichtete Rahmen wird bei CLEAR=LEFT
5066 : // oder ALL und auf rechtsbuendige ausgerichtete Rahmen bei
5067 : // CLEAR=RIGHT oder ALL der Durchlauf wie folgt geaendert:
5068 : // 3.) Wenn der Absatz keinen Text enthaelt, bekommt der Rahmen keinen
5069 : // Umlauf
5070 : // 4.) sonst erhaelt ein links ausgerichteter Rahmen eine rechten
5071 : // "nur Anker" Umlauf und recht rechst ausg. Rahmen einen linken
5072 : // "nur Anker" Umlauf.
5073 : // 5.) wenn in einem nicht-leeren Absatz der Umlauf eines Rahmens
5074 : // geaendert wird, wird ein neuer Absatz aufgemacht
5075 : // 6.) Wenn von keinem Rahmen der Umlauf geaendert wird, wird ein
5076 : // harter Zeilenumbruch eingefuegt
5077 :
5078 1052 : OUString aId, aStyle, aClass; // die ID der Bookmark
5079 526 : bool bClearLeft = false, bClearRight = false;
5080 526 : bool bCleared = false; // wurde ein CLEAR ausgefuehrt?
5081 :
5082 : // dann holen wir mal die Optionen
5083 526 : const HTMLOptions& rHTMLOptions = GetOptions();
5084 1052 : for (size_t i = rHTMLOptions.size(); i; )
5085 : {
5086 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5087 0 : switch( rOption.GetToken() )
5088 : {
5089 : case HTML_O_CLEAR:
5090 : {
5091 0 : const OUString &rClear = rOption.GetString();
5092 0 : if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_all ) )
5093 : {
5094 0 : bClearLeft = true;
5095 0 : bClearRight = true;
5096 : }
5097 0 : else if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_left ) )
5098 0 : bClearLeft = true;
5099 0 : else if( rClear.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_AL_right ) )
5100 0 : bClearRight = true;
5101 : }
5102 0 : break;
5103 : case HTML_O_ID:
5104 0 : aId = rOption.GetString();
5105 0 : break;
5106 : case HTML_O_STYLE:
5107 0 : aStyle = rOption.GetString();
5108 0 : break;
5109 : case HTML_O_CLASS:
5110 0 : aClass = rOption.GetString();
5111 0 : break;
5112 : }
5113 : }
5114 :
5115 : // CLEAR wird nur fuer den aktuellen Absaetz unterstuetzt
5116 526 : if( bClearLeft || bClearRight )
5117 : {
5118 0 : SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
5119 0 : SwTxtNode* pTxtNd = rNodeIdx.GetNode().GetTxtNode();
5120 0 : if( pTxtNd )
5121 : {
5122 0 : const SwFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
5123 :
5124 0 : for( sal_uInt16 i=0; i<rFrmFmtTbl.size(); i++ )
5125 : {
5126 0 : SwFrmFmt *const pFmt = rFrmFmtTbl[i];
5127 0 : SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
5128 0 : SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
5129 0 : if (pAPos &&
5130 0 : ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
5131 0 : (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
5132 0 : pAPos->nNode == rNodeIdx &&
5133 0 : pFmt->GetSurround().GetSurround() != SURROUND_NONE )
5134 : {
5135 0 : sal_Int16 eHori = RES_DRAWFRMFMT == pFmt->Which()
5136 : ? text::HoriOrientation::LEFT
5137 0 : : pFmt->GetHoriOrient().GetHoriOrient();
5138 :
5139 0 : SwSurround eSurround = SURROUND_PARALLEL;
5140 0 : if( pPam->GetPoint()->nContent.GetIndex() )
5141 : {
5142 0 : if( bClearLeft && text::HoriOrientation::LEFT==eHori )
5143 0 : eSurround = SURROUND_RIGHT;
5144 0 : else if( bClearRight && text::HoriOrientation::RIGHT==eHori )
5145 0 : eSurround = SURROUND_LEFT;
5146 : }
5147 0 : else if( (bClearLeft && text::HoriOrientation::LEFT==eHori) ||
5148 0 : (bClearRight && text::HoriOrientation::RIGHT==eHori) )
5149 : {
5150 0 : eSurround = SURROUND_NONE;
5151 : }
5152 :
5153 0 : if( SURROUND_PARALLEL != eSurround )
5154 : {
5155 0 : SwFmtSurround aSurround( eSurround );
5156 0 : if( SURROUND_NONE != eSurround )
5157 0 : aSurround.SetAnchorOnly( true );
5158 0 : pFmt->SetFmtAttr( aSurround );
5159 0 : bCleared = true;
5160 : }
5161 : } // Anker ist nicht im Node
5162 : } // Schleife ueber Fly-Frames
5163 : } // kein Text-Node
5164 : } // kein CLEAR
5165 :
5166 : // Styles parsen
5167 526 : SvxFmtBreakItem aBreakItem( SVX_BREAK_NONE, RES_BREAK );
5168 526 : bool bBreakItem = false;
5169 526 : if( HasStyleOptions( aStyle, aId, aClass ) )
5170 : {
5171 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
5172 0 : SvxCSS1PropertyInfo aPropInfo;
5173 :
5174 0 : if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo ) )
5175 : {
5176 0 : if( pCSS1Parser->SetFmtBreak( aItemSet, aPropInfo ) )
5177 : {
5178 0 : aBreakItem = (const SvxFmtBreakItem &)aItemSet.Get( RES_BREAK );
5179 0 : bBreakItem = true;
5180 : }
5181 0 : if( !aPropInfo.aId.isEmpty() )
5182 0 : InsertBookmark( aPropInfo.aId );
5183 0 : }
5184 : }
5185 :
5186 526 : if( bBreakItem && SVX_BREAK_PAGE_AFTER==aBreakItem.GetBreak() )
5187 : {
5188 0 : NewAttr( &aAttrTab.pBreak, aBreakItem );
5189 0 : EndAttr( aAttrTab.pBreak, 0, false );
5190 : }
5191 :
5192 526 : if( !bCleared && !bBreakItem )
5193 : {
5194 : // wenn kein CLEAR ausgefuehrt werden sollte oder konnte, wird
5195 : // ein Zeilenumbruch eingef?gt
5196 526 : OUString sTmp( (sal_Unicode)0x0a ); // make the Mac happy :-)
5197 526 : pDoc->getIDocumentContentOperations().InsertString( *pPam, sTmp );
5198 : }
5199 0 : else if( pPam->GetPoint()->nContent.GetIndex() )
5200 : {
5201 : // wenn ein clear in einem nicht-leeren Absatz ausgefuehrt wurde,
5202 : // muss anschliessen ein neuer Absatz aufgemacht werden
5203 : // MIB 21.02.97: Eigentlich muesste man hier den unteren Absatz-
5204 : // Absatnd auf 0 drehen. Das geht aber bei sowas wie <BR ..><P>
5205 : // schief (>Netacpe). Deshalb lassen wir das erstmal.
5206 0 : AppendTxtNode( AM_NOSPACE );
5207 : }
5208 526 : if( bBreakItem && SVX_BREAK_PAGE_BEFORE==aBreakItem.GetBreak() )
5209 : {
5210 0 : NewAttr( &aAttrTab.pBreak, aBreakItem );
5211 0 : EndAttr( aAttrTab.pBreak, 0, false );
5212 1052 : }
5213 526 : }
5214 :
5215 0 : void SwHTMLParser::InsertHorzRule()
5216 : {
5217 0 : sal_uInt16 nSize = 0;
5218 0 : sal_uInt16 nWidth = 0;
5219 :
5220 0 : SvxAdjust eAdjust = SVX_ADJUST_END;
5221 :
5222 0 : bool bPrcWidth = false;
5223 0 : bool bNoShade = false;
5224 0 : bool bColor = false;
5225 :
5226 0 : Color aColor;
5227 0 : OUString aId;
5228 :
5229 : // dann holen wir mal die Optionen
5230 0 : const HTMLOptions& rHTMLOptions = GetOptions();
5231 0 : for (size_t i = rHTMLOptions.size(); i; )
5232 : {
5233 0 : const HTMLOption& rOption = rHTMLOptions[--i];
5234 0 : switch( rOption.GetToken() )
5235 : {
5236 : case HTML_O_ID:
5237 0 : aId = rOption.GetString();
5238 0 : break;
5239 : case HTML_O_SIZE:
5240 0 : nSize = (sal_uInt16)rOption.GetNumber();
5241 0 : break;
5242 : case HTML_O_WIDTH:
5243 0 : bPrcWidth = (rOption.GetString().indexOf('%') != -1);
5244 0 : nWidth = (sal_uInt16)rOption.GetNumber();
5245 0 : if( bPrcWidth && nWidth>=100 )
5246 : {
5247 : // 100%-Linien sind der default-Fall (keine Attrs neotig)
5248 0 : nWidth = 0;
5249 0 : bPrcWidth = false;
5250 : }
5251 0 : break;
5252 : case HTML_O_ALIGN:
5253 : eAdjust =
5254 0 : (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
5255 0 : break;
5256 : case HTML_O_NOSHADE:
5257 0 : bNoShade = true;
5258 0 : break;
5259 : case HTML_O_COLOR:
5260 0 : rOption.GetColor( aColor );
5261 0 : bColor = true;
5262 0 : break;
5263 : }
5264 : }
5265 :
5266 0 : if( pPam->GetPoint()->nContent.GetIndex() )
5267 0 : AppendTxtNode( AM_NOSPACE );
5268 0 : if( nOpenParaToken )
5269 0 : EndPara();
5270 0 : AppendTxtNode();
5271 0 : pPam->Move( fnMoveBackward );
5272 :
5273 : // ... und in einem Kontext merken
5274 : _HTMLAttrContext *pCntxt =
5275 0 : new _HTMLAttrContext( HTML_HORZRULE, RES_POOLCOLL_HTML_HR, aEmptyOUStr );
5276 :
5277 0 : PushContext( pCntxt );
5278 :
5279 : // die neue Vorlage setzen
5280 0 : SetTxtCollAttrs( pCntxt );
5281 :
5282 : // die harten Attribute an diesem Absatz werden nie mehr ungueltig
5283 0 : if( !aParaAttrs.empty() )
5284 0 : aParaAttrs.clear();
5285 :
5286 0 : if( nSize>0 || bColor || bNoShade )
5287 : {
5288 : // Farbe und/oder Breite der Linie setzen
5289 0 : if( !bColor )
5290 0 : aColor.SetColor( COL_GRAY );
5291 :
5292 0 : SvxBorderLine aBorderLine( &aColor );
5293 0 : if( nSize )
5294 : {
5295 0 : long nPWidth = 0;
5296 0 : long nPHeight = (long)nSize;
5297 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
5298 0 : if ( !bNoShade )
5299 : {
5300 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
5301 : }
5302 0 : aBorderLine.SetWidth( nPHeight );
5303 : }
5304 0 : else if( bNoShade )
5305 : {
5306 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_2 );
5307 : }
5308 : else
5309 : {
5310 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
5311 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
5312 : }
5313 :
5314 0 : SvxBoxItem aBoxItem(RES_BOX);
5315 0 : aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
5316 0 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aBoxItem );
5317 0 : aSetAttrTab.push_back( pTmp );
5318 : }
5319 0 : if( nWidth )
5320 : {
5321 : // Wenn wir in keiner Tabelle sind, wird die Breitenangabe durch
5322 : // Absatz-Einzuege "getuerkt". In einer Tabelle macht das wenig
5323 : // Sinn. Um zu Vermeiden, dass die Linie bei der Breitenberechnung
5324 : // beruecksichtigt wird, bekommt sie aber trotzdem entsprechendes
5325 : // LRSpace-Item verpasst.
5326 0 : if( !pTable )
5327 : {
5328 : // Laenge und Ausrichtung der Linie ueber Absatz-Einzuege "tuerken"
5329 0 : long nBrowseWidth = GetCurrentBrowseWidth();
5330 0 : nWidth = bPrcWidth ? (sal_uInt16)((nWidth*nBrowseWidth) / 100)
5331 0 : : ToTwips( (sal_uInt16)nBrowseWidth );
5332 0 : if( nWidth < MINLAY )
5333 0 : nWidth = MINLAY;
5334 :
5335 0 : if( (long)nWidth < nBrowseWidth )
5336 : {
5337 0 : const SwFmtColl *pColl = GetCurrFmtColl();
5338 0 : SvxLRSpaceItem aLRItem( pColl->GetLRSpace() );
5339 0 : long nDist = nBrowseWidth - nWidth;
5340 :
5341 0 : switch( eAdjust )
5342 : {
5343 : case SVX_ADJUST_RIGHT:
5344 0 : aLRItem.SetTxtLeft( (sal_uInt16)nDist );
5345 0 : break;
5346 : case SVX_ADJUST_LEFT:
5347 0 : aLRItem.SetRight( (sal_uInt16)nDist );
5348 0 : break;
5349 : case SVX_ADJUST_CENTER:
5350 : default:
5351 0 : nDist /= 2;
5352 0 : aLRItem.SetTxtLeft( (sal_uInt16)nDist );
5353 0 : aLRItem.SetRight( (sal_uInt16)nDist );
5354 0 : break;
5355 : }
5356 :
5357 0 : _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aLRItem );
5358 0 : aSetAttrTab.push_back( pTmp );
5359 : }
5360 : }
5361 : }
5362 :
5363 : // Bookmarks koennen nicht in Hyperlinks eingefueht werden
5364 0 : if( !aId.isEmpty() )
5365 0 : InsertBookmark( aId );
5366 :
5367 : // den aktuellen Kontext vom Stack holen
5368 0 : _HTMLAttrContext *pPoppedContext = PopContext( HTML_HORZRULE );
5369 : OSL_ENSURE( pPoppedContext==pCntxt, "wo kommt denn da ein HR-Kontext her?" );
5370 0 : delete pPoppedContext;
5371 :
5372 0 : pPam->Move( fnMoveForward );
5373 :
5374 : // und im Absatz danach die dort aktuelle Vorlage setzen
5375 0 : SetTxtCollAttrs();
5376 0 : }
5377 :
5378 46 : void SwHTMLParser::ParseMoreMetaOptions()
5379 : {
5380 68 : OUString aName, aContent;
5381 46 : bool bHTTPEquiv = false;
5382 :
5383 46 : const HTMLOptions& rHTMLOptions = GetOptions();
5384 184 : for (size_t i = rHTMLOptions.size(); i; )
5385 : {
5386 92 : const HTMLOption& rOption = rHTMLOptions[--i];
5387 92 : switch( rOption.GetToken() )
5388 : {
5389 : case HTML_O_NAME:
5390 32 : aName = rOption.GetString();
5391 32 : bHTTPEquiv = false;
5392 32 : break;
5393 : case HTML_O_HTTPEQUIV:
5394 14 : aName = rOption.GetString();
5395 14 : bHTTPEquiv = true;
5396 14 : break;
5397 : case HTML_O_CONTENT:
5398 46 : aContent = rOption.GetString();
5399 46 : break;
5400 : }
5401 : }
5402 :
5403 : // Hier wird es etwas tricky: Wir wissen genau, da? die Dok-Info
5404 : // nicht geaendert wurde. Deshalb genuegt es, auf Generator und
5405 : // auf refresh abzufragen, um noch nicht verarbeitete Token zu finden,
5406 : // denn das sind die einzigen, die die Dok-Info nicht modifizieren.
5407 128 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_generator ) ||
5408 72 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_refresh ) ||
5409 104 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_content_type ) ||
5410 22 : aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
5411 24 : return;
5412 :
5413 22 : aContent = comphelper::string::remove(aContent, '\r');
5414 22 : aContent = comphelper::string::remove(aContent, '\n');
5415 :
5416 22 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_sdendnote ) )
5417 : {
5418 0 : FillEndNoteInfo( aContent );
5419 0 : return;
5420 : }
5421 :
5422 22 : if( aName.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_META_sdfootnote ) )
5423 : {
5424 0 : FillFootNoteInfo( aContent );
5425 0 : return;
5426 : }
5427 :
5428 22 : OUStringBuffer sText;
5429 22 : sText.append("HTML: <");
5430 22 : sText.append(OOO_STRING_SVTOOLS_HTML_meta);
5431 22 : sText.append(' ');
5432 22 : if( bHTTPEquiv )
5433 0 : sText.append(OOO_STRING_SVTOOLS_HTML_O_httpequiv);
5434 : else
5435 22 : sText.append(OOO_STRING_SVTOOLS_HTML_O_name);
5436 22 : sText.append("=\"");
5437 22 : sText.append(aName);
5438 22 : sText.append("\" ");
5439 22 : sText.append(OOO_STRING_SVTOOLS_HTML_O_content);
5440 22 : sText.append("=\"");
5441 22 : sText.append(aContent);
5442 22 : sText.append("\">");
5443 :
5444 : SwPostItField aPostItFld(
5445 22 : (SwPostItFieldType*)pDoc->getIDocumentFieldsAccess().GetSysFldType( RES_POSTITFLD ),
5446 66 : aEmptyOUStr, sText.makeStringAndClear(), aEmptyOUStr, aEmptyOUStr, DateTime( DateTime::SYSTEM ) );
5447 44 : SwFmtFld aFmtFld( aPostItFld );
5448 66 : InsertAttr( aFmtFld );
5449 : }
5450 :
5451 1696 : _HTMLAttr::_HTMLAttr( const SwPosition& rPos, const SfxPoolItem& rItem,
5452 : _HTMLAttr **ppHd ) :
5453 : nSttPara( rPos.nNode ),
5454 : nEndPara( rPos.nNode ),
5455 1696 : nSttCntnt( rPos.nContent.GetIndex() ),
5456 1696 : nEndCntnt(rPos.nContent.GetIndex() ),
5457 : bInsAtStart( true ),
5458 : bLikePara( false ),
5459 : bValid( true ),
5460 : nCount( 1 ),
5461 : pNext( 0 ),
5462 : pPrev( 0 ),
5463 5088 : ppHead( ppHd )
5464 : {
5465 1696 : pItem = rItem.Clone();
5466 1696 : }
5467 :
5468 10 : _HTMLAttr::_HTMLAttr( const _HTMLAttr &rAttr, const SwNodeIndex &rEndPara,
5469 : sal_Int32 nEndCnt, _HTMLAttr **ppHd ) :
5470 : nSttPara( rAttr.nSttPara ),
5471 : nEndPara( rEndPara ),
5472 : nSttCntnt( rAttr.nSttCntnt ),
5473 : nEndCntnt( nEndCnt ),
5474 : bInsAtStart( rAttr.bInsAtStart ),
5475 : bLikePara( rAttr.bLikePara ),
5476 : bValid( rAttr.bValid ),
5477 : nCount( rAttr.nCount ),
5478 : pNext( 0 ),
5479 : pPrev( 0 ),
5480 10 : ppHead( ppHd )
5481 : {
5482 10 : pItem = rAttr.pItem->Clone();
5483 10 : }
5484 :
5485 3412 : _HTMLAttr::~_HTMLAttr()
5486 : {
5487 1706 : delete pItem;
5488 1706 : }
5489 :
5490 10 : _HTMLAttr *_HTMLAttr::Clone(const SwNodeIndex& rEndPara, sal_Int32 nEndCnt) const
5491 : {
5492 : // das Attribut mit der alten Start-Position neu anlegen
5493 10 : _HTMLAttr *pNew = new _HTMLAttr( *this, rEndPara, nEndCnt, ppHead );
5494 :
5495 : // die Previous-Liste muss uebernommen werden, die Next-Liste nicht!
5496 10 : pNew->pPrev = pPrev;
5497 :
5498 10 : return pNew;
5499 : }
5500 :
5501 0 : void _HTMLAttr::Reset(const SwNodeIndex& rSttPara, sal_Int32 nSttCnt,
5502 : _HTMLAttr **ppHd)
5503 : {
5504 : // den Anfang (und das Ende) neu setzen
5505 0 : nSttPara = rSttPara;
5506 0 : nSttCntnt = nSttCnt;
5507 0 : nEndPara = rSttPara;
5508 0 : nEndCntnt = nSttCnt;
5509 :
5510 : // den Head korrigieren und die Verkettungen aufheben
5511 0 : pNext = 0;
5512 0 : pPrev = 0;
5513 0 : ppHead = ppHd;
5514 0 : }
5515 :
5516 2 : void _HTMLAttr::InsertPrev( _HTMLAttr *pPrv )
5517 : {
5518 : OSL_ENSURE( !pPrv->pNext || pPrv->pNext == this,
5519 : "_HTMLAttr::InsertPrev: pNext falsch" );
5520 2 : pPrv->pNext = 0;
5521 :
5522 : OSL_ENSURE( 0 == pPrv->ppHead || ppHead == pPrv->ppHead,
5523 : "_HTMLAttr::InsertPrev: ppHead falsch" );
5524 2 : pPrv->ppHead = 0;
5525 :
5526 2 : _HTMLAttr *pAttr = this;
5527 4 : while( pAttr->GetPrev() )
5528 0 : pAttr = pAttr->GetPrev();
5529 :
5530 2 : pAttr->pPrev = pPrv;
5531 2 : }
5532 :
5533 66 : bool SwHTMLParser::ParseMetaOptions(
5534 : const uno::Reference<document::XDocumentProperties> & i_xDocProps,
5535 : SvKeyValueIterator *i_pHeader )
5536 : {
5537 : // always call base ParseMetaOptions, it sets the encoding (#i96700#)
5538 66 : bool ret( HTMLParser::ParseMetaOptions(i_xDocProps, i_pHeader) );
5539 66 : if (!ret && IsNewDoc())
5540 : {
5541 46 : ParseMoreMetaOptions();
5542 : }
5543 66 : return ret;
5544 : }
5545 :
5546 : // override so we can parse DOCINFO field subtypes INFO[1-4]
5547 18 : void SwHTMLParser::AddMetaUserDefined( OUString const & i_rMetaName )
5548 : {
5549 : // unless we already have 4 names, append the argument to m_InfoNames
5550 : OUString* pName // the first empty string in m_InfoNames
5551 18 : (m_InfoNames[0].isEmpty() ? &m_InfoNames[0] :
5552 10 : (m_InfoNames[1].isEmpty() ? &m_InfoNames[1] :
5553 8 : (m_InfoNames[2].isEmpty() ? &m_InfoNames[2] :
5554 36 : (m_InfoNames[3].isEmpty() ? &m_InfoNames[3] : 0 ))));
5555 18 : if (pName)
5556 : {
5557 14 : (*pName) = i_rMetaName;
5558 : }
5559 288 : }
5560 :
5561 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|