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