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