LibreOffice Module sw (master)  1
htmlsect.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 <rtl/uri.hxx>
21 
22 #include <svl/urihelper.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/wrkwin.hxx>
25 #include <editeng/adjustitem.hxx>
26 #include <editeng/ulspitem.hxx>
28 #include <svtools/htmltokn.h>
29 #include <svtools/htmlkywd.hxx>
30 #include <sfx2/linkmgr.hxx>
31 #include <osl/diagnose.h>
32 
33 #include <hintids.hxx>
34 #include <fmtornt.hxx>
35 #include <fmthdft.hxx>
36 #include <fmtcntnt.hxx>
37 #include <fmtfsize.hxx>
38 #include <fmtclds.hxx>
39 #include <fmtanchr.hxx>
40 #include <fmtpdsc.hxx>
41 #include <fmtsrnd.hxx>
42 #include <fmtflcnt.hxx>
43 #include <frmatr.hxx>
44 #include <doc.hxx>
45 #include <pam.hxx>
46 #include <ndtxt.hxx>
47 #include <shellio.hxx>
48 #include <section.hxx>
49 #include <poolfmt.hxx>
50 #include <pagedesc.hxx>
51 #include <swtable.hxx>
52 #include <viewsh.hxx>
53 #include "swcss1.hxx"
54 #include "swhtml.hxx"
55 
56 
57 using namespace ::com::sun::star;
58 
60 {
61  OUString aId, aHRef;
62  OUString aStyle, aLang, aDir;
63  OUString aClass;
64  SvxAdjust eAdjust = HtmlTokenId::CENTER_ON==nToken ? SvxAdjust::Center
65  : SvxAdjust::End;
66 
67  bool bHeader=false, bFooter=false;
68  const HTMLOptions& rHTMLOptions = GetOptions();
69  for (size_t i = rHTMLOptions.size(); i; )
70  {
71  const HTMLOption& rOption = rHTMLOptions[--i];
72  switch( rOption.GetToken() )
73  {
74  case HtmlOptionId::ID:
75  aId = rOption.GetString();
76  break;
77  case HtmlOptionId::ALIGN:
78  if( HtmlTokenId::DIVISION_ON==nToken )
79  eAdjust = rOption.GetEnum( aHTMLPAlignTable, eAdjust );
80  break;
81  case HtmlOptionId::STYLE:
82  aStyle = rOption.GetString();
83  break;
84  case HtmlOptionId::CLASS:
85  aClass = rOption.GetString();
86  break;
87  case HtmlOptionId::LANG:
88  aLang = rOption.GetString();
89  break;
90  case HtmlOptionId::DIR:
91  aDir = rOption.GetString();
92  break;
93  case HtmlOptionId::HREF:
94  aHRef = rOption.GetString();
95  break;
96  case HtmlOptionId::TITLE:
97  {
98  const OUString& rType = rOption.GetString();
99  if( rType.equalsIgnoreAsciiCase("header") )
100  bHeader = true;
101  else if( rType.equalsIgnoreAsciiCase("footer") )
102  bFooter = true;
103  }
104  break;
105  default: break;
106  }
107  }
108 
109  bool bAppended = false;
110  if( m_pPam->GetPoint()->nContent.GetIndex() )
111  {
112  AppendTextNode( bHeader||bFooter||!aId.isEmpty()|| !aHRef.isEmpty() ? AM_NORMAL
113  : AM_NOSPACE );
114  bAppended = true;
115  }
116 
117  std::unique_ptr<HTMLAttrContext> xCntxt(new HTMLAttrContext(nToken));
118 
119  bool bStyleParsed = false, bPositioned = false;
120  SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
121  SvxCSS1PropertyInfo aPropInfo;
122  if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
123  {
124  bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
125  aItemSet, aPropInfo, &aLang, &aDir );
126  if( bStyleParsed )
127  {
128  if ( aPropInfo.m_nColumnCount >= 2 )
129  {
130  xCntxt.reset();
131  NewMultiCol( aPropInfo.m_nColumnCount );
132  return;
133  }
134  bPositioned = HtmlTokenId::DIVISION_ON == nToken && !aClass.isEmpty() &&
135  CreateContainer(aClass, aItemSet, aPropInfo,
136  xCntxt.get());
137  if( !bPositioned )
138  bPositioned = DoPositioning(aItemSet, aPropInfo, xCntxt.get());
139  }
140  }
141 
142  if (!bPositioned && (bHeader || bFooter) && IsNewDoc() && !m_bReadingHeaderOrFooter)
143  {
145  xCntxt->SetHeaderOrFooter(true);
146 
147  SwPageDesc *pPageDesc = m_pCSS1Parser->GetMasterPageDesc();
148  SwFrameFormat& rPageFormat = pPageDesc->GetMaster();
149 
150  SwFrameFormat *pHdFtFormat;
151  bool bNew = false;
153  if( bHeader )
154  {
155  pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat());
156  if( !pHdFtFormat )
157  {
158  // still no header, then create one
159  rPageFormat.SetFormatAttr( SwFormatHeader( true ));
160  pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat());
161  bNew = true;
162  }
164  }
165  else
166  {
167  pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
168  if( !pHdFtFormat )
169  {
170  // still no footer, then create one
171  rPageFormat.SetFormatAttr( SwFormatFooter( true ));
172  pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
173  bNew = true;
174  }
176  }
177 
178  const SwFormatContent& rFlyContent = pHdFtFormat->GetContent();
179  const SwNodeIndex& rContentStIdx = *rFlyContent.GetContentIdx();
180  SwContentNode *pCNd;
181 
182  if( bNew )
183  {
184  pCNd = m_xDoc->GetNodes()[rContentStIdx.GetIndex()+1]
185  ->GetContentNode();
186  }
187  else
188  {
189  // Create a new node at the beginning of the section
190  SwNodeIndex aSttIdx( rContentStIdx, 1 );
191  pCNd = m_xDoc->GetNodes().MakeTextNode( aSttIdx,
192  m_pCSS1Parser->GetTextCollFromPool(RES_POOLCOLL_TEXT));
193 
194  // delete the current content of the section
195  SwPaM aDelPam( aSttIdx );
196  aDelPam.SetMark();
197 
198  const SwStartNode *pStNd =
199  static_cast<const SwStartNode *>( &rContentStIdx.GetNode() );
200  aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1;
201 
202  if (!PendingObjectsInPaM(aDelPam))
203  {
204  ClearFootnotesMarksInRange(aDelPam.GetMark()->nNode, aDelPam.GetPoint()->nNode);
205  m_xDoc->getIDocumentContentOperations().DelFullPara(aDelPam);
206  }
207 
208  // update page style
209  for( size_t i=0; i < m_xDoc->GetPageDescCnt(); i++ )
210  {
211  if( RES_POOLPAGE_HTML == m_xDoc->GetPageDesc(i).GetPoolFormatId() )
212  {
213  m_xDoc->ChgPageDesc( i, *pPageDesc );
214  break;
215  }
216  }
217  }
218 
219  SwPosition aNewPos( SwNodeIndex( rContentStIdx, 1 ), SwIndex( pCNd, 0 ) );
220  SaveDocContext(xCntxt.get(), nFlags, &aNewPos);
221  }
222  else if( !bPositioned && aId.getLength() > 9 &&
223  (aId[0] == 's' || aId[0] == 'S' ) &&
224  (aId[1] == 'd' || aId[1] == 'D' ) )
225  {
226  bool bEndNote = false, bFootNote = false;
227  if( aId.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdendnote ) )
228  bEndNote = true;
229  else if( aId.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdfootnote ) )
230  bFootNote = true;
231  if( bFootNote || bEndNote )
232  {
233  SwNodeIndex *pStartNdIdx = GetFootEndNoteSection( aId );
234  if( pStartNdIdx )
235  {
236  SwContentNode *pCNd =
237  m_xDoc->GetNodes()[pStartNdIdx->GetIndex()+1]->GetContentNode();
238  SwNodeIndex aTmpSwNodeIndex(*pCNd);
239  SwPosition aNewPos( aTmpSwNodeIndex, SwIndex( pCNd, 0 ) );
240  SaveDocContext(xCntxt.get(), HtmlContextFlags::MultiColMask, &aNewPos);
241  aId.clear();
242  aPropInfo.m_aId.clear();
243  }
244  }
245  }
246 
247  // We only insert sections into frames if the section is linked.
248  if( (!aId.isEmpty() && !bPositioned) || !aHRef.isEmpty() )
249  {
250  // Insert section (has to be done before setting of attributes,
251  // because the section is inserted before the PaM position.
252 
253  // If we are in the first node of a section, we insert the section
254  // before the current section and not in the current section.
255  // Therefore we have to add a node and delete it again!
256  if( !bAppended )
257  {
258  SwNodeIndex aPrvNdIdx( m_pPam->GetPoint()->nNode, -1 );
259  if (aPrvNdIdx.GetNode().IsSectionNode())
260  {
261  AppendTextNode();
262  bAppended = true;
263  }
264  }
265  std::unique_ptr<std::deque<std::unique_ptr<HTMLAttr>>> pPostIts(bAppended ? nullptr : new std::deque<std::unique_ptr<HTMLAttr>>);
266  SetAttr( true, true, pPostIts.get() );
267 
268  // make name of section unique
269  const OUString aName( m_xDoc->GetUniqueSectionName( !aId.isEmpty() ? &aId : nullptr ) );
270 
271  if( !aHRef.isEmpty() )
272  {
273  sal_Unicode cDelim = 255U;
274  sal_Int32 nPos = aHRef.lastIndexOf( cDelim );
275  sal_Int32 nPos2 = -1;
276  if( nPos != -1 )
277  {
278  nPos2 = aHRef.lastIndexOf( cDelim, nPos );
279  if( nPos2 != -1 )
280  {
281  sal_Int32 nTmp = nPos;
282  nPos = nPos2;
283  nPos2 = nTmp;
284  }
285  }
286  OUString aURL;
287  if( nPos == -1 )
288  {
290  }
291  else
292  {
293  aURL = URIHelper::SmartRel2Abs(INetURLObject( m_sBaseURL ), aHRef.copy( 0, nPos ), Link<OUString *, bool>(), false )
294  + OUStringLiteral1(sfx2::cTokenSeparator);
295  if( nPos2 == -1 )
296  {
297  aURL += aHRef.copy( nPos+1 );
298  }
299  else
300  {
301  aURL += aHRef.copy( nPos+1, nPos2 - (nPos+1) )
302  + OUStringLiteral1(sfx2::cTokenSeparator)
303  + rtl::Uri::decode( aHRef.copy( nPos2+1 ),
304  rtl_UriDecodeWithCharset,
305  RTL_TEXTENCODING_ISO_8859_1 );
306  }
307  }
308  aHRef = aURL;
309  }
310 
311  SwSectionData aSection( (!aHRef.isEmpty()) ? FILE_LINK_SECTION
312  : CONTENT_SECTION, aName );
313  if( !aHRef.isEmpty() )
314  {
315  aSection.SetLinkFileName( aHRef );
316  aSection.SetProtectFlag(true);
317  }
318 
319  SfxItemSet aFrameItemSet( m_xDoc->GetAttrPool(),
321  if( !IsNewDoc() )
322  Reader::ResetFrameFormatAttrs(aFrameItemSet );
323 
324  const SfxPoolItem *pItem;
325  if( SfxItemState::SET == aItemSet.GetItemState( RES_BACKGROUND, false,
326  &pItem ) )
327  {
328  aFrameItemSet.Put( *pItem );
329  aItemSet.ClearItem( RES_BACKGROUND );
330  }
331  if( SfxItemState::SET == aItemSet.GetItemState( RES_FRAMEDIR, false,
332  &pItem ) )
333  {
334  aFrameItemSet.Put( *pItem );
335  aItemSet.ClearItem( RES_FRAMEDIR );
336  }
337 
338  m_xDoc->InsertSwSection( *m_pPam, aSection, nullptr, &aFrameItemSet, false );
339 
340  // maybe jump to section
341  if( JumpToMarks::Region == m_eJumpTo && aName == m_sJmpMark )
342  {
343  m_bChkJumpMark = true;
345  }
346 
347  SwTextNode* pOldTextNd =
348  bAppended ? nullptr : m_pPam->GetPoint()->nNode.GetNode().GetTextNode();
349 
351 
352  // move PageDesc and SwFormatBreak attribute from current node into
353  // (first) node of the section
354  if( pOldTextNd )
355  MovePageDescAttrs( pOldTextNd, m_pPam->GetPoint()->nNode.GetIndex(),
356  true );
357 
358  if( pPostIts )
359  {
360  // move still existing PostIts in the first paragraph of the table
361  InsertAttrs( std::move(*pPostIts) );
362  pPostIts.reset();
363  }
364 
365  xCntxt->SetSpansSection( true );
366 
367  // don't insert Bookmarks with same name as sections
368  if( !aPropInfo.m_aId.isEmpty() && aPropInfo.m_aId==aName )
369  aPropInfo.m_aId.clear();
370  }
371  else
372  {
373  xCntxt->SetAppendMode( AM_NOSPACE );
374  }
375 
376  if( SvxAdjust::End != eAdjust )
377  {
378  InsertAttr(&m_xAttrTab->pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST), xCntxt.get());
379  }
380 
381  // parse style
382  if( bStyleParsed )
383  InsertAttrs( aItemSet, aPropInfo, xCntxt.get(), true );
384 
385  PushContext(xCntxt);
386 }
387 
389 {
390  // search for the stack entry of the token (because we still have the div stack
391  // we don't make a difference between DIV and CENTER)
392  std::unique_ptr<HTMLAttrContext> xCntxt;
393  auto nPos = m_aContexts.size();
394  while (!xCntxt && nPos>m_nContextStMin)
395  {
396  switch( m_aContexts[--nPos]->GetToken() )
397  {
398  case HtmlTokenId::CENTER_ON:
399  case HtmlTokenId::DIVISION_ON:
400  xCntxt = std::move(m_aContexts[nPos]);
401  m_aContexts.erase( m_aContexts.begin() + nPos );
402  break;
403  default: break;
404  }
405  }
406 
407  if (xCntxt)
408  {
409  // close attribute
410  EndContext(xCntxt.get());
411  SetAttr(); // set paragraph attributes really fast because of JavaScript
412  if (xCntxt->IsHeaderOrFooter())
413  m_bReadingHeaderOrFooter = false;
414  }
415 }
416 
418  const SwPosition *pOldPos )
419 {
420  SwPageDesc *pPageDesc = m_pCSS1Parser->GetMasterPageDesc();
421  SwFrameFormat& rPageFormat = pPageDesc->GetMaster();
422 
423  SwFrameFormat *pHdFtFormat =
424  bHeader ? const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat())
425  : const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
426  OSL_ENSURE( pHdFtFormat, "No header or footer" );
427 
428  const SwFormatContent& rFlyContent = pHdFtFormat->GetContent();
429  const SwNodeIndex& rContentStIdx = *rFlyContent.GetContentIdx();
430 
431  sal_uLong nPrvNxtIdx;
432  if( bHeader )
433  {
434  nPrvNxtIdx = rContentStIdx.GetNode().EndOfSectionIndex()-1;
435  }
436  else
437  {
438  nPrvNxtIdx = pOldPos->nNode.GetIndex() - 1;
439  }
440 
441  sal_uInt16 nSpace = 0;
442  SwTextNode *pTextNode = m_xDoc->GetNodes()[nPrvNxtIdx]->GetTextNode();
443  if( pTextNode )
444  {
445  const SvxULSpaceItem& rULSpace =
446  static_cast<const SvxULSpaceItem&>(pTextNode
447  ->SwContentNode::GetAttr( RES_UL_SPACE ));
448 
449  // The bottom paragraph padding becomes the padding
450  // to header or footer
451  nSpace = rULSpace.GetLower();
452 
453  // and afterwards set to a valid value
454  const SvxULSpaceItem& rCollULSpace =
455  pTextNode->GetAnyFormatColl().GetULSpace();
456  if( rCollULSpace.GetUpper() == rULSpace.GetUpper() )
457  pTextNode->ResetAttr( RES_UL_SPACE );
458  else
459  pTextNode->SetAttr(
460  SvxULSpaceItem( rULSpace.GetUpper(),
461  rCollULSpace.GetLower(), RES_UL_SPACE ) );
462  }
463 
464  if( bHeader )
465  {
466  nPrvNxtIdx = pOldPos->nNode.GetIndex();
467  }
468  else
469  {
470  nPrvNxtIdx = rContentStIdx.GetIndex() + 1;
471  }
472 
473  pTextNode = m_xDoc->GetNodes()[nPrvNxtIdx]
474  ->GetTextNode();
475  if( pTextNode )
476  {
477  const SvxULSpaceItem& rULSpace =
478  static_cast<const SvxULSpaceItem&>(pTextNode
479  ->SwContentNode::GetAttr( RES_UL_SPACE ));
480 
481  // The top paragraph padding becomes the padding
482  // to headline or footer if it is greater then the
483  // bottom padding of the paragraph beforehand
484  if( rULSpace.GetUpper() > nSpace )
485  nSpace = rULSpace.GetUpper();
486 
487  // and afterwards set to a valid value
488  const SvxULSpaceItem& rCollULSpace =
489  pTextNode->GetAnyFormatColl().GetULSpace();
490  if( rCollULSpace.GetLower() == rULSpace.GetLower() )
491  pTextNode->ResetAttr( RES_UL_SPACE );
492  else
493  pTextNode->SetAttr(
494  SvxULSpaceItem( rCollULSpace.GetUpper(),
495  rULSpace.GetLower(), RES_UL_SPACE ) );
496  }
497 
498  SvxULSpaceItem aULSpace( RES_UL_SPACE );
499  if( bHeader )
500  aULSpace.SetLower( nSpace );
501  else
502  aULSpace.SetUpper( nSpace );
503 
504  pHdFtFormat->SetFormatAttr( aULSpace );
505 }
506 
507 bool SwHTMLParser::EndSection( bool bLFStripped )
508 {
509  SwEndNode *pEndNd = m_xDoc->GetNodes()[m_pPam->GetPoint()->nNode.GetIndex()+1]
510  ->GetEndNode();
511  if( pEndNd && pEndNd->StartOfSectionNode()->IsSectionNode() )
512  {
513  // close the section
514  if( !bLFStripped )
517  return true;
518  }
519 
520  OSL_ENSURE( false, "Wrong PaM position at end of section" );
521 
522  return false;
523 }
524 
525 bool SwHTMLParser::EndSections( bool bLFStripped )
526 {
527  bool bSectionClosed = false;
528  auto nPos = m_aContexts.size();
529  while( nPos>m_nContextStMin )
530  {
531  HTMLAttrContext *pCntxt = m_aContexts[--nPos].get();
532  if( pCntxt->GetSpansSection() && EndSection( bLFStripped ) )
533  {
534  bSectionClosed = true;
535  pCntxt->SetSpansSection( false );
536  bLFStripped = false;
537  }
538  }
539 
540  return bSectionClosed;
541 }
542 
543 void SwHTMLParser::NewMultiCol( sal_uInt16 columnsFromCss )
544 {
545  OUString aId;
546  OUString aStyle, aClass, aLang, aDir;
547  long nWidth = 100;
548  sal_uInt16 nCols = columnsFromCss, nGutter = 10;
549  bool bPrcWidth = true;
550 
551  const HTMLOptions& rHTMLOptions = GetOptions();
552  for (size_t i = rHTMLOptions.size(); i; )
553  {
554  const HTMLOption& rOption = rHTMLOptions[--i];
555  switch( rOption.GetToken() )
556  {
557  case HtmlOptionId::ID:
558  aId = rOption.GetString();
559  break;
560  case HtmlOptionId::STYLE:
561  aStyle = rOption.GetString();
562  break;
563  case HtmlOptionId::CLASS:
564  aClass = rOption.GetString();
565  break;
566  case HtmlOptionId::LANG:
567  aLang = rOption.GetString();
568  break;
569  case HtmlOptionId::DIR:
570  aDir = rOption.GetString();
571  break;
572  case HtmlOptionId::COLS:
573  nCols = static_cast<sal_uInt16>(rOption.GetNumber());
574  break;
575  case HtmlOptionId::WIDTH:
576  nWidth = rOption.GetNumber();
577  bPrcWidth = (rOption.GetString().indexOf('%') != -1);
578  if( bPrcWidth && nWidth>100 )
579  nWidth = 100;
580  break;
581  case HtmlOptionId::GUTTER:
582  nGutter = static_cast<sal_uInt16>(rOption.GetNumber());
583  break;
584  default: break;
585  }
586  }
587 
588  std::unique_ptr<HTMLAttrContext> xCntxt(new HTMLAttrContext(HtmlTokenId::MULTICOL_ON));
589 
590  //.is the multicol element contained in a container? That may be the
591  // case for 5.0 documents.
592  bool bInCntnr = false;
593  auto i = m_aContexts.size();
594  while( !bInCntnr && i > m_nContextStMin )
595  bInCntnr = nullptr != m_aContexts[--i]->GetFrameItemSet();
596 
597  // Parse style sheets, but don't position anything by now.
598  bool bStyleParsed = false;
599  SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
600  SvxCSS1PropertyInfo aPropInfo;
601  if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
602  bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
603  aItemSet, aPropInfo, &aLang, &aDir );
604 
605  // Calculate width.
606  sal_uInt8 nPrcWidth = bPrcWidth ? static_cast<sal_uInt8>(nWidth) : 0;
607  SwTwips nTwipWidth = 0;
608  if( !bPrcWidth && nWidth && Application::GetDefaultDevice() )
609  {
610  nTwipWidth = Application::GetDefaultDevice()
611  ->PixelToLogic( Size(nWidth, 0),
612  MapMode(MapUnit::MapTwip) ).Width();
613  }
614 
615  if( !nPrcWidth && nTwipWidth < MINFLY )
616  nTwipWidth = MINFLY;
617 
618  // Do positioning.
619  bool bPositioned = false;
620  if( bInCntnr || SwCSS1Parser::MayBePositioned( aPropInfo, true ) )
621  {
622  SfxItemSet aFrameItemSet( m_xDoc->GetAttrPool(),
624  if( !IsNewDoc() )
625  Reader::ResetFrameFormatAttrs(aFrameItemSet );
626 
628  aFrameItemSet );
629 
630  // The width is either the WIDTH attribute's value or contained
631  // in some style option.
632  SetVarSize( aPropInfo, aFrameItemSet, nTwipWidth, nPrcWidth );
633 
634  SetSpace( Size(0,0), aItemSet, aPropInfo, aFrameItemSet );
635 
636  // Set some other frame attributes. If the background is set, its
637  // it will be cleared here. That for, it won't be set at the section,
638  // too.
639  SetFrameFormatAttrs( aItemSet,
641  aFrameItemSet );
642 
643  // Insert fly frame. If the are columns, the fly frame's name is not
644  // the sections name but a generated one.
645  OUString aFlyName;
646  if( nCols < 2 )
647  {
648  aFlyName = aId;
649  aPropInfo.m_aId.clear();
650  }
651 
652  InsertFlyFrame(aFrameItemSet, xCntxt.get(), aFlyName);
653 
654  xCntxt->SetPopStack( true );
655  bPositioned = true;
656  }
657 
658  bool bAppended = false;
659  if( !bPositioned )
660  {
661  if( m_pPam->GetPoint()->nContent.GetIndex() )
662  {
664  bAppended = true;
665  }
666  else
667  {
668  AddParSpace();
669  }
670  }
671 
672  // If there are less then 2 columns, no section is inserted.
673  if( nCols >= 2 )
674  {
675  if( !bAppended )
676  {
677  // If the pam is at the start of a section, a additional text
678  // node must be inserted. Otherwise, the new section will be
679  // inserted in front of the old one.
680  SwNodeIndex aPrvNdIdx( m_pPam->GetPoint()->nNode, -1 );
681  if (aPrvNdIdx.GetNode().IsSectionNode())
682  {
683  AppendTextNode();
684  bAppended = true;
685  }
686  }
687  std::unique_ptr<std::deque<std::unique_ptr<HTMLAttr>>> pPostIts(bAppended ? nullptr : new std::deque<std::unique_ptr<HTMLAttr>>);
688  SetAttr( true, true, pPostIts.get() );
689 
690  // Make section name unique.
691  OUString aName( m_xDoc->GetUniqueSectionName( !aId.isEmpty() ? &aId : nullptr ) );
692  SwSectionData aSection( CONTENT_SECTION, aName );
693 
694  SfxItemSet aFrameItemSet( m_xDoc->GetAttrPool(),
696  if( !IsNewDoc() )
697  Reader::ResetFrameFormatAttrs(aFrameItemSet );
698 
699  if( nGutter && Application::GetDefaultDevice() )
700  {
701  nGutter = static_cast<sal_uInt16>(Application::GetDefaultDevice()
702  ->PixelToLogic( Size(nGutter, 0),
703  MapMode(MapUnit::MapTwip) ).Width());
704  }
705 
706  SwFormatCol aFormatCol;
707 
708  aFormatCol.Init( nCols, nGutter, USHRT_MAX );
709  aFrameItemSet.Put( aFormatCol );
710 
711  const SfxPoolItem *pItem;
712  if( SfxItemState::SET == aItemSet.GetItemState( RES_BACKGROUND, false,
713  &pItem ) )
714  {
715  aFrameItemSet.Put( *pItem );
716  aItemSet.ClearItem( RES_BACKGROUND );
717  }
718  if( SfxItemState::SET == aItemSet.GetItemState( RES_FRAMEDIR, false,
719  &pItem ) )
720  {
721  aFrameItemSet.Put( *pItem );
722  aItemSet.ClearItem( RES_FRAMEDIR );
723  }
724  m_xDoc->InsertSwSection( *m_pPam, aSection, nullptr, &aFrameItemSet, false );
725 
726  // Jump to section, if this is requested.
727  if( JumpToMarks::Region == m_eJumpTo && aName == m_sJmpMark )
728  {
729  m_bChkJumpMark = true;
731  }
732 
733  SwTextNode* pOldTextNd =
734  bAppended ? nullptr : m_pPam->GetPoint()->nNode.GetNode().GetTextNode();
735 
737 
738  // Move PageDesc and SwFormatBreak attributes of the current node
739  // to the section's first node.
740  if( pOldTextNd )
741  MovePageDescAttrs( pOldTextNd, m_pPam->GetPoint()->nNode.GetIndex(),
742  true );
743 
744  if( pPostIts )
745  {
746  // Move pending PostIts into the section.
747  InsertAttrs( std::move(*pPostIts) );
748  pPostIts.reset();
749  }
750 
751  xCntxt->SetSpansSection( true );
752 
753  // Insert a bookmark if its name differs from the section's name only.
754  if( !aPropInfo.m_aId.isEmpty() && aPropInfo.m_aId==aName )
755  aPropInfo.m_aId.clear();
756  }
757 
758  // Additional attributes must be set as hard ones.
759  if( bStyleParsed )
760  InsertAttrs( aItemSet, aPropInfo, xCntxt.get(), true );
761 
762  PushContext(xCntxt);
763 }
764 
766  HTMLAttrContext *pCntxt,
767  const OUString& rName )
768 {
769  RndStdIds eAnchorId =
770  rItemSet.Get( RES_ANCHOR ).GetAnchorId();
771 
772  // create frame
773  SwFlyFrameFormat* pFlyFormat = m_xDoc->MakeFlySection( eAnchorId, m_pPam->GetPoint(),
774  &rItemSet );
775  if( !rName.isEmpty() )
776  pFlyFormat->SetName( rName );
777 
778  RegisterFlyFrame( pFlyFormat );
779 
780  const SwFormatContent& rFlyContent = pFlyFormat->GetContent();
781  const SwNodeIndex& rFlyCntIdx = *rFlyContent.GetContentIdx();
782  SwContentNode *pCNd = m_xDoc->GetNodes()[rFlyCntIdx.GetIndex()+1]
783  ->GetContentNode();
784 
785  SwPosition aNewPos( SwNodeIndex( rFlyCntIdx, 1 ), SwIndex( pCNd, 0 ) );
787  SaveDocContext( pCntxt, nFlags, &aNewPos );
788 }
789 
791  sal_uLong nDestIdx,
792  bool bFormatBreak )
793 {
794  SwContentNode* pDestContentNd =
795  m_xDoc->GetNodes()[nDestIdx]->GetContentNode();
796 
797  OSL_ENSURE( pDestContentNd, "Why is the target not a Content-Node?" );
798 
799  if( pSrcNd->IsContentNode() )
800  {
801  SwContentNode* pSrcContentNd = pSrcNd->GetContentNode();
802 
803  const SfxPoolItem* pItem;
804  if( SfxItemState::SET == pSrcContentNd->GetSwAttrSet()
805  .GetItemState( RES_PAGEDESC, false, &pItem ) &&
806  static_cast<const SwFormatPageDesc *>(pItem)->GetPageDesc() )
807  {
808  pDestContentNd->SetAttr( *pItem );
809  pSrcContentNd->ResetAttr( RES_PAGEDESC );
810  }
811  if( SfxItemState::SET == pSrcContentNd->GetSwAttrSet()
812  .GetItemState( RES_BREAK, false, &pItem ) )
813  {
814  switch( static_cast<const SvxFormatBreakItem *>(pItem)->GetBreak() )
815  {
816  case SvxBreak::PageBefore:
817  case SvxBreak::PageAfter:
818  case SvxBreak::PageBoth:
819  if( bFormatBreak )
820  pDestContentNd->SetAttr( *pItem );
821  pSrcContentNd->ResetAttr( RES_BREAK );
822  break;
823  default:
824  break;
825  }
826  }
827  }
828  else if( pSrcNd->IsTableNode() )
829  {
830  SwFrameFormat *pFrameFormat = pSrcNd->GetTableNode()->GetTable().GetFrameFormat();
831 
832  const SfxPoolItem* pItem;
833  if( SfxItemState::SET == pFrameFormat->GetAttrSet().
834  GetItemState( RES_PAGEDESC, false, &pItem ) )
835  {
836  if (pDestContentNd)
837  pDestContentNd->SetAttr(*pItem);
838  pFrameFormat->ResetFormatAttr( RES_PAGEDESC );
839  }
840  }
841 }
842 
843 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Starts a section of nodes in the document model.
Definition: node.hxx:303
bool EndSection(bool bLFStripped=false)
Definition: htmlsect.cxx:507
static void SetSpace(const Size &rPixSpace, SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo, SfxItemSet &rFlyItemSet)
Definition: htmlplug.cxx:245
void SetAnchorAndAdjustment(sal_Int16 eVertOri, sal_Int16 eHoriOri, const SvxCSS1PropertyInfo &rPropInfo, SfxItemSet &rFrameSet)
Definition: htmlgrin.cxx:153
EnumT GetEnum(const HTMLOptionEnum< EnumT > *pOptEnums, EnumT nDflt=static_cast< EnumT >(0)) const
HtmlOptionId GetToken() const
Marks a position in the document model.
Definition: pam.hxx:35
void SetAttr(bool bChkEnd=true, bool bBeforeTable=false, std::deque< std::unique_ptr< HTMLAttr >> *pPostIts=nullptr)
Definition: swhtml.hxx:486
bool IsSectionNode() const
Definition: node.hxx:644
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
sal_uInt16 GetLower() const
SAL_DLLPRIVATE void SetProtectFlag(bool const bFlag)
Definition: section.hxx:106
void FixHeaderFooterDistance(bool bHeader, const SwPosition *pOldPos)
Definition: htmlsect.cxx:417
void SetLinkFileName(OUString const &rNew)
Definition: section.hxx:118
const SwFormatHeader & GetHeader(bool=true) const
Definition: fmthdft.hxx:97
virtual bool SetAttr(const SfxPoolItem &) override
overriding to handle change of certain paragraph attributes
Definition: ndtxt.cxx:4890
SwNodeIndex nNode
Definition: pam.hxx:37
#define MINFLY
Definition: swtypes.hxx:65
sal_uIntPtr sal_uLong
#define RES_FRAMEDIR
Definition: hintids.hxx:225
const SwPosition * GetMark() const
Definition: pam.hxx:209
const sal_Unicode cTokenSeparator
#define RES_FRMATR_END
Definition: hintids.hxx:236
const OUString & GetString() const
JumpToMarks m_eJumpTo
Definition: swhtml.hxx:408
HTMLAttrContexts m_aContexts
Definition: swhtml.hxx:363
SwNode & GetNode() const
Definition: ndindex.hxx:118
long SwTwips
Definition: swtypes.hxx:49
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
OUString m_sBaseURL
Definition: swhtml.hxx:341
bool m_bReadingHeaderOrFooter
Definition: swhtml.hxx:454
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
static OutputDevice * GetDefaultDevice()
void NewDivision(HtmlTokenId nToken)
Definition: htmlsect.cxx:59
sal_uInt16 sal_Unicode
static void ResetFrameFormatAttrs(SfxItemSet &rFrameSet)
Definition: shellio.cxx:625
SwTableNode * GetTableNode()
Definition: node.hxx:599
SwIndex nContent
Definition: pam.hxx:38
void InsertAttrs(std::deque< std::unique_ptr< HTMLAttr >> rAttrs)
Definition: swhtml.cxx:3425
bool ParseStyleOptions(const OUString &rStyle, const OUString &rId, const OUString &rClass, SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo, const OUString *pLang=nullptr, const OUString *pDir=nullptr)
Definition: htmlcss1.cxx:1845
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2464
static void SetVarSize(SvxCSS1PropertyInfo const &rPropInfo, SfxItemSet &rFlyItemSet, SwTwips nDfltWidth=MINLAY, sal_uInt8 nDltPrcWidth=0)
Definition: htmlcss1.cxx:2029
HtmlContextFlags
Definition: swhtml.hxx:304
#define RES_UL_SPACE
Definition: hintids.hxx:197
void MovePageDescAttrs(SwNode *pSrcNd, sal_uLong nDestIdx, bool bFormatBreak)
Definition: htmlsect.cxx:790
const SwTable & GetTable() const
Definition: node.hxx:497
SwPaM * m_pPam
Definition: swhtml.hxx:377
bool CreateContainer(const OUString &rClass, SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo, HTMLAttrContext *pContext)
Definition: htmlctxt.cxx:506
void EndDivision()
Definition: htmlsect.cxx:388
const sal_Unicode cDelim
#define OOO_STRING_SVTOOLS_HTML_sdfootnote
void SetLower(const sal_uInt16 nL, const sal_uInt16 nProp=100)
void InsertAttr(const SfxPoolItem &rItem, bool bInsAtStart)
Definition: swhtml.cxx:3416
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:716
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0)
Definition: node.cxx:1583
#define RES_BACKGROUND
Definition: hintids.hxx:210
OUString m_sJmpMark
Definition: swhtml.hxx:352
static bool HasStyleOptions(const OUString &rStyle, const OUString &rId, const OUString &rClass, const OUString *pLang=nullptr, const OUString *pDir=nullptr)
Definition: swhtml.hxx:991
static void SetFrameFormatAttrs(SfxItemSet &rItemSet, HtmlFrameFormatFlags nFlags, SfxItemSet &rFrameItemSet)
Definition: htmlcss1.cxx:2068
bool IsContentNode() const
Definition: node.hxx:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwNodeIndex * GetFootEndNoteSection(const OUString &rName)
Definition: htmlftn.cxx:220
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:483
Style of a layout element.
Definition: frmfmt.hxx:57
#define RES_ANCHOR
Definition: hintids.hxx:209
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
SvxAdjust
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwFrameFormat * GetFooterFormat() const
Definition: fmthdft.hxx:85
const SwPosition * GetPoint() const
Definition: pam.hxx:207
Text body.
Definition: poolfmt.hxx:251
int i
std::unique_ptr< SwCSS1Parser > m_pCSS1Parser
Definition: swhtml.hxx:372
SwContentNode * GetContentNode()
Definition: node.hxx:615
void AddParSpace()
Definition: swhtml.cxx:2449
void EndContext(HTMLAttrContext *pContext)
Definition: htmlctxt.cxx:372
Marks a character position inside a document model node.
Definition: index.hxx:37
const SwFormatFooter & GetFooter(bool=true) const
Definition: fmthdft.hxx:99
void StripTrailingPara()
Definition: htmlgrin.cxx:1403
bool DoPositioning(SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo, HTMLAttrContext *pContext)
Definition: htmlctxt.cxx:468
void SetSpansSection(bool bSet)
Definition: swhtml.hxx:265
Marks a node in the document model.
Definition: ndindex.hxx:31
void RegisterFlyFrame(SwFrameFormat *pFlyFrame)
Definition: htmlgrin.cxx:280
void InsertFlyFrame(const SfxItemSet &rItemSet, HTMLAttrContext *pCntxt, const OUString &rId)
Definition: htmlsect.cxx:765
sal_uInt32 GetNumber() const
size_t m_nContextStMin
Definition: swhtml.hxx:402
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
void NewMultiCol(sal_uInt16 columnsFromCss=0)
Definition: htmlsect.cxx:543
HtmlTokenId
Point PixelToLogic(const Point &rDevicePt) const
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:460
void ClearFootnotesMarksInRange(const SwNodeIndex &rSttIdx, const SwNodeIndex &rEndIdx)
Definition: htmltab.cxx:4914
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:216
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
bool PendingObjectsInPaM(SwPaM &rPam) const
Definition: htmltab.cxx:5289
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
virtual bool ResetFormatAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0)
Definition: format.cxx:652
bool EndSections(bool bLFStripped)
Definition: htmlsect.cxx:525
virtual bool SetAttr(const SfxPoolItem &)
made virtual
Definition: node.cxx:1471
HTMLOptionEnum< SvxAdjust > const aHTMLPAlignTable[]
Definition: swhtml.cxx:143
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
#define OOO_STRING_SVTOOLS_HTML_sdendnote
unsigned char sal_uInt8
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:261
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
::std::vector< HTMLOption > HTMLOptions
sal_Int32 GetIndex() const
Definition: index.hxx:95
#define RES_PARATR_ADJUST
Definition: hintids.hxx:162
Header, for PageFormats Client of FrameFormat describing the header.
Definition: fmthdft.hxx:33
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
OString const aName
RndStdIds
bool IsTableNode() const
Definition: node.hxx:640
Ends a section of nodes in the document model.
Definition: node.hxx:333
std::shared_ptr< HTMLAttrTable > m_xAttrTab
Definition: swhtml.hxx:362
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:457
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
bool AppendTextNode(SwHTMLAppendMode eMode=AM_NORMAL, bool bUpdateNum=true)
Definition: swhtml.cxx:2146
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0) override
Definition: ndtxt.cxx:5120
void Init(sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct)
This function allows to (repeatedly) initialize the columns.
Definition: atrfrm.cxx:947
#define RES_PAGEDESC
Definition: hintids.hxx:198
#define RES_BREAK
Definition: hintids.hxx:199
void PushContext(std::unique_ptr< HTMLAttrContext > &rCntxt)
Definition: swhtml.hxx:550
bool m_bChkJumpMark
Definition: swhtml.hxx:442
void SetUpper(const sal_uInt16 nU, const sal_uInt16 nProp=100)
sal_Int32 nPos
rtl::Reference< SwDoc > m_xDoc
Definition: swhtml.hxx:376
#define RES_FRMATR_BEGIN
Definition: hintids.hxx:192
void SaveDocContext(HTMLAttrContext *pCntxt, HtmlContextFlags nFlags, const SwPosition *pNewPos)
Definition: htmlctxt.cxx:273
bool GetSpansSection() const
Definition: swhtml.hxx:266
const SwFrameFormat * GetHeaderFormat() const
Definition: fmthdft.hxx:54
static bool MayBePositioned(const SvxCSS1PropertyInfo &rPropInfo, bool bAutoWidth=false)
Definition: htmlcss1.cxx:1420
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
sal_uInt16 GetUpper() const
SVL_DLLPUBLIC OUString SmartRel2Abs(INetURLObject const &rTheBaseURIRef, OUString const &rTheRelURIRef, Link< OUString *, bool > const &rMaybeFileHdl=Link< OUString *, bool >(), bool bCheckFileExists=true, bool bIgnoreFragment=false, INetURLObject::EncodeMechanism eEncodeMechanism=INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
Base class of the Writer document model elements.
Definition: node.hxx:79