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