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