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