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
28 #include <com/sun/star/frame/XModel.hpp>
29 #include <com/sun/star/form/FormSubmitEncoding.hpp>
30 #include <com/sun/star/form/FormSubmitMethod.hpp>
31 #include <com/sun/star/form/FormButtonType.hpp>
32 #include <com/sun/star/script/XEventAttacher.hpp>
33 #include <com/sun/star/script/XEventAttacherManager.hpp>
34 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
35 #include <com/sun/star/form/XFormsSupplier.hpp>
36 #include <com/sun/star/form/XForm.hpp>
37 #include <com/sun/star/form/FormComponentType.hpp>
38 #include <com/sun/star/awt/XTextLayoutConstrains.hpp>
39 #include <hintids.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/wrkwin.hxx>
42 #include <svl/macitem.hxx>
43 #include <tools/urlobj.hxx>
44 #include <svtools/htmlout.hxx>
45 #include <svtools/htmltokn.h>
46 #include <svtools/htmlkywd.hxx>
47 #include <svl/urihelper.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <svx/svdouno.hxx>
50 #include <svx/fmglob.hxx>
51 #include <editeng/brshitem.hxx>
52 #include <editeng/colritem.hxx>
53 #include <editeng/fhgtitem.hxx>
54 #include <editeng/fontitem.hxx>
55 #include <editeng/wghtitem.hxx>
56 #include <editeng/postitem.hxx>
57 #include <editeng/udlnitem.hxx>
58 #include <editeng/crsditem.hxx>
59 #include <docsh.hxx>
60 #include <fmtanchr.hxx>
61 #include <docary.hxx>
62 #include <viewsh.hxx>
63 #include "pam.hxx"
64 #include "doc.hxx"
65 #include "ndtxt.hxx"
66 #include "flypos.hxx"
67 #include "wrthtml.hxx"
68 #include "htmlfly.hxx"
69 #include "htmlform.hxx"
70 #include "frmfmt.hxx"
71
72 using namespace ::com::sun::star;
73 using ::rtl::OUString;
74 /* */
75
76 const sal_uInt32 HTML_FRMOPTS_CONTROL =
77 0;
78 const sal_uInt32 HTML_FRMOPTS_CONTROL_CSS1 =
79 HTML_FRMOPT_S_ALIGN |
80 HTML_FRMOPT_S_SIZE |
81 HTML_FRMOPT_S_SPACE |
82 HTML_FRMOPT_BRCLEAR;
83 const sal_uInt32 HTML_FRMOPTS_IMG_CONTROL =
84 HTML_FRMOPT_ALIGN |
85 HTML_FRMOPT_BRCLEAR;
86 const sal_uInt32 HTML_FRMOPTS_IMG_CONTROL_CSS1 =
87 HTML_FRMOPT_S_ALIGN |
88 HTML_FRMOPT_S_SPACE;
89
90
91 /* */
92
93 struct HTMLControl
94 {
95 // die Form, zu der das Control gehoert
96 uno::Reference< container::XIndexContainer > xFormComps;
97 sal_uLong nNdIdx; // der Node, in dem es verankert ist
98 xub_StrLen nCount; // wie viele Controls sind in dem Node
99
100 HTMLControl( const uno::Reference< container::XIndexContainer > & rForm,
101 sal_uInt32 nIdx );
102 ~HTMLControl();
103
104 // operatoren fuer das Sort-Array
operator ==HTMLControl105 sal_Bool operator==( const HTMLControl& rCtrl )
106 {
107 return nNdIdx == rCtrl.nNdIdx;
108 }
operator <HTMLControl109 sal_Bool operator<( const HTMLControl& rCtrl )
110 {
111 return nNdIdx < rCtrl.nNdIdx;
112 }
113 };
114
SV_IMPL_OP_PTRARR_SORT(HTMLControls,HTMLControl *)115 SV_IMPL_OP_PTRARR_SORT( HTMLControls, HTMLControl* )
116
117 /* */
118
119 void lcl_html_outEvents( SvStream& rStrm,
120 const uno::Reference< form::XFormComponent > rFormComp,
121 sal_Bool bCfgStarBasic,
122 rtl_TextEncoding eDestEnc,
123 String *pNonConvertableChars )
124 {
125 uno::Reference< container::XChild > xChild( rFormComp, uno::UNO_QUERY );
126 uno::Reference< uno::XInterface > xParentIfc = xChild->getParent();
127 ASSERT( xParentIfc.is(), "lcl_html_outEvents: no parent interface" );
128 if( !xParentIfc.is() )
129 return;
130 uno::Reference< container::XIndexAccess > xIndexAcc( xParentIfc, uno::UNO_QUERY );
131 uno::Reference< script::XEventAttacherManager > xEventManager( xParentIfc,
132 uno::UNO_QUERY );
133 if( !xIndexAcc.is() || !xEventManager.is() )
134 return;
135
136 // Und die Position des ControlModel darin suchen
137 sal_Int32 nCount = xIndexAcc->getCount(), nPos;
138 for( nPos = 0 ; nPos < nCount; nPos++ )
139 {
140 uno::Any aTmp = xIndexAcc->getByIndex(nPos);
141 ASSERT( aTmp.getValueType() ==
142 ::getCppuType( (uno::Reference<form::XFormComponent>*)0 ) ||
143 aTmp.getValueType() ==
144 ::getCppuType( (uno::Reference<form::XForm>*)0 ),
145 "lcl_html_outEvents: falsche Reflection" );
146 if( aTmp.getValueType() ==
147 ::getCppuType( (uno::Reference< form::XFormComponent >*)0) )
148
149 {
150 if( rFormComp ==
151 *(uno::Reference< form::XFormComponent > *)aTmp.getValue() )
152 break;
153 }
154 else if( aTmp.getValueType() ==
155 ::getCppuType( (uno::Reference< form::XForm>*)0) )
156 {
157 uno::Reference< form::XFormComponent > xFC(
158 *(uno::Reference< form::XForm > *)aTmp.getValue(), uno::UNO_QUERY );
159 if( rFormComp == xFC )
160 break;
161 }
162 }
163
164 if( nPos == nCount )
165 return;
166
167 uno::Sequence< script::ScriptEventDescriptor > aDescs =
168 xEventManager->getScriptEvents( nPos );
169 nCount = aDescs.getLength();
170 if( !nCount )
171 return;
172
173 const script::ScriptEventDescriptor *pDescs = aDescs.getConstArray();
174 for( sal_Int32 i = 0; i < nCount; i++ )
175 {
176 ScriptType eScriptType = EXTENDED_STYPE;
177 String aScriptType( pDescs[i].ScriptType );
178 if( aScriptType.EqualsIgnoreCaseAscii(SVX_MACRO_LANGUAGE_JAVASCRIPT) )
179 eScriptType = JAVASCRIPT;
180 else if( aScriptType.EqualsIgnoreCaseAscii(SVX_MACRO_LANGUAGE_STARBASIC ) )
181 eScriptType = STARBASIC;
182 if( JAVASCRIPT != eScriptType && !bCfgStarBasic )
183 continue;
184
185 String sListener( pDescs[i].ListenerType );
186 xub_StrLen nTok = sListener.GetTokenCount( '.' );
187 if( nTok )
188 sListener = sListener.GetToken( nTok-1, '.' );
189 String sMethod( pDescs[i].EventMethod );
190
191 const sal_Char *pOpt = 0;
192 for( sal_uInt16 j=0; aEventListenerTable[j]; j++ )
193 {
194 if( sListener.EqualsAscii( aEventListenerTable[j] ) &&
195 sMethod.EqualsAscii( aEventMethodTable[j] ) )
196 {
197 pOpt = (STARBASIC==eScriptType ? aEventSDOptionTable
198 : aEventOptionTable)[j];
199 break;
200 }
201 }
202
203 ByteString sOut( ' ' );
204 if( pOpt && (EXTENDED_STYPE != eScriptType ||
205 !pDescs[i].AddListenerParam.getLength()) )
206 sOut += pOpt;
207 else
208 (((sOut += OOO_STRING_SVTOOLS_HTML_O_sdevent)
209 += ByteString( sListener, RTL_TEXTENCODING_ASCII_US)) += '-')
210 += ByteString( sMethod, RTL_TEXTENCODING_ASCII_US);
211 sOut += "=\"";
212 rStrm << sOut.GetBuffer();
213 HTMLOutFuncs::Out_String( rStrm, pDescs[i].ScriptCode, eDestEnc, pNonConvertableChars );
214 rStrm << '\"';
215 if( EXTENDED_STYPE == eScriptType &&
216 pDescs[i].AddListenerParam.getLength() )
217 {
218 (((((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_sdaddparam)
219 += ByteString( sListener, RTL_TEXTENCODING_ASCII_US)) += '-')
220 += ByteString( sMethod, RTL_TEXTENCODING_ASCII_US))
221 += "=\"";
222 rStrm << sOut.GetBuffer();
223 HTMLOutFuncs::Out_String( rStrm, pDescs[i].AddListenerParam,
224 eDestEnc, pNonConvertableChars );
225 rStrm << '\"';
226 }
227 }
228 }
229
lcl_html_isHTMLControl(sal_Int16 nClassId)230 sal_Bool lcl_html_isHTMLControl( sal_Int16 nClassId )
231 {
232 sal_Bool bRet = sal_False;
233
234 switch( nClassId )
235 {
236 case form::FormComponentType::TEXTFIELD:
237 case form::FormComponentType::COMMANDBUTTON:
238 case form::FormComponentType::RADIOBUTTON:
239 case form::FormComponentType::CHECKBOX:
240 case form::FormComponentType::LISTBOX:
241 case form::FormComponentType::IMAGEBUTTON:
242 case form::FormComponentType::FILECONTROL:
243 bRet = sal_True;
244 break;
245 }
246
247 return bRet;
248 }
249
HasControls() const250 sal_Bool SwHTMLWriter::HasControls() const
251 {
252 sal_uInt32 nStartIdx = pCurPam->GetPoint()->nNode.GetIndex();
253 sal_uInt16 i;
254
255 // Skip all controls in front of the current paragraph
256 for( i = 0; i < aHTMLControls.Count() &&
257 aHTMLControls[i]->nNdIdx < nStartIdx; i++ )
258 ;
259
260 return i < aHTMLControls.Count() && aHTMLControls[i]->nNdIdx == nStartIdx;
261 }
262
OutForm(sal_Bool bTag_On,const SwStartNode * pStartNd)263 void SwHTMLWriter::OutForm( sal_Bool bTag_On, const SwStartNode *pStartNd )
264 {
265 if( bPreserveForm ) // wir sind in einer Tabelle oder einem Bereich
266 return; // ueber dem eine Form aufgespannt wurde
267
268 if( !bTag_On )
269 {
270 // die Form beenden wenn alle Controls ausgegeben wurden
271 if( pxFormComps && pxFormComps->is() &&
272 (*pxFormComps)->getCount() == nFormCntrlCnt )
273 {
274 OutForm( sal_False, *pxFormComps );
275 (*pxFormComps) = 0;
276 }
277 return;
278 }
279
280 uno::Reference< container::XIndexContainer > xNewFormComps; // die neue Form
281 sal_uInt32 nStartIdx = pStartNd ? pStartNd->GetIndex()
282 : pCurPam->GetPoint()->nNode.GetIndex();
283
284 // Ueberspringen von Controls vor dem interesanten Bereich
285 sal_uInt16 i;
286 for( i = 0; i < aHTMLControls.Count() &&
287 aHTMLControls[i]->nNdIdx < nStartIdx; i++ )
288 ;
289
290 if( !pStartNd )
291 {
292 // Check fuer einen einzelnen Node: da ist nur interessant, ob
293 // es zu dem Node ein Control gibt und zu welcher Form es gehoert
294 if( i < aHTMLControls.Count() &&
295 aHTMLControls[i]->nNdIdx == nStartIdx )
296 xNewFormComps = aHTMLControls[i]->xFormComps;
297 }
298 else
299 {
300 // wir klappern eine Tabelle/einen Bereich ab: hier interessiert uns:
301 // - ob es Controls mit unterschiedlichen Start-Nodes gibt
302 // - ob es eine Form gibt, fuer die nicht alle Controls in der
303 // Tabelle/dem Bereich liegen
304
305 uno::Reference< container::XIndexContainer > xCurrentFormComps;// die aktuelle Form in der Tabelle
306 const SwStartNode *pCurrentStNd = 0; // und der Start-Node eines Ctrls
307 xub_StrLen nCurrentCtrls = 0; // und die in ihr gefundenen Controls
308 sal_uInt32 nEndIdx = pStartNd->EndOfSectionIndex();
309 for( ; i < aHTMLControls.Count() &&
310 aHTMLControls[i]->nNdIdx <= nEndIdx; i++ )
311 {
312 const SwStartNode *pCntrlStNd =
313 pDoc->GetNodes()[aHTMLControls[i]->nNdIdx]->StartOfSectionNode();
314
315 if( xCurrentFormComps.is() )
316 {
317 // Wir befinden uns bereits in einer Form ...
318 if( xCurrentFormComps==aHTMLControls[i]->xFormComps )
319 {
320 // ... und das Control befindet sich auch darin ...
321 if( pCurrentStNd!=pCntrlStNd )
322 {
323 // ... aber es liegt in einer anderen Zelle:
324 // Dann muessen eir eine Form ueber der Tabelle
325 // aufmachen
326 xNewFormComps = xCurrentFormComps;
327 break;
328 }
329 nCurrentCtrls = nCurrentCtrls + aHTMLControls[i]->nCount;
330 }
331 else
332 {
333 // ... aber das Control liegt in einer anderen Zelle:
334 // Da tun wir so, als ob wir eine neue Form aufmachen
335 // und suchen weiter.
336 xCurrentFormComps = aHTMLControls[i]->xFormComps;
337 pCurrentStNd = pCntrlStNd;
338 nCurrentCtrls = aHTMLControls[i]->nCount;
339 }
340 }
341 else
342 {
343 // Wir befinden uns noch in keiner Form:
344 // Da tun wir mal so, als ob wie wir die Form aufmachen.
345 xCurrentFormComps = aHTMLControls[i]->xFormComps;
346 pCurrentStNd = pCntrlStNd;
347 nCurrentCtrls = aHTMLControls[i]->nCount;
348 }
349 }
350 if( !xNewFormComps.is() && xCurrentFormComps.is() &&
351 nCurrentCtrls != xCurrentFormComps->getCount() )
352 {
353 // In der Tablle/dem Bereich sollte eine Form aufgemacht werden,
354 // die nicht vollstaendig in der Tabelle liegt. Dan muessen
355 // wie die Form jetzt ebenfalls oeffen.
356 xNewFormComps = xCurrentFormComps;
357 }
358 }
359
360 if( xNewFormComps.is() &&
361 (!pxFormComps || !(xNewFormComps == *pxFormComps)) )
362 {
363 // Es soll eine Form aufgemacht werden ...
364 if( pxFormComps && pxFormComps->is() )
365 {
366 // .. es ist aber noch eine Form offen: Das ist in
367 // jedem Fall eine Fehler, aber wir schliessen die alte
368 // Form trotzdem
369 OutForm( sal_False, *pxFormComps );
370
371 //!!!nWarn = 1; // Control wird falscher Form zugeordnet
372 }
373
374 if( !pxFormComps )
375 pxFormComps = new uno::Reference< container::XIndexContainer > ;
376 *pxFormComps = xNewFormComps;
377
378 OutForm( sal_True, *pxFormComps );
379 uno::Reference< beans::XPropertySet > xTmp;
380 OutHiddenControls( *pxFormComps, xTmp );
381 }
382 }
383
OutHiddenForms()384 void SwHTMLWriter::OutHiddenForms()
385 {
386 // Ohne DrawModel kann es auch keine Controls geben. Dann darf man
387 // auch nicht per UNO auf das Dok zugreifen, weil sonst ein DrawModel
388 // angelegt wird.
389 if( !pDoc->GetDrawModel() )
390 return;
391
392 SwDocShell *pDocSh = pDoc->GetDocShell();
393 if( !pDocSh )
394 return;
395
396 uno::Reference< drawing::XDrawPageSupplier > xDPSupp( pDocSh->GetBaseModel(),
397 uno::UNO_QUERY );
398 ASSERT( xDPSupp.is(), "XTextDocument nicht vom XModel erhalten" );
399 uno::Reference< drawing::XDrawPage > xDrawPage = xDPSupp->getDrawPage();
400
401 ASSERT( xDrawPage.is(), "XDrawPage nicht erhalten" );
402 if( !xDrawPage.is() )
403 return;
404
405 uno::Reference< form::XFormsSupplier > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
406 ASSERT( xFormsSupplier.is(),
407 "XFormsSupplier nicht vom XDrawPage erhalten" );
408
409 uno::Reference< container::XNameContainer > xTmp = xFormsSupplier->getForms();
410 ASSERT( xTmp.is(), "XForms nicht erhalten" );
411 uno::Reference< container::XIndexContainer > xForms( xTmp, uno::UNO_QUERY );
412 ASSERT( xForms.is(), "XForms ohne container::XIndexContainer?" );
413
414 sal_Int32 nCount = xForms->getCount();
415 for( sal_Int32 i=0; i<nCount; i++)
416 {
417 uno::Any aTmp = xForms->getByIndex( i );
418 ASSERT( aTmp.getValueType() ==
419 ::getCppuType((uno::Reference< form::XForm >*)0),
420 "OutHiddenForms: falsche Reflection" );
421 if( aTmp.getValueType() ==
422 ::getCppuType((uno::Reference< form::XForm >*)0) )
423 OutHiddenForm( *(uno::Reference< form::XForm > *)aTmp.getValue() );
424 }
425 }
426
OutHiddenForm(const uno::Reference<form::XForm> & rForm)427 void SwHTMLWriter::OutHiddenForm( const uno::Reference< form::XForm > & rForm )
428 {
429 uno::Reference< container::XIndexContainer > xFormComps( rForm, uno::UNO_QUERY );
430 if( !xFormComps.is() )
431 return;
432
433 sal_Int32 nCount = xFormComps->getCount();
434 sal_Bool bHiddenOnly = nCount > 0, bHidden = sal_False;
435 for( sal_Int32 i=0; i<nCount; i++ )
436 {
437 uno::Any aTmp = xFormComps->getByIndex( i );
438 ASSERT( aTmp.getValueType() ==
439 ::getCppuType((uno::Reference<form::XFormComponent>*)0),
440 "OutHiddenForm: falsche Reflection" );
441 if( aTmp.getValueType() !=
442 ::getCppuType((uno::Reference<form::XFormComponent>*)0) )
443 continue;
444
445 uno::Reference< form::XFormComponent > xFormComp =
446 *(uno::Reference< form::XFormComponent > *)aTmp.getValue();
447 uno::Reference< form::XForm > xForm( xFormComp, uno::UNO_QUERY );
448 if( xForm.is() )
449 OutHiddenForm( xForm );
450
451 if( bHiddenOnly )
452 {
453 uno::Reference< beans::XPropertySet > xPropSet( xFormComp, uno::UNO_QUERY );
454 OUString sPropName = OUString::createFromAscii( "ClassId" );
455 if( xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
456 {
457 uno::Any aAny2 = xPropSet->getPropertyValue( sPropName );
458 if( aAny2.getValueType() == ::getCppuType((sal_Int16*)0) )
459 {
460 if( form::FormComponentType::HIDDENCONTROL ==
461 *(sal_Int16*)aAny2.getValue() )
462 bHidden = sal_True;
463 else if( lcl_html_isHTMLControl(
464 *(sal_Int16*)aAny2.getValue() ) )
465 bHiddenOnly = sal_False;
466 }
467 }
468 }
469 }
470
471 if( bHidden && bHiddenOnly )
472 {
473 OutForm( sal_True, xFormComps );
474 uno::Reference< beans::XPropertySet > xTmp;
475 OutHiddenControls( xFormComps, xTmp );
476 OutForm( sal_False, xFormComps );
477 }
478 }
479
OutForm(sal_Bool bOn,const uno::Reference<container::XIndexContainer> & rFormComps)480 void SwHTMLWriter::OutForm( sal_Bool bOn,
481 const uno::Reference< container::XIndexContainer > & rFormComps )
482 {
483 nFormCntrlCnt = 0;
484
485 if( !bOn )
486 {
487 DecIndentLevel(); // Inhalt der Form einruecken
488 if( bLFPossible )
489 OutNewLine();
490 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_form, sal_False );
491 bLFPossible = sal_True;
492
493 return;
494 }
495
496 // die neue Form wird geoeffnet
497 if( bLFPossible )
498 OutNewLine();
499 ByteString sOut( '<' );
500 sOut += OOO_STRING_SVTOOLS_HTML_form;
501
502 uno::Reference< beans::XPropertySet > xFormPropSet( rFormComps, uno::UNO_QUERY );
503
504 uno::Any aTmp = xFormPropSet->getPropertyValue(
505 OUString::createFromAscii( "Name" ) );
506 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
507 ((OUString*)aTmp.getValue())->getLength() )
508 {
509 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
510 Strm() << sOut.GetBuffer();
511 HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
512 eDestEnc, &aNonConvertableCharacters );
513 sOut = '\"';
514 }
515
516 aTmp = xFormPropSet->getPropertyValue(
517 OUString::createFromAscii( "TargetURL" ) );
518 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
519 ((OUString*)aTmp.getValue())->getLength() )
520 {
521 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_action) += "=\"";
522 Strm() << sOut.GetBuffer();
523 String aURL( *(OUString*)aTmp.getValue() );
524 aURL = URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), aURL);
525 HTMLOutFuncs::Out_String( Strm(), aURL, eDestEnc, &aNonConvertableCharacters );
526 sOut = '\"';
527 }
528
529 aTmp = xFormPropSet->getPropertyValue(
530 OUString::createFromAscii( "SubmitMethod" ) );
531 if( aTmp.getValueType() == ::getCppuType((const form::FormSubmitMethod*)0) )
532 {
533 form::FormSubmitMethod eMethod =
534 *( form::FormSubmitMethod*)aTmp.getValue();
535 if( form::FormSubmitMethod_POST==eMethod )
536 {
537 ((((sOut += ' ')
538 += OOO_STRING_SVTOOLS_HTML_O_method) += "=\"")
539 += OOO_STRING_SVTOOLS_HTML_METHOD_post) += '\"';
540 }
541 }
542 aTmp = xFormPropSet->getPropertyValue(
543 OUString::createFromAscii( "SubmitEncoding" ) );
544 if( aTmp.getValueType()==::getCppuType((const form::FormSubmitEncoding*)0) )
545 {
546 form::FormSubmitEncoding eEncType =
547 *( form::FormSubmitEncoding*)aTmp.getValue();
548 const sal_Char *pStr = 0;
549 switch( eEncType )
550 {
551 case form::FormSubmitEncoding_MULTIPART:
552 pStr = OOO_STRING_SVTOOLS_HTML_ET_multipart;
553 break;
554 case form::FormSubmitEncoding_TEXT:
555 pStr = OOO_STRING_SVTOOLS_HTML_ET_text;
556 break;
557 default:
558 ;
559 }
560
561 if( pStr )
562 {
563 ((((sOut += ' ')
564 += OOO_STRING_SVTOOLS_HTML_O_enctype) += "=\"")
565 += pStr) += '\"';
566 }
567 }
568
569 aTmp = xFormPropSet->getPropertyValue(
570 OUString::createFromAscii( "TargetFrame" ) );
571 if( aTmp.getValueType() == ::getCppuType((const OUString*)0)&&
572 ((OUString*)aTmp.getValue())->getLength() )
573 {
574 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
575 Strm() << sOut.GetBuffer();
576 HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
577 eDestEnc, &aNonConvertableCharacters );
578 sOut = '\"';
579 }
580
581 Strm() << sOut.GetBuffer();
582 uno::Reference< form::XFormComponent > xFormComp( rFormComps, uno::UNO_QUERY );
583 lcl_html_outEvents( Strm(), xFormComp, bCfgStarBasic, eDestEnc, &aNonConvertableCharacters );
584 Strm() << '>';
585
586 IncIndentLevel(); // Inhalt der Form einruecken
587 bLFPossible = sal_True;
588 }
589
OutHiddenControls(const uno::Reference<container::XIndexContainer> & rFormComps,const uno::Reference<beans::XPropertySet> & rPropSet)590 void SwHTMLWriter::OutHiddenControls(
591 const uno::Reference< container::XIndexContainer > & rFormComps,
592 const uno::Reference< beans::XPropertySet > & rPropSet )
593 {
594 sal_Int32 nCount = rFormComps->getCount();
595 sal_Int32 nPos = 0;
596 sal_Bool bDone = sal_False;
597 if( rPropSet.is() )
598 {
599 uno::Reference< form::XFormComponent > xFC( rPropSet, uno::UNO_QUERY );
600 for( nPos=0; !bDone && nPos < nCount; nPos++ )
601 {
602 uno::Any aTmp = rFormComps->getByIndex( nPos );
603 ASSERT( aTmp.getValueType() ==
604 ::getCppuType((uno::Reference< form::XFormComponent>*)0),
605 "OutHiddenControls: falsche Reflection" );
606 bDone = aTmp.getValueType() ==
607 ::getCppuType((uno::Reference< form::XFormComponent>*)0) &&
608 *(uno::Reference< form::XFormComponent > *)aTmp.getValue() ==
609 xFC;
610 }
611 }
612
613 for( ; nPos < nCount; nPos++ )
614 {
615 uno::Any aTmp = rFormComps->getByIndex( nPos );
616 ASSERT( aTmp.getValueType() ==
617 ::getCppuType((uno::Reference< form::XFormComponent>*)0),
618 "OutHiddenControls: falsche Reflection" );
619 if( aTmp.getValueType() !=
620 ::getCppuType((uno::Reference< form::XFormComponent>*)0) )
621 continue;
622 uno::Reference< form::XFormComponent > xFC =
623 *(uno::Reference< form::XFormComponent > *)aTmp.getValue();
624 uno::Reference< beans::XPropertySet > xPropSet( xFC, uno::UNO_QUERY );
625
626 OUString sPropName = OUString::createFromAscii( "ClassId" );
627 if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
628 continue;
629
630 aTmp = xPropSet->getPropertyValue( sPropName );
631 if( aTmp.getValueType() != ::getCppuType((const sal_Int16*)0) )
632 continue;
633
634 if( form::FormComponentType::HIDDENCONTROL ==
635 *(sal_Int16*) aTmp.getValue() )
636 {
637 if( bLFPossible )
638 OutNewLine( sal_True );
639 ByteString sOut( '<' );
640 ((((sOut += OOO_STRING_SVTOOLS_HTML_input) += ' ') +=
641 OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_IT_hidden;
642
643 aTmp = xPropSet->getPropertyValue(
644 OUString::createFromAscii( "Name" ) );
645 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
646 ((OUString*)aTmp.getValue())->getLength() )
647 {
648 (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_name ) += "=\"";
649 Strm() << sOut.GetBuffer();
650 HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
651 eDestEnc, &aNonConvertableCharacters );
652 sOut = '\"';
653 }
654 aTmp = xPropSet->getPropertyValue(
655 OUString::createFromAscii( "HiddenValue" ) );
656 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
657 ((OUString*)aTmp.getValue())->getLength() )
658 {
659 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
660 Strm() << sOut.GetBuffer();
661 HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
662 eDestEnc, &aNonConvertableCharacters );
663 sOut = '\"';
664 }
665 sOut += '>';
666 Strm() << sOut.GetBuffer();
667
668 nFormCntrlCnt++;
669 }
670 else if( lcl_html_isHTMLControl( *(sal_Int16*) aTmp.getValue() ) )
671 {
672 break;
673 }
674 }
675 }
676
677 /* */
678
679 // hier folgen die Ausgabe-Routinen, dadurch sind die form::Forms gebuendelt:
680
GetHTMLControl(const SwDrawFrmFmt & rFmt)681 const SdrObject *SwHTMLWriter::GetHTMLControl( const SwDrawFrmFmt& rFmt )
682 {
683 // es muss ein Draw-Format sein
684 ASSERT( RES_DRAWFRMFMT == rFmt.Which(),
685 "GetHTMLControl nuer fuer Draw-Formate erlaubt" );
686
687 // Schauen, ob es ein SdrObject dafuer gibt
688 const SdrObject *pObj = rFmt.FindSdrObject();
689 if( !pObj || FmFormInventor != pObj->GetObjInventor() )
690 return 0;
691
692 SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, pObj );
693 uno::Reference< awt::XControlModel > xControlModel =
694 pFormObj->GetUnoControlModel();
695
696 ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
697 if( !xControlModel.is() )
698 return 0;
699
700 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
701
702 OUString sPropName = OUString::createFromAscii( "ClassId" );
703 if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
704 return 0;
705
706 uno::Any aTmp = xPropSet->getPropertyValue( sPropName );
707 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0)&&
708 lcl_html_isHTMLControl( *(sal_Int16*) aTmp.getValue() ) )
709 {
710 return pObj;
711 }
712
713 return 0;
714 }
715
GetControlSize(const SdrObject & rSdrObj,Size & rSz,SwDoc * pDoc)716 static void GetControlSize( const SdrObject& rSdrObj, Size& rSz,
717 SwDoc *pDoc )
718 {
719 ViewShell *pVSh = 0;
720 pDoc->GetEditShell( &pVSh );
721 if( !pVSh )
722 return;
723
724 SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, &rSdrObj );
725 uno::Reference< awt::XControl > xControl;
726 SdrView* pDrawView = pVSh->GetDrawView();
727 ASSERT( pDrawView && pVSh->GetWin(), "no DrawView or window!" );
728 if ( pDrawView && pVSh->GetWin() )
729 xControl = pFormObj->GetUnoControl( *pDrawView, *pVSh->GetWin() );
730 uno::Reference< awt::XTextLayoutConstrains > xLC( xControl, uno::UNO_QUERY );
731 ASSERT( xLC.is(), "kein XTextLayoutConstrains" );
732 if( !xLC.is() )
733 return;
734
735 sal_Int16 nCols=0, nLines=0;
736 xLC->getColumnsAndLines( nCols, nLines );
737 rSz.Width() = nCols;
738 rSz.Height() = nLines;
739 }
740
OutHTML_DrawFrmFmtAsControl(Writer & rWrt,const SwDrawFrmFmt & rFmt,const SdrObject & rSdrObject,sal_Bool bInCntnr)741 Writer& OutHTML_DrawFrmFmtAsControl( Writer& rWrt,
742 const SwDrawFrmFmt& rFmt,
743 const SdrObject& rSdrObject,
744 sal_Bool bInCntnr )
745 {
746 SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
747
748 SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, &rSdrObject );
749 uno::Reference< awt::XControlModel > xControlModel =
750 pFormObj->GetUnoControlModel();
751
752 ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
753 if( !xControlModel.is() )
754 return rWrt;
755
756 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
757 uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
758 xPropSet->getPropertySetInfo();
759
760 //!!! if( rHTMLWrt.pForm != pVCSbxCtrl->GetVCForm() )
761 //!!! rHTMLWrt.nWarn = 1; // Control wird falscher Form zugeordnet
762 rHTMLWrt.nFormCntrlCnt++;
763
764 enum Tag { TAG_INPUT, TAG_SELECT, TAG_TEXTAREA, TAG_NONE };
765 static char const * const TagNames[] = {
766 OOO_STRING_SVTOOLS_HTML_input, OOO_STRING_SVTOOLS_HTML_select,
767 OOO_STRING_SVTOOLS_HTML_textarea };
768 Tag eTag = TAG_INPUT;
769 enum Type {
770 TYPE_TEXT, TYPE_PASSWORD, TYPE_CHECKBOX, TYPE_RADIO, TYPE_FILE,
771 TYPE_SUBMIT, TYPE_IMAGE, TYPE_RESET, TYPE_BUTTON, TYPE_NONE };
772 static char const * const TypeNames[] = {
773 OOO_STRING_SVTOOLS_HTML_IT_text, OOO_STRING_SVTOOLS_HTML_IT_password,
774 OOO_STRING_SVTOOLS_HTML_IT_checkbox, OOO_STRING_SVTOOLS_HTML_IT_radio,
775 OOO_STRING_SVTOOLS_HTML_IT_file, OOO_STRING_SVTOOLS_HTML_IT_submit,
776 OOO_STRING_SVTOOLS_HTML_IT_image, OOO_STRING_SVTOOLS_HTML_IT_reset,
777 OOO_STRING_SVTOOLS_HTML_IT_button };
778 Type eType = TYPE_NONE;
779 OUString sValue;
780 ByteString sOptions;
781 sal_Bool bEmptyValue = sal_False;
782 uno::Any aTmp = xPropSet->getPropertyValue(
783 OUString::createFromAscii( "ClassId" ) );
784 sal_Int16 nClassId = *(sal_Int16*) aTmp.getValue();
785 sal_uInt32 nFrmOpts = HTML_FRMOPTS_CONTROL;
786 switch( nClassId )
787 {
788 case form::FormComponentType::CHECKBOX:
789 case form::FormComponentType::RADIOBUTTON:
790 eType = (form::FormComponentType::CHECKBOX == nClassId
791 ? TYPE_CHECKBOX : TYPE_RADIO);
792 aTmp = xPropSet->getPropertyValue(
793 OUString::createFromAscii( "DefaultState" ) );
794 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
795 STATE_NOCHECK != *(sal_Int16*) aTmp.getValue() )
796 {
797 (sOptions += ' ') += OOO_STRING_SVTOOLS_HTML_O_checked;
798 }
799
800 aTmp = xPropSet->getPropertyValue(
801 OUString::createFromAscii( "RefValue" ) );
802 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) )
803
804 {
805 const OUString& rVal = *(OUString*)aTmp.getValue();
806 if( !rVal.getLength() )
807 bEmptyValue = sal_True;
808 else if( rVal.compareToAscii( OOO_STRING_SVTOOLS_HTML_on ) != 0 )
809 sValue = rVal;
810 }
811 break;
812
813 case form::FormComponentType::COMMANDBUTTON:
814 {
815 form::FormButtonType eButtonType = form::FormButtonType_PUSH;
816 aTmp = xPropSet->getPropertyValue(
817 OUString::createFromAscii( "ButtonType" ) );
818 if( aTmp.getValueType() ==
819 ::getCppuType((const form::FormButtonType*)0) )
820 eButtonType = *( form::FormButtonType*)aTmp.getValue();
821
822 switch( eButtonType )
823 {
824 case form::FormButtonType_RESET:
825 eType = TYPE_RESET;
826 break;
827 case form::FormButtonType_SUBMIT:
828 eType = TYPE_SUBMIT;
829 break;
830 case form::FormButtonType_PUSH:
831 default:
832 eType = TYPE_BUTTON;
833 }
834
835 aTmp = xPropSet->getPropertyValue(
836 OUString::createFromAscii( "Label" ) );
837 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
838 ((OUString*)aTmp.getValue())->getLength() )
839 {
840 sValue = *(OUString*)aTmp.getValue();
841 }
842 }
843 break;
844
845 case form::FormComponentType::LISTBOX:
846 if( rHTMLWrt.bLFPossible )
847 rHTMLWrt.OutNewLine( sal_True );
848 eTag = TAG_SELECT;
849 aTmp = xPropSet->getPropertyValue(
850 OUString::createFromAscii( "Dropdown" ) );
851 if( aTmp.getValueType() == ::getBooleanCppuType() &&
852 !*(sal_Bool*)aTmp.getValue() )
853 {
854 Size aSz( 0, 0 );
855 GetControlSize( rSdrObject, aSz, rWrt.pDoc );
856
857 // wieviele sind sichtbar ??
858 if( aSz.Height() )
859 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
860 += ByteString::CreateFromInt32( aSz.Height() );
861
862 aTmp = xPropSet->getPropertyValue(
863 OUString::createFromAscii( "MultiSelection" ) );
864 if( aTmp.getValueType() == ::getBooleanCppuType() &&
865 *(sal_Bool*)aTmp.getValue() )
866 {
867 (sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_multiple;
868 }
869 }
870 break;
871
872 case form::FormComponentType::TEXTFIELD:
873 {
874 Size aSz( 0, 0 );
875 GetControlSize( rSdrObject, aSz, rWrt.pDoc );
876
877 sal_Bool bMultiLine = sal_False;
878 OUString sMultiLine( OUString::createFromAscii( "MultiLine" ) );
879 if( xPropSetInfo->hasPropertyByName( sMultiLine ) )
880 {
881 aTmp = xPropSet->getPropertyValue( sMultiLine );
882 bMultiLine = aTmp.getValueType() == ::getBooleanCppuType() &&
883 *(sal_Bool*)aTmp.getValue();
884 }
885
886 if( bMultiLine )
887 {
888 if( rHTMLWrt.bLFPossible )
889 rHTMLWrt.OutNewLine( sal_True );
890 eTag = TAG_TEXTAREA;
891
892 if( aSz.Height() )
893 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rows ) += '=' )
894 += ByteString::CreateFromInt32( aSz.Height() );
895 if( aSz.Width() )
896 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cols ) += '=' )
897 += ByteString::CreateFromInt32( aSz.Width() );
898
899 aTmp = xPropSet->getPropertyValue(
900 OUString::createFromAscii( "HScroll" ) );
901 if( aTmp.getValueType() == ::getVoidCppuType() ||
902 (aTmp.getValueType() == ::getBooleanCppuType() &&
903 !*(sal_Bool*)aTmp.getValue()) )
904 {
905 const sal_Char *pWrapStr = 0;
906 aTmp = xPropSet->getPropertyValue(
907 OUString::createFromAscii( "HardLineBreaks" ) );
908 pWrapStr =
909 (aTmp.getValueType() == ::getBooleanCppuType() &&
910 *(sal_Bool*)aTmp.getValue()) ? OOO_STRING_SVTOOLS_HTML_WW_hard
911 : OOO_STRING_SVTOOLS_HTML_WW_soft;
912 (((sOptions += ' ') += OOO_STRING_SVTOOLS_HTML_O_wrap) += '=') += pWrapStr;
913 }
914 }
915 else
916 {
917 eType = TYPE_TEXT;
918 OUString sEchoChar( OUString::createFromAscii( "EchoChar" ) );
919 if( xPropSetInfo->hasPropertyByName( sEchoChar ) )
920 {
921 aTmp = xPropSet->getPropertyValue( sEchoChar );
922 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
923 *(sal_Int16*)aTmp.getValue() != 0 )
924 eType = TYPE_PASSWORD;
925 }
926
927 if( aSz.Width() )
928 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
929 += ByteString::CreateFromInt32( aSz.Width() );
930
931 aTmp = xPropSet->getPropertyValue(
932 OUString::createFromAscii( "MaxTextLen" ) );
933 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
934 *(sal_Int16*) aTmp.getValue() != 0 )
935 {
936 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_maxlength ) += '=' )
937 += ByteString::CreateFromInt32(
938 *(sal_Int16*) aTmp.getValue() );
939 }
940
941 OUString sDefaultText( OUString::createFromAscii( "DefaultText" ) );
942 if( xPropSetInfo->hasPropertyByName( sDefaultText ) )
943 {
944 aTmp = xPropSet->getPropertyValue( sDefaultText );
945 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
946 ((OUString*)aTmp.getValue())->getLength() )
947 {
948 sValue = *(OUString*)aTmp.getValue();
949 }
950 }
951 }
952 }
953 break;
954
955 case form::FormComponentType::FILECONTROL:
956 {
957 Size aSz( 0, 0 );
958 GetControlSize( rSdrObject, aSz, rWrt.pDoc );
959 eType = TYPE_FILE;
960
961 if( aSz.Width() )
962 (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
963 += ByteString::CreateFromInt32( aSz.Width() );
964
965 // VALUE vim form aus Sicherheitsgruenden nicht exportieren
966 }
967 break;
968
969
970 case form::FormComponentType::IMAGEBUTTON:
971 eType = TYPE_IMAGE;
972 nFrmOpts = HTML_FRMOPTS_IMG_CONTROL;
973 break;
974
975 default: // kennt HTML nicht
976 eTag = TAG_NONE; // also ueberspringen
977 break;
978 }
979
980 if( eTag == TAG_NONE )
981 return rWrt;
982
983 ByteString sOut( '<' );
984 sOut += TagNames[eTag];
985 if( eType != TYPE_NONE )
986 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') +=
987 TypeNames[eType];
988
989 aTmp = xPropSet->getPropertyValue( OUString::createFromAscii( "Name" ) );
990 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
991 ((OUString*)aTmp.getValue())->getLength() )
992 {
993 (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_name ) += "=\"";
994 rWrt.Strm() << sOut.GetBuffer();
995 HTMLOutFuncs::Out_String( rWrt.Strm(), *(OUString*)aTmp.getValue(),
996 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
997 sOut = '\"';
998 }
999
1000 aTmp = xPropSet->getPropertyValue( OUString::createFromAscii( "Enabled" ) );
1001 if( aTmp.getValueType() == ::getBooleanCppuType() &&
1002 !*(sal_Bool*)aTmp.getValue() )
1003 {
1004 (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_disabled );
1005 }
1006
1007 if( sValue.getLength() || bEmptyValue )
1008 {
1009 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
1010 rWrt.Strm() << sOut.GetBuffer();
1011 HTMLOutFuncs::Out_String( rWrt.Strm(), sValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1012 sOut = '\"';
1013 }
1014
1015 sOut += sOptions;
1016
1017 if( TYPE_IMAGE == eType )
1018 {
1019 aTmp = xPropSet->getPropertyValue(
1020 OUString::createFromAscii( "ImageURL" ) );
1021 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
1022 ((OUString*)aTmp.getValue())->getLength() )
1023 {
1024 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
1025 rWrt.Strm() << sOut.GetBuffer();
1026
1027 HTMLOutFuncs::Out_String( rWrt.Strm(),
1028 URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), *(OUString*)aTmp.getValue()),
1029 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1030 sOut = '\"';
1031 }
1032
1033 Size aTwipSz( rSdrObject.GetLogicRect().GetSize() );
1034 Size aPixelSz( 0, 0 );
1035 if( (aTwipSz.Width() || aTwipSz.Height()) &&
1036 Application::GetDefaultDevice() )
1037 {
1038 aPixelSz =
1039 Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
1040 MapMode(MAP_TWIP) );
1041 if( !aPixelSz.Width() && aTwipSz.Width() )
1042 aPixelSz.Width() = 1;
1043 if( !aPixelSz.Height() && aTwipSz.Height() )
1044 aPixelSz.Height() = 1;
1045 }
1046
1047 if( aPixelSz.Width() )
1048 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
1049 += ByteString::CreateFromInt32( aPixelSz.Width() );
1050
1051 if( aPixelSz.Height() )
1052 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
1053 += ByteString::CreateFromInt32( aPixelSz.Height() );
1054 }
1055
1056 aTmp = xPropSet->getPropertyValue(
1057 OUString::createFromAscii( "TabIndex" ) );
1058 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) )
1059 {
1060 sal_Int16 nTabIndex = *(sal_Int16*) aTmp.getValue();
1061 if( nTabIndex > 0 )
1062 {
1063 if( nTabIndex >= 32767 )
1064 nTabIndex = 32767;
1065
1066 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_tabindex) += '=')
1067 += ByteString::CreateFromInt32( nTabIndex );
1068 }
1069 }
1070
1071 if( sOut.Len() )
1072 {
1073 rWrt.Strm() << sOut.GetBuffer();
1074 sOut.Erase();
1075 }
1076
1077 ASSERT( !bInCntnr, "Container wird fuer Controls nicht unterstuertzt" );
1078 if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) && !bInCntnr )
1079 {
1080 // Wenn Zeichen-Objekte nicht absolut positioniert werden duerfen,
1081 // das entsprechende Flag loeschen.
1082 nFrmOpts |= (TYPE_IMAGE == eType
1083 ? HTML_FRMOPTS_IMG_CONTROL_CSS1
1084 : HTML_FRMOPTS_CONTROL_CSS1);
1085 }
1086 ByteString aEndTags;
1087 if( nFrmOpts != 0 )
1088 rHTMLWrt.OutFrmFmtOptions( rFmt, aEmptyStr, aEndTags, nFrmOpts );
1089
1090 if( rHTMLWrt.bCfgOutStyles )
1091 {
1092 sal_Bool bEdit = TAG_TEXTAREA == eTag || TYPE_FILE == eType ||
1093 TYPE_TEXT == eType;
1094
1095 SfxItemSet aItemSet( rHTMLWrt.pDoc->GetAttrPool(), RES_CHRATR_BEGIN,
1096 RES_CHRATR_END );
1097 OUString sPropName = OUString::createFromAscii( "BackgroundColor" );
1098 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1099 {
1100 aTmp = xPropSet->getPropertyValue( sPropName );
1101 if( aTmp.getValueType() == ::getCppuType((const sal_Int32*)0) )
1102 {
1103 Color aCol(*(sal_Int32*)aTmp .getValue());
1104 aItemSet.Put( SvxBrushItem( aCol, RES_CHRATR_BACKGROUND ) );
1105 }
1106 }
1107 sPropName = OUString::createFromAscii( "TextColor" );
1108 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1109 {
1110 aTmp = xPropSet->getPropertyValue( sPropName );
1111 if( aTmp.getValueType() == ::getCppuType((const sal_Int32*)0) )
1112 {
1113 Color aColor( *(sal_Int32*)aTmp .getValue() );
1114 aItemSet.Put( SvxColorItem( aColor, RES_CHRATR_COLOR ) );
1115 }
1116 }
1117 sPropName = OUString::createFromAscii( "FontHeight" );
1118 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1119 {
1120 aTmp = xPropSet->getPropertyValue( sPropName );
1121 if( aTmp.getValueType() == ::getCppuType((const float*)0) )
1122
1123 {
1124 float nHeight = *(float*)aTmp.getValue();
1125 if( nHeight > 0 && (!bEdit || nHeight != 10.) )
1126 aItemSet.Put( SvxFontHeightItem( sal_Int16(nHeight * 20.), 100, RES_CHRATR_FONTSIZE ) );
1127 }
1128 }
1129 sPropName = OUString::createFromAscii( "FontName" );
1130 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1131 {
1132 aTmp = xPropSet->getPropertyValue( sPropName );
1133 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
1134 ((OUString*)aTmp.getValue())->getLength() )
1135 {
1136 Font aFixedFont( OutputDevice::GetDefaultFont(
1137 DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US,
1138 DEFAULTFONT_FLAGS_ONLYONE ) );
1139 String aFName( *(OUString*)aTmp.getValue() );
1140 if( !bEdit || aFName != aFixedFont.GetName() )
1141 {
1142 FontFamily eFamily = FAMILY_DONTKNOW;
1143 sPropName = OUString::createFromAscii( "FontFamily" );
1144 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1145 {
1146 aTmp = xPropSet->getPropertyValue( sPropName );
1147 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
1148 eFamily = (FontFamily)*(sal_Int16*) aTmp.getValue();
1149 }
1150 SvxFontItem aItem( eFamily, aFName, aEmptyStr, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, RES_CHRATR_FONT );
1151 aItemSet.Put( aItem );
1152 }
1153 }
1154 }
1155 sPropName = OUString::createFromAscii( "FontWeight" );
1156 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1157 {
1158 aTmp = xPropSet->getPropertyValue( sPropName );
1159 if( aTmp.getValueType() == ::getCppuType((const float*)0) )
1160 {
1161 FontWeight eWeight =
1162 VCLUnoHelper::ConvertFontWeight( *(float*)aTmp.getValue() );
1163 if( eWeight != WEIGHT_DONTKNOW && eWeight != WEIGHT_NORMAL )
1164 aItemSet.Put( SvxWeightItem( eWeight, RES_CHRATR_WEIGHT ) );
1165 }
1166 }
1167 sPropName = OUString::createFromAscii( "FontSlant" );
1168 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1169 {
1170 aTmp = xPropSet->getPropertyValue( sPropName );
1171 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
1172 {
1173 FontItalic eItalic = (FontItalic)*(sal_Int16*)aTmp.getValue();
1174 if( eItalic != ITALIC_DONTKNOW && eItalic != ITALIC_NONE )
1175 aItemSet.Put( SvxPostureItem( eItalic, RES_CHRATR_POSTURE ) );
1176 }
1177 }
1178 sPropName = OUString::createFromAscii( "FontUnderline" );
1179 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1180 {
1181 aTmp = xPropSet->getPropertyValue( sPropName );
1182 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) )
1183 {
1184 FontUnderline eUnderline =
1185 (FontUnderline)*(sal_Int16*)aTmp.getValue();
1186 if( eUnderline != UNDERLINE_DONTKNOW &&
1187 eUnderline != UNDERLINE_NONE )
1188 aItemSet.Put( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ) );
1189 }
1190 }
1191 sPropName = OUString::createFromAscii( "FontStrikeout" );
1192 if( xPropSetInfo->hasPropertyByName( sPropName ) )
1193 {
1194 aTmp = xPropSet->getPropertyValue( sPropName );
1195 if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
1196 {
1197 FontStrikeout eStrikeout =
1198 (FontStrikeout)*(sal_Int16*)aTmp.getValue();
1199 if( eStrikeout != STRIKEOUT_DONTKNOW &&
1200 eStrikeout != STRIKEOUT_NONE )
1201 aItemSet.Put( SvxCrossedOutItem( eStrikeout, RES_CHRATR_CROSSEDOUT ) );
1202 }
1203 }
1204
1205 rHTMLWrt.OutCSS1_FrmFmtOptions( rFmt, nFrmOpts, &rSdrObject,
1206 &aItemSet );
1207 }
1208
1209 uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
1210 lcl_html_outEvents( rWrt.Strm(), xFormComp, rHTMLWrt.bCfgStarBasic,
1211 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1212
1213 rWrt.Strm() << '>';
1214
1215 if( TAG_SELECT == eTag )
1216 {
1217 aTmp = xPropSet->getPropertyValue(
1218 OUString::createFromAscii( "StringItemList" ) );
1219 if( aTmp.getValueType() == ::getCppuType((uno::Sequence<OUString>*)0) )
1220 {
1221 rHTMLWrt.IncIndentLevel(); // der Inhalt von Select darf
1222 // eingerueckt werden
1223 uno::Sequence<OUString> aList( *(uno::Sequence<OUString>*)aTmp.getValue() );
1224 sal_Int32 nCnt = aList.getLength();
1225 const OUString *pStrings = aList.getConstArray();
1226
1227 const OUString *pValues = 0;
1228 sal_Int32 nValCnt = 0;
1229 aTmp = xPropSet->getPropertyValue(
1230 OUString::createFromAscii( "ListSource" ) );
1231 uno::Sequence<OUString> aValList;
1232 if( aTmp.getValueType() == ::getCppuType((uno::Sequence<OUString>*)0) )
1233 {
1234 aValList = *(uno::Sequence<OUString>*)aTmp.getValue();
1235 nValCnt = aValList.getLength();
1236 pValues = aValList.getConstArray();
1237 }
1238
1239 uno::Any aSelTmp = xPropSet->getPropertyValue(
1240 OUString::createFromAscii( "DefaultSelection" ) );
1241 const sal_Int16 *pSels = 0;
1242 sal_Int32 nSel = 0;
1243 sal_Int32 nSelCnt = 0;
1244 uno::Sequence<sal_Int16> aSelList;
1245 if( aSelTmp.getValueType() ==::getCppuType((uno::Sequence<sal_Int16>*)0))
1246 {
1247 aSelList = *(uno::Sequence<sal_Int16>*)aSelTmp.getValue();
1248 nSelCnt = aSelList.getLength();
1249 pSels = aSelList.getConstArray();
1250 }
1251
1252 for( sal_Int32 i = 0; i < nCnt; i++ )
1253 {
1254 OUString sVal;
1255 sal_Bool bSelected = sal_False, bEmptyVal = sal_False;
1256 if( i < nValCnt )
1257 {
1258 const OUString& rVal = pValues[i];
1259 if( rVal.compareToAscii( "$$$empty$$$" ) == 0 )
1260 bEmptyVal = sal_True;
1261 else
1262 sVal = rVal;
1263 }
1264
1265 bSelected = (nSel < nSelCnt) && pSels[nSel] == i;
1266 if( bSelected )
1267 nSel++;
1268
1269 rHTMLWrt.OutNewLine(); // jede Option bekommt eine eigene Zeile
1270 (sOut = '<') += OOO_STRING_SVTOOLS_HTML_option;
1271 if( sVal.getLength() || bEmptyVal )
1272 {
1273 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
1274 rWrt.Strm() << sOut.GetBuffer();
1275 HTMLOutFuncs::Out_String( rWrt.Strm(), sVal,
1276 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1277 sOut = '\"';
1278 }
1279 if( bSelected )
1280 (sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_selected;
1281
1282 sOut += '>';
1283 rWrt.Strm() << sOut.GetBuffer();
1284
1285 HTMLOutFuncs::Out_String( rWrt.Strm(), pStrings[i],
1286 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1287 }
1288 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_option, sal_False );
1289
1290 rHTMLWrt.DecIndentLevel();
1291 rHTMLWrt.OutNewLine();// das </SELECT> bekommt eine eigene Zeile
1292 }
1293 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_select, sal_False );
1294 }
1295 else if( TAG_TEXTAREA == eTag )
1296 {
1297 // In TextAreas duerfen keine zusaetzlichen Spaces oder LF exportiert
1298 // werden!
1299 String sVal;
1300 aTmp = xPropSet->getPropertyValue(
1301 OUString::createFromAscii( "DefaultText" ) );
1302 if( aTmp.getValueType() == ::getCppuType((const OUString*)0)&&
1303 ((OUString*)aTmp.getValue())->getLength() )
1304 {
1305 sVal = String( *(OUString*)aTmp.getValue() );
1306 }
1307 if( sVal.Len() )
1308 {
1309 sVal.ConvertLineEnd( LINEEND_LF );
1310 xub_StrLen nPos = 0;
1311 while ( nPos != STRING_NOTFOUND )
1312 {
1313 if( nPos )
1314 rWrt.Strm() << SwHTMLWriter::sNewLine;
1315 String aLine = sVal.GetToken( 0, 0x0A, nPos );
1316 HTMLOutFuncs::Out_String( rWrt.Strm(), aLine,
1317 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
1318 }
1319 }
1320 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_textarea, sal_False );
1321 }
1322 else if( TYPE_CHECKBOX == eType || TYPE_RADIO == eType )
1323 {
1324 aTmp = xPropSet->getPropertyValue( OUString::createFromAscii("Label") );
1325 if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
1326 ((OUString*)aTmp.getValue())->getLength() )
1327 {
1328 sValue = *(OUString*)aTmp.getValue();
1329 HTMLOutFuncs::Out_String( rWrt.Strm(), sValue,
1330 rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << ' ';
1331 }
1332 }
1333
1334 if( aEndTags.Len() )
1335 rWrt.Strm() << aEndTags.GetBuffer();
1336
1337 // Controls sind nicht absatz-gebunden, deshalb kein LF mehr ausgeben!
1338 rHTMLWrt.bLFPossible = sal_False;
1339
1340 if( rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() )
1341 rHTMLWrt.OutHiddenControls( *rHTMLWrt.pxFormComps, xPropSet );
1342 return rWrt;
1343 }
1344
1345 /* */
1346
1347 // Ermitteln, ob eine Format zu einem Control gehoert und wenn ja
1348 // dessen Form zurueckgeben
AddControl(HTMLControls & rControls,const SdrObject * pSdrObj,sal_uInt32 nNodeIdx)1349 static void AddControl( HTMLControls& rControls,
1350 const SdrObject *pSdrObj,
1351 sal_uInt32 nNodeIdx )
1352 {
1353 SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, pSdrObj );
1354 ASSERT( pFormObj, "Doch kein FormObj" );
1355 uno::Reference< awt::XControlModel > xControlModel =
1356 pFormObj->GetUnoControlModel();
1357 if( !xControlModel.is() )
1358 return;
1359
1360 uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
1361 uno::Reference< uno::XInterface > xIfc = xFormComp->getParent();
1362 uno::Reference< form::XForm > xForm(xIfc, uno::UNO_QUERY);
1363
1364 ASSERT( xForm.is(), "Wo ist die Form?" );
1365 if( xForm.is() )
1366 {
1367 uno::Reference< container::XIndexContainer > xFormComps( xForm, uno::UNO_QUERY );
1368 HTMLControl *pHCntrl = new HTMLControl( xFormComps, nNodeIdx );
1369 if( !rControls.C40_PTR_INSERT( HTMLControl, pHCntrl ) )
1370 {
1371 sal_uInt16 nPos = 0;
1372 if( rControls.Seek_Entry(pHCntrl,&nPos) &&
1373 rControls[nPos]->xFormComps==xFormComps )
1374 rControls[nPos]->nCount++;
1375 delete pHCntrl;
1376 }
1377 }
1378 }
1379
1380
GetControls()1381 void SwHTMLWriter::GetControls()
1382 {
1383 // Idee: die absatz- und zeichengebundenen Controls werden erst einmal
1384 // eingesammelt. Dabei wird fuer jedes Control des Absatz-Position
1385 // und VCForm in einem Array gemerkt.
1386 // Ueber dieses Array laesst sich dann feststellen, wo form::Forms geoeffnet
1387 // und geschlossen werden muessen.
1388 sal_uInt16 i;
1389 if( pHTMLPosFlyFrms )
1390 {
1391 // die absatz-gebundenen Controls einsammeln
1392 for( i=0; i<pHTMLPosFlyFrms->Count(); i++ )
1393 {
1394 const SwHTMLPosFlyFrm* pPosFlyFrm = pHTMLPosFlyFrms->GetObject( i );
1395 if( HTML_OUT_CONTROL != pPosFlyFrm->GetOutFn() )
1396 continue;
1397
1398 const SdrObject *pSdrObj = pPosFlyFrm->GetSdrObject();
1399 ASSERT( pSdrObj, "Wo ist das SdrObject?" );
1400 if( !pSdrObj )
1401 continue;
1402
1403 AddControl( aHTMLControls, pSdrObj,
1404 pPosFlyFrm->GetNdIndex().GetIndex() );
1405 }
1406 }
1407
1408 // und jetzt die in einem zeichengebundenen Rahmen
1409 const SwSpzFrmFmts* pSpzFrmFmts = pDoc->GetSpzFrmFmts();
1410 for( i=0; i<pSpzFrmFmts->Count(); i++ )
1411 {
1412 const SwFrmFmt *pFrmFmt = (*pSpzFrmFmts)[i];
1413 if( RES_DRAWFRMFMT != pFrmFmt->Which() )
1414 continue;
1415
1416 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
1417 const SwPosition *pPos = rAnchor.GetCntntAnchor();
1418 if ((FLY_AS_CHAR != rAnchor.GetAnchorId()) || !pPos)
1419 continue;
1420
1421 const SdrObject *pSdrObj =
1422 SwHTMLWriter::GetHTMLControl( *(const SwDrawFrmFmt*)pFrmFmt );
1423 if( !pSdrObj )
1424 continue;
1425
1426 AddControl( aHTMLControls, pSdrObj, pPos->nNode.GetIndex() );
1427 }
1428 }
1429
1430 /* */
1431
HTMLControl(const uno::Reference<container::XIndexContainer> & rFormComps,sal_uInt32 nIdx)1432 HTMLControl::HTMLControl(
1433 const uno::Reference< container::XIndexContainer > & rFormComps,
1434 sal_uInt32 nIdx ) :
1435 xFormComps( rFormComps ), nNdIdx( nIdx ), nCount( 1 )
1436 {}
1437
1438
~HTMLControl()1439 HTMLControl::~HTMLControl()
1440 {}
1441
1442
1443