LibreOffice Module sw (master) 1
htmlforw.cxx
Go to the documentation of this file.
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/form/FormSubmitEncoding.hpp>
21#include <com/sun/star/form/FormSubmitMethod.hpp>
22#include <com/sun/star/form/FormButtonType.hpp>
23#include <com/sun/star/frame/XModel.hpp>
24#include <com/sun/star/script/XEventAttacherManager.hpp>
25#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
26#include <com/sun/star/form/XFormsSupplier.hpp>
27#include <com/sun/star/form/XForm.hpp>
28#include <com/sun/star/form/FormComponentType.hpp>
29#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
30#include <com/sun/star/beans/XPropertySet.hpp>
31#include <hintids.hxx>
32#include <o3tl/any.hxx>
33#include <rtl/math.hxx>
34#include <utility>
35#include <vcl/svapp.hxx>
36#include <svl/macitem.hxx>
37#include <svtools/htmlout.hxx>
38#include <svtools/htmlkywd.hxx>
39#include <svl/urihelper.hxx>
40#include <vcl/unohelp.hxx>
41#include <svx/svdouno.hxx>
42#include <editeng/brushitem.hxx>
43#include <editeng/colritem.hxx>
44#include <editeng/fhgtitem.hxx>
45#include <editeng/fontitem.hxx>
46#include <editeng/wghtitem.hxx>
47#include <editeng/postitem.hxx>
48#include <editeng/udlnitem.hxx>
50#include <osl/diagnose.h>
51#include <docsh.hxx>
52#include <fmtanchr.hxx>
53#include <viewsh.hxx>
54#include <pam.hxx>
55#include <doc.hxx>
58#include "wrthtml.hxx"
59#include "htmlfly.hxx"
60#include "htmlform.hxx"
61#include <frmfmt.hxx>
62#include <frameformats.hxx>
63#include <memory>
64
65using namespace ::com::sun::star;
66
80
81static void lcl_html_outEvents( SvStream& rStrm,
82 const uno::Reference< form::XFormComponent >& rFormComp,
83 bool bCfgStarBasic )
84{
85 uno::Reference< uno::XInterface > xParentIfc = rFormComp->getParent();
86 OSL_ENSURE( xParentIfc.is(), "lcl_html_outEvents: no parent interface" );
87 if( !xParentIfc.is() )
88 return;
89 uno::Reference< container::XIndexAccess > xIndexAcc( xParentIfc, uno::UNO_QUERY );
90 uno::Reference< script::XEventAttacherManager > xEventManager( xParentIfc,
91 uno::UNO_QUERY );
92 if( !xIndexAcc.is() || !xEventManager.is() )
93 return;
94
95 // and search for the position of the ControlModel within
96 sal_Int32 nCount = xIndexAcc->getCount(), nPos;
97 for( nPos = 0 ; nPos < nCount; nPos++ )
98 {
99 uno::Any aTmp = xIndexAcc->getByIndex(nPos);
100 if( auto x1 = o3tl::tryAccess<uno::Reference<form::XFormComponent>>(aTmp) )
101
102 {
103 if( rFormComp == *x1 )
104 break;
105 }
106 else if( auto x2 = o3tl::tryAccess<uno::Reference<form::XForm>>(aTmp) )
107 {
108 if( rFormComp == *x2 )
109 break;
110 }
111 else
112 {
113 OSL_ENSURE( false, "lcl_html_outEvents: wrong reflection" );
114 }
115 }
116
117 if( nPos == nCount )
118 return;
119
120 const uno::Sequence< script::ScriptEventDescriptor > aDescs =
121 xEventManager->getScriptEvents( nPos );
122 if( !aDescs.hasElements() )
123 return;
124
125 for( const script::ScriptEventDescriptor& rDesc : aDescs )
126 {
127 ScriptType eScriptType = EXTENDED_STYPE;
128 OUString aScriptType( rDesc.ScriptType );
129 if( aScriptType.equalsIgnoreAsciiCase(SVX_MACRO_LANGUAGE_JAVASCRIPT) )
130 eScriptType = JAVASCRIPT;
131 else if( aScriptType.equalsIgnoreAsciiCase(SVX_MACRO_LANGUAGE_STARBASIC ) )
132 eScriptType = STARBASIC;
133 if( JAVASCRIPT != eScriptType && !bCfgStarBasic )
134 continue;
135
136 OUString sListener( rDesc.ListenerType );
137 if (!sListener.isEmpty())
138 {
139 const sal_Int32 nIdx { sListener.lastIndexOf('.')+1 };
140 if (nIdx>0)
141 {
142 if (nIdx<sListener.getLength())
143 {
144 sListener = sListener.copy(nIdx);
145 }
146 else
147 {
148 sListener.clear();
149 }
150 }
151 }
152 OUString sMethod( rDesc.EventMethod );
153
154 const char *pOpt = nullptr;
155 for( int j=0; aEventListenerTable[j]; j++ )
156 {
157 if( sListener.equalsAscii( aEventListenerTable[j] ) &&
158 sMethod.equalsAscii( aEventMethodTable[j] ) )
159 {
160 pOpt = (STARBASIC==eScriptType ? aEventSDOptionTable
161 : aEventOptionTable)[j];
162 break;
163 }
164 }
165
166 OString sOut = " ";
167 if( pOpt && (EXTENDED_STYPE != eScriptType ||
168 rDesc.AddListenerParam.isEmpty()) )
169 sOut += pOpt;
170 else
171 {
173 OUStringToOString(sListener, RTL_TEXTENCODING_ASCII_US) + "-" +
174 OUStringToOString(sMethod, RTL_TEXTENCODING_ASCII_US);
175 }
176 sOut += "=\"";
177 rStrm.WriteOString( sOut );
178 HTMLOutFuncs::Out_String( rStrm, rDesc.ScriptCode );
179 rStrm.WriteChar( '\"' );
180 if( EXTENDED_STYPE == eScriptType &&
181 !rDesc.AddListenerParam.isEmpty() )
182 {
184 OUStringToOString(sListener, RTL_TEXTENCODING_ASCII_US) + "-" +
185 OUStringToOString(sMethod, RTL_TEXTENCODING_ASCII_US) + "=\"";
186 rStrm.WriteOString( sOut );
187 HTMLOutFuncs::Out_String( rStrm, rDesc.AddListenerParam );
188 rStrm.WriteChar( '\"' );
189 }
190 }
191}
192
193static bool lcl_html_isHTMLControl( sal_Int16 nClassId )
194{
195 bool bRet = false;
196
197 switch( nClassId )
198 {
199 case form::FormComponentType::TEXTFIELD:
200 case form::FormComponentType::COMMANDBUTTON:
201 case form::FormComponentType::RADIOBUTTON:
202 case form::FormComponentType::CHECKBOX:
203 case form::FormComponentType::LISTBOX:
204 case form::FormComponentType::IMAGEBUTTON:
205 case form::FormComponentType::FILECONTROL:
206 bRet = true;
207 break;
208 }
209
210 return bRet;
211}
212
214{
215 SwNodeOffset nStartIdx = m_pCurrentPam->GetPoint()->GetNodeIndex();
216 size_t i = 0;
217
218 // Skip all controls in front of the current paragraph
219 while ( i < m_aHTMLControls.size() && m_aHTMLControls[i]->nNdIdx < nStartIdx )
220 ++i;
221
222 return i < m_aHTMLControls.size() && m_aHTMLControls[i]->nNdIdx == nStartIdx;
223}
224
225void SwHTMLWriter::OutForm( bool bTag_On, const SwStartNode *pStartNd )
226{
227 if( m_bPreserveForm ) // we are in a table or an area with form spanned over it
228 return;
229
230 if( !bTag_On )
231 {
232 // end the form when all controls are output
233 if( mxFormComps.is() &&
234 mxFormComps->getCount() == m_nFormCntrlCnt )
235 {
236 OutForm( false, mxFormComps );
237 mxFormComps.clear();
238 }
239 return;
240 }
241
242 uno::Reference< container::XIndexContainer > xNewFormComps;
243 SwNodeOffset nStartIdx = pStartNd ? pStartNd->GetIndex()
244 : m_pCurrentPam->GetPoint()->GetNodeIndex();
245
246 // skip controls before the interesting area
247 size_t i = 0;
248 while ( i < m_aHTMLControls.size() && m_aHTMLControls[i]->nNdIdx < nStartIdx )
249 ++i;
250
251 if( !pStartNd )
252 {
253 // Check for a single node: there it's only interesting, if there is
254 // a control for the node and to which form it belongs.
255 if( i < m_aHTMLControls.size() &&
256 m_aHTMLControls[i]->nNdIdx == nStartIdx )
257 xNewFormComps = m_aHTMLControls[i]->xFormComps;
258 }
259 else
260 {
261 // we iterate over a table/an area: we're interested in:
262 // - if there are controls with different start nodes
263 // - if there is a form, with controls which aren't all in the table/area
264
265 uno::Reference< container::XIndexContainer > xCurrentFormComps;// current form in table
266 const SwStartNode *pCurrentStNd = nullptr; // and the start node of a Control
267 sal_Int32 nCurrentCtrls = 0; // and the found controls in it
268 SwNodeOffset nEndIdx = pStartNd->EndOfSectionIndex();
269 for( ; i < m_aHTMLControls.size() &&
270 m_aHTMLControls[i]->nNdIdx <= nEndIdx; i++ )
271 {
272 const SwStartNode *pCntrlStNd =
273 m_pDoc->GetNodes()[m_aHTMLControls[i]->nNdIdx]->StartOfSectionNode();
274
275 if( xCurrentFormComps.is() )
276 {
277 // already inside a form ...
278 if( xCurrentFormComps==m_aHTMLControls[i]->xFormComps )
279 {
280 // ... and the control is also inside ...
281 if( pCurrentStNd!=pCntrlStNd )
282 {
283 // ... but it's inside another cell:
284 // Then open a form above the table
285 xNewFormComps = xCurrentFormComps;
286 break;
287 }
288 nCurrentCtrls = nCurrentCtrls + m_aHTMLControls[i]->nCount;
289 }
290 else
291 {
292 // ... but the Control is in another cell:
293 // There we act as if we open a new from and continue searching.
294 xCurrentFormComps = m_aHTMLControls[i]->xFormComps;
295 pCurrentStNd = pCntrlStNd;
296 nCurrentCtrls = m_aHTMLControls[i]->nCount;
297 }
298 }
299 else
300 {
301 // We aren't in a form:
302 // There we act as if we open a form.
303 xCurrentFormComps = m_aHTMLControls[i]->xFormComps;
304 pCurrentStNd = pCntrlStNd;
305 nCurrentCtrls = m_aHTMLControls[i]->nCount;
306 }
307 }
308 if( !xNewFormComps.is() && xCurrentFormComps.is() &&
309 nCurrentCtrls != xCurrentFormComps->getCount() )
310 {
311 // A form should be opened in the table/area which isn't completely
312 // inside the table. Then we must also now open the form.
313 xNewFormComps = xCurrentFormComps;
314 }
315 }
316
317 if( !(xNewFormComps.is() &&
318 (!mxFormComps.is() || xNewFormComps != mxFormComps)) )
319 return;
320
321 // A form should be opened ...
322 if( mxFormComps.is() )
323 {
324 // ... but a form is still open: That is in every case an error,
325 // but we'll close the old form nevertheless.
326 OutForm( false, mxFormComps );
327
329 }
330
331 mxFormComps = xNewFormComps;
332
333 OutForm( true, mxFormComps );
334 uno::Reference< beans::XPropertySet > xTmp;
336}
337
339{
340 // Without DrawModel there can't be controls. Then you also can't access the
341 // document via UNO, because otherwise a DrawModel would be created.
343 return;
344
345 SwDocShell *pDocSh = m_pDoc->GetDocShell();
346 if( !pDocSh )
347 return;
348
349 uno::Reference< drawing::XDrawPageSupplier > xDPSupp( pDocSh->GetBaseModel(),
350 uno::UNO_QUERY );
351 OSL_ENSURE( xDPSupp.is(), "XTextDocument not received from XModel" );
352 uno::Reference< drawing::XDrawPage > xDrawPage = xDPSupp->getDrawPage();
353
354 OSL_ENSURE( xDrawPage.is(), "XDrawPage not received" );
355 if( !xDrawPage.is() )
356 return;
357
358 uno::Reference< form::XFormsSupplier > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
359 OSL_ENSURE( xFormsSupplier.is(),
360 "XFormsSupplier not received from XDrawPage" );
361
362 uno::Reference< container::XNameContainer > xTmp = xFormsSupplier->getForms();
363 OSL_ENSURE( xTmp.is(), "XForms not received" );
364 uno::Reference< container::XIndexContainer > xForms( xTmp, uno::UNO_QUERY );
365 OSL_ENSURE( xForms.is(), "XForms without container::XIndexContainer?" );
366
367 sal_Int32 nCount = xForms->getCount();
368 for( sal_Int32 i=0; i<nCount; i++)
369 {
370 uno::Any aTmp = xForms->getByIndex( i );
371 if( auto x = o3tl::tryAccess<uno::Reference<form::XForm>>(aTmp) )
372 OutHiddenForm( *x );
373 else
374 {
375 OSL_ENSURE( false, "OutHiddenForms: wrong reflection" );
376 }
377 }
378}
379
380void SwHTMLWriter::OutHiddenForm( const uno::Reference< form::XForm > & rForm )
381{
382 uno::Reference< container::XIndexContainer > xFormComps( rForm, uno::UNO_QUERY );
383 if( !xFormComps.is() )
384 return;
385
386 sal_Int32 nCount = xFormComps->getCount();
387 bool bHiddenOnly = nCount > 0, bHidden = false;
388 for( sal_Int32 i=0; i<nCount; i++ )
389 {
390 uno::Any aTmp = xFormComps->getByIndex( i );
391 auto xFormComp = o3tl::tryAccess<uno::Reference<form::XFormComponent>>(
392 aTmp);
393 OSL_ENSURE( xFormComp, "OutHiddenForm: wrong reflection" );
394 if( !xFormComp )
395 continue;
396
397 uno::Reference< form::XForm > xForm( *xFormComp, uno::UNO_QUERY );
398 if( xForm.is() )
399 OutHiddenForm( xForm );
400
401 if( bHiddenOnly )
402 {
403 uno::Reference< beans::XPropertySet > xPropSet( *xFormComp, uno::UNO_QUERY );
404 OUString sPropName("ClassId");
405 if( xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
406 {
407 uno::Any aAny2 = xPropSet->getPropertyValue( sPropName );
408 if( auto n = o3tl::tryAccess<sal_Int16>(aAny2) )
409 {
410 if( form::FormComponentType::HIDDENCONTROL == *n )
411 bHidden = true;
412 else if( lcl_html_isHTMLControl( *n ) )
413 bHiddenOnly = false;
414 }
415 }
416 }
417 }
418
419 if( bHidden && bHiddenOnly )
420 {
421 OutForm( true, xFormComps );
422 uno::Reference< beans::XPropertySet > xTmp;
423 OutHiddenControls( xFormComps, xTmp );
424 OutForm( false, xFormComps );
425 }
426}
427
428void SwHTMLWriter::OutForm( bool bOn,
429 const uno::Reference< container::XIndexContainer > & rFormComps )
430{
431 m_nFormCntrlCnt = 0;
432
433 if( !bOn )
434 {
435 DecIndentLevel(); // indent content of form
436 if( m_bLFPossible )
437 OutNewLine();
438 HTMLOutFuncs::Out_AsciiTag( Strm(), Concat2View(GetNamespace() + OOO_STRING_SVTOOLS_HTML_form), false );
439 m_bLFPossible = true;
440
441 return;
442 }
443
444 // the new form is opened
445 if( m_bLFPossible )
446 OutNewLine();
447 OString sOut = "<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_form;
448
449 uno::Reference< beans::XPropertySet > xFormPropSet( rFormComps, uno::UNO_QUERY );
450
451 uno::Any aTmp = xFormPropSet->getPropertyValue( "Name" );
452 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
453 {
454 if( !s->isEmpty() )
455 {
456 sOut += " " OOO_STRING_SVTOOLS_HTML_O_name "=\"";
457 Strm().WriteOString( sOut );
459 sOut = "\"";
460 }
461 }
462
463 aTmp = xFormPropSet->getPropertyValue( "TargetURL" );
464 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
465 {
466 if ( !s->isEmpty() )
467 {
468 sOut += " " OOO_STRING_SVTOOLS_HTML_O_action "=\"";
469 Strm().WriteOString( sOut );
470 OUString aURL
473 sOut = "\"";
474 }
475 }
476
477 aTmp = xFormPropSet->getPropertyValue( "SubmitMethod" );
478 if( auto eMethod = o3tl::tryAccess<form::FormSubmitMethod>(aTmp) )
479 {
480 if( form::FormSubmitMethod_POST==*eMethod )
481 {
482 sOut += " " OOO_STRING_SVTOOLS_HTML_O_method "=\""
484 }
485 }
486 aTmp = xFormPropSet->getPropertyValue( "SubmitEncoding" );
487 if( auto eEncType = o3tl::tryAccess<form::FormSubmitEncoding>(aTmp) )
488 {
489 const char *pStr = nullptr;
490 switch( *eEncType )
491 {
492 case form::FormSubmitEncoding_MULTIPART:
494 break;
495 case form::FormSubmitEncoding_TEXT:
497 break;
498 default:
499 ;
500 }
501
502 if( pStr )
503 {
504 sOut += OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_enctype "=\"") +
505 pStr + "\"";
506 }
507 }
508
509 aTmp = xFormPropSet->getPropertyValue( "TargetFrame" );
510 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
511 {
512 if (!s->isEmpty() )
513 {
514 sOut += " " OOO_STRING_SVTOOLS_HTML_O_target "=\"";
515 Strm().WriteOString( sOut );
517 sOut = "\"";
518 }
519 }
520
521 Strm().WriteOString( sOut );
522 uno::Reference< form::XFormComponent > xFormComp( rFormComps, uno::UNO_QUERY );
523 lcl_html_outEvents( Strm(), xFormComp, m_bCfgStarBasic );
524 Strm().WriteChar( '>' );
525
526 IncIndentLevel(); // indent content of form
527 m_bLFPossible = true;
528}
529
531 const uno::Reference< container::XIndexContainer > & rFormComps,
532 const uno::Reference< beans::XPropertySet > & rPropSet )
533{
534 sal_Int32 nCount = rFormComps->getCount();
535 sal_Int32 nPos = 0;
536 if( rPropSet.is() )
537 {
538 bool bDone = false;
539
540 uno::Reference< form::XFormComponent > xFC( rPropSet, uno::UNO_QUERY );
541 for( nPos=0; !bDone && nPos < nCount; nPos++ )
542 {
543 uno::Any aTmp = rFormComps->getByIndex( nPos );
544 auto x = o3tl::tryAccess<uno::Reference<form::XFormComponent>>(aTmp);
545 OSL_ENSURE( x,
546 "OutHiddenControls: wrong reflection" );
547 bDone = x && *x == xFC;
548 }
549 }
550
551 for( ; nPos < nCount; nPos++ )
552 {
553 uno::Any aTmp = rFormComps->getByIndex( nPos );
554 auto xFC = o3tl::tryAccess<uno::Reference<form::XFormComponent>>(aTmp);
555 OSL_ENSURE( xFC,
556 "OutHiddenControls: wrong reflection" );
557 if( !xFC )
558 continue;
559 uno::Reference< beans::XPropertySet > xPropSet( *xFC, uno::UNO_QUERY );
560
561 OUString sPropName = "ClassId";
562 if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
563 continue;
564
565 aTmp = xPropSet->getPropertyValue( sPropName );
566 auto n = o3tl::tryAccess<sal_Int16>(aTmp);
567 if( !n )
568 continue;
569
570 if( form::FormComponentType::HIDDENCONTROL == *n )
571 {
572 if( m_bLFPossible )
573 OutNewLine( true );
574 OString sOut = "<" + GetNamespace() + OOO_STRING_SVTOOLS_HTML_input " "
577
578 aTmp = xPropSet->getPropertyValue( "Name" );
579 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
580 {
581 if( !s->isEmpty() )
582 {
583 sOut += " " OOO_STRING_SVTOOLS_HTML_O_name "=\"";
584 Strm().WriteOString( sOut );
586 sOut = "\"";
587 }
588 }
589 aTmp = xPropSet->getPropertyValue( "HiddenValue" );
590 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
591 {
592 if( !s->isEmpty() )
593 {
594 sOut += " " OOO_STRING_SVTOOLS_HTML_O_value "=\"";
595 Strm().WriteOString( sOut );
597 sOut = "\"";
598 }
599 }
600 sOut += ">";
601 Strm().WriteOString( sOut );
602
604 }
605 else if( lcl_html_isHTMLControl( *n ) )
606 {
607 break;
608 }
609 }
610}
611
612// here are the output routines, thus the form::Forms are bundled:
613
615{
616 // it must be a Draw-Format
617 OSL_ENSURE( RES_DRAWFRMFMT == rFormat.Which(),
618 "GetHTMLControl only allow for Draw-Formats" );
619
620 // Look if a SdrObject exists for it
621 const SdrObject *pObj = rFormat.FindSdrObject();
622 if( !pObj || SdrInventor::FmForm != pObj->GetObjInventor() )
623 return nullptr;
624
625 const SdrUnoObj& rFormObj = dynamic_cast<const SdrUnoObj&>(*pObj);
626 const uno::Reference< awt::XControlModel >& xControlModel =
627 rFormObj.GetUnoControlModel();
628
629 OSL_ENSURE( xControlModel.is(), "UNO-Control without model" );
630 if( !xControlModel.is() )
631 return nullptr;
632
633 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
634
635 OUString sPropName("ClassId");
636 if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
637 return nullptr;
638
639 uno::Any aTmp = xPropSet->getPropertyValue( sPropName );
640 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
641 {
642 if( lcl_html_isHTMLControl( *n ) )
643 {
644 return pObj;
645 }
646 }
647
648 return nullptr;
649}
650
651static void GetControlSize(const SdrUnoObj& rFormObj, Size& rSz, SwDoc *pDoc)
652{
654 if( !pVSh )
655 return;
656
657 uno::Reference< awt::XControl > xControl;
658 SdrView* pDrawView = pVSh->GetDrawView();
659 OSL_ENSURE( pDrawView && pVSh->GetWin(), "no DrawView or window!" );
660 if ( pDrawView && pVSh->GetWin() )
661 xControl = rFormObj.GetUnoControl( *pDrawView, *pVSh->GetWin()->GetOutDev() );
662 uno::Reference< awt::XTextLayoutConstrains > xLC( xControl, uno::UNO_QUERY );
663 OSL_ENSURE( xLC.is(), "no XTextLayoutConstrains" );
664 if( !xLC.is() )
665 return;
666
667 sal_Int16 nCols=0, nLines=0;
668 xLC->getColumnsAndLines( nCols, nLines );
669 rSz.setWidth( nCols );
670 rSz.setHeight( nLines );
671}
672
674 const SwDrawFrameFormat& rFormat,
675 const SdrUnoObj& rFormObj,
676 bool bInCntnr )
677{
678 const uno::Reference< awt::XControlModel >& xControlModel =
679 rFormObj.GetUnoControlModel();
680
681 OSL_ENSURE( xControlModel.is(), "UNO-Control without model" );
682 if( !xControlModel.is() )
683 return rWrt;
684
685 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
686 uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
687 xPropSet->getPropertySetInfo();
688
689 rWrt.m_nFormCntrlCnt++;
690
691 enum Tag { TAG_INPUT, TAG_SELECT, TAG_TEXTAREA, TAG_NONE };
692 static char const * const TagNames[] = {
695 Tag eTag = TAG_INPUT;
696 enum Type {
697 TYPE_TEXT, TYPE_PASSWORD, TYPE_CHECKBOX, TYPE_RADIO, TYPE_FILE,
698 TYPE_SUBMIT, TYPE_IMAGE, TYPE_RESET, TYPE_BUTTON, TYPE_NONE };
699 static char const * const TypeNames[] = {
706 OUString sValue;
707 OString sOptions;
708 bool bEmptyValue = false;
709 uno::Any aTmp = xPropSet->getPropertyValue( "ClassId" );
710 sal_Int16 nClassId = *o3tl::doAccess<sal_Int16>(aTmp);
712 switch( nClassId )
713 {
714 case form::FormComponentType::CHECKBOX:
715 case form::FormComponentType::RADIOBUTTON:
716 eType = (form::FormComponentType::CHECKBOX == nClassId
717 ? TYPE_CHECKBOX : TYPE_RADIO);
718 aTmp = xPropSet->getPropertyValue( "DefaultState" );
719 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
720 {
721 if ( TRISTATE_FALSE != *n )
722 {
723 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_checked "=\""
725 "\"";
726 }
727 }
728
729 aTmp = xPropSet->getPropertyValue( "RefValue" );
730 if( auto rVal = o3tl::tryAccess<OUString>(aTmp) )
731
732 {
733 if( rVal->isEmpty() )
734 bEmptyValue = true;
735 else if( *rVal != OOO_STRING_SVTOOLS_HTML_on )
736 sValue = *rVal;
737 }
738 break;
739
740 case form::FormComponentType::COMMANDBUTTON:
741 {
742 form::FormButtonType eButtonType = form::FormButtonType_PUSH;
743 aTmp = xPropSet->getPropertyValue( "ButtonType" );
744 if( auto t = o3tl::tryAccess<form::FormButtonType>(aTmp) )
745 eButtonType = *t;
746
747 switch( eButtonType )
748 {
749 case form::FormButtonType_RESET:
750 eType = TYPE_RESET;
751 break;
752 case form::FormButtonType_SUBMIT:
753 eType = TYPE_SUBMIT;
754 break;
755 case form::FormButtonType_PUSH:
756 default:
757 eType = TYPE_BUTTON;
758 }
759
760 aTmp = xPropSet->getPropertyValue( "Label" );
761 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
762 {
763 if( !s->isEmpty() )
764 {
765 sValue = *s;
766 }
767 }
768 }
769 break;
770
771 case form::FormComponentType::LISTBOX:
772 if( rWrt.m_bLFPossible )
773 rWrt.OutNewLine( true );
774 eTag = TAG_SELECT;
775 aTmp = xPropSet->getPropertyValue( "Dropdown" );
776 if( auto b1 = o3tl::tryAccess<bool>(aTmp) )
777 {
778 if( !*b1 )
779 {
780 Size aSz( 0, 0 );
781 GetControlSize( rFormObj, aSz, rWrt.m_pDoc );
782
783 // How many are visible ??
784 if( aSz.Height() )
785 {
786 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_size "=\"" +
787 OString::number(static_cast<sal_Int32>(aSz.Height())) + "\"";
788 }
789
790 auto aTmp2 = xPropSet->getPropertyValue( "MultiSelection" );
791 if( auto b2 = o3tl::tryAccess<bool>(aTmp2) )
792 {
793 if ( *b2 )
794 {
796 }
797 }
798 }
799 }
800 break;
801
802 case form::FormComponentType::TEXTFIELD:
803 {
804 Size aSz( 0, 0 );
805 GetControlSize( rFormObj, aSz, rWrt.m_pDoc );
806
807 bool bMultiLine = false;
808 OUString sMultiLine("MultiLine");
809 if( xPropSetInfo->hasPropertyByName( sMultiLine ) )
810 {
811 aTmp = xPropSet->getPropertyValue( sMultiLine );
812 auto b = o3tl::tryAccess<bool>(aTmp);
813 bMultiLine = b && *b;
814 }
815
816 if( bMultiLine )
817 {
818 if( rWrt.m_bLFPossible )
819 rWrt.OutNewLine( true );
820 eTag = TAG_TEXTAREA;
821
822 if( aSz.Height() )
823 {
824 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_rows "=\"" +
825 OString::number(static_cast<sal_Int32>(aSz.Height())) + "\"";
826 }
827 if( aSz.Width() )
828 {
829 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_cols "=\"" +
830 OString::number(static_cast<sal_Int32>(aSz.Width())) + "\"";
831 }
832
833 aTmp = xPropSet->getPropertyValue( "HScroll" );
834 if( aTmp.getValueType() == cppu::UnoType<void>::get() ||
835 (aTmp.getValueType() == cppu::UnoType<bool>::get() &&
836 !*o3tl::forceAccess<bool>(aTmp)) )
837 {
838 const char *pWrapStr = nullptr;
839 auto aTmp2 = xPropSet->getPropertyValue( "HardLineBreaks" );
840 auto b = o3tl::tryAccess<bool>(aTmp2);
841 pWrapStr = (b && *b) ? OOO_STRING_SVTOOLS_HTML_WW_hard
843 sOptions += OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_wrap "=\"") +
844 pWrapStr + "\"";
845 }
846 }
847 else
848 {
850 OUString sEchoChar("EchoChar");
851 if( xPropSetInfo->hasPropertyByName( sEchoChar ) )
852 {
853 aTmp = xPropSet->getPropertyValue( sEchoChar );
854 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
855 {
856 if( *n != 0 )
857 eType = TYPE_PASSWORD;
858 }
859 }
860
861 if( aSz.Width() )
862 {
863 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_size "=\"" +
864 OString::number(static_cast<sal_Int32>(aSz.Width())) + "\"";
865 }
866
867 aTmp = xPropSet->getPropertyValue( "MaxTextLen" );
868 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
869 {
870 if( *n != 0 )
871 {
872 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_maxlength "=\"" +
873 OString::number(static_cast<sal_Int32>(*n)) + "\"";
874 }
875 }
876
877 if( xPropSetInfo->hasPropertyByName( "DefaultText" ) )
878 {
879 aTmp = xPropSet->getPropertyValue( "DefaultText" );
880 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
881 {
882 if( !s->isEmpty() )
883 {
884 sValue = *s;
885 }
886 }
887 }
888 }
889 }
890 break;
891
892 case form::FormComponentType::FILECONTROL:
893 {
894 Size aSz( 0, 0 );
895 GetControlSize( rFormObj, aSz, rWrt.m_pDoc );
896 eType = TYPE_FILE;
897
898 if( aSz.Width() )
899 {
900 sOptions += " " OOO_STRING_SVTOOLS_HTML_O_size "=\"" +
901 OString::number(static_cast<sal_Int32>(aSz.Width())) + "\"";
902 }
903
904 // VALUE vim form: don't export because of security reasons
905 }
906 break;
907
908 case form::FormComponentType::IMAGEBUTTON:
910 nFrameOpts = HTML_FRMOPTS_IMG_CONTROL;
911 break;
912
913 default: // doesn't know HTML
914 eTag = TAG_NONE; // therefore skip it
915 break;
916 }
917
918 if( eTag == TAG_NONE )
919 return rWrt;
920
921 OString sOut = OString::Concat("<") + TagNames[eTag];
922 if( eType != TYPE_NONE )
923 {
924 sOut += OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_type "=\"") +
925 TypeNames[eType] + "\"";
926 }
927
928 aTmp = xPropSet->getPropertyValue("Name");
929 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
930 {
931 if( !s->isEmpty() )
932 {
933 sOut += " " OOO_STRING_SVTOOLS_HTML_O_name "=\"";
934 rWrt.Strm().WriteOString( sOut );
935 HTMLOutFuncs::Out_String( rWrt.Strm(), *s );
936 sOut = "\"";
937 }
938 }
939
940 aTmp = xPropSet->getPropertyValue("Enabled");
941 if( auto b = o3tl::tryAccess<bool>(aTmp) )
942 {
943 if( !*b )
944 {
946 }
947 }
948
949 if( !sValue.isEmpty() || bEmptyValue )
950 {
951 sOut += " " OOO_STRING_SVTOOLS_HTML_O_value "=\"";
952 rWrt.Strm().WriteOString( sOut );
953 HTMLOutFuncs::Out_String( rWrt.Strm(), sValue );
954 sOut = "\"";
955 }
956
957 sOut += " " + sOptions;
958
959 if( TYPE_IMAGE == eType )
960 {
961 aTmp = xPropSet->getPropertyValue( "ImageURL" );
962 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
963 {
964 if( !s->isEmpty() )
965 {
966 sOut += " " OOO_STRING_SVTOOLS_HTML_O_src "=\"";
967 rWrt.Strm().WriteOString( sOut );
968
971 sOut = "\"";
972 }
973 }
974
975 Size aTwipSz( rFormObj.GetLogicRect().GetSize() );
976 Size aPixelSz( 0, 0 );
977 if( (aTwipSz.Width() || aTwipSz.Height()) &&
979 {
980 aPixelSz =
982 MapMode(MapUnit::MapTwip) );
983 if( !aPixelSz.Width() && aTwipSz.Width() )
984 aPixelSz.setWidth( 1 );
985 if( !aPixelSz.Height() && aTwipSz.Height() )
986 aPixelSz.setHeight( 1 );
987 }
988
989 if( aPixelSz.Width() )
990 {
991 sOut += " " OOO_STRING_SVTOOLS_HTML_O_width "=\"" +
992 OString::number(static_cast<sal_Int32>(aPixelSz.Width())) + "\"";
993 }
994
995 if( aPixelSz.Height() )
996 {
997 sOut += " " OOO_STRING_SVTOOLS_HTML_O_height "=\"" +
998 OString::number(static_cast<sal_Int32>(aPixelSz.Height())) + "\"";
999 }
1000 }
1001
1002 aTmp = xPropSet->getPropertyValue( "TabIndex" );
1003 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
1004 {
1005 sal_Int16 nTabIndex = *n;
1006 if( nTabIndex > 0 )
1007 {
1008 if( nTabIndex >= 32767 )
1009 nTabIndex = 32767;
1010
1011 sOut += " " OOO_STRING_SVTOOLS_HTML_O_tabindex "=\"" +
1012 OString::number(static_cast<sal_Int32>(nTabIndex)) + "\"";
1013 }
1014 }
1015
1016 if( !sOut.isEmpty() )
1017 rWrt.Strm().WriteOString( sOut );
1018
1019 OSL_ENSURE( !bInCntnr, "Container is not supported for Controls" );
1020 if( rWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) && !bInCntnr )
1021 {
1022 // If Character-Objects can't be positioned absolutely,
1023 // then delete the corresponding flag.
1024 nFrameOpts |= (TYPE_IMAGE == eType
1027 }
1028 OString aEndTags;
1029 if( nFrameOpts != HtmlFrmOpts::NONE )
1030 aEndTags = rWrt.OutFrameFormatOptions(rFormat, OUString(), nFrameOpts);
1031
1032 if( rWrt.m_bCfgOutStyles )
1033 {
1034 bool bEdit = TAG_TEXTAREA == eTag || TYPE_FILE == eType ||
1035 TYPE_TEXT == eType;
1036
1038 if( xPropSetInfo->hasPropertyByName( "BackgroundColor" ) )
1039 {
1040 aTmp = xPropSet->getPropertyValue( "BackgroundColor" );
1041 if( auto n = o3tl::tryAccess<sal_Int32>(aTmp) )
1042 {
1043 Color aCol(ColorTransparency, *n);
1044 aItemSet.Put( SvxBrushItem( aCol, RES_CHRATR_BACKGROUND ) );
1045 }
1046 }
1047 if( xPropSetInfo->hasPropertyByName( "TextColor" ) )
1048 {
1049 aTmp = xPropSet->getPropertyValue( "TextColor" );
1050 if( auto n = o3tl::tryAccess<sal_Int32>(aTmp) )
1051 {
1052 Color aColor( ColorTransparency, *n );
1053 aItemSet.Put( SvxColorItem( aColor, RES_CHRATR_COLOR ) );
1054 }
1055 }
1056 if( xPropSetInfo->hasPropertyByName( "FontHeight" ) )
1057 {
1058 aTmp = xPropSet->getPropertyValue( "FontHeight" );
1059 if( auto nHeight = o3tl::tryAccess<float>(aTmp) )
1060
1061 {
1062 if( *nHeight > 0 && (!bEdit || !rtl::math::approxEqual(*nHeight, 10.0)) )
1063 aItemSet.Put( SvxFontHeightItem( sal_Int16(*nHeight * 20.), 100, RES_CHRATR_FONTSIZE ) );
1064 }
1065 }
1066 if( xPropSetInfo->hasPropertyByName( "FontName" ) )
1067 {
1068 aTmp = xPropSet->getPropertyValue( "FontName" );
1069 if( auto aFName = o3tl::tryAccess<OUString>(aTmp) )
1070 {
1071 if( !aFName->isEmpty() )
1072 {
1074 DefaultFontType::FIXED, LANGUAGE_ENGLISH_US,
1075 GetDefaultFontFlags::OnlyOne ) );
1076 if( !bEdit || *aFName != aFixedFont.GetFamilyName() )
1077 {
1078 FontFamily eFamily = FAMILY_DONTKNOW;
1079 if( xPropSetInfo->hasPropertyByName( "FontFamily" ) )
1080 {
1081 auto aTmp2 = xPropSet->getPropertyValue( "FontFamily" );
1082 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp2) )
1083 eFamily = static_cast<FontFamily>(*n);
1084 }
1085 SvxFontItem aItem(eFamily, *aFName, OUString(), PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, RES_CHRATR_FONT);
1086 aItemSet.Put( aItem );
1087 }
1088 }
1089 }
1090 }
1091 if( xPropSetInfo->hasPropertyByName( "FontWeight" ) )
1092 {
1093 aTmp = xPropSet->getPropertyValue( "FontWeight" );
1094 if( auto x = o3tl::tryAccess<float>(aTmp) )
1095 {
1096 FontWeight eWeight =
1098 if( eWeight != WEIGHT_DONTKNOW && eWeight != WEIGHT_NORMAL )
1099 aItemSet.Put( SvxWeightItem( eWeight, RES_CHRATR_WEIGHT ) );
1100 }
1101 }
1102 if( xPropSetInfo->hasPropertyByName( "FontSlant" ) )
1103 {
1104 aTmp = xPropSet->getPropertyValue( "FontSlant" );
1105 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
1106 {
1107 FontItalic eItalic = static_cast<FontItalic>(*n);
1108 if( eItalic != ITALIC_DONTKNOW && eItalic != ITALIC_NONE )
1109 aItemSet.Put( SvxPostureItem( eItalic, RES_CHRATR_POSTURE ) );
1110 }
1111 }
1112 if( xPropSetInfo->hasPropertyByName( "FontLineStyle" ) )
1113 {
1114 aTmp = xPropSet->getPropertyValue( "FontLineStyle" );
1115 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
1116 {
1117 FontLineStyle eUnderline = static_cast<FontLineStyle>(*n);
1118 if( eUnderline != LINESTYLE_DONTKNOW &&
1119 eUnderline != LINESTYLE_NONE )
1120 aItemSet.Put( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ) );
1121 }
1122 }
1123 if( xPropSetInfo->hasPropertyByName( "FontStrikeout" ) )
1124 {
1125 aTmp = xPropSet->getPropertyValue( "FontStrikeout" );
1126 if( auto n = o3tl::tryAccess<sal_Int16>(aTmp) )
1127 {
1128 FontStrikeout eStrikeout = static_cast<FontStrikeout>(*n);
1129 if( eStrikeout != STRIKEOUT_DONTKNOW &&
1130 eStrikeout != STRIKEOUT_NONE )
1131 aItemSet.Put( SvxCrossedOutItem( eStrikeout, RES_CHRATR_CROSSEDOUT ) );
1132 }
1133 }
1134
1135 rWrt.OutCSS1_FrameFormatOptions( rFormat, nFrameOpts, &rFormObj,
1136 &aItemSet );
1137 }
1138
1139 uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
1140 lcl_html_outEvents( rWrt.Strm(), xFormComp, rWrt.m_bCfgStarBasic );
1141
1142 rWrt.Strm().WriteChar( '>' );
1143
1144 if( TAG_SELECT == eTag )
1145 {
1146 aTmp = xPropSet->getPropertyValue( "StringItemList" );
1147 if( auto aList = o3tl::tryAccess<uno::Sequence<OUString>>(aTmp) )
1148 {
1149 rWrt.IncIndentLevel(); // the content of Select can be indented
1150 sal_Int32 nCnt = aList->getLength();
1151 const OUString *pStrings = aList->getConstArray();
1152
1153 const OUString *pValues = nullptr;
1154 sal_Int32 nValCnt = 0;
1155 auto aTmp2 = xPropSet->getPropertyValue( "ListSource" );
1156 uno::Sequence<OUString> aValList;
1157 if( auto s = o3tl::tryAccess<uno::Sequence<OUString>>(aTmp2) )
1158 {
1159 aValList = *s;
1160 nValCnt = aValList.getLength();
1161 pValues = aValList.getConstArray();
1162 }
1163
1164 uno::Any aSelTmp = xPropSet->getPropertyValue( "DefaultSelection" );
1165 const sal_Int16 *pSels = nullptr;
1166 sal_Int32 nSel = 0;
1167 sal_Int32 nSelCnt = 0;
1168 uno::Sequence<sal_Int16> aSelList;
1169 if( auto s = o3tl::tryAccess<uno::Sequence<sal_Int16>>(aSelTmp) )
1170 {
1171 aSelList = *s;
1172 nSelCnt = aSelList.getLength();
1173 pSels = aSelList.getConstArray();
1174 }
1175
1176 for( sal_Int32 i = 0; i < nCnt; i++ )
1177 {
1178 OUString sVal;
1179 bool bSelected = false, bEmptyVal = false;
1180 if( i < nValCnt )
1181 {
1182 const OUString& rVal = pValues[i];
1183 if( rVal == "$$$empty$$$" )
1184 bEmptyVal = true;
1185 else
1186 sVal = rVal;
1187 }
1188
1189 bSelected = (nSel < nSelCnt) && pSels[nSel] == i;
1190 if( bSelected )
1191 nSel++;
1192
1193 rWrt.OutNewLine(); // every Option gets its own line
1194 sOut = "<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_option;
1195 if( !sVal.isEmpty() || bEmptyVal )
1196 {
1197 sOut += " " OOO_STRING_SVTOOLS_HTML_O_value "=\"";
1198 rWrt.Strm().WriteOString( sOut );
1199 HTMLOutFuncs::Out_String( rWrt.Strm(), sVal );
1200 sOut = "\"";
1201 }
1202 if( bSelected )
1204
1205 sOut += ">";
1206 rWrt.Strm().WriteOString( sOut );
1207
1208 HTMLOutFuncs::Out_String( rWrt.Strm(), pStrings[i] );
1209 }
1210 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_option), false );
1211
1212 rWrt.DecIndentLevel();
1213 rWrt.OutNewLine();// the </SELECT> gets its own line
1214 }
1215 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_select), false );
1216 }
1217 else if( TAG_TEXTAREA == eTag )
1218 {
1219 // In TextAreas no additional spaces or LF may be exported!
1220 OUString sVal;
1221 aTmp = xPropSet->getPropertyValue( "DefaultText" );
1222 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
1223 {
1224 if( !s->isEmpty() )
1225 {
1226 sVal = *s;
1227 }
1228 }
1229 if( !sVal.isEmpty() )
1230 {
1231 sVal = convertLineEnd(sVal, LINEEND_LF);
1232 sal_Int32 nPos = 0;
1233 while ( nPos != -1 )
1234 {
1235 if( nPos )
1237 OUString aLine = sVal.getToken( 0, 0x0A, nPos );
1238 HTMLOutFuncs::Out_String( rWrt.Strm(), aLine );
1239 }
1240 }
1241 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_textarea), false );
1242 }
1243 else if( TYPE_CHECKBOX == eType || TYPE_RADIO == eType )
1244 {
1245 aTmp = xPropSet->getPropertyValue("Label");
1246 if( auto s = o3tl::tryAccess<OUString>(aTmp) )
1247 {
1248 if( !s->isEmpty() )
1249 {
1250 HTMLOutFuncs::Out_String( rWrt.Strm(), *s ).WriteChar( ' ' );
1251 }
1252 }
1253 }
1254
1255 if( !aEndTags.isEmpty() )
1256 rWrt.Strm().WriteOString( aEndTags );
1257
1258 // Controls aren't bound to a paragraph, therefore don't output LF anymore!
1259 rWrt.m_bLFPossible = false;
1260
1261 if( rWrt.mxFormComps.is() )
1262 rWrt.OutHiddenControls( rWrt.mxFormComps, xPropSet );
1263 return rWrt;
1264}
1265
1269static void AddControl( HTMLControls& rControls,
1270 const SdrUnoObj& rFormObj,
1271 SwNodeOffset nNodeIdx )
1272{
1273 const uno::Reference< awt::XControlModel >& xControlModel =
1274 rFormObj.GetUnoControlModel();
1275 if( !xControlModel.is() )
1276 return;
1277
1278 uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
1279 uno::Reference< uno::XInterface > xIfc = xFormComp->getParent();
1280 uno::Reference< form::XForm > xForm(xIfc, uno::UNO_QUERY);
1281
1282 OSL_ENSURE( xForm.is(), "Where is the form?" );
1283 if( xForm.is() )
1284 {
1285 uno::Reference< container::XIndexContainer > xFormComps( xForm, uno::UNO_QUERY );
1286 std::unique_ptr<HTMLControl> pHCntrl(new HTMLControl( xFormComps, nNodeIdx ));
1287 auto itPair = rControls.insert( std::move(pHCntrl) );
1288 if (!itPair.second )
1289 {
1290 if( (*itPair.first)->xFormComps==xFormComps )
1291 (*itPair.first)->nCount++;
1292 }
1293 }
1294}
1295
1297{
1298 // Idea: first off collect the paragraph- and character-bound controls.
1299 // In the process for every control the paragraph position and VCForm are
1300 // saved in an array.
1301 // With that array it's possible to find out where form::Forms must be
1302 // opened and closed.
1303
1304 // collect the paragraph-bound controls
1305 for( size_t i=0; i<m_aHTMLPosFlyFrames.size(); i++ )
1306 {
1307 const SwHTMLPosFlyFrame* pPosFlyFrame = m_aHTMLPosFlyFrames[ i ].get();
1308 if( HtmlOut::Control != pPosFlyFrame->GetOutFn() )
1309 continue;
1310
1311 const SdrObject *pSdrObj = pPosFlyFrame->GetSdrObject();
1312 OSL_ENSURE( pSdrObj, "Where is the SdrObject?" );
1313 if( !pSdrObj )
1314 continue;
1315
1316 AddControl( m_aHTMLControls, dynamic_cast<const SdrUnoObj&>(*pSdrObj),
1317 pPosFlyFrame->GetNdIndex().GetIndex() );
1318 }
1319
1320 // and now the ones in a character-bound frame
1322 {
1323 if( RES_DRAWFRMFMT != pSpz->Which() )
1324 continue;
1325
1326 const SwFormatAnchor& rAnchor = pSpz->GetAnchor();
1327 const SwNode *pAnchorNode = rAnchor.GetAnchorNode();
1328 if ((RndStdIds::FLY_AS_CHAR != rAnchor.GetAnchorId()) || !pAnchorNode)
1329 continue;
1330
1331 const SdrObject *pSdrObj =
1332 SwHTMLWriter::GetHTMLControl(*static_cast<SwDrawFrameFormat*>(pSpz) );
1333 if( !pSdrObj )
1334 continue;
1335
1336 AddControl( m_aHTMLControls, dynamic_cast<const SdrUnoObj&>(*pSdrObj), pAnchorNode->GetIndex() );
1337 }
1338}
1339
1341 uno::Reference< container::XIndexContainer > _xFormComps,
1342 SwNodeOffset nIdx ) :
1343 xFormComps(std::move( _xFormComps )), nNdIdx( nIdx ), nCount( 1 )
1344{}
1345
1347{}
1348
1349/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
Tag
XPropertyListType t
static OutputDevice * GetDefaultDevice()
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
virtual SdrInventor GetObjInventor() const
virtual const tools::Rectangle & GetLogicRect() const override
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
css::uno::Reference< css::awt::XControl > GetUnoControl(const SdrView &_rView, const OutputDevice &_rOut) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SvStream & WriteOString(std::string_view rStr)
SvStream & WriteChar(char nChar)
Definition: doc.hxx:197
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1337
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:169
const sw::FrameFormats< sw::SpzFrameFormat * > * GetSpzFrameFormats() const
Definition: doc.hxx:759
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1614
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:153
HtmlOut GetOutFn() const
Definition: htmlfly.hxx:118
const SwNodeIndex & GetNdIndex() const
Definition: htmlfly.hxx:115
const SdrObject * GetSdrObject() const
Definition: htmlfly.hxx:114
bool m_bPreserveForm
Definition: wrthtml.hxx:399
SwHTMLPosFlyFrames m_aHTMLPosFlyFrames
Definition: wrthtml.hxx:274
void OutHiddenControls(const css::uno::Reference< css::container::XIndexContainer > &rFormComps, const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Definition: htmlforw.cxx:530
bool HasControls() const
Definition: htmlforw.cxx:213
void OutHiddenForm(const css::uno::Reference< css::form::XForm > &rForm)
Definition: htmlforw.cxx:380
void IncIndentLevel()
Definition: wrthtml.hxx:525
void OutHiddenForms()
Definition: htmlforw.cxx:338
bool m_bLFPossible
Definition: wrthtml.hxx:395
css::uno::Reference< css::container::XIndexContainer > mxFormComps
Definition: wrthtml.hxx:313
bool m_bCfgOutStyles
Definition: wrthtml.hxx:355
HTMLControls m_aHTMLControls
Definition: wrthtml.hxx:304
void DecIndentLevel()
Definition: wrthtml.hxx:529
sal_uInt16 m_nFormCntrlCnt
Definition: wrthtml.hxx:329
OString GetNamespace() const
Determines the prefix string needed to respect the requested namespace alias.
Definition: wrthtml.cxx:1586
void GetControls()
Definition: htmlforw.cxx:1296
OString OutFrameFormatOptions(const SwFrameFormat &rFrameFormat, const OUString &rAltText, HtmlFrmOpts nFrameOpts)
void OutCSS1_FrameFormatOptions(const SwFrameFormat &rFrameFormat, HtmlFrmOpts nFrameOpts, const SdrObject *pSdrObj=nullptr, const SfxItemSet *pItemSet=nullptr)
Definition: css1atr.cxx:1840
void OutNewLine(bool bCheck=false)
Definition: wrthtml.cxx:1537
bool m_bCfgStarBasic
Definition: wrthtml.hxx:358
static const SdrObject * GetHTMLControl(const SwDrawFrameFormat &rFormat)
Definition: htmlforw.cxx:614
bool IsHTMLMode(sal_uInt32 nMode) const
Definition: wrthtml.hxx:598
void OutForm(bool bTagOn=true, const SwStartNode *pStNd=nullptr)
Definition: htmlforw.cxx:225
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
Base class of the Writer document model elements.
Definition: node.hxx:98
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
Starts a section of nodes in the document model.
Definition: node.hxx:348
vcl::Window * GetWin() const
Definition: viewsh.hxx:364
SdrView * GetDrawView()
Definition: vnew.cxx:386
SvStream & Strm()
Definition: writer.cxx:193
SwDoc * m_pDoc
Definition: shellio.hxx:407
std::shared_ptr< SwUnoCursor > m_pCurrentPam
Definition: shellio.hxx:409
const OUString & GetBaseURL() const
Definition: shellio.hxx:443
size_type size() const
std::pair< const_iterator, bool > insert(Value &&x)
constexpr Size GetSize() const
const OUString & GetFamilyName() const
::OutputDevice const * GetOutDev() const
ColorTransparency
#define SAL_NEWLINE_STRING
int nCount
URL aURL
float x
OUString const aScriptType
DocumentType eType
FontLineStyle
LINESTYLE_NONE
LINESTYLE_DONTKNOW
FontStrikeout
STRIKEOUT_NONE
STRIKEOUT_DONTKNOW
PITCH_DONTKNOW
FontItalic
ITALIC_NONE
ITALIC_DONTKNOW
FontFamily
FAMILY_DONTKNOW
WEIGHT_NORMAL
WEIGHT_DONTKNOW
TRISTATE_FALSE
#define TYPE_CHECKBOX
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
constexpr TypedWhichId< SvxBrushItem > RES_CHRATR_BACKGROUND(21)
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_POSTURE(11)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(165)
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
const char * aEventListenerTable[]
Definition: htmlform.cxx:139
const char * aEventSDOptionTable[]
Definition: htmlform.cxx:163
const char * aEventOptionTable[]
Definition: htmlform.cxx:175
const char * aEventMethodTable[]
Definition: htmlform.cxx:151
SwHTMLWriter & OutHTML_DrawFrameFormatAsControl(SwHTMLWriter &rWrt, const SwDrawFrameFormat &rFormat, const SdrUnoObj &rFormObj, bool bInCntnr)
Definition: htmlforw.cxx:673
static void lcl_html_outEvents(SvStream &rStrm, const uno::Reference< form::XFormComponent > &rFormComp, bool bCfgStarBasic)
Definition: htmlforw.cxx:81
static void GetControlSize(const SdrUnoObj &rFormObj, Size &rSz, SwDoc *pDoc)
Definition: htmlforw.cxx:651
const HtmlFrmOpts HTML_FRMOPTS_CONTROL_CSS1
Definition: htmlforw.cxx:69
static bool lcl_html_isHTMLControl(sal_Int16 nClassId)
Definition: htmlforw.cxx:193
static void AddControl(HTMLControls &rControls, const SdrUnoObj &rFormObj, SwNodeOffset nNodeIdx)
Find out if a format belongs to a control and if yes return its form.
Definition: htmlforw.cxx:1269
const HtmlFrmOpts HTML_FRMOPTS_IMG_CONTROL_CSS1
Definition: htmlforw.cxx:77
const HtmlFrmOpts HTML_FRMOPTS_CONTROL
Definition: htmlforw.cxx:67
const HtmlFrmOpts HTML_FRMOPTS_IMG_CONTROL
Definition: htmlforw.cxx:74
#define OOO_STRING_SVTOOLS_HTML_IT_checkbox
#define OOO_STRING_SVTOOLS_HTML_O_height
#define OOO_STRING_SVTOOLS_HTML_O_selected
#define OOO_STRING_SVTOOLS_HTML_IT_password
#define OOO_STRING_SVTOOLS_HTML_O_target
#define OOO_STRING_SVTOOLS_HTML_IT_button
#define OOO_STRING_SVTOOLS_HTML_O_rows
#define OOO_STRING_SVTOOLS_HTML_O_action
#define OOO_STRING_SVTOOLS_HTML_O_value
#define OOO_STRING_SVTOOLS_HTML_IT_reset
#define OOO_STRING_SVTOOLS_HTML_IT_submit
#define OOO_STRING_SVTOOLS_HTML_IT_file
#define OOO_STRING_SVTOOLS_HTML_O_tabindex
#define OOO_STRING_SVTOOLS_HTML_WW_soft
#define OOO_STRING_SVTOOLS_HTML_O_multiple
#define OOO_STRING_SVTOOLS_HTML_IT_image
#define OOO_STRING_SVTOOLS_HTML_O_size
#define OOO_STRING_SVTOOLS_HTML_IT_hidden
#define OOO_STRING_SVTOOLS_HTML_option
#define OOO_STRING_SVTOOLS_HTML_O_disabled
#define OOO_STRING_SVTOOLS_HTML_ET_text
#define OOO_STRING_SVTOOLS_HTML_O_wrap
#define OOO_STRING_SVTOOLS_HTML_O_src
#define OOO_STRING_SVTOOLS_HTML_METHOD_post
#define OOO_STRING_SVTOOLS_HTML_textarea
#define OOO_STRING_SVTOOLS_HTML_O_cols
#define OOO_STRING_SVTOOLS_HTML_O_maxlength
#define OOO_STRING_SVTOOLS_HTML_IT_text
#define OOO_STRING_SVTOOLS_HTML_O_sdaddparam
#define OOO_STRING_SVTOOLS_HTML_form
#define OOO_STRING_SVTOOLS_HTML_O_checked
#define OOO_STRING_SVTOOLS_HTML_O_sdevent
#define OOO_STRING_SVTOOLS_HTML_O_type
#define OOO_STRING_SVTOOLS_HTML_select
#define OOO_STRING_SVTOOLS_HTML_on
#define OOO_STRING_SVTOOLS_HTML_O_name
#define OOO_STRING_SVTOOLS_HTML_IT_radio
#define OOO_STRING_SVTOOLS_HTML_WW_hard
#define OOO_STRING_SVTOOLS_HTML_O_width
#define OOO_STRING_SVTOOLS_HTML_ET_multipart
#define OOO_STRING_SVTOOLS_HTML_O_method
#define OOO_STRING_SVTOOLS_HTML_input
sal_Int64 n
#define LANGUAGE_ENGLISH_US
LINEEND_LF
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
sal_uInt16 nPos
ScriptType
EXTENDED_STYPE
JAVASCRIPT
STARBASIC
constexpr OUStringLiteral SVX_MACRO_LANGUAGE_JAVASCRIPT
constexpr OUStringLiteral SVX_MACRO_LANGUAGE_STARBASIC
SVL_DLLPUBLIC OUString simpleNormalizedMakeRelative(OUString const &baseUriReference, OUString const &uriReference)
Type
const sal_uInt16 TYPE_IMAGE
const sal_uInt16 TYPE_TEXT
int i
void SvStream & rStrm
detail::Optional< bool >::type tryAccess< bool >(css::uno::Any const &any)
detail::Optional< float >::type tryAccess< float >(css::uno::Any const &any)
detail::Optional< sal_Int32 >::type tryAccess< sal_Int32 >(css::uno::Any const &any)
detail::Optional< sal_Int16 >::type tryAccess< sal_Int16 >(css::uno::Any const &any)
std::enable_if<!(detail::IsDerivedReference< T >::value||detail::IsUnoSequenceType< T >::value||std::is_base_of< css::uno::XInterface, T >::value), typenamedetail::Optional< T >::type >::type tryAccess(css::uno::Any const &any)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
FontWeight
VCL_DLLPUBLIC float ConvertFontWeight(FontWeight eWeight)
HTMLControl(css::uno::Reference< css::container::XIndexContainer > xForm, SwNodeOffset nIdx)
Definition: htmlforw.cxx:1340
static SVT_DLLPUBLIC SvStream & Out_AsciiTag(SvStream &, std::string_view rStr, bool bOn=true)
static SVT_DLLPUBLIC SvStream & Out_String(SvStream &, const OUString &, OUString *pNonConvertableChars=nullptr)
HtmlFrmOpts
Definition: wrthtml.hxx:76
#define HTMLMODE_ABS_POS_DRAW
Definition: wrthtml.hxx:124