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