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