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