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