xref: /trunk/main/sw/source/filter/html/swhtml.hxx (revision 81caa1bc)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _SWHTML_HXX
25 #define _SWHTML_HXX
26 
27 #if !defined(_SVSTDARR_XUB_STRLEN_DECL) || !defined(_SVSTDARR_LONGS_DECL) || \
28 	!defined(_SVSTDARR_USHORTS_DECL) || !defined(_SVSTDARR_STRINGSDTOR_DECL)
29 #ifndef _SVSTDARR_XUB_STRLEN_DECL
30 #define _SVSTDARR_XUB_STRLEN
31 #endif
32 #ifndef _SVSTDARR_LONGS_DECL
33 #define _SVSTDARR_LONGS
34 #endif
35 #ifndef _SVSTDARR_USHORTS_DECL
36 #define _SVSTDARR_USHORTS
37 #endif
38 #ifndef _SVSTDARR_STRINGSDTOR_DECL
39 #define _SVSTDARR_STRINGSDTOR
40 #endif
41 #include <svl/svstdarr.hxx>
42 #endif
43 #include <tools/urlobj.hxx>
44 #include <sfx2/sfxhtml.hxx>
45 #include <svl/macitem.hxx>
46 #include <editeng/svxenum.hxx>
47 #include <fmtornt.hxx>
48 #include <com/sun/star/drawing/XShape.hpp>
49 #include <com/sun/star/form/XFormComponent.hpp>
50 #include <pam.hxx>
51 
52 #include "calbck.hxx"
53 #include "htmlvsh.hxx"
54 
55 class SfxMedium;
56 class SfxViewFrame;
57 class SdrObject;
58 class SvxMacroTableDtor;
59 class SvStringsDtor;
60 class SwDoc;
61 class SwPaM;
62 class ViewShell;
63 class SwStartNode;
64 class SwFmtColl;
65 class SwField;
66 class SwHTMLForm_Impl;
67 class SwApplet_Impl;
68 struct SwHTMLFootEndNote_Impl;
69 class HTMLTableCnts;
70 struct SwPendingStack;
71 class SvxCSS1PropertyInfo;
72 
73 #define HTML_PARSPACE (MM50)
74 
75 #define HTML_DFLT_IMG_WIDTH (MM50*4)
76 #define HTML_DFLT_IMG_HEIGHT (MM50*2)
77 
78 // a few things that are needed from time to time
79 extern HTMLOptionEnum __FAR_DATA aHTMLPAlignTable[];
80 extern HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[];
81 extern HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[];
82 
83 
84 // the attribute stack:
85 
86 class _HTMLAttr;
87 typedef _HTMLAttr *_HTMLAttrPtr;
88 SV_DECL_PTRARR( _HTMLAttrs, _HTMLAttrPtr, 5, 5 )
89 
90 class _HTMLAttr
91 {
92 	friend class SwHTMLParser;
93 	friend class _CellSaveStruct;
94 
95 	SwNodeIndex nSttPara, nEndPara;
96 	xub_StrLen nSttCntnt, nEndCntnt;
97 	sal_Bool bInsAtStart : 1;
98 	sal_Bool bLikePara : 1;// Set attribute over the entire paragraph
99 	sal_Bool bValid : 1;// is the attribute valid?
100 
101 	SfxPoolItem* pItem;
102 	sal_uInt16 nCount;// open attrs, with different values
103 	_HTMLAttr *pNext;// Attrs with different values still to be closed. Values
104 	_HTMLAttr *pPrev;// Attrs already closed but not yet legislated
105 	_HTMLAttr **ppHead;// the list header
106 
107 	_HTMLAttr( const SwPosition& rPos, const SfxPoolItem& rItem, _HTMLAttr **pHd=0 );
108 
109 	_HTMLAttr( const _HTMLAttr &rAttr, const SwNodeIndex &rEndPara, xub_StrLen nEndCnt, _HTMLAttr **pHd );
110 
111 public:
112 
113 	~_HTMLAttr();
114 
115 	_HTMLAttr *Clone( const SwNodeIndex& rEndPara, xub_StrLen nEndCnt ) const;
116 	void Reset( const SwNodeIndex& rSttPara, xub_StrLen nSttCnt, _HTMLAttr **pHd );
117 	inline void SetStart( const SwPosition& rPos );
118 
GetSttParaIdx() const119 	sal_uInt32 GetSttParaIdx() const { return nSttPara.GetIndex(); }
GetEndParaIdx() const120 	sal_uInt32 GetEndParaIdx() const { return nEndPara.GetIndex(); }
121 
GetSttPara() const122 	const SwNodeIndex& GetSttPara() const { return nSttPara; }
GetEndPara() const123 	const SwNodeIndex& GetEndPara() const { return nEndPara; }
124 
GetSttCnt() const125 	xub_StrLen GetSttCnt() const { return nSttCntnt; }
GetEndCnt() const126 	xub_StrLen GetEndCnt() const { return nEndCntnt; }
127 
IsLikePara() const128 	sal_Bool IsLikePara() const { return bLikePara; }
SetLikePara(sal_Bool bPara=sal_True)129 	void SetLikePara( sal_Bool bPara=sal_True ) { bLikePara = bPara; }
130 
GetItem()131 		  SfxPoolItem& GetItem()		{ return *pItem; }
GetItem() const132 	const SfxPoolItem& GetItem() const	{ return *pItem; }
133 
GetNext() const134 	_HTMLAttr *GetNext() const { return pNext; }
InsertNext(_HTMLAttr * pNxt)135 	void InsertNext( _HTMLAttr *pNxt ) { pNext = pNxt; }
136 
GetPrev() const137 	_HTMLAttr *GetPrev() const { return pPrev; }
138 	void InsertPrev( _HTMLAttr *pPrv );
ClearPrev()139 	void ClearPrev() { pPrev = 0; }
140 
SetHead(_HTMLAttr ** ppHd)141 	void SetHead( _HTMLAttr **ppHd ) { ppHead = ppHd; }
142 
143 	// When setting attributes from templates, it can happen,
144 	// that attributes should not be set after all. To delete them
145 	// would be very time-consuming, because you don't know exactly
146 	// where they are chained. Therefore, they are simply invalidated
147 	// and deleted with next _SetAttr().
Invalidate()148 	void Invalidate() { bValid = sal_False; }
IsValid() const149 	sal_Bool IsValid() const { return bValid; }
150 };
151 
152 // Table of attributes: Here the order is important: the attributes
153 // at the front of the table are also set first in EndAllAttrs.
154 struct _HTMLAttrTable
155 {
156 	_HTMLAttr
157 				*pKeep,// ::com::sun::star::frame::Frame-Attribute
158 				*pBox,
159 				*pBrush,
160 				*pBreak,
161 				*pPageDesc,
162 
163 				*pLRSpace,// paragraph-attributes
164 				*pULSpace,
165 				*pLineSpacing,
166 				*pAdjust,
167 				*pDropCap,
168 				*pSplit,
169 				*pWidows,
170 				*pOrphans,
171 				*pDirection,
172 
173 				*pCharFmts,// text-attributes
174 				*pINetFmt,
175 
176 				*pBold,// character-attributes
177 				*pBoldCJK,
178 				*pBoldCTL,
179 				*pItalic,
180 				*pItalicCJK,
181 				*pItalicCTL,
182 				*pStrike,
183 				*pUnderline,
184 				*pBlink,
185 				*pFont,
186 				*pFontCJK,
187 				*pFontCTL,
188 				*pFontHeight,
189 				*pFontHeightCJK,
190 				*pFontHeightCTL,
191 				*pFontColor,
192 				*pEscapement,
193 				*pCaseMap,
194 				*pKerning,// (only for SPACER)
195 				*pCharBrush,// Character background
196 				*pLanguage,
197 				*pLanguageCJK,
198 				*pLanguageCTL
199 				;
200 };
201 
202 class _HTMLAttrContext_SaveDoc;
203 
204 enum SwHTMLAppendMode {
205 	 AM_NORMAL,// no paragraph spacing treatment
206 	 AM_NOSPACE,// Force 0cm spacing
207 	 AM_SPACE,// Force 0.5 cm spacing
208 	 AM_SOFTNOSPACE,// Do not set distance but remember 0cm
209 	 AM_NONE// no append at all
210 };
211 
212 class _HTMLAttrContext
213 {
214 	_HTMLAttrs aAttrs;// the attributes started in the context
215 
216 	String aClass;// the class of the context
217 
218 	_HTMLAttrContext_SaveDoc *pSaveDocContext;
219 	SfxItemSet *pFrmItemSet;
220 
221 	sal_uInt16 	nToken;// the token to which the context belongs
222 
223 	sal_uInt16 	nTxtFmtColl;// a template started in the context or 0
224 
225 	sal_uInt16 	nLeftMargin;// a changed left edge
226 	sal_uInt16 	nRightMargin;// a changed right edge
227 	sal_uInt16	nFirstLineIndent;// a changed first line indent
228 
229 	sal_uInt16	nUpperSpace;
230 	sal_uInt16	nLowerSpace;
231 
232 	SwHTMLAppendMode eAppend;
233 
234 	sal_Bool	bLRSpaceChanged : 1;// left/right edge, indent changed?
235 	sal_Bool	bULSpaceChanged : 1;// upper/lower edge changed?
236 	sal_Bool	bDfltTxtFmtColl : 1;// nTxtFmtColl is only a default
237 	sal_Bool	bSpansSection : 1;// The context spans a SwSection
238 	sal_Bool	bPopStack : 1;// Delete the element above in the stack
239 	sal_Bool	bFinishPREListingXMP : 1;
240 	sal_Bool	bRestartPRE : 1;
241 	sal_Bool	bRestartXMP : 1;
242 	sal_Bool	bRestartListing : 1;
243 
244 public:
245 	void ClearSaveDocContext();
246 
_HTMLAttrContext(sal_uInt16 nTokn,sal_uInt16 nPoolId,const String & rClass,sal_Bool bDfltColl=sal_False)247 	_HTMLAttrContext( sal_uInt16 nTokn, sal_uInt16 nPoolId, const String& rClass,
248 					  sal_Bool bDfltColl=sal_False ) :
249 		aClass( rClass ),
250 		pSaveDocContext( 0 ),
251 		pFrmItemSet( 0 ),
252 		nToken( nTokn ),
253 		nTxtFmtColl( nPoolId ),
254 		nLeftMargin( 0 ),
255 		nRightMargin( 0 ),
256 		nFirstLineIndent( 0 ),
257 		nUpperSpace( 0 ),
258 		nLowerSpace( 0 ),
259 		eAppend( AM_NONE ),
260 		bLRSpaceChanged( sal_False ),
261 		bULSpaceChanged( sal_False ),
262 		bDfltTxtFmtColl( bDfltColl ),
263 		bSpansSection( sal_False ),
264 		bPopStack( sal_False ),
265 		bFinishPREListingXMP( sal_False ),
266 		bRestartPRE( sal_False ),
267 		bRestartXMP( sal_False ),
268 		bRestartListing( sal_False )
269 	{}
270 
_HTMLAttrContext(sal_uInt16 nTokn)271 	_HTMLAttrContext( sal_uInt16 nTokn ) :
272 		pSaveDocContext( 0 ),
273 		pFrmItemSet( 0 ),
274 		nToken( nTokn ),
275 		nTxtFmtColl( 0 ),
276 		nLeftMargin( 0 ),
277 		nRightMargin( 0 ),
278 		nFirstLineIndent( 0 ),
279 		nUpperSpace( 0 ),
280 		nLowerSpace( 0 ),
281 		eAppend( AM_NONE ),
282 		bLRSpaceChanged( sal_False ),
283 		bULSpaceChanged( sal_False ),
284 		bDfltTxtFmtColl( sal_False ),
285 		bSpansSection( sal_False ),
286 		bPopStack( sal_False ),
287 		bFinishPREListingXMP( sal_False ),
288 		bRestartPRE( sal_False ),
289 		bRestartXMP( sal_False ),
290 		bRestartListing( sal_False )
291 	{}
292 
~_HTMLAttrContext()293 	~_HTMLAttrContext() { ClearSaveDocContext(); delete pFrmItemSet; }
294 
GetToken() const295 	sal_uInt16 GetToken() const { return nToken; }
296 
GetTxtFmtColl() const297 	sal_uInt16 GetTxtFmtColl() const { return bDfltTxtFmtColl ? 0 : nTxtFmtColl; }
GetDfltTxtFmtColl() const298 	sal_uInt16 GetDfltTxtFmtColl() const { return bDfltTxtFmtColl ? nTxtFmtColl : 0; }
299 
GetClass() const300 	const String& GetClass() const { return aClass; }
301 
302 	inline void SetMargins( sal_uInt16 nLeft, sal_uInt16 nRight, short nIndent );
303 
IsLRSpaceChanged() const304 	inline sal_Bool IsLRSpaceChanged() const { return bLRSpaceChanged; }
305 	inline void GetMargins( sal_uInt16& nLeft, sal_uInt16& nRight,
306 							short &nIndent ) const;
307 
308 	inline void SetULSpace( sal_uInt16 nUpper, sal_uInt16 nLower );
IsULSpaceChanged() const309 	inline sal_Bool IsULSpaceChanged() const { return bULSpaceChanged; }
310 	inline void GetULSpace( sal_uInt16& rUpper, sal_uInt16& rLower ) const;
311 
HasAttrs() const312 	sal_Bool HasAttrs() const { return aAttrs.Count() != 0; }
GetAttrs() const313 	const _HTMLAttrs& GetAttrs() const { return aAttrs; }
GetAttrs()314 	_HTMLAttrs& GetAttrs() { return aAttrs; }
315 
SetSpansSection(sal_Bool bSet)316 	void SetSpansSection( sal_Bool bSet ) { bSpansSection = bSet; }
GetSpansSection() const317 	sal_Bool GetSpansSection() const { return bSpansSection; }
318 
SetPopStack(sal_Bool bSet)319 	void SetPopStack( sal_Bool bSet ) { bPopStack = bSet; }
GetPopStack() const320 	sal_Bool GetPopStack() const { return bPopStack; }
321 
HasSaveDocContext() const322 	sal_Bool HasSaveDocContext() const { return pSaveDocContext!=0; }
323 	_HTMLAttrContext_SaveDoc *GetSaveDocContext( sal_Bool bCreate=sal_False );
324 
GetFrmItemSet() const325 	const SfxItemSet *GetFrmItemSet() const { return pFrmItemSet; }
326 	SfxItemSet *GetFrmItemSet( SwDoc *pCreateDoc );
327 
SetFinishPREListingXMP(sal_Bool bSet)328 	void SetFinishPREListingXMP( sal_Bool bSet ) { bFinishPREListingXMP = bSet; }
IsFinishPREListingXMP() const329 	sal_Bool IsFinishPREListingXMP() const { return bFinishPREListingXMP; }
330 
SetRestartPRE(sal_Bool bSet)331 	void SetRestartPRE( sal_Bool bSet ) { bRestartPRE = bSet; }
IsRestartPRE() const332 	sal_Bool IsRestartPRE() const { return bRestartPRE; }
333 
SetRestartXMP(sal_Bool bSet)334 	void SetRestartXMP( sal_Bool bSet ) { bRestartXMP = bSet; }
IsRestartXMP() const335 	sal_Bool IsRestartXMP() const { return bRestartXMP; }
336 
SetRestartListing(sal_Bool bSet)337 	void SetRestartListing( sal_Bool bSet ) { bRestartListing = bSet; }
IsRestartListing() const338 	sal_Bool IsRestartListing() const { return bRestartListing; }
339 
SetAppendMode(SwHTMLAppendMode eMode=AM_NORMAL)340 	void SetAppendMode( SwHTMLAppendMode eMode=AM_NORMAL ) { eAppend = eMode; }
GetAppendMode() const341 	SwHTMLAppendMode GetAppendMode() const { return eAppend; }
342 };
343 
344 typedef _HTMLAttrContext *_HTMLAttrContextPtr;
345 SV_DECL_PTRARR( _HTMLAttrContexts, _HTMLAttrContextPtr, 5, 5 )
346 
347 class HTMLTable;
348 class SwCSS1Parser;
349 class SwHTMLNumRuleInfo;
350 
351 typedef ImageMap *ImageMapPtr;
352 SV_DECL_PTRARR_DEL( ImageMaps, ImageMapPtr, 1, 1 )
353 typedef SwFrmFmt *SwFrmFmtPtr;
354 SV_DECL_PTRARR( SwHTMLFrmFmts, SwFrmFmtPtr, 2, 2 )
355 
356 #define HTML_CNTXT_PROTECT_STACK	0x0001
357 #define HTML_CNTXT_STRIP_PARA		0x0002
358 #define HTML_CNTXT_KEEP_NUMRULE		0x0004
359 #define HTML_CNTXT_HEADER_DIST		0x0008
360 #define HTML_CNTXT_FOOTER_DIST	 	0x0010
361 #define HTML_CNTXT_KEEP_ATTRS		0x0020
362 
363 #define CONTEXT_FLAGS_ABSPOS	\
364 	(HTML_CNTXT_PROTECT_STACK | \
365 	 HTML_CNTXT_STRIP_PARA)
366 
367 #define HTML_FF_BOX		 		0x0001
368 #define HTML_FF_BACKGROUND			0x0002
369 #define HTML_FF_PADDING				0x0004
370 #define HTML_FF_DIRECTION			0x0008
371 
372 class SwHTMLParser : public SfxHTMLParser, public SwClient
373 {
374 	friend class _SectionSaveStruct;
375 	friend class _CellSaveStruct;
376 	friend class _CaptionSaveStruct;
377 
378 	String		aPathToFile;
379 	String		sBaseURL;
380 	String		sSaveBaseURL;
381 	String		aBasicLib;
382 	String		aBasicModule;
383 	String		aScriptSource;// Content of the current script block
384 	String		aScriptType;// Type of the loaded script (StarBasic/VB/JAVA)
385 	String		aScriptURL;// URL of a script
386 	String		aStyleSource;// Contents of the current style sheet
387 	String		aContents;// Text of the actual marquee, field, etc.
388 	String		sTitle;
389 	String		aUnknownToken;// a started unknown token
390 	String		aBulletGrfs[MAXLEVEL];
391 	String		sJmpMark;
392 
393 	SvUShorts	aBaseFontStack;// Stack for <BASEFONT>
394                                        // Bit 0-2: Font size (1-7)
395 	SvUShorts	aFontStack;// Stack for <FONT>, <BIG>, <SMALL>
396 				   // Bit 0-2: Font size (1-7)
397 				   // Bit 15: Font color was set
398 
399 	_HTMLAttrs		aSetAttrTab;// "closed" attribute, not set yet
400 	_HTMLAttrs		aParaAttrs;// leading paragraph attributes
401 	_HTMLAttrTable	aAttrTab;// "open" attributes
402 	_HTMLAttrContexts aContexts;// the current attribute/token context
403 	SwHTMLFrmFmts	aMoveFlyFrms;// Fly-Frames, der Anker wird verschoben
404 	SvXub_StrLens	aMoveFlyCnts;// and the Content-Positions
405 
406 	SwApplet_Impl *pAppletImpl;// the current applet
407 
408 	SwCSS1Parser 	*pCSS1Parser;// the style sheet parser
409 	SwHTMLNumRuleInfo *pNumRuleInfo;
410 	SwPendingStack	*pPendStack;
411 
412 	SwDoc			*pDoc;
413 	SwPaM			*pPam;// SwPosition should be enough, right?
414 	ViewShell		*pActionViewShell;// ViewShell, at which the StartAction
415 										// was called.
416 	SwNodeIndex		*pSttNdIdx;
417 
418 	HTMLTable		*pTable;// the current "outermost" table
419 	SwHTMLForm_Impl *pFormImpl;// the current form
420 	SdrObject		*pMarquee;// current marquee
421 	SwField			*pField;// current field
422 	ImageMap		*pImageMap;// current image map
423 	ImageMaps		*pImageMaps;// all image maps read so far
424 	SwHTMLFootEndNote_Impl *pFootEndNoteImpl;
425 
426 	Size 	aHTMLPageSize;// the page size of the HTML template
427 
428 	sal_uInt32 	aFontHeights[7];// the font heights 1-7
429 	sal_uInt32	nScriptStartLineNr;// Line number of a script block
430 	sal_uLong		nEventId;
431 
432 	sal_uInt16	nBaseFontStMin;
433 	sal_uInt16	nFontStMin;
434 	sal_uInt16	nDefListDeep;
435 	sal_uInt16	nFontStHeadStart;// Elements in the font stack at <Hn>.
436 	sal_uInt16	nSBModuleCnt;// Counter for Basic modules
437 	sal_uInt16	nMissingImgMaps;// How many image maps are missing?
438 	sal_uInt16 	nParaCnt;
439 	sal_uInt16	nContextStMin;// Lower limit for PopContext
440 	sal_uInt16	nContextStAttrMin;// Lower limit for attribution
441 	sal_uInt16	nSelectEntryCnt;// Number of entries in the current list box
442 	sal_uInt16	nOpenParaToken;// an opened paragraph element
443 
444 	enum JumpToMarks { JUMPTO_NONE, JUMPTO_MARK, JUMPTO_TABLE, JUMPTO_FRAME,
445 						JUMPTO_REGION, JUMPTO_GRAPHIC } eJumpTo;
446 
447 #ifdef DBG_UTIL
448 	sal_uInt16	nContinue;// Depth of Continue calls
449 #endif
450 
451 	SvxAdjust	eParaAdjust;// Alignment of the current paragraph
452 	HTMLScriptLanguage eScriptLang;// the current script language
453 
454 	sal_Bool bOldIsHTMLMode : 1;// Was it once an HTML document?
455 
456 	sal_Bool bDocInitialized : 1;// Document or shell were initialized
457                                      // Flag used to avoid double initialization due to recursion
458 	sal_Bool bViewCreated : 1;// the view was already created (asynchronous)
459 	sal_Bool bSetCrsr : 1;// Set Crsr back to the beginning
460 	sal_Bool bSetModEnabled : 1;
461 
462 	sal_Bool bInFloatingFrame : 1;// We are in a floating ::com::sun::star::frame::Frame
463 	sal_Bool bInField : 1;
464 	sal_Bool bKeepUnknown : 1;// unknown/unsupported tokens treatment
465 	// 8
466 	sal_Bool bCallNextToken : 1;// In tables: Call NextToken in any case
467 	sal_Bool bIgnoreRawData : 1;// Ignore content of a script/style.
468 	sal_Bool bLBEntrySelected : 1;// Is the current listbox entry selected.
469 	sal_Bool bTAIgnoreNewPara : 1;// ignore next LF in TextArea?
470 	sal_Bool bFixMarqueeWidth : 1;// Adjust the size of a ticker?
471 	sal_Bool bFixMarqueeHeight : 1;
472 
473 	sal_Bool bUpperSpace : 1;// upper paragraph spacing is required
474 	sal_Bool bNoParSpace : 1;
475 	// 16
476 
477 	sal_Bool bAnyStarBasic : 1;// there is a StarBasic module at all
478 	sal_Bool bInNoEmbed : 1;// We are in a NOEMBED area
479 
480 	sal_Bool bInTitle : 1;// We are in the title
481 
482 	sal_Bool bChkJumpMark : 1;// jump to a given marker if necessary
483 	sal_Bool bUpdateDocStat : 1;
484 	sal_Bool bFixSelectWidth : 1;// Reset the width of a select?
485 	sal_Bool bFixSelectHeight : 1;// Reset the height of a select?
486 	sal_Bool bTextArea : 1;
487 	// 24
488 	sal_Bool bSelect : 1;
489 	sal_Bool bInFootEndNoteAnchor : 1;
490 	sal_Bool bInFootEndNoteSymbol : 1;
491         sal_Bool bIgnoreHTMLComments : 1;
492         sal_Bool bRemoveHidden : 1;// the filter implementation might set the hidden flag
493 
494         // the names corresponding to the DOCINFO field subtypes INFO[1-4]
495         ::rtl::OUString m_InfoNames[4];
496 
497 	SfxViewFrame* pTempViewFrame;
498 
499 	void DeleteFormImpl();
500 
501 	void DocumentDetected();
502 	void Show();
503 	void ShowStatline();
504 	ViewShell *CallStartAction( ViewShell *pVSh = 0, sal_Bool bChkPtr = sal_True );
505 	ViewShell *CallEndAction( sal_Bool bChkAction = sal_False, sal_Bool bChkPtr = sal_True );
506 	ViewShell *CheckActionViewShell();
507 
508 	DECL_LINK( AsyncCallback, void* );
509 
510 	// Attribute am Dok setzen
511 	void _SetAttr( sal_Bool bChkEnd, sal_Bool bBeforeTable, _HTMLAttrs *pPostIts );
SetAttr(sal_Bool bChkEnd=sal_True,sal_Bool bBeforeTable=sal_False,_HTMLAttrs * pPostIts=0)512 	inline void SetAttr( sal_Bool bChkEnd = sal_True, sal_Bool bBeforeTable = sal_False,
513 						 _HTMLAttrs *pPostIts = 0 )
514 	{
515 		if( aSetAttrTab.Count() || aMoveFlyFrms.Count() )
516 			_SetAttr( bChkEnd, bBeforeTable, pPostIts );
517 	}
518 
519 	_HTMLAttr **GetAttrTabEntry( sal_uInt16 nWhich );
520 
521 	// Create a new text node at PaM position
522 	sal_Bool AppendTxtNode( SwHTMLAppendMode eMode=AM_NORMAL, sal_Bool bUpdateNum=sal_True );
523 	void AddParSpace();
524 
525 	// Start/end an attribute
526 	// ppDepAttr specifies an attribute table entry whose attributes
527 	// must be set before the attribute can be terminated.
528 	void NewAttr( _HTMLAttr **ppAttr, const SfxPoolItem& rItem );
529 	void EndAttr( _HTMLAttr *pAttr, _HTMLAttr **ppDepAttr=0,
530 				  sal_Bool bChkEmpty=sal_True );
531 	void DeleteAttr( _HTMLAttr* pAttr );
532 
533 	void EndContextAttrs( _HTMLAttrContext *pContext, sal_Bool bRemove=sal_False );
534 	void SaveAttrTab( _HTMLAttrTable& rNewAttrTab );
535 	void SplitAttrTab( const SwPosition& rNewPos );
536 	void SplitAttrTab( _HTMLAttrTable& rNewAttrTab, sal_Bool bMoveEndBack = sal_True );
537 	void RestoreAttrTab( const _HTMLAttrTable& rNewAttrTab,
538 						 sal_Bool bSetNewStart = sal_False );
539 	void InsertAttr( const SfxPoolItem& rItem, sal_Bool bLikePara = sal_False,
540 					 sal_Bool bInsAtStart=sal_False );
541 	void InsertAttrs( _HTMLAttrs& rAttrs );
542 
543 	sal_Bool DoPositioning( SfxItemSet &rItemSet,
544 						SvxCSS1PropertyInfo &rPropInfo,
545 						_HTMLAttrContext *pContext );
546 	sal_Bool CreateContainer( const String& rClass, SfxItemSet &rItemSet,
547 						  SvxCSS1PropertyInfo &rPropInfo,
548 						  _HTMLAttrContext *pContext );
549 	sal_Bool EndSection( sal_Bool bLFStripped=sal_False );
550 
551 	void InsertAttrs( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
552 					  _HTMLAttrContext *pContext, sal_Bool bCharLvl=sal_False );
553 	void InsertAttr( _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
554 					 _HTMLAttrContext *pCntxt );
555 	void SplitPREListingXMP( _HTMLAttrContext *pCntxt );
556 	void FixHeaderFooterDistance( sal_Bool bHeader,	const SwPosition *pOldPos );
557 
558 	void EndContext( _HTMLAttrContext *pContext );
559 	void ClearContext( _HTMLAttrContext *pContext );
560 
561 	const SwFmtColl *GetCurrFmtColl() const;
562 
563 	SwTwips GetCurrentBrowseWidth();
564 
GetNumInfo()565 	SwHTMLNumRuleInfo& GetNumInfo() { return *pNumRuleInfo; }
566         // --> OD 2008-04-02 #refactorlists#
567         // add parameter <bCountedInList>
568         void SetNodeNum( sal_uInt8 nLevel, bool bCountedInList );
569         // <--
570 
571 	// Manage paragraph templates
572 
573 	// set the templates on the stack or their attributes.
574 	void SetTxtCollAttrs( _HTMLAttrContext *pContext = 0 );
575 
576 	void InsertParaAttrs( const SfxItemSet& rItemSet );
577 
578 	// Manage the attribute context
579 
580 	// remember current context
581 	inline void PushContext( _HTMLAttrContext *pCntxt );
582 
583 	// get the topmost/specified context, but do not search outside
584 	// of the context with token nLimit. If bRemove is set,
585 	// it is removed
586 	_HTMLAttrContext *PopContext( sal_uInt16 nToken=0, sal_uInt16 nLimit=0,
587 								  sal_Bool bRemove=sal_True );
588 	inline const _HTMLAttrContext *GetTopContext() const;
589 
590 	sal_Bool GetMarginsFromContext( sal_uInt16 &nLeft, sal_uInt16 &nRight, short& nIndent,
591 								sal_Bool bIgnoreCurrent=sal_False ) const;
592 	sal_Bool GetMarginsFromContextWithNumBul( sal_uInt16 &nLeft, sal_uInt16 &nRight,
593 										  short& nIndent ) const;
594 	void GetULSpaceFromContext( sal_uInt16 &rUpper, sal_uInt16 &rLower ) const;
595 
596 
597 	void MovePageDescAttrs( SwNode *pSrcNd, sal_uLong nDestIdx, sal_Bool bFmtBreak );
598 
599 	// Handling tags at paragraph level
600 
601 	// <P> and <H1> to <H6>
602 	void NewPara();
603 	void EndPara( sal_Bool bReal = sal_False );
604 	void NewHeading( int nToken );
605 	void EndHeading();
606 
607 	// <ADDRESS>, <BLOCKQUOTE> and <PRE>
608 	void NewTxtFmtColl( int nToken, sal_uInt16 nPoolId );
609 	void EndTxtFmtColl( int nToken );
610 
611 	// <DIV> and <CENTER>
612 	void NewDivision( int nToken );
613 	void EndDivision( int nToken );
614 
615 	// Insert/exit fly frames
616 	void InsertFlyFrame( const SfxItemSet& rItemSet, _HTMLAttrContext *pCntxt,
617 						 const String& rId, sal_uInt16 nFlags );
618 
619 	void SaveDocContext( _HTMLAttrContext *pCntxt, sal_uInt16 nFlags,
620 					   const SwPosition *pNewPos );
621 	void RestoreDocContext( _HTMLAttrContext *pCntxt );
622 
623 	// leave all areas spanned by <DIV>.
624 	sal_Bool EndSections( sal_Bool bLFStripped );
625 
626 	// <MULTICOL>
627 	void NewMultiCol();
628 	void EndMultiCol();
629 
630 	// <MARQUEE>
631 	void NewMarquee( HTMLTable *pCurTable=0 );
632 	void EndMarquee();
633 	void InsertMarqueeText();
634 
635 	// List handling
636 
637 	// Numbering <OL> and Enumeration Lists <UL> with <LI>
638 	void NewNumBulList( int nToken );
639 	void EndNumBulList( int nToken=0 );
640 	void NewNumBulListItem( int nToken );
641 	void EndNumBulListItem( int nToken=0, sal_Bool bSetColl=sal_True,
642 							sal_Bool bLastPara=sal_False );
643 
644 	// Definition lists <DL> with <DD>, <DT>
645 	void NewDefList();
646 	void EndDefList();
647 	void NewDefListItem( int nToken );
648 	void EndDefListItem( int nToken=0, sal_Bool bSetColl=sal_True,
649 						 sal_Bool bLastPara=sal_False );
650 
651 
652 	// Handling tags at character level
653 
654 	// handle tags like <B>, <I> etc that turn a specific attribute
655 	// on and off, or which like SPAN only fetch attributes from styles.
656 	void NewStdAttr( int nToken );
657 	void NewStdAttr( int nToken,
658 					 _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
659 					 _HTMLAttr **ppAttr2=0, const SfxPoolItem *pItem2=0,
660 					 _HTMLAttr **ppAttr3=0, const SfxPoolItem *pItem3=0 );
661 	void EndTag( int nToken );
662 
663 	// Handle font attributes
664 	void NewBasefontAttr(); 			// for <BASEFONT>
665 	void EndBasefontAttr();
666 	void NewFontAttr( int nToken );	// for <FONT>, <BIG> and <SMALL>
667 	void EndFontAttr( int nToken );
668 
669 	// Tags realized by character templates
670 	void NewCharFmt( int nToken );
671 
672 	// <SDFIELD>
673 public:
674 	static sal_uInt16 GetNumType( const String& rStr, sal_uInt16 eDfltType );
675 private:
676         void NewField();
677 	void EndField();
678 	void InsertFieldText();
679 
680 	// <SPACER>
681 	void InsertSpacer();
682 
683 	// Inserting graphics, plugins and applets
684 
685 	// Search image maps and connect them with graphic nodes
686 	ImageMap *FindImageMap( const String& rURL ) const;
687 	void ConnectImageMaps();
688 
689         // Determine anchoring of a fly frame and set corresponding attributes
690         // set in the attrset (htmlgrin.cxx)
691         void SetAnchorAndAdjustment( sal_Int16 eVertOri,
692                                      sal_Int16 eHoriOri,
693                                      const SfxItemSet &rItemSet,
694                                      const SvxCSS1PropertyInfo &rPropInfo,
695                                      SfxItemSet& rFrmSet );
696         void SetAnchorAndAdjustment( sal_Int16 eVertOri,
697                                      sal_Int16 eHoriOri,
698                                      SfxItemSet& rFrmSet,
699                                      sal_Bool bDontAppend=sal_False );
700 	void SetAnchorAndAdjustment( const SfxItemSet &rItemSet,
701                                      const SvxCSS1PropertyInfo &rPropInfo,
702                                      SfxItemSet &rFrmItemSet );
703 
704 	void SetFrmFmtAttrs( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
705 						 sal_uInt16 nFlags, SfxItemSet &rFrmItemSet );
706 
707 	// Create frames and register auto-bound frames
708 	void RegisterFlyFrm( SwFrmFmt *pFlyFrm );
709 
710 	// Adapt the size of the fly-frame to the specifications and conditions.
711 	// (not for graphics, therefore htmlplug.cxx)
712 	void SetFixSize( const Size& rPixSize, const Size& rTwipDfltSize,
713 					 sal_Bool bPrcWidth, sal_Bool bPrcHeight,
714 					 SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
715 					 SfxItemSet& rFlyItemSet );
716 	void SetVarSize( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
717 					 SfxItemSet& rFlyItemSet, SwTwips nDfltWidth=MINLAY,
718 					 sal_uInt8 nDltPrcWidth=0 );
719 	void SetSpace( const Size& rPixSpace, SfxItemSet &rItemSet,
720 				   SvxCSS1PropertyInfo &rPropInfo, SfxItemSet& rFlyItemSet );
721 
722 	sal_uInt16 IncGrfsThatResizeTable();
723 
724 	void GetDefaultScriptType( ScriptType& rType,
725 							   String& rTypeStr ) const;
726 
727 	// the actual insert methods for <IMG>, <EMBED>, and <APPLET>
728 	// and <PARAM>
729 	void InsertImage();// htmlgrin.cxx
730 	void InsertEmbed();// htmlplug.cxx
731 
732 #ifdef SOLAR_JAVA
733 	void NewObject();// htmlplug.cxx
734 #endif
735 	void EndObject();// CommandLine with Applet link. (htmlplug.cxx)
736 #ifdef SOLAR_JAVA
737 	void InsertApplet();// htmlplug.cxx
738 #endif
739 	void EndApplet();// CommandLine with Applet link. (htmlplug.cxx)
740 	void InsertParam();// htmlplug.cxx
741 
742 	void InsertFloatingFrame();
EndFloatingFrame()743 	void EndFloatingFrame() { bInFloatingFrame = sal_False; }
744 
745 	// <BODY> tag evaluate: set background graphics and colors (htmlgrin.cxx)
746 	void InsertBodyOptions();
747 
748 
749 	// Inserting links and ::com::sun::star::text::Bookmarks (htmlgrin.cxx)
750 
751 	// Evaluate <A> tag: insert a link or ::com::sun::star::text::bookmark.
752 	void NewAnchor();
753 	void EndAnchor();
754 
755 	// insert a ::com::sun::star::text::bookmark
756 	void InsertBookmark( const String& rName );
757 
758 
759 	void InsertCommentText( const sal_Char *pTag = 0 );
760 	void InsertComment( const String& rName, const sal_Char *pTag = 0 );
761 
762 	// are there any ::com::sun::star::text::bookmarks in the current paragraph?
763 	sal_Bool HasCurrentParaBookmarks( sal_Bool bIgnoreStack=sal_False ) const;
764 
765 
766 	// Inserting Script/Basic elements
767 
768 	// parse the last Basic module (htmlbas.cxx) that was loaded
769 	void NewScript();
770 	void EndScript();
771 
772 	void AddScriptSource();
773 
774 	// add an event to the SFX configuration (htmlbas.cxx)
775 	void InsertBasicDocEvent( rtl::OUString aEventName, const String& rName,
776 							  ScriptType eScrType, const String& rScrType );
777 
778 	// attach an event to a VC control (htmlform.cxx)
779 	void InsertBasicCtrlEvent( sal_uInt16 nEvent, const String& rName );
780 
781 	// Inserting styles
782 
783 	// <STYLE>
784 	void NewStyle();
785 	void EndStyle();
786 
787 	inline sal_Bool HasStyleOptions( const String &rStyle, const String &rId,const String &rClass, const String *pLang=0,const String *pDir=0 );
788 	sal_Bool ParseStyleOptions( const String &rStyle, const String &rId,
789 							const String &rClass, SfxItemSet &rItemSet,
790 							SvxCSS1PropertyInfo &rPropInfo,
791 							 const String *pLang=0, const String *pDir=0 );
792 
793 
794 	// Inserting controls and ::com::sun::star::form::Forms (htmlform.cxx)
795 
796 	// Add a Draw object to the document
797 	void InsertDrawObject( SdrObject* pNewDrawObj, const Size& rSpace,
798                                sal_Int16 eVertOri,
799                                sal_Int16 eHoriOri,
800                                SfxItemSet& rCSS1ItemSet,
801                                SvxCSS1PropertyInfo& rCSS1PropInfo,
802                                sal_Bool bHidden=sal_False );
803         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >  InsertControl( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent > & rFormComp,
804                                                                                               const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rFCompPropSet,
805                                                                                               const Size& rSize,
806                                                                                               sal_Int16 eVertOri,
807                                                                                               sal_Int16 eHoriOri,
808 	                                                                                      SfxItemSet& rCSS1ItemSet,
809                                                                                               SvxCSS1PropertyInfo& rCSS1PropInfo,
810 	                                                                                      const SvxMacroTableDtor& rMacroTbl,
811 	                                                                                      const SvStringsDtor& rUnoMacroTbl,
812 	                                                                                      const SvStringsDtor& rUnoMacroParamTbl,
813                                                                                               sal_Bool bSetPropSet = sal_True,
814                                                                                               sal_Bool bHidden = sal_False );
815 
816 	void SetControlSize( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rShape, const Size& rTextSz,sal_Bool bMinWidth, sal_Bool bMinHeight, int nToken );
817 	void SetPendingControlSize( int nToken );
818 
819 public:
820 	void ResizeDrawObject( SdrObject* pObj, SwTwips nWidth );
821 private:
822 	void RegisterDrawObjectToTable( HTMLTable *pCurTable, SdrObject* pObj, sal_uInt8 nWidth );
823 
824 
825 	// start a new form
826 	void NewForm( sal_Bool bAppend=sal_True );
827 	void EndForm( sal_Bool bAppend=sal_True );
828 
829 	// the insertion methods for <INPUT>, <TEXTAREA> and <SELECT>
830 	void InsertInput();
831 
832 	void NewTextArea();
833 	void InsertTextAreaText( sal_uInt16 nToken );
834 	void EndTextArea();
835 
836 	void NewSelect();
837 	void InsertSelectOption();
838 	void InsertSelectText();
839 	void EndSelect();
840 
841 	// Insert tables (htmltab.cxx)
842 
843 public:// is needed in tables
844 
845 	// insert a box content after the specified node
846 	const SwStartNode *InsertTableSection( const SwStartNode *pPrevStNd );
847 
848 	// Insert a box content at the end of the table containing the PaM
849 	// and move the PaM into the cell
850 	const SwStartNode *InsertTableSection( sal_uInt16 nPoolId );
851 
852 	// Insert methods for the various table tags
853 	HTMLTableCnts *InsertTableContents( sal_Bool bHead );
854 
855 private:
856 	// Create a section for the temporary setting of the table heading
857 	SwStartNode *InsertTempTableCaptionSection();
858 
859 	void BuildTableCell( HTMLTable *pTable, sal_Bool bReadOptions, sal_Bool bHead );
860 	void BuildTableRow( HTMLTable *pTable, sal_Bool bReadOptions,SvxAdjust eGrpAdjust, sal_Int16 eVertOri );
861 	void BuildTableSection( HTMLTable *pTable, sal_Bool bReadOptions, sal_Bool bHead );
862 	void BuildTableColGroup( HTMLTable *pTable, sal_Bool bReadOptions );
863 	void BuildTableCaption( HTMLTable *pTable );
864 	HTMLTable *BuildTable( SvxAdjust eCellAdjust, sal_Bool bIsParentHead = sal_False, sal_Bool bHasParentSection=sal_True, sal_Bool bIsInMulticol = sal_False, sal_Bool bHasToFlow = sal_False );
865 
866 
867 // miscellaneous ...
868 	void ParseMoreMetaOptions();
869 
870 	sal_Bool FileDownload( const String& rURL, String& rStr );
871 	void InsertLink();
872 
873 	void InsertIDOption();
874 	void InsertLineBreak();
875 	void InsertHorzRule();
876 
877 	void FillEndNoteInfo( const String& rContent );
878 	void FillFootNoteInfo( const String& rContent );
879 	void InsertFootEndNote( const String& rName, sal_Bool bEndNote, sal_Bool bFixed );
880 	void FinishFootEndNote();
881 	void InsertFootEndNoteText();
882 	SwNodeIndex *GetFootEndNoteSection( const String& rName );
883 	void DeleteFootEndNoteImpl();
884 
885 	// Remove line break at the end of a paragraph
886 	xub_StrLen StripTrailingLF();
887 
888 
889 	// Remove an empty paragraph at the PaM position.
890 	void StripTrailingPara();
891 
892 	// Are there any visible Fly-Frames in the current paragraph?
893 	sal_Bool HasCurrentParaFlys( sal_Bool bNoSurroundOnly = sal_False, sal_Bool bSurroundOnly = sal_False ) const;
894 
895 public:// is needed in tables
896 
897 	// generate a BrushItem (with new) or 0
898 	SvxBrushItem* CreateBrushItem( const Color *pColor,
899                                        const String &rImageURL,
900                                        const String &rStyle,
901                                        const String &rId,
902                                        const String &rClass );
903 
904 protected:
905 	// is called for every token that is recognized in CallParser
906 	virtual void NextToken( int nToken );
907 	virtual ~SwHTMLParser();
908 
909 	// if the doc is deleted, the parser has to be deleted as well
910 	virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew );
911 
912     virtual void AddMetaUserDefined( ::rtl::OUString const & i_rMetaName );
913 
914 public:
915 
916 	SwHTMLParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
917                     const String& rFileName,
918                     const String& rBaseURL,
919                     int bReadNewDoc = sal_True,
920                     SfxMedium* pMed = 0, sal_Bool bReadUTF8 = sal_False,
921                     sal_Bool bIgnoreHTMLComments = sal_False );
922 
923 	virtual SvParserState CallParser();// Call the parser
924 
925 
926 	sal_uInt16 ToTwips( sal_uInt16 nPixel ) const;
927 
928 	// for asynchronous reading from the SvStream
929 	virtual void Continue( int nToken );
930 
931     virtual bool ParseMetaOptions( const ::com::sun::star::uno::Reference < ::com::sun::star::document::XDocumentProperties>&, SvKeyValueIterator* );
932 };
933 
934 
935 struct SwPendingStackData
936 {
~SwPendingStackDataSwPendingStackData937 	virtual ~SwPendingStackData() {}
938 };
939 
940 struct SwPendingStack
941 {
942 	int nToken;
943 	SwPendingStackData* pData;
944 	SwPendingStack* pNext;
945 
SwPendingStackSwPendingStack946 	SwPendingStack( int nTkn, SwPendingStack* pNxt )
947 		: nToken( nTkn ), pData( 0 ), pNext( pNxt )
948 		{}
949 };
950 
SetStart(const SwPosition & rPos)951 inline void _HTMLAttr::SetStart( const SwPosition& rPos )
952 {
953 	nSttPara = rPos.nNode;
954 	nSttCntnt = rPos.nContent.GetIndex();
955 	nEndPara = nSttPara;
956 	nEndCntnt = nSttCntnt;
957 }
958 
SetMargins(sal_uInt16 nLeft,sal_uInt16 nRight,short nIndent)959 inline void _HTMLAttrContext::SetMargins( sal_uInt16 nLeft, sal_uInt16 nRight, short nIndent )
960 {
961 	nLeftMargin = nLeft;
962 	nRightMargin = nRight;
963 	nFirstLineIndent = nIndent;
964 	bLRSpaceChanged = sal_True;
965 }
966 
GetMargins(sal_uInt16 & nLeft,sal_uInt16 & nRight,short & nIndent) const967 inline void _HTMLAttrContext::GetMargins( sal_uInt16& nLeft,
968                                           sal_uInt16& nRight,
969                                           short& nIndent ) const
970 {
971 	if( bLRSpaceChanged )
972 	{
973 		nLeft = nLeftMargin;
974 		nRight = nRightMargin;
975 		nIndent = nFirstLineIndent;
976 	}
977 }
978 
SetULSpace(sal_uInt16 nUpper,sal_uInt16 nLower)979 inline void _HTMLAttrContext::SetULSpace( sal_uInt16 nUpper, sal_uInt16 nLower )
980 {
981 	nUpperSpace = nUpper;
982 	nLowerSpace = nLower;
983 	bULSpaceChanged = sal_True;
984 }
985 
GetULSpace(sal_uInt16 & rUpper,sal_uInt16 & rLower) const986 inline void _HTMLAttrContext::GetULSpace( sal_uInt16& rUpper,
987 										  sal_uInt16& rLower ) const
988 {
989 	if( bULSpaceChanged )
990 	{
991 		rUpper = nUpperSpace;
992 		rLower = nLowerSpace;
993 	}
994 }
995 
HasStyleOptions(const String & rStyle,const String & rId,const String & rClass,const String * pLang,const String * pDir)996 inline sal_Bool SwHTMLParser::HasStyleOptions( const String &rStyle,
997                                                const String &rId,
998                                                const String &rClass,
999                                                const String *pLang,
1000                                                const String *pDir )
1001 {
1002 	return rStyle.Len() || rId.Len() || rClass.Len() ||
1003 		   (pLang && pLang->Len()) || (pDir && pDir->Len());
1004 }
1005 
GetTopContext() const1006 inline const _HTMLAttrContext *SwHTMLParser::GetTopContext() const
1007 {
1008 	return aContexts.Count() > nContextStMin
1009 			? aContexts[aContexts.Count()-1] : 0;
1010 }
1011 
PushContext(_HTMLAttrContext * pCntxt)1012 inline void SwHTMLParser::PushContext( _HTMLAttrContext *pCntxt )
1013 {
1014 	aContexts.Insert( pCntxt, aContexts.Count() );
1015 }
1016 
1017 
1018 #endif
1019 
1020 
1021