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