xref: /aoo4110/main/sw/source/filter/html/htmlforw.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 
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