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