xref: /aoo4110/main/sw/source/filter/html/htmlgrin.cxx (revision b1cdbd2c)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include "hintids.hxx"
28 #include <vcl/svapp.hxx>
29 #include <vcl/wrkwin.hxx>
30 #include <svx/svxids.hrc>
31 #include <sfx2/sfx.hrc>
32 #include <i18npool/mslangid.hxx>
33 #include <svl/stritem.hxx>
34 #include <svl/urihelper.hxx>
35 #include <editeng/fhgtitem.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include <editeng/adjitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <editeng/brshitem.hxx>
40 #include <editeng/colritem.hxx>
41 #include <editeng/boxitem.hxx>
42 #include <editeng/ulspitem.hxx>
43 #include <editeng/langitem.hxx>
44 #include <editeng/scripttypeitem.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <svtools/imap.hxx>
47 #include <svtools/htmltokn.h>
48 #include <svtools/htmlkywd.hxx>
49 #include <unotools/eventcfg.hxx>
50 
51 #include <fmtornt.hxx>
52 #include <fmturl.hxx>
53 #include <fmtanchr.hxx>
54 #include <fmtsrnd.hxx>
55 #include <fmtinfmt.hxx>
56 #include <fmtcntnt.hxx>
57 #include <fmtanchr.hxx>
58 #include <fmtfsize.hxx>
59 #include <fmtinfmt.hxx>
60 #include "frmatr.hxx"
61 #include "charatr.hxx"
62 #include <frmfmt.hxx>
63 #include <charfmt.hxx>
64 #include <docary.hxx>
65 #include <docsh.hxx>
66 #include <pam.hxx>
67 #include <doc.hxx>
68 #include <ndtxt.hxx>
69 #include <shellio.hxx>
70 #include <poolfmt.hxx>
71 #include <IMark.hxx>
72 #include <ndgrf.hxx>
73 #include <htmlnum.hxx>
74 #include <swcss1.hxx>
75 #include <swhtml.hxx>
76 #include <numrule.hxx>
77 #include <boost/shared_ptr.hpp>
78 
79 using namespace ::com::sun::star;
80 
81 
82 HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[] =
83 {
84     { OOO_STRING_SVTOOLS_HTML_AL_left,    text::HoriOrientation::LEFT       },
85     { OOO_STRING_SVTOOLS_HTML_AL_right,   text::HoriOrientation::RIGHT      },
86 	{ 0,				0				}
87 };
88 
89 
90 HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[] =
91 {
92     { OOO_STRING_SVTOOLS_HTML_VA_top,         text::VertOrientation::LINE_TOP       },
93     { OOO_STRING_SVTOOLS_HTML_VA_texttop,     text::VertOrientation::CHAR_TOP       },
94     { OOO_STRING_SVTOOLS_HTML_VA_middle,      text::VertOrientation::CENTER         },
95     { OOO_STRING_SVTOOLS_HTML_AL_center,      text::VertOrientation::CENTER         },
96     { OOO_STRING_SVTOOLS_HTML_VA_absmiddle,   text::VertOrientation::LINE_CENTER    },
97     { OOO_STRING_SVTOOLS_HTML_VA_bottom,      text::VertOrientation::TOP            },
98     { OOO_STRING_SVTOOLS_HTML_VA_baseline,    text::VertOrientation::TOP            },
99     { OOO_STRING_SVTOOLS_HTML_VA_absbottom,   text::VertOrientation::LINE_BOTTOM    },
100 	{ 0,					0					}
101 };
102 
SV_IMPL_PTRARR(ImageMaps,ImageMapPtr)103 SV_IMPL_PTRARR( ImageMaps, ImageMapPtr )
104 
105 ImageMap *SwHTMLParser::FindImageMap( const String& rName ) const
106 {
107 	ImageMap *pMap = 0;
108 
109 	ASSERT( rName.GetChar(0) != '#', "FindImageName: Name beginnt mit #!" );
110 
111 	if( pImageMaps )
112 	{
113 		for( sal_uInt16 i=0; i<pImageMaps->Count(); i++ )
114 		{
115 			ImageMap *pIMap = (*pImageMaps)[i];
116 			if( rName.EqualsIgnoreCaseAscii( pIMap->GetName() ) )
117 			{
118 				pMap = pIMap;
119 				break;
120 			}
121 		}
122 	}
123 	return pMap;
124 }
125 
ConnectImageMaps()126 void SwHTMLParser::ConnectImageMaps()
127 {
128 	SwNodes& rNds = pDoc->GetNodes();
129 	// auf den Start-Node der 1. Section
130 	sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 1;
131 	sal_uLong nEndIdx = rNds.GetEndOfAutotext().GetIndex();
132 
133 	SwGrfNode* pGrfNd;
134 	while( nMissingImgMaps > 0 && nIdx < nEndIdx )
135 	{
136 		SwNode *pNd = rNds[nIdx + 1];
137 		if( 0 != (pGrfNd = pNd->GetGrfNode()) )
138 		{
139 			SwFrmFmt *pFmt = pGrfNd->GetFlyFmt();
140 			SwFmtURL aURL( pFmt->GetURL() );
141 			const ImageMap *pIMap = aURL.GetMap();
142 			if( pIMap && pIMap->GetIMapObjectCount()==0 )
143 			{
144 				// Die (leere) Image-Map des Nodes wird entweder
145 				// durch die jetzt gefundene Image-Map ersetzt
146 				// oder geloescht.
147 				ImageMap *pNewIMap =
148 					FindImageMap( pIMap->GetName() );
149 				aURL.SetMap( pNewIMap );
150                 pFmt->SetFmtAttr( aURL );
151 				if( !pGrfNd->IsScaleImageMap() )
152 				{
153 					// die Grafikgroesse ist mitlerweile da oder dir
154 					// Grafik muss nicht skaliert werden
155 					pGrfNd->ScaleImageMap();
156 				}
157 				nMissingImgMaps--;	// eine Map weniger suchen
158 			}
159 		}
160 		nIdx = rNds[nIdx]->EndOfSectionIndex() + 1;
161 	}
162 }
163 
164 
165 /*  */
166 
SetAnchorAndAdjustment(sal_Int16 eVertOri,sal_Int16 eHoriOri,const SfxItemSet & rCSS1ItemSet,const SvxCSS1PropertyInfo & rCSS1PropInfo,SfxItemSet & rFrmItemSet)167 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
168                                            sal_Int16 eHoriOri,
169 										   const SfxItemSet &rCSS1ItemSet,
170 										   const SvxCSS1PropertyInfo &rCSS1PropInfo,
171 										   SfxItemSet& rFrmItemSet )
172 {
173 	const SfxItemSet *pCntnrItemSet = 0;
174 	sal_uInt16 i = aContexts.Count();
175 	while( !pCntnrItemSet && i > nContextStMin )
176 		pCntnrItemSet = aContexts[--i]->GetFrmItemSet();
177 
178 	if( pCntnrItemSet )
179 	{
180 		// Wenn wir und in einem Container befinden wird die Verankerung
181 		// des Containers uebernommen.
182 		rFrmItemSet.Put( *pCntnrItemSet );
183 	}
184 	else if( pCSS1Parser->MayBePositioned( rCSS1PropInfo, sal_True ) )
185 	{
186 		// Wenn die Ausrichtung anhand der CSS1-Optionen gesetzt werden kann
187 		// werden die benutzt.
188 		SetAnchorAndAdjustment( rCSS1ItemSet, rCSS1PropInfo, rFrmItemSet );
189 	}
190 	else
191 	{
192 		// Sonst wird die Ausrichtung entsprechend der normalen HTML-Optionen
193 		// gesetzt.
194 		SetAnchorAndAdjustment( eVertOri, eHoriOri, rFrmItemSet );
195 	}
196 }
197 
SetAnchorAndAdjustment(sal_Int16 eVertOri,sal_Int16 eHoriOri,SfxItemSet & rFrmSet,sal_Bool bDontAppend)198 void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
199                                            sal_Int16 eHoriOri,
200 										   SfxItemSet& rFrmSet,
201 										   sal_Bool bDontAppend )
202 {
203 	sal_Bool bMoveBackward = sal_False;
204     SwFmtAnchor aAnchor( FLY_AS_CHAR );
205     sal_Int16 eVertRel = text::RelOrientation::FRAME;
206 
207     if( text::HoriOrientation::NONE != eHoriOri )
208 	{
209 		// den Absatz-Einzug bestimmen
210 		sal_uInt16 nLeftSpace = 0, nRightSpace = 0;
211 		short nIndent = 0;
212 		GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
213 
214 		// Horizonale Ausrichtung und Umlauf bestimmen.
215         sal_Int16 eHoriRel;
216 		SwSurround eSurround;
217 		switch( eHoriOri )
218 		{
219         case text::HoriOrientation::LEFT:
220             eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
221 			eSurround = SURROUND_RIGHT;
222 			break;
223         case text::HoriOrientation::RIGHT:
224             eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
225 			eSurround = SURROUND_LEFT;
226 			break;
227         case text::HoriOrientation::CENTER:   // fuer Tabellen
228             eHoriRel = text::RelOrientation::FRAME;
229 			eSurround = SURROUND_NONE;
230 			break;
231 		default:
232             eHoriRel = text::RelOrientation::FRAME;
233 			eSurround = SURROUND_PARALLEL;
234 			break;
235 		}
236 
237 		// Einen neuen Absatz aufmachen, wenn der aktuelle
238 		// absatzgebundene Rahmen ohne Umlauf enthaelt.
239 		if( !bDontAppend && HasCurrentParaFlys( sal_True ) )
240 		{
241 			// Wenn der Absatz nur Grafiken enthaelt, braucht er
242 			// auch keinen unteren Absatz-Abstand. Da hier auch bei
243 			// Verwendung von Styles kein Abstand enstehen soll, wird
244 			// hier auch geweohnlich attributiert !!!
245 			sal_uInt16 nUpper=0, nLower=0;
246 			GetULSpaceFromContext( nUpper, nLower );
247             InsertAttr( SvxULSpaceItem( nUpper, 0, RES_UL_SPACE ), sal_False, sal_True );
248 
249 			AppendTxtNode( AM_NOSPACE );
250 
251 			if( nUpper )
252 			{
253                 NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, nLower, RES_UL_SPACE ) );
254 				aParaAttrs.Insert( aAttrTab.pULSpace, aParaAttrs.Count() );
255 				EndAttr( aAttrTab.pULSpace, 0, sal_False );
256 			}
257 		}
258 
259 		// Vertikale Ausrichtung und Verankerung bestimmen.
260 		xub_StrLen nCntnt = pPam->GetPoint()->nContent.GetIndex();
261 		if( nCntnt )
262 		{
263             aAnchor.SetType( FLY_AT_CHAR );
264 			bMoveBackward = sal_True;
265             eVertOri = text::VertOrientation::CHAR_BOTTOM;
266             eVertRel = text::RelOrientation::CHAR;
267 		}
268 		else
269         {
270             aAnchor.SetType( FLY_AT_PARA );
271             eVertOri = text::VertOrientation::TOP;
272             eVertRel = text::RelOrientation::PRINT_AREA;
273 		}
274 
275 		rFrmSet.Put( SwFmtHoriOrient( 0, eHoriOri, eHoriRel) );
276 
277 		rFrmSet.Put( SwFmtSurround( eSurround ) );
278 	}
279 	rFrmSet.Put( SwFmtVertOrient( 0, eVertOri, eVertRel) );
280 
281 	if( bMoveBackward )
282 		pPam->Move( fnMoveBackward );
283 
284 	aAnchor.SetAnchor( pPam->GetPoint() );
285 
286 	if( bMoveBackward )
287 		pPam->Move( fnMoveForward );
288 
289 	rFrmSet.Put( aAnchor );
290 }
291 
RegisterFlyFrm(SwFrmFmt * pFlyFmt)292 void SwHTMLParser::RegisterFlyFrm( SwFrmFmt *pFlyFmt )
293 {
294 	// automatisch verankerte Rahmen muessen noch um eine Position
295 	// nach vorne verschoben werden.
296 	if( RES_DRAWFRMFMT != pFlyFmt->Which() &&
297         (FLY_AT_PARA == pFlyFmt->GetAnchor().GetAnchorId()) &&
298 		SURROUND_THROUGHT == pFlyFmt->GetSurround().GetSurround() )
299 	{
300 		aMoveFlyFrms.Insert( pFlyFmt, aMoveFlyFrms.Count() );
301 		aMoveFlyCnts.push_back( pPam->GetPoint()->nContent.GetIndex() );
302 	}
303 }
304 
305 /*  */
306 
GetDefaultScriptType(ScriptType & rType,String & rTypeStr) const307 void SwHTMLParser::GetDefaultScriptType( ScriptType& rType,
308 										 String& rTypeStr ) const
309 {
310 	SwDocShell *pDocSh = pDoc->GetDocShell();
311 	SvKeyValueIterator* pHeaderAttrs = pDocSh ? pDocSh->GetHeaderAttributes()
312 											  : 0;
313 	rType = GetScriptType( pHeaderAttrs );
314 	rTypeStr = GetScriptTypeString( pHeaderAttrs );
315 }
316 
317 /*  */
318 
InsertImage()319 void SwHTMLParser::InsertImage()
320 {
321 	// und jetzt auswerten
322 	String sGrfNm, sAltNm, aId, aClass, aStyle, aMap, sHTMLGrfName;
323     sal_Int16 eVertOri = text::VertOrientation::TOP;
324     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
325 	long nWidth=0, nHeight=0;
326 	long nVSpace=0, nHSpace=0;
327 
328 	sal_uInt16 nBorder = (aAttrTab.pINetFmt ? 1 : 0);
329 	sal_Bool bIsMap = sal_False;
330 	sal_Bool bPrcWidth = sal_False;
331 	sal_Bool bPrcHeight = sal_False;
332     SvxMacroItem aMacroItem(RES_FRMMACRO);
333 
334 	ScriptType eDfltScriptType;
335 	String sDfltScriptType;
336 	GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
337 
338 	const HTMLOptions *pHTMLOptions = GetOptions();
339 	for( sal_uInt16 i = pHTMLOptions->Count(); i; )
340 	{
341 		sal_uInt16 nEvent = 0;
342 		ScriptType eScriptType2 = eDfltScriptType;
343 		const HTMLOption *pOption = (*pHTMLOptions)[--i];
344 		switch( pOption->GetToken() )
345 		{
346 			case HTML_O_ID:
347 				aId = pOption->GetString();
348 				break;
349 			case HTML_O_STYLE:
350 				aStyle = pOption->GetString();
351 				break;
352 			case HTML_O_CLASS:
353 				aClass = pOption->GetString();
354 				break;
355 			case HTML_O_SRC:
356 				sGrfNm = pOption->GetString();
357 				if( !InternalImgToPrivateURL(sGrfNm) )
358                     sGrfNm = INetURLObject::GetAbsURL( sBaseURL, sGrfNm );
359 				break;
360 			case HTML_O_ALIGN:
361 				eVertOri =
362                     pOption->GetEnum( aHTMLImgVAlignTable,
363                                                     text::VertOrientation::TOP );
364 				eHoriOri =
365                     pOption->GetEnum( aHTMLImgHAlignTable,
366                                                     text::HoriOrientation::NONE );
367 				break;
368 			case HTML_O_WIDTH:
369 				// erstmal nur als Pixelwerte merken!
370 				nWidth = pOption->GetNumber();
371 				bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
372 				if( bPrcWidth && nWidth>100 )
373 					nWidth = 100;
374 				break;
375 			case HTML_O_HEIGHT:
376 				// erstmal nur als Pixelwerte merken!
377 				nHeight = pOption->GetNumber();
378 				bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
379 				if( bPrcHeight && nHeight>100 )
380 					nHeight = 100;
381 				break;
382 			case HTML_O_VSPACE:
383 				nVSpace = pOption->GetNumber();
384 				break;
385 			case HTML_O_HSPACE:
386 				nHSpace = pOption->GetNumber();
387 				break;
388 			case HTML_O_ALT:
389 				sAltNm = pOption->GetString();
390 				break;
391 			case HTML_O_BORDER:
392 				nBorder = (sal_uInt16)pOption->GetNumber();
393 				break;
394 			case HTML_O_ISMAP:
395 				bIsMap = sal_True;
396 				break;
397 			case HTML_O_USEMAP:
398 				aMap = pOption->GetString();
399 				break;
400 			case HTML_O_NAME:
401 				sHTMLGrfName = pOption->GetString();
402 				break;
403 
404 			case HTML_O_SDONLOAD:
405 				eScriptType2 = STARBASIC;
406 			case HTML_O_ONLOAD:
407 				nEvent = SVX_EVENT_IMAGE_LOAD;
408 				goto IMAGE_SETEVENT;
409 
410 			case HTML_O_SDONABORT:
411 				eScriptType2 = STARBASIC;
412 			case HTML_O_ONABORT:
413 				nEvent = SVX_EVENT_IMAGE_ABORT;
414 				goto IMAGE_SETEVENT;
415 
416 			case HTML_O_SDONERROR:
417 				eScriptType2 = STARBASIC;
418 			case HTML_O_ONERROR:
419 				nEvent = SVX_EVENT_IMAGE_ERROR;
420 				goto IMAGE_SETEVENT;
421 IMAGE_SETEVENT:
422 				{
423 					String sTmp( pOption->GetString() );
424 					if( sTmp.Len() )
425 					{
426 						sTmp.ConvertLineEnd();
427 						String sScriptType;
428 						if( EXTENDED_STYPE == eScriptType2 )
429 							sScriptType = sDfltScriptType;
430 						aMacroItem.SetMacro( nEvent,
431 							SvxMacro( sTmp, sScriptType, eScriptType2 ));
432 					}
433 				}
434 				break;
435 		}
436 	}
437 
438 	if( !sGrfNm.Len() )
439 		return;
440 
441 	// Wenn wir in einer Numerierung stehen und der Absatz noch leer und
442 	// nicht numeriert ist, handelt es sich vielleicht um die Grafik
443 	// einer Bullet-Liste
444 	if( !pPam->GetPoint()->nContent.GetIndex() &&
445 		GetNumInfo().GetDepth() > 0 && GetNumInfo().GetDepth() <= MAXLEVEL &&
446 		aBulletGrfs[GetNumInfo().GetDepth()-1].Len() &&
447 		aBulletGrfs[GetNumInfo().GetDepth()-1]==sGrfNm )
448 	{
449 		SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
450 
451         if( pTxtNode && ! pTxtNode->IsCountedInList())
452 		{
453             ASSERT( pTxtNode->GetActualListLevel() == GetNumInfo().GetLevel(),
454 					"Numerierungs-Ebene stimmt nicht" );
455 
456             pTxtNode->SetCountedInList( true );
457 
458 			// Rule invalisieren ist noetig, weil zwischem dem einlesen
459 			// des LI und der Grafik ein EndAction gerufen worden sein kann.
460 			if( GetNumInfo().GetNumRule() )
461 				GetNumInfo().GetNumRule()->SetInvalidRule( sal_True );
462 
463 			// Die Vorlage novh mal setzen. Ist noetig, damit der
464 			// Erstzeilen-Einzug stimmt.
465 			SetTxtCollAttrs();
466 
467 			return;
468 		}
469 	}
470 
471 	SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
472 	SvxCSS1PropertyInfo aPropInfo;
473 	if( HasStyleOptions( aStyle, aId, aClass ) )
474 		ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
475 
476 	SfxItemSet aFrmSet( pDoc->GetAttrPool(),
477 						RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
478 	if( !IsNewDoc() )
479 		Reader::ResetFrmFmtAttrs( aFrmSet );
480 
481 	// Umrandung setzen
482 	long nHBorderWidth = 0, nVBorderWidth = 0;
483 	if( nBorder )
484 	{
485 		nHBorderWidth = (long)nBorder;
486 		nVBorderWidth = (long)nBorder;
487 		SvxCSS1Parser::PixelToTwip( nVBorderWidth, nHBorderWidth );
488 
489 		SvxBorderLine aHBorderLine;
490 		SvxBorderLine aVBorderLine;
491 
492 		SvxCSS1Parser::SetBorderWidth( aHBorderLine,
493 									   (sal_uInt16)nHBorderWidth, sal_False );
494 		if( nHBorderWidth == nVBorderWidth )
495 			aVBorderLine.SetOutWidth( aHBorderLine.GetOutWidth() );
496 		else
497 			SvxCSS1Parser::SetBorderWidth( aVBorderLine,
498 										   (sal_uInt16)nVBorderWidth, sal_False );
499 
500 		// die tatsaechlich gesetzter Rahmenbreite benutzen und nicht die
501 		// Wunschbreite!
502 		nHBorderWidth = aHBorderLine.GetOutWidth();
503 		nVBorderWidth = aVBorderLine.GetOutWidth();
504 
505 		if( aAttrTab.pINetFmt )
506 		{
507 			const String& rURL =
508 				((const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem()).GetValue();
509 
510 			pCSS1Parser->SetATagStyles();
511             sal_uInt16 nPoolId =  static_cast< sal_uInt16 >(pDoc->IsVisitedURL( rURL )
512 									? RES_POOLCHR_INET_VISIT
513                                     : RES_POOLCHR_INET_NORMAL);
514 			const SwCharFmt *pCharFmt =	pCSS1Parser->GetCharFmtFromPool( nPoolId );
515 			aHBorderLine.SetColor( pCharFmt->GetColor().GetValue() );
516 			aVBorderLine.SetColor( aHBorderLine.GetColor() );
517 		}
518 		else
519 		{
520 			const SvxColorItem& rColorItem = aAttrTab.pFontColor ?
521 			  (const SvxColorItem &)aAttrTab.pFontColor->GetItem() :
522 			  (const SvxColorItem &)pDoc->GetDefault(RES_CHRATR_COLOR);
523 			aHBorderLine.SetColor( rColorItem.GetValue() );
524 			aVBorderLine.SetColor( aHBorderLine.GetColor() );
525 		}
526 
527 
528         SvxBoxItem aBoxItem( RES_BOX );
529 		aBoxItem.SetLine( &aHBorderLine, BOX_LINE_TOP );
530 		aBoxItem.SetLine( &aHBorderLine, BOX_LINE_BOTTOM );
531 		aBoxItem.SetLine( &aVBorderLine, BOX_LINE_LEFT );
532 		aBoxItem.SetLine( &aVBorderLine, BOX_LINE_RIGHT );
533 		aFrmSet.Put( aBoxItem );
534 	}
535 
536 	// Ausrichtung setzen
537 	SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet );
538 
539 	// Abstaende setzen
540 	SetSpace( Size( nHSpace, nVSpace), aItemSet, aPropInfo, aFrmSet );
541 
542 	// Sonstige CSS1-Attribute Setzen
543 	SetFrmFmtAttrs( aItemSet, aPropInfo, HTML_FF_BOX, aFrmSet );
544 
545 	Size aTwipSz( bPrcWidth ? 0 : nWidth, bPrcHeight ? 0 : nHeight );
546 	if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
547 	{
548 		aTwipSz = Application::GetDefaultDevice()
549 					->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
550 	}
551 
552 	// CSS1-Groesse auf "normale" Groesse umrechnen
553 	switch( aPropInfo.eWidthType )
554 	{
555 		case SVX_CSS1_LTYPE_TWIP:
556 			aTwipSz.Width() = aPropInfo.nWidth;
557 			nWidth = 1;	// != 0
558 			bPrcWidth = sal_False;
559 			break;
560 		case SVX_CSS1_LTYPE_PERCENTAGE:
561 			aTwipSz.Width() = 0;
562 			nWidth = aPropInfo.nWidth;
563 			bPrcWidth = sal_True;
564 			break;
565 		default:
566 			;
567 	}
568 	switch( aPropInfo.eHeightType )
569 	{
570 		case SVX_CSS1_LTYPE_TWIP:
571 			aTwipSz.Height() = aPropInfo.nHeight;
572 			nHeight = 1;	// != 0
573 			bPrcHeight = sal_False;
574 			break;
575 		case SVX_CSS1_LTYPE_PERCENTAGE:
576 			aTwipSz.Height() = 0;
577 			nHeight = aPropInfo.nHeight;
578 			bPrcHeight = sal_True;
579 			break;
580 		default:
581 			;
582 	}
583 
584 	Size aGrfSz( 0, 0 );
585 	sal_Bool bSetTwipSize = sal_True;		// Twip-Size am Node setzen?
586 	sal_Bool bChangeFrmSize = sal_False;	// Frame-Format nachtraeglich anpassen?
587 	sal_Bool bRequestGrfNow = sal_False;
588 	sal_Bool bSetScaleImageMap = sal_False;
589 	sal_uInt8 nPrcWidth = 0, nPrcHeight = 0;
590 
591 	if( !nWidth || !nHeight )
592 	{
593 		// Es fehlt die Breite oder die Hoehe
594 		// Wenn die Grfik in einer Tabelle steht, wird sie gleich
595 		// angefordert, damit sie eventuell schon da ist, bevor die
596 		// Tabelle layoutet wird.
597 		if( pTable!=0 && !nWidth )
598 		{
599 			bRequestGrfNow = sal_True;
600 			IncGrfsThatResizeTable();
601 		}
602 
603 		// Die Groesse des Rahmens wird nachtraeglich gesetzt
604 		bChangeFrmSize = sal_True;
605 		aGrfSz = aTwipSz;
606 		if( !nWidth && !nHeight )
607 		{
608 			aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
609 			aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
610 		}
611 		else if( nWidth )
612 		{
613 			// eine %-Angabe
614 			if( bPrcWidth )
615 			{
616 				nPrcWidth = (sal_uInt8)nWidth;
617 				nPrcHeight = 255;
618 			}
619 			else
620 			{
621 				aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
622 			}
623 		}
624 		else if( nHeight )
625 		{
626 			if( bPrcHeight )
627 			{
628 				nPrcHeight = (sal_uInt8)nHeight;
629 				nPrcWidth = 255;
630 			}
631 			else
632 			{
633 				aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
634 			}
635 		}
636 	}
637 	else
638 	{
639 		// Breite und Hoehe wurden angegeben und brauchen nicht gesetzt
640 		// zu werden
641 		bSetTwipSize = sal_False;
642 
643 		if( bPrcWidth )
644 			nPrcWidth = (sal_uInt8)nWidth;
645 
646 		if( bPrcHeight )
647 			nPrcHeight = (sal_uInt8)nHeight;
648 	}
649 
650 	// Image-Map setzen
651 	aMap.EraseTrailingChars();
652 	if( aMap.Len() )
653 	{
654 		// Da wir nur lokale Image-Maps kennen nehmen wireinfach alles
655 		// hinter dem # als Namen
656 		xub_StrLen nPos = aMap.Search( '#' );
657 		String aName;
658 		if ( STRING_NOTFOUND==nPos )
659 			aName = aMap ;
660 		else
661 			aName = aMap.Copy(nPos+1);
662 
663 		ImageMap *pImgMap = FindImageMap( aName );
664 		if( pImgMap )
665 		{
666 			SwFmtURL aURL; aURL.SetMap( pImgMap );//wird kopieiert
667 
668 			bSetScaleImageMap = !nPrcWidth || !nPrcHeight;
669 			aFrmSet.Put( aURL );
670 		}
671 		else
672 		{
673 			ImageMap aEmptyImgMap( aName );
674 			SwFmtURL aURL; aURL.SetMap( &aEmptyImgMap );//wird kopieiert
675 			aFrmSet.Put( aURL );
676 			nMissingImgMaps++;			// es fehlen noch Image-Maps
677 
678 			// die Grafik muss beim SetTwipSize skaliert werden, wenn
679 			// wir keine Groesse am Node gesetzt haben oder die Groesse
680 			// nicht der Grafikgroesse entsprach.
681 			bSetScaleImageMap = sal_True;
682 		}
683 	}
684 
685 	// min. Werte einhalten !!
686 	if( nPrcWidth )
687 	{
688 		ASSERT( !aTwipSz.Width(),
689 				"Wieso ist da trotz %-Angabe eine Breite gesetzt?" );
690 		aTwipSz.Width() = aGrfSz.Width() ? aGrfSz.Width()
691 										 : HTML_DFLT_IMG_WIDTH;
692 	}
693 	else
694 	{
695 		aTwipSz.Width() += 2*nVBorderWidth;
696 		if( aTwipSz.Width() < MINFLY )
697 			aTwipSz.Width() = MINFLY;
698 	}
699 	if( nPrcHeight )
700 	{
701 		ASSERT( !aTwipSz.Height(),
702 				"Wieso ist da trotz %-Angabe eine Hoehe gesetzt?" );
703 		aTwipSz.Height() = aGrfSz.Height() ? aGrfSz.Height()
704 										   : HTML_DFLT_IMG_HEIGHT;
705 	}
706 	else
707 	{
708 		aTwipSz.Height() += 2*nHBorderWidth;
709 		if( aTwipSz.Height() < MINFLY )
710 			aTwipSz.Height() = MINFLY;
711 	}
712 
713 	SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() );
714 	aFrmSize.SetWidthPercent( nPrcWidth );
715 	aFrmSize.SetHeightPercent( nPrcHeight );
716 	aFrmSet.Put( aFrmSize );
717 
718 	Graphic aEmptyGrf;
719 	aEmptyGrf.SetDefaultType();
720 	SwFrmFmt *pFlyFmt = pDoc->Insert( *pPam, sGrfNm, aEmptyStr, &aEmptyGrf,
721 									  &aFrmSet, NULL, NULL );
722 	SwGrfNode *pGrfNd = pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
723 								  ->GetIndex()+1 ]->GetGrfNode();
724 
725 	if( sHTMLGrfName.Len() )
726 	{
727 		pFlyFmt->SetName( sHTMLGrfName );
728 
729 		// ggfs. eine Grafik anspringen
730 		if( JUMPTO_GRAPHIC == eJumpTo && sHTMLGrfName == sJmpMark )
731 		{
732 			bChkJumpMark = sal_True;
733 			eJumpTo = JUMPTO_NONE;
734 		}
735 	}
736 
737 	if( sAltNm.Len() )
738         pGrfNd->SetTitle( sAltNm );
739 
740 	if( bSetTwipSize )
741 		pGrfNd->SetTwipSize( aGrfSz );
742 
743 	pGrfNd->SetChgTwipSize( bChangeFrmSize, bChangeFrmSize );
744 
745 	if( bSetScaleImageMap )
746 		pGrfNd->SetScaleImageMap( sal_True );
747 
748 	if( aAttrTab.pINetFmt )
749 	{
750 		const SwFmtINetFmt &rINetFmt =
751 			(const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem();
752 
753 		SwFmtURL aURL( pFlyFmt->GetURL() );
754 
755 		aURL.SetURL( rINetFmt.GetValue(), bIsMap );
756 		aURL.SetTargetFrameName( rINetFmt.GetTargetFrame() );
757 		aURL.SetName( rINetFmt.GetName() );
758         pFlyFmt->SetFmtAttr( aURL );
759 
760 		{
761 			const SvxMacro *pMacro;
762 			static sal_uInt16 __READONLY_DATA aEvents[] = {
763 				SFX_EVENT_MOUSEOVER_OBJECT,
764 				SFX_EVENT_MOUSECLICK_OBJECT,
765 				SFX_EVENT_MOUSEOUT_OBJECT,
766 				0 };
767 
768 			for( sal_uInt16 n = 0; aEvents[ n ]; ++n )
769 				if( 0 != ( pMacro = rINetFmt.GetMacro( aEvents[ n ] ) ))
770 					aMacroItem.SetMacro( aEvents[ n ], *pMacro );
771 		}
772 
773         if ((FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()) &&
774 			aAttrTab.pINetFmt->GetSttPara() ==
775 						pPam->GetPoint()->nNode &&
776 			aAttrTab.pINetFmt->GetSttCnt() ==
777 						pPam->GetPoint()->nContent.GetIndex() - 1 )
778 		{
779 			// das Attribut wurde unmitellbar vor einer zeichengeb.
780 			// Grafik eingefuegt, also verschieben wir es
781 			aAttrTab.pINetFmt->SetStart( *pPam->GetPoint() );
782 
783 			// Wenn das Attribut auch ein Sprungziel ist, fuegen
784 			// wir noch eine Bookmark vor der Grafik ein, weil das
785 			// SwFmtURL kein Sprungziel ist.
786 			if( rINetFmt.GetName().Len() )
787 			{
788 				pPam->Move( fnMoveBackward );
789 				InsertBookmark( rINetFmt.GetName() );
790 				pPam->Move( fnMoveForward );
791 			}
792 		}
793 
794 	}
795 
796 	if( aMacroItem.GetMacroTable().Count() )
797         pFlyFmt->SetFmtAttr( aMacroItem );
798 
799 	// Wenn die Grafik gleich angeforder wird, muss dies geschehen,
800 	// nachdem das Format vollstaendig aufgebaut ist, weil es evtl.
801 	// gleich (synchron) angepasst wird (war bug #40983#)
802 	if( bRequestGrfNow )
803 	{
804 		pGrfNd->SwapIn();
805 	}
806 
807 	// Ggf. Frames anlegen und Auto-gebundenen Rahmen registrieren
808 	RegisterFlyFrm( pFlyFmt );
809 
810 	if( aId.Len() )
811 		InsertBookmark( aId );
812 }
813 
814 /*  */
815 
InsertBodyOptions()816 void SwHTMLParser::InsertBodyOptions()
817 {
818 	pDoc->SetTxtFmtColl( *pPam,
819 						 pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
820 
821 	String aBackGround, aId, aStyle, aLang, aDir;
822 	Color aBGColor, aTextColor, aLinkColor, aVLinkColor;
823 	sal_Bool bBGColor=sal_False, bTextColor=sal_False;
824 	sal_Bool bLinkColor=sal_False, bVLinkColor=sal_False;
825 
826 	ScriptType eDfltScriptType;
827 	String sDfltScriptType;
828 	GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
829 
830 	const HTMLOptions *pHTMLOptions = GetOptions();
831 	for( sal_uInt16 i = pHTMLOptions->Count(); i; )
832 	{
833 		const HTMLOption *pOption = (*pHTMLOptions)[--i];
834 		ScriptType eScriptType2 = eDfltScriptType;
835 		rtl::OUString aEvent;
836 		sal_Bool bSetEvent = sal_False;
837 
838 		switch( pOption->GetToken() )
839 		{
840 			case HTML_O_ID:
841 				aId = pOption->GetString();
842 				break;
843 			case HTML_O_BACKGROUND:
844 				aBackGround = pOption->GetString();
845 				break;
846 			case HTML_O_BGCOLOR:
847 				pOption->GetColor( aBGColor );
848 				bBGColor = sal_True;
849 				break;
850 			case HTML_O_TEXT:
851 				pOption->GetColor( aTextColor );
852 				bTextColor = sal_True;
853 				break;
854 			case HTML_O_LINK:
855 				pOption->GetColor( aLinkColor );
856 				bLinkColor = sal_True;
857 				break;
858 			case HTML_O_VLINK:
859 				pOption->GetColor( aVLinkColor );
860 				bVLinkColor = sal_True;
861 				break;
862 
863 			case HTML_O_SDONLOAD:
864 				eScriptType2 = STARBASIC;
865 			case HTML_O_ONLOAD:
866 				aEvent = GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC );
867 				bSetEvent = sal_True;
868 				break;
869 
870 			case HTML_O_SDONUNLOAD:
871 				eScriptType2 = STARBASIC;
872 			case HTML_O_ONUNLOAD:
873 				aEvent = GlobalEventConfig::GetEventName( STR_EVENT_PREPARECLOSEDOC );
874 				bSetEvent = sal_True;
875 				break;
876 
877 			case HTML_O_SDONFOCUS:
878 				eScriptType2 = STARBASIC;
879 			case HTML_O_ONFOCUS:
880 				aEvent = GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC );
881 				bSetEvent = sal_True;
882 				break;
883 
884 			case HTML_O_SDONBLUR:
885 				eScriptType2 = STARBASIC;
886 			case HTML_O_ONBLUR:
887 				aEvent = GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC );
888 				bSetEvent = sal_True;
889 				break;
890 
891 			case HTML_O_ONERROR:
892 //				if( bAnyStarBasic )
893 //					InsertBasicDocEvent( SFX_EVENT_ACTIVATEDOC,
894 //										 pOption->GetString() );
895 				break;
896 
897 			case HTML_O_STYLE:
898 				aStyle = pOption->GetString();
899 				bTextColor = sal_True;
900 				break;
901 			case HTML_O_LANG:
902 				aLang = pOption->GetString();
903 				break;
904 			case HTML_O_DIR:
905 				aDir = pOption->GetString();
906 				break;
907 		}
908 
909 		if( bSetEvent )
910 		{
911 			const String& rEvent = pOption->GetString();
912 			if( rEvent.Len() )
913 				InsertBasicDocEvent( aEvent, rEvent, eScriptType2,
914 									 sDfltScriptType );
915 		}
916 	}
917 
918 	if( bTextColor && !pCSS1Parser->IsBodyTextSet() )
919 	{
920 		// Die Textfarbe wird an der Standard-Vorlage gesetzt
921 		pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
922             ->SetFmtAttr( SvxColorItem(aTextColor, RES_CHRATR_COLOR) );
923 		pCSS1Parser->SetBodyTextSet();
924 	}
925 
926 
927 	// Die Item fuer die Seitenvorlage vorbereiten (Hintergrund, Umrandung)
928 	// Beim BrushItem muessen schon gesetzte werte erhalten bleiben!
929 	SvxBrushItem aBrushItem( pCSS1Parser->GetPageDescBackground() );
930 	sal_Bool bSetBrush = sal_False;
931 
932 	if( bBGColor && !pCSS1Parser->IsBodyBGColorSet() )
933 	{
934 		// Hintergrundfarbe aus "BGCOLOR"
935 		String aLink;
936 		if( aBrushItem.GetGraphicLink() )
937 			aLink = *aBrushItem.GetGraphicLink();
938 		SvxGraphicPosition ePos = aBrushItem.GetGraphicPos();
939 
940 		aBrushItem.SetColor( aBGColor );
941 
942 		if( aLink.Len() )
943 		{
944 			aBrushItem.SetGraphicLink( aLink );
945 			aBrushItem.SetGraphicPos( ePos );
946 		}
947 		bSetBrush = sal_True;
948 		pCSS1Parser->SetBodyBGColorSet();
949 	}
950 
951 	if( aBackGround.Len() && !pCSS1Parser->IsBodyBackgroundSet() )
952 	{
953 		// Hintergrundgrafik aus "BACKGROUND"
954         aBrushItem.SetGraphicLink( INetURLObject::GetAbsURL( sBaseURL, aBackGround ) );
955 		aBrushItem.SetGraphicPos( GPOS_TILED );
956 		bSetBrush = sal_True;
957 		pCSS1Parser->SetBodyBackgroundSet();
958 	}
959 
960 	if( aStyle.Len() || aDir.Len() )
961 	{
962 		SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
963 		SvxCSS1PropertyInfo aPropInfo;
964 		String aDummy;
965 		ParseStyleOptions( aStyle, aDummy, aDummy, aItemSet, aPropInfo, 0, &aDir );
966 
967 		// Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
968 		// und zwar die, die nicht vererbit werden
969 		pCSS1Parser->SetPageDescAttrs( bSetBrush ? &aBrushItem : 0,
970 									   &aItemSet );
971 
972 		const SfxPoolItem *pItem;
973 		static sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,
974 									   RES_CHRATR_CJK_FONTSIZE,
975 									   RES_CHRATR_CTL_FONTSIZE };
976 		for( sal_uInt16 i=0; i<3; i++ )
977 		{
978 			if( SFX_ITEM_SET == aItemSet.GetItemState( aWhichIds[i], sal_False,
979 													   &pItem ) &&
980 				static_cast <const SvxFontHeightItem * >(pItem)->GetProp() != 100)
981 			{
982 				sal_uInt32 nHeight =
983 					( aFontHeights[2] *
984 					 static_cast <const SvxFontHeightItem * >(pItem)->GetProp() ) / 100;
985 				SvxFontHeightItem aNewItem( nHeight, 100, aWhichIds[i] );
986 				aItemSet.Put( aNewItem );
987 			}
988 		}
989 
990 		// alle noch uebrigen Optionen koennen an der Standard-Vorlage
991 		// gesetzt werden und gelten dann automatisch als defaults
992 		pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
993             ->SetFmtAttr( aItemSet );
994 	}
995 	else if( bSetBrush )
996 	{
997 		pCSS1Parser->SetPageDescAttrs( &aBrushItem );
998 	}
999 
1000 	if( bLinkColor && !pCSS1Parser->IsBodyLinkSet() )
1001 	{
1002 		SwCharFmt *pCharFmt =
1003 			pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_NORMAL);
1004         pCharFmt->SetFmtAttr( SvxColorItem(aLinkColor, RES_CHRATR_COLOR) );
1005 		pCSS1Parser->SetBodyLinkSet();
1006 	}
1007 	if( bVLinkColor && !pCSS1Parser->IsBodyVLinkSet() )
1008 	{
1009 		SwCharFmt *pCharFmt =
1010 			pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_VISIT);
1011         pCharFmt->SetFmtAttr( SvxColorItem(aVLinkColor, RES_CHRATR_COLOR) );
1012 		pCSS1Parser->SetBodyVLinkSet();
1013 	}
1014 	if( aLang.Len() )
1015 	{
1016 		LanguageType eLang = MsLangId::convertIsoStringToLanguage( aLang );
1017 		sal_uInt16 nWhich = 0;
1018 		if( LANGUAGE_DONTKNOW != eLang )
1019 		{
1020 			switch( SvtLanguageOptions::GetScriptTypeOfLanguage( eLang ) )
1021 			{
1022 			case SCRIPTTYPE_LATIN:
1023 				nWhich = RES_CHRATR_LANGUAGE;
1024 				break;
1025 			case SCRIPTTYPE_ASIAN:
1026 				nWhich = RES_CHRATR_CJK_LANGUAGE;
1027 				break;
1028 			case SCRIPTTYPE_COMPLEX:
1029 				nWhich = RES_CHRATR_CTL_LANGUAGE;
1030 				break;
1031 			}
1032 			if( nWhich )
1033 			{
1034                 SvxLanguageItem aLanguage( eLang, nWhich );
1035 				aLanguage.SetWhich( nWhich );
1036 				pDoc->SetDefault( aLanguage );
1037 			}
1038 		}
1039 	}
1040 
1041 	if( aId.Len() )
1042 		InsertBookmark( aId );
1043 }
1044 
1045 /*  */
1046 
NewAnchor()1047 void SwHTMLParser::NewAnchor()
1048 {
1049 	// den voherigen Link beenden, falls es einen gab
1050 	_HTMLAttrContext *pOldCntxt = PopContext( HTML_ANCHOR_ON );
1051 	if( pOldCntxt )
1052 	{
1053 		// und ggf. die Attribute beenden
1054 		EndContext( pOldCntxt );
1055 		delete pOldCntxt;
1056 	}
1057 
1058 	SvxMacroTableDtor aMacroTbl;
1059 	String sHRef, aName, sTarget;
1060 	String aId, aStyle, aClass, aLang, aDir;
1061 	sal_Bool bHasHRef = sal_False, bFixed = sal_False;
1062 
1063 	ScriptType eDfltScriptType;
1064 	String sDfltScriptType;
1065 	GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
1066 
1067 	const HTMLOptions *pHTMLOptions = GetOptions();
1068 	for( sal_uInt16 i = pHTMLOptions->Count(); i; )
1069 	{
1070 		sal_uInt16 nEvent = 0;
1071 		ScriptType eScriptType2 = eDfltScriptType;
1072 		const HTMLOption *pOption = (*pHTMLOptions)[--i];
1073 		switch( pOption->GetToken() )
1074 		{
1075 			case HTML_O_NAME:
1076 				aName = pOption->GetString();
1077 				break;
1078 
1079 			case HTML_O_HREF:
1080 				sHRef = pOption->GetString();
1081 				bHasHRef = sal_True;
1082 				break;
1083 			case HTML_O_TARGET:
1084 				sTarget = pOption->GetString();
1085 				break;
1086 
1087 			case HTML_O_STYLE:
1088 				aStyle = pOption->GetString();
1089 				break;
1090 			case HTML_O_ID:
1091 				aId = pOption->GetString();
1092 				break;
1093 			case HTML_O_CLASS:
1094 				aClass = pOption->GetString();
1095 				break;
1096 			case HTML_O_SDFIXED:
1097 				bFixed = sal_True;
1098 				break;
1099 			case HTML_O_LANG:
1100 				aLang = pOption->GetString();
1101 				break;
1102 			case HTML_O_DIR:
1103 				aDir = pOption->GetString();
1104 				break;
1105 
1106 			case HTML_O_SDONCLICK:
1107 				eScriptType2 = STARBASIC;
1108 			case HTML_O_ONCLICK:
1109 				nEvent = SFX_EVENT_MOUSECLICK_OBJECT;
1110 				goto ANCHOR_SETEVENT;
1111 
1112 			case HTML_O_SDONMOUSEOVER:
1113 				eScriptType2 = STARBASIC;
1114 			case HTML_O_ONMOUSEOVER:
1115 				nEvent = SFX_EVENT_MOUSEOVER_OBJECT;
1116 				goto ANCHOR_SETEVENT;
1117 
1118 			case HTML_O_SDONMOUSEOUT:
1119 				eScriptType2 = STARBASIC;
1120 			case HTML_O_ONMOUSEOUT:
1121 				nEvent = SFX_EVENT_MOUSEOUT_OBJECT;
1122 				goto ANCHOR_SETEVENT;
1123 ANCHOR_SETEVENT:
1124 				{
1125 					String sTmp( pOption->GetString() );
1126 					if( sTmp.Len() )
1127 					{
1128 						sTmp.ConvertLineEnd();
1129 						String sScriptType;
1130 						if( EXTENDED_STYPE == eScriptType2 )
1131 							sScriptType = sDfltScriptType;
1132 						aMacroTbl.Insert( nEvent,
1133 							new SvxMacro( sTmp, sScriptType, eScriptType2 ));
1134 					}
1135 				}
1136 				break;
1137 
1138 		}
1139 	}
1140 
1141 	// Sprungziele, die unseren ipmliziten Zielen entsprechen, schmeissen
1142 	// wir hier ganz rigoros raus.
1143 	if( aName.Len() )
1144 	{
1145 		String sDecoded( INetURLObject::decode( aName, INET_HEX_ESCAPE,
1146 						   				INetURLObject::DECODE_UNAMBIGUOUS,
1147 										RTL_TEXTENCODING_UTF8 ));
1148 		xub_StrLen nPos = sDecoded.SearchBackward( cMarkSeperator );
1149 		if( STRING_NOTFOUND != nPos )
1150 		{
1151 			String sCmp( sDecoded.Copy( nPos+1 ) );
1152 			sCmp.EraseAllChars();
1153 			if( sCmp.Len() )
1154 			{
1155 				sCmp.ToLowerAscii();
1156 				if( sCmp.EqualsAscii( pMarkToRegion ) ||
1157 					sCmp.EqualsAscii( pMarkToFrame ) ||
1158 					sCmp.EqualsAscii( pMarkToGraphic ) ||
1159 					sCmp.EqualsAscii( pMarkToOLE ) ||
1160 					sCmp.EqualsAscii( pMarkToTable ) ||
1161 					sCmp.EqualsAscii( pMarkToOutline ) ||
1162 					sCmp.EqualsAscii( pMarkToText ) )
1163 				{
1164 					aName.Erase();
1165 				}
1166 			}
1167 		}
1168 	}
1169 
1170 	// einen neuen Kontext anlegen
1171 	_HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_ANCHOR_ON );
1172 
1173 	sal_Bool bEnAnchor = sal_False, bFtnAnchor = sal_False, bFtnEnSymbol = sal_False;
1174 	String aFtnName;
1175 	String aStrippedClass( aClass );
1176 	SwCSS1Parser::GetScriptFromClass( aStrippedClass, sal_False );
1177 	if( aStrippedClass.Len() >=9  && bHasHRef && sHRef.Len() > 1 &&
1178 		('s' == aStrippedClass.GetChar(0) || 'S' == aStrippedClass.GetChar(0)) &&
1179 		('d' == aStrippedClass.GetChar(1) || 'D' == aStrippedClass.GetChar(1)) )
1180 	{
1181 		if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc ) )
1182 			bEnAnchor = sal_True;
1183 		else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc ) )
1184 			bFtnAnchor = sal_True;
1185 		else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym ) ||
1186 				 aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym ) )
1187 			bFtnEnSymbol = sal_True;
1188 		if( bEnAnchor || bFtnAnchor || bFtnEnSymbol )
1189 		{
1190 			aFtnName = sHRef.Copy( 1 );
1191 			aClass = aStrippedClass = aName = aEmptyStr;
1192 			bHasHRef = sal_False;
1193 		}
1194 	}
1195 
1196 	// Styles parsen
1197 	if( HasStyleOptions( aStyle, aId, aStrippedClass, &aLang, &aDir ) )
1198 	{
1199 		SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
1200 		SvxCSS1PropertyInfo aPropInfo;
1201 
1202 		if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
1203 		{
1204 			DoPositioning( aItemSet, aPropInfo, pCntxt );
1205 			InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True );
1206 		}
1207 	}
1208 
1209 	if( bHasHRef )
1210 	{
1211 		if( sHRef.Len() )
1212 		{
1213             sHRef = URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), sHRef, Link(), false );
1214 		}
1215 		else
1216 		{
1217 			// Bei leerer URL das Directory nehmen
1218 			INetURLObject aURLObj( aPathToFile );
1219 			sHRef = aURLObj.GetPartBeforeLastName();
1220 		}
1221 
1222 		pCSS1Parser->SetATagStyles();
1223 		SwFmtINetFmt aINetFmt( sHRef, sTarget );
1224 		aINetFmt.SetName( aName );
1225 
1226 		if( aMacroTbl.Count() )
1227 			aINetFmt.SetMacroTbl( &aMacroTbl );
1228 
1229 		// das Default-Attribut setzen
1230 		InsertAttr( &aAttrTab.pINetFmt, aINetFmt, pCntxt );
1231 	}
1232 	else if( aName.Len() )
1233 	{
1234 		InsertBookmark( aName );
1235 	}
1236 
1237 	if( bEnAnchor || bFtnAnchor )
1238 	{
1239 		InsertFootEndNote( aFtnName, bEnAnchor, bFixed );
1240 		bInFootEndNoteAnchor = bCallNextToken = sal_True;
1241 	}
1242 	else if( bFtnEnSymbol )
1243 	{
1244 		bInFootEndNoteSymbol = bCallNextToken = sal_True;
1245 	}
1246 
1247 	// den Kontext merken
1248 	PushContext( pCntxt );
1249 }
1250 
EndAnchor()1251 void SwHTMLParser::EndAnchor()
1252 {
1253 	if( bInFootEndNoteAnchor )
1254 	{
1255 		FinishFootEndNote();
1256 		bInFootEndNoteAnchor = sal_False;
1257 	}
1258 	else if( bInFootEndNoteSymbol )
1259 	{
1260 		bInFootEndNoteSymbol = sal_False;
1261 	}
1262 
1263 	EndTag( HTML_ANCHOR_OFF );
1264 }
1265 
1266 /*  */
1267 
InsertBookmark(const String & rName)1268 void SwHTMLParser::InsertBookmark( const String& rName )
1269 {
1270 	_HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
1271 			SfxStringItem( RES_FLTR_BOOKMARK, rName ));
1272 	aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
1273 }
1274 
HasCurrentParaBookmarks(sal_Bool bIgnoreStack) const1275 sal_Bool SwHTMLParser::HasCurrentParaBookmarks( sal_Bool bIgnoreStack ) const
1276 {
1277     sal_Bool bHasMarks = sal_False;
1278     sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
1279 
1280     // first step: are there still bookmark in the attribute-stack?
1281     // bookmarks are added to the end of the stack - thus we only have
1282     // to check the last bookmark
1283     if( !bIgnoreStack )
1284     {
1285         _HTMLAttr* pAttr;
1286         for( sal_uInt16 i = aSetAttrTab.Count(); i; )
1287         {
1288             pAttr = aSetAttrTab[ --i ];
1289             if( RES_FLTR_BOOKMARK == pAttr->pItem->Which() )
1290             {
1291                 if( pAttr->GetSttParaIdx() == nNodeIdx )
1292                     bHasMarks = sal_True;
1293                 break;
1294             }
1295         }
1296     }
1297 
1298     if( !bHasMarks )
1299     {
1300         // second step: when we didnt find a bookmark, check if there is one set already
1301         IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1302         for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
1303             ppMark != pMarkAccess->getAllMarksEnd();
1304             ppMark++)
1305         {
1306             const ::sw::mark::IMark* pBookmark = ppMark->get();
1307 
1308             const sal_uLong nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex();
1309             if( nBookNdIdx==nNodeIdx )
1310             {
1311                 bHasMarks = sal_True;
1312                 break;
1313             }
1314             else if( nBookNdIdx > nNodeIdx )
1315                 break;
1316         }
1317     }
1318 
1319     return bHasMarks;
1320 }
1321 
1322 /*  */
1323 
StripTrailingPara()1324 void SwHTMLParser::StripTrailingPara()
1325 {
1326     sal_Bool bSetSmallFont = sal_False;
1327 
1328     SwCntntNode* pCNd = pPam->GetCntntNode();
1329     if( !pPam->GetPoint()->nContent.GetIndex() )
1330     {
1331         if( pCNd && pCNd->StartOfSectionIndex()+2 <
1332             pCNd->EndOfSectionIndex() )
1333         {
1334             sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
1335 
1336             const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
1337 
1338             for( sal_uInt16 i=0; i<rFrmFmtTbl.Count(); i++ )
1339             {
1340                 SwFrmFmt const*const pFmt = rFrmFmtTbl[i];
1341                 SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
1342                 SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
1343                 if (pAPos &&
1344                     ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
1345                      (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
1346                     pAPos->nNode == nNodeIdx )
1347 
1348                     return;     // den Knoten duerfen wir nicht loeschen
1349             }
1350 
1351             SetAttr( sal_False );   // die noch offenen Attribute muessen
1352                                 // beendet werden, bevor der Node
1353                                 // geloescht wird, weil sonst der
1354                                 // End-Index in die Botanik zeigt
1355 
1356             if( pCNd->Len() && pCNd->IsTxtNode() )
1357             {
1358                 // es wurden Felder in den Node eingefuegt, die muessen
1359                 // wir jetzt verschieben
1360                 SwTxtNode *pPrvNd = pDoc->GetNodes()[nNodeIdx-1]->GetTxtNode();
1361                 if( pPrvNd )
1362                 {
1363                     SwIndex aSrc( pCNd, 0 );
1364                     pCNd->GetTxtNode()->CutText( pPrvNd, aSrc, pCNd->Len() );
1365                 }
1366             }
1367 
1368             // jetz muessen wir noch eventuell vorhandene Bookmarks verschieben
1369             IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1370             for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
1371                 ppMark != pMarkAccess->getAllMarksEnd();
1372                 ppMark++)
1373             {
1374                 ::sw::mark::IMark* pMark = ppMark->get();
1375 
1376                 sal_uLong nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex();
1377                 if(nBookNdIdx==nNodeIdx)
1378                 {
1379                     SwNodeIndex nNewNdIdx(pPam->GetPoint()->nNode);
1380                     SwCntntNode* pNd = pDoc->GetNodes().GoPrevious(&nNewNdIdx);
1381                     if(!pNd)
1382                     {
1383                         ASSERT(!this, "Hoppla, wo ist mein Vorgaenger-Node");
1384                         return;
1385                     }
1386                     {
1387                         SwPosition aNewPos(*pNd);
1388                         aNewPos.nContent.Assign(pNd, pNd->Len());
1389                         const SwPaM aPaM(aNewPos);
1390                         pMarkAccess->repositionMark(ppMark->get(), aPaM);
1391                     }
1392                 }
1393                 else if( nBookNdIdx > nNodeIdx )
1394                     break;
1395             }
1396 
1397             pPam->GetPoint()->nContent.Assign( 0, 0 );
1398             pPam->SetMark();
1399             pPam->DeleteMark();
1400             pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
1401             pPam->Move( fnMoveBackward, fnGoNode );
1402         }
1403         else if( pCNd && pCNd->IsTxtNode() && pTable )
1404         {
1405             // In leeren Zellen stellen wir einen kleinen Font ein, damit die
1406             // Zelle nicht hoeher wird als die Grafik bzw. so niedrig wie
1407             // moeglich bleibt.
1408             bSetSmallFont = sal_True;
1409         }
1410     }
1411     else if( pCNd && pCNd->IsTxtNode() && pTable &&
1412              pCNd->StartOfSectionIndex()+2 ==
1413              pCNd->EndOfSectionIndex() )
1414     {
1415         // Wenn die Zelle nur zeichengebundene Grafiken/Rahmen enthaelt
1416         // stellen wir ebenfalls einen kleinen Font ein.
1417         bSetSmallFont = sal_True;
1418         SwTxtNode* pTxtNd = pCNd->GetTxtNode();
1419 
1420         xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
1421         while( bSetSmallFont && nPos>0 )
1422         {
1423             --nPos;
1424             bSetSmallFont =
1425                 (CH_TXTATR_BREAKWORD == pTxtNd->GetTxt().GetChar( nPos )) &&
1426                 (0 != pTxtNd->GetTxtAttrForCharAt( nPos, RES_TXTATR_FLYCNT ));
1427         }
1428     }
1429 
1430     if( bSetSmallFont )
1431     {
1432         SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
1433         pCNd->SetAttr( aFontHeight );
1434         aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
1435         pCNd->SetAttr( aFontHeight );
1436         aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
1437         pCNd->SetAttr( aFontHeight );
1438     }
1439 }
1440 
1441