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