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