LibreOffice Module sw (master)  1
content.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 <comphelper/string.hxx>
21 #include <svl/urlbmk.hxx>
22 #include <osl/thread.h>
23 #include <sal/log.hxx>
24 #include <tools/urlobj.hxx>
25 #include <sfx2/docfile.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <sfx2/event.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <o3tl/enumrange.hxx>
30 #include <o3tl/sorted_vector.hxx>
31 #include <vcl/commandevent.hxx>
32 #include <vcl/help.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/weldutils.hxx>
35 #include <sot/formats.hxx>
36 #include <uiitems.hxx>
37 #include <fmtinfmt.hxx>
38 #include <txtinet.hxx>
39 #include <fmtfld.hxx>
40 #include <swmodule.hxx>
41 #include <wrtsh.hxx>
42 #include <view.hxx>
43 #include <docsh.hxx>
44 #include <drawdoc.hxx>
45 #include <content.hxx>
46 #include <frmfmt.hxx>
47 #include <fldbas.hxx>
48 #include <IMark.hxx>
49 #include <section.hxx>
50 #include <tox.hxx>
51 #include <navipi.hxx>
52 #include <navicont.hxx>
53 #include <navicfg.hxx>
54 #include <edtwin.hxx>
55 #include <doc.hxx>
59 #include <unotxvw.hxx>
60 #include <cmdid.h>
61 #include <helpids.h>
62 #include <strings.hrc>
63 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
64 #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
65 #include <com/sun/star/text/XTextTablesSupplier.hpp>
66 #include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
67 #include <com/sun/star/text/XDocumentIndex.hpp>
68 #include <com/sun/star/text/XBookmarksSupplier.hpp>
69 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
70 #include <com/sun/star/text/XTextFramesSupplier.hpp>
71 #include <dcontact.hxx>
72 #include <svx/svdpage.hxx>
73 #include <svx/svdview.hxx>
74 #include <SwRewriter.hxx>
75 #include <hints.hxx>
76 #include <numrule.hxx>
77 #include <swundo.hxx>
78 #include <ndtxt.hxx>
79 #include <PostItMgr.hxx>
80 #include <postithelper.hxx>
81 
82 #include <swabstdlg.hxx>
83 #include <bitmaps.hlst>
84 
85 #include <navmgr.hxx>
86 #include <AnnotationWin.hxx>
87 #include <memory>
88 
89 #include <fmtcntnt.hxx>
90 #include <docstat.hxx>
91 
92 #include <viewopt.hxx>
93 
94 #define CTYPE_CNT 0
95 #define CTYPE_CTT 1
96 
97 using namespace ::std;
98 using namespace ::com::sun::star;
99 using namespace ::com::sun::star::text;
100 using namespace ::com::sun::star::uno;
101 using namespace ::com::sun::star::container;
102 
103 namespace {
104 
105 constexpr char NAVI_BOOKMARK_DELIM = '\x01';
106 
107 }
108 
110  : public o3tl::sorted_vector<std::unique_ptr<SwContent>, o3tl::less_uniqueptr_to<SwContent>,
111  o3tl::find_partialorder_ptrequals>
112 {
113 };
114 
115 namespace
116 {
117  bool lcl_IsContent(const weld::TreeIter& rEntry, const weld::TreeView& rTreeView)
118  {
119  return reinterpret_cast<const SwTypeNumber*>(rTreeView.get_id(rEntry).toInt64())->GetTypeId() == CTYPE_CNT;
120  }
121 
122  bool lcl_IsContentType(const weld::TreeIter& rEntry, const weld::TreeView& rTreeView)
123  {
124  return reinterpret_cast<const SwTypeNumber*>(rTreeView.get_id(rEntry).toInt64())->GetTypeId() == CTYPE_CTT;
125  }
126 
127  bool lcl_FindShell(SwWrtShell const * pShell)
128  {
129  bool bFound = false;
130  SwView *pView = SwModule::GetFirstView();
131  while (pView)
132  {
133  if(pShell == &pView->GetWrtShell())
134  {
135  bFound = true;
136  break;
137  }
138  pView = SwModule::GetNextView(pView);
139  }
140  return bFound;
141  }
142 
143  bool lcl_IsUiVisibleBookmark(const ::sw::mark::IMark* pMark)
144  {
146  }
147 
148  size_t lcl_InsertURLFieldContent(
149  SwContentArr *pMember,
150  SwWrtShell* pWrtShell,
151  const SwContentType *pCntType)
152  {
154  pWrtShell->GetINetAttrs( aArr );
155  const SwGetINetAttrs::size_type nCount {aArr.size()};
156  for( SwGetINetAttrs::size_type n = 0; n < nCount; ++n )
157  {
158  SwGetINetAttr* p = &aArr[ n ];
159  std::unique_ptr<SwURLFieldContent> pCnt(new SwURLFieldContent(
160  pCntType,
161  p->sText,
165  &p->rINetAttr,
166  n ));
167  pMember->insert( std::move(pCnt) );
168  }
169  return nCount;
170  }
171 }
172 
173 // Content, contains names and reference at the content type.
174 
175 SwContent::SwContent(const SwContentType* pCnt, const OUString& rName, long nYPos) :
177  pParent(pCnt),
178  sContentName(rName),
179  nYPosition(nYPos),
180  bInvisible(false)
181 {
182 }
183 
184 
186 {
187 }
188 
190 {
191  return false;
192 }
193 
195 {
196  return pField->IsProtect();
197 }
198 
200 {
201  return pINetAttr->IsProtect();
202 }
203 
205 {
206 }
207 
209 {
210 }
211 
212 static const char* STR_CONTENT_TYPE_ARY[] =
213 {
214  STR_CONTENT_TYPE_OUTLINE,
215  STR_CONTENT_TYPE_TABLE,
216  STR_CONTENT_TYPE_FRAME,
217  STR_CONTENT_TYPE_GRAPHIC,
218  STR_CONTENT_TYPE_OLE,
219  STR_CONTENT_TYPE_BOOKMARK,
220  STR_CONTENT_TYPE_REGION,
221  STR_CONTENT_TYPE_URLFIELD,
222  STR_CONTENT_TYPE_REFERENCE,
223  STR_CONTENT_TYPE_INDEX,
224  STR_CONTENT_TYPE_POSTIT,
225  STR_CONTENT_TYPE_DRAWOBJECT
226 };
227 
228 static const char* STR_CONTENT_TYPE_SINGLE_ARY[] =
229 {
230  STR_CONTENT_TYPE_SINGLE_OUTLINE,
231  STR_CONTENT_TYPE_SINGLE_TABLE,
232  STR_CONTENT_TYPE_SINGLE_FRAME,
233  STR_CONTENT_TYPE_SINGLE_GRAPHIC,
234  STR_CONTENT_TYPE_SINGLE_OLE,
235  STR_CONTENT_TYPE_SINGLE_BOOKMARK,
236  STR_CONTENT_TYPE_SINGLE_REGION,
237  STR_CONTENT_TYPE_SINGLE_URLFIELD,
238  STR_CONTENT_TYPE_SINGLE_REFERENCE,
239  STR_CONTENT_TYPE_SINGLE_INDEX,
240  STR_CONTENT_TYPE_SINGLE_POSTIT,
241  STR_CONTENT_TYPE_SINGLE_DRAWOBJECT
242 };
243 
244 namespace
245 {
246  bool checkVisibilityChanged(
247  const SwContentArr& rSwContentArrA,
248  const SwContentArr& rSwContentArrB)
249  {
250  if(rSwContentArrA.size() != rSwContentArrB.size())
251  {
252  return true;
253  }
254 
255  for(size_t a(0); a < rSwContentArrA.size(); a++)
256  {
257  if(rSwContentArrA[a]->IsInvisible() != rSwContentArrB[a]->IsInvisible())
258  {
259  return true;
260  }
261  }
262 
263  return false;
264  }
265 } // end of anonymous namespace
266 
269  m_pWrtShell(pShell),
270  m_sContentTypeName(SwResId(STR_CONTENT_TYPE_ARY[static_cast<int>(nType)])),
271  m_sSingleContentTypeName(SwResId(STR_CONTENT_TYPE_SINGLE_ARY[static_cast<int>(nType)])),
272  m_nMemberCount(0),
273  m_nContentType(nType),
274  m_nOutlineLevel(nLevel),
275  m_bDataValid(false),
276  m_bEdit(false),
277  m_bDelete(true)
278 {
279  Init();
280 }
281 
282 void SwContentType::Init(bool* pbInvalidateWindow)
283 {
284  // if the MemberCount is changing ...
285  size_t nOldMemberCount = m_nMemberCount;
286  m_nMemberCount = 0;
287  switch(m_nContentType)
288  {
290  {
291  m_sTypeToken = "outline";
293  if (m_nMemberCount < MAXLEVEL)
294  {
295  const size_t nOutlineCount = m_nMemberCount;
296  for(size_t j = 0; j < nOutlineCount; ++j)
297  {
300  {
301  m_nMemberCount --;
302  }
303  }
304  }
305  }
306  break;
307 
308  case ContentTypeId::TABLE :
309  m_sTypeToken = "table";
311  m_bEdit = true;
312  break;
313 
314  case ContentTypeId::FRAME :
316  case ContentTypeId::OLE :
317  {
319  m_sTypeToken = "frame";
321  {
322  eType = FLYCNTTYPE_OLE;
323  m_sTypeToken = "ole";
324  }
326  {
327  eType = FLYCNTTYPE_GRF;
328  m_sTypeToken = "graphic";
329  }
330  m_nMemberCount = m_pWrtShell->GetFlyCount(eType, /*bIgnoreTextBoxes=*/true);
331  m_bEdit = true;
332  }
333  break;
335  {
337  m_nMemberCount = count_if(
338  pMarkAccess->getBookmarksBegin(),
339  pMarkAccess->getBookmarksEnd(),
340  &lcl_IsUiVisibleBookmark);
341  m_sTypeToken.clear();
343  m_bEdit = !bProtectedBM;
344  m_bDelete = !bProtectedBM;
345  }
346  break;
347  case ContentTypeId::REGION :
348  {
349  std::unique_ptr<SwContentArr> pOldMember;
350  if(!m_pMember)
351  m_pMember.reset( new SwContentArr );
352  else if(!m_pMember->empty())
353  {
354  pOldMember = std::move(m_pMember);
355  m_pMember.reset( new SwContentArr );
356  }
357  const Point aNullPt;
359  for(size_t i = 0; i < m_nMemberCount; ++i)
360  {
361  const SwSectionFormat* pFormat;
362  SectionType eTmpType;
363  if( (pFormat = &m_pWrtShell->GetSectionFormat(i))->IsInNodesArr() &&
364  (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
365  && SectionType::ToxHeader != eTmpType )
366  {
367  const OUString& rSectionName =
368  pFormat->GetSection()->GetSectionName();
369  sal_uInt8 nLevel = 0;
370  SwSectionFormat* pParentFormat = pFormat->GetParent();
371  while(pParentFormat)
372  {
373  nLevel++;
374  pParentFormat = pParentFormat->GetParent();
375  }
376 
377  std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, rSectionName,
378  nLevel,
379  pFormat->FindLayoutRect( false, &aNullPt ).Top()));
380 
381  SwPtrMsgPoolItem aAskItem( RES_CONTENT_VISIBLE, nullptr );
382  if( !pFormat->GetInfo( aAskItem ) &&
383  !aAskItem.pObject ) // not visible
384  pCnt->SetInvisible();
385  m_pMember->insert(std::move(pCnt));
386  }
387  }
388  m_nMemberCount = m_pMember->size();
389  m_sTypeToken = "region";
390  m_bEdit = true;
391  m_bDelete = false;
392  if(pOldMember)
393  {
394  if(nullptr != pbInvalidateWindow)
395  {
396  // need to check visibility (and equal entry number) after
397  // creation due to a sorted list being used here (before,
398  // entries with same index were compared already at creation
399  // time what worked before a sorted list was used)
400  *pbInvalidateWindow = checkVisibilityChanged(
401  *pOldMember,
402  *m_pMember);
403  }
404  }
405  }
406  break;
408  {
410  m_bEdit = true;
411  m_bDelete = false;
412  }
413  break;
415  {
417  m_bDelete = false;
418  }
419  break;
421  {
422  m_nMemberCount = 0;
423  if(!m_pMember)
424  m_pMember.reset( new SwContentArr );
425  else
426  m_pMember->clear();
427 
428  m_nMemberCount = lcl_InsertURLFieldContent(m_pMember.get(), m_pWrtShell, this);
429 
430  m_bEdit = true;
431  nOldMemberCount = m_nMemberCount;
432  m_bDelete = true;
433  }
434  break;
436  {
437  m_nMemberCount = 0;
438  if(!m_pMember)
439  m_pMember.reset( new SwContentArr );
440  else
441  m_pMember->clear();
442 
444  if (aMgr)
445  {
446  for(SwPostItMgr::const_iterator i = aMgr->begin(); i != aMgr->end(); ++i)
447  {
448  if (const SwFormatField* pFormatField = dynamic_cast<const SwFormatField *>((*i)->GetBroadcaster())) // SwPostit
449  {
450  if (pFormatField->GetTextField() && pFormatField->IsFieldInDoc() &&
451  (*i)->mLayoutStatus!=SwPostItHelper::INVISIBLE )
452  {
453  OUString sEntry = pFormatField->GetField()->GetPar2();
454  sEntry = RemoveNewline(sEntry);
455  std::unique_ptr<SwPostItContent> pCnt(new SwPostItContent(
456  this,
457  sEntry,
458  pFormatField,
459  m_nMemberCount));
460  m_pMember->insert(std::move(pCnt));
461  m_nMemberCount++;
462  }
463  }
464  }
465  }
466  m_sTypeToken.clear();
467  m_bEdit = true;
468  nOldMemberCount = m_nMemberCount;
469  }
470  break;
472  {
473  m_sTypeToken.clear();
474  m_bEdit = true;
475  m_nMemberCount = 0;
477  if(pModel)
478  {
479  SdrPage* pPage = pModel->GetPage(0);
480  const size_t nCount = pPage->GetObjCount();
481  for( size_t i=0; i<nCount; ++i )
482  {
483  SdrObject* pTemp = pPage->GetObj(i);
484  // #i51726# - all drawing objects can be named now
485  if (!pTemp->GetName().isEmpty())
486  m_nMemberCount++;
487  }
488  }
489  }
490  break;
491  default: break;
492  }
493  // ... then, the data can also no longer be valid,
494  // apart from those which have already been corrected,
495  // then nOldMemberCount is nevertheless not so old.
496  if( nOldMemberCount != m_nMemberCount )
497  m_bDataValid = false;
498 }
499 
501 {
502 }
503 
504 const SwContent* SwContentType::GetMember(size_t nIndex)
505 {
506  if(!m_bDataValid || !m_pMember)
507  {
508  FillMemberList();
509  }
510  if(nIndex < m_pMember->size())
511  return (*m_pMember)[nIndex].get();
512 
513  return nullptr;
514 }
515 
517 {
518  m_bDataValid = false;
519 }
520 
521 void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged)
522 {
523  std::unique_ptr<SwContentArr> pOldMember;
524  size_t nOldMemberCount = 0;
525  SwPtrMsgPoolItem aAskItem( RES_CONTENT_VISIBLE, nullptr );
526  if(m_pMember && pbLevelOrVisibilityChanged)
527  {
528  pOldMember = std::move(m_pMember);
529  nOldMemberCount = pOldMember->size();
530  m_pMember.reset( new SwContentArr );
531  *pbLevelOrVisibilityChanged = false;
532  }
533  else if(!m_pMember)
534  m_pMember.reset( new SwContentArr );
535  else
536  m_pMember->clear();
537  switch(m_nContentType)
538  {
540  {
541  const size_t nOutlineCount = m_nMemberCount =
543 
544  size_t nPos = 0;
545  for (size_t i = 0; i < nOutlineCount; ++i)
546  {
548  if(nLevel >= m_nOutlineLevel )
549  m_nMemberCount--;
550  else
551  {
553  {
554  --m_nMemberCount;
555  continue; // don't hide it, just skip it
556  }
557  OUString aEntry(comphelper::string::stripStart(
559  aEntry = SwNavigationPI::CleanEntry(aEntry);
560  std::unique_ptr<SwOutlineContent> pCnt(new SwOutlineContent(this, aEntry, i, nLevel,
561  m_pWrtShell->IsOutlineMovable( i ), nPos ));
562  m_pMember->insert(std::move(pCnt));
563  // with the same number and existing "pOldMember" the
564  // old one is compared with the new OutlinePos.
565  if (nOldMemberCount > nPos && static_cast<SwOutlineContent*>((*pOldMember)[nPos].get())->GetOutlineLevel() != nLevel)
566  *pbLevelOrVisibilityChanged = true;
567 
568  nPos++;
569  }
570  }
571 
572  }
573  break;
574 
575  case ContentTypeId::TABLE :
576  {
577  const size_t nCount = m_pWrtShell->GetTableFrameFormatCount(true);
578  OSL_ENSURE(m_nMemberCount == nCount, "MemberCount differs");
579  Point aNullPt;
580  m_nMemberCount = nCount;
581  for(size_t i = 0; i < m_nMemberCount; ++i)
582  {
583  const SwFrameFormat& rTableFormat = m_pWrtShell->GetTableFrameFormat(i, true);
584  const OUString& sTableName( rTableFormat.GetName() );
585 
586  SwContent* pCnt = new SwContent(this, sTableName,
587  rTableFormat.FindLayoutRect(false, &aNullPt).Top() );
588  if( !rTableFormat.GetInfo( aAskItem ) &&
589  !aAskItem.pObject ) // not visible
590  pCnt->SetInvisible();
591 
592  m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
593 
594  if(nOldMemberCount > i &&
595  (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible())
596  *pbLevelOrVisibilityChanged = true;
597  }
598  }
599  break;
600  case ContentTypeId::OLE :
601  case ContentTypeId::FRAME :
603  {
606  eType = FLYCNTTYPE_OLE;
608  eType = FLYCNTTYPE_GRF;
609  Point aNullPt;
610  m_nMemberCount = m_pWrtShell->GetFlyCount(eType, /*bIgnoreTextBoxes=*/true);
611  std::vector<SwFrameFormat const*> formats(m_pWrtShell->GetFlyFrameFormats(eType, /*bIgnoreTextBoxes=*/true));
612  SAL_WARN_IF(m_nMemberCount != formats.size(), "sw.ui", "MemberCount differs");
613  m_nMemberCount = formats.size();
614  for (size_t i = 0; i < m_nMemberCount; ++i)
615  {
616  SwFrameFormat const*const pFrameFormat = formats[i];
617  const OUString sFrameName = pFrameFormat->GetName();
618 
619  SwContent* pCnt;
621  {
622  OUString sLink;
623  m_pWrtShell->GetGrfNms( &sLink, nullptr, static_cast<const SwFlyFrameFormat*>( pFrameFormat));
624  pCnt = new SwGraphicContent(this, sFrameName,
625  INetURLObject::decode( sLink,
627  pFrameFormat->FindLayoutRect(false, &aNullPt).Top());
628  }
629  else
630  {
631  pCnt = new SwContent(this, sFrameName,
632  pFrameFormat->FindLayoutRect(false, &aNullPt).Top() );
633  }
634  if( !pFrameFormat->GetInfo( aAskItem ) &&
635  !aAskItem.pObject ) // not visible
636  pCnt->SetInvisible();
637  m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
638  if (nOldMemberCount > i &&
639  (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible())
640  *pbLevelOrVisibilityChanged = true;
641  }
642  }
643  break;
645  {
647  for(IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
648  ppBookmark != pMarkAccess->getBookmarksEnd();
649  ++ppBookmark)
650  {
651  if(lcl_IsUiVisibleBookmark(*ppBookmark))
652  {
653  const OUString& rBkmName = (*ppBookmark)->GetName();
654  //nYPos from 0 -> text::Bookmarks will be sorted alphabetically
655  std::unique_ptr<SwContent> pCnt(new SwContent(this, rBkmName, 0));
656  m_pMember->insert(std::move(pCnt));
657  }
658  }
659  }
660  break;
661  case ContentTypeId::REGION :
662  {
663  const Point aNullPt;
665  for(size_t i = 0; i < m_nMemberCount; ++i)
666  {
667  const SwSectionFormat* pFormat;
668  SectionType eTmpType;
669  if( (pFormat = &m_pWrtShell->GetSectionFormat(i))->IsInNodesArr() &&
670  (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
671  && SectionType::ToxHeader != eTmpType )
672  {
673  OUString sSectionName = pFormat->GetSection()->GetSectionName();
674 
675  sal_uInt8 nLevel = 0;
676  SwSectionFormat* pParentFormat = pFormat->GetParent();
677  while(pParentFormat)
678  {
679  nLevel++;
680  pParentFormat = pParentFormat->GetParent();
681  }
682 
683  std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, sSectionName,
684  nLevel,
685  pFormat->FindLayoutRect( false, &aNullPt ).Top()));
686  if( !pFormat->GetInfo( aAskItem ) &&
687  !aAskItem.pObject ) // not visible
688  pCnt->SetInvisible();
689  m_pMember->insert(std::move(pCnt));
690  }
691 
692  if(nullptr != pbLevelOrVisibilityChanged)
693  {
694  assert(pOldMember);
695  // need to check visibility (and equal entry number) after
696  // creation due to a sorted list being used here (before,
697  // entries with same index were compared already at creation
698  // time what worked before a sorted list was used)
699  *pbLevelOrVisibilityChanged = checkVisibilityChanged(
700  *pOldMember,
701  *m_pMember);
702  }
703  }
704  m_nMemberCount = m_pMember->size();
705  }
706  break;
708  {
709  std::vector<OUString> aRefMarks;
710  m_nMemberCount = m_pWrtShell->GetRefMarks( &aRefMarks );
711 
712  for (const auto& rRefMark : aRefMarks)
713  {
714  // References sorted alphabetically
715  m_pMember->insert(std::make_unique<SwContent>(this, rRefMark, 0));
716  }
717  }
718  break;
720  m_nMemberCount = lcl_InsertURLFieldContent(m_pMember.get(), m_pWrtShell, this);
721  break;
723  {
724 
725  const sal_uInt16 nCount = m_pWrtShell->GetTOXCount();
726  m_nMemberCount = nCount;
727  for ( sal_uInt16 nTox = 0; nTox < nCount; nTox++ )
728  {
729  const SwTOXBase* pBase = m_pWrtShell->GetTOX( nTox );
730  OUString sTOXNm( pBase->GetTOXName() );
731 
732  SwContent* pCnt = new SwTOXBaseContent(
733  this, sTOXNm, nTox, *pBase);
734 
735  if(pBase && !pBase->IsVisible())
736  pCnt->SetInvisible();
737 
738  m_pMember->insert( std::unique_ptr<SwContent>(pCnt) );
739  const size_t nPos = m_pMember->size() - 1;
740  if(nOldMemberCount > nPos &&
741  (*pOldMember)[nPos]->IsInvisible()
742  != pCnt->IsInvisible())
743  *pbLevelOrVisibilityChanged = true;
744  }
745  }
746  break;
748  {
749  m_nMemberCount = 0;
750  m_pMember->clear();
752  if (aMgr)
753  {
754  for(SwPostItMgr::const_iterator i = aMgr->begin(); i != aMgr->end(); ++i)
755  {
756  if (const SwFormatField* pFormatField = dynamic_cast<const SwFormatField *>((*i)->GetBroadcaster())) // SwPostit
757  {
758  if (pFormatField->GetTextField() && pFormatField->IsFieldInDoc() &&
759  (*i)->mLayoutStatus!=SwPostItHelper::INVISIBLE )
760  {
761  OUString sEntry = pFormatField->GetField()->GetPar2();
762  sEntry = RemoveNewline(sEntry);
763  std::unique_ptr<SwPostItContent> pCnt(new SwPostItContent(
764  this,
765  sEntry,
766  pFormatField,
767  m_nMemberCount));
768  m_pMember->insert(std::move(pCnt));
769  m_nMemberCount++;
770  }
771  }
772  }
773  }
774  }
775  break;
777  {
778  m_nMemberCount = 0;
779  m_pMember->clear();
780 
782  SwDrawModel* pModel = rIDDMA.GetDrawModel();
783  if(pModel)
784  {
785  SdrPage* pPage = pModel->GetPage(0);
786  const size_t nCount = pPage->GetObjCount();
787  for( size_t i=0; i<nCount; ++i )
788  {
789  SdrObject* pTemp = pPage->GetObj(i);
790  // #i51726# - all drawing objects can be named now
791  if (!pTemp->GetName().isEmpty())
792  {
793  SwContact* pContact = static_cast<SwContact*>(pTemp->GetUserCall());
794  long nYPos = 0;
795  const Point aNullPt;
796  if(pContact && pContact->GetFormat())
797  nYPos = pContact->GetFormat()->FindLayoutRect(false, &aNullPt).Top();
798  SwContent* pCnt = new SwContent(
799  this,
800  pTemp->GetName(),
801  nYPos);
802  if(!rIDDMA.IsVisibleLayerId(pTemp->GetLayer()))
803  pCnt->SetInvisible();
804  m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
805  m_nMemberCount++;
806  if (nOldMemberCount > i &&
807  (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible() )
808  *pbLevelOrVisibilityChanged = true;
809  }
810  }
811  }
812  }
813  break;
814  default: break;
815  }
816  m_bDataValid = true;
817 }
818 
819 namespace {
820 
822 {
823  IDX_STR_OUTLINE_LEVEL = 0,
824  IDX_STR_DRAGMODE = 1,
825  IDX_STR_HYPERLINK = 2,
826  IDX_STR_LINK_REGION = 3,
827  IDX_STR_COPY_REGION = 4,
828  IDX_STR_DISPLAY = 5,
829  IDX_STR_ACTIVE_VIEW = 6,
830  IDX_STR_HIDDEN = 7,
831  IDX_STR_ACTIVE = 8,
832  IDX_STR_INACTIVE = 9,
833  IDX_STR_EDIT_ENTRY = 10,
834  IDX_STR_DELETE_ENTRY = 11,
835  IDX_STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY = 12,
836  IDX_STR_OUTLINE_TRACKING = 13,
837  IDX_STR_OUTLINE_TRACKING_DEFAULT = 14,
838  IDX_STR_OUTLINE_TRACKING_FOCUS = 15,
839  IDX_STR_OUTLINE_TRACKING_OFF = 16
840 };
841 
842 }
843 
844 static const char* STR_CONTEXT_ARY[] =
845 {
846  STR_OUTLINE_LEVEL,
847  STR_DRAGMODE,
848  STR_HYPERLINK,
849  STR_LINK_REGION,
850  STR_COPY_REGION,
851  STR_DISPLAY,
852  STR_ACTIVE_VIEW,
853  STR_HIDDEN,
854  STR_ACTIVE,
855  STR_INACTIVE,
856  STR_EDIT_ENTRY,
857  STR_DELETE_ENTRY,
858  STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY,
859  STR_OUTLINE_TRACKING,
860  STR_OUTLINE_TRACKING_DEFAULT,
861  STR_OUTLINE_TRACKING_FOCUS,
862  STR_OUTLINE_TRACKING_OFF
863 };
864 
865 SwContentTree::SwContentTree(std::unique_ptr<weld::TreeView> xTreeView, SwNavigationPI* pDialog)
866  : m_xTreeView(std::move(xTreeView))
867  , m_xScratchIter(m_xTreeView->make_iterator())
868  , m_aDropTargetHelper(*this)
869  , m_xDialog(pDialog)
870  , m_sSpace(OUString(" "))
871  , m_sInvisible(SwResId(STR_INVISIBLE))
872  , m_pHiddenShell(nullptr)
873  , m_pActiveShell(nullptr)
874  , m_pConfig(SW_MOD()->GetNavigationConfig())
875  , m_nActiveBlock(0)
876  , m_nHiddenBlock(0)
877  , m_nEntryCount(0)
878  , m_nRootType(ContentTypeId::UNKNOWN)
879  , m_nLastSelType(ContentTypeId::UNKNOWN)
880  , m_nOutlineLevel(MAXLEVEL)
881  , m_eState(State::ACTIVE)
882  , m_bIsRoot(false)
883  , m_bIsIdleClear(false)
884  , m_bIsLastReadOnly(false)
885  , m_bIsOutlineMoveable(true)
886  , m_bViewHasChanged(false)
887 {
888  Size aSize(m_xDialog->LogicToPixel(Size(110, 112), MapMode(MapUnit::MapAppFont)));
889  m_xTreeView->set_size_request(aSize.Width(), aSize.Height());
890 
891  m_xTreeView->set_help_id(HID_NAVIGATOR_TREELIST);
892 
893  m_xTreeView->connect_expanding(LINK(this, SwContentTree, ExpandHdl));
894  m_xTreeView->connect_collapsing(LINK(this, SwContentTree, CollapseHdl));
895  m_xTreeView->connect_row_activated(LINK(this, SwContentTree, ContentDoubleClickHdl));
896  m_xTreeView->connect_changed(LINK(this, SwContentTree, SelectHdl));
897  m_xTreeView->connect_focus_in(LINK(this, SwContentTree, FocusHdl));
898  m_xTreeView->connect_key_press(LINK(this, SwContentTree, KeyInputHdl));
899  m_xTreeView->connect_popup_menu(LINK(this, SwContentTree, CommandHdl));
900  m_xTreeView->connect_query_tooltip(LINK(this, SwContentTree, QueryTooltipHdl));
901  m_xTreeView->connect_drag_begin(LINK(this, SwContentTree, DragBeginHdl));
902 
904  {
905  m_aActiveContentArr[i] = nullptr;
906  m_aHiddenContentArr[i] = nullptr;
907  }
908  for (int i = 0; i < CONTEXT_COUNT; ++i)
909  {
910  m_aContextStrings[i] = SwResId(STR_CONTEXT_ARY[i]);
911  }
913  m_aUpdTimer.SetInvokeHandler(LINK(this, SwContentTree, TimerUpdate));
914  m_aUpdTimer.SetTimeout(1000);
915 }
916 
918 {
919  clear(); // If applicable erase content types previously.
920  m_aUpdTimer.Stop();
921  SetActiveShell(nullptr);
922  m_xDialog.clear();
923 }
924 
925 // Drag&Drop methods
926 IMPL_LINK(SwContentTree, DragBeginHdl, bool&, rUnsetDragIcon, bool)
927 {
928  rUnsetDragIcon = true;
929 
930  bool bDisallow = true;
931 
932  // don't allow if tree root is selected
933  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
934  bool bEntry = m_xTreeView->get_selected(xEntry.get());
935  if (!bEntry || lcl_IsContentType(*xEntry, *m_xTreeView))
936  {
937  return true; // disallow
938  }
939 
942 
943  if (FillTransferData(*xContainer, nDragMode))
944  bDisallow = false;
945 
946  if (m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE)
947  {
948  // Only move drag entry and continuous selected siblings:
949  m_aDndOutlinesSelected.clear();
950 
951  std::unique_ptr<weld::TreeIter> xScratch(m_xTreeView->make_iterator());
952 
953  // Find first selected of continuous siblings
954  while (true)
955  {
956  m_xTreeView->copy_iterator(*xEntry, *xScratch);
957  if (!m_xTreeView->iter_previous_sibling(*xScratch))
958  break;
959  if (!m_xTreeView->is_selected(*xScratch))
960  break;
961  m_xTreeView->copy_iterator(*xScratch, *xEntry);
962  }
963  // Record continuous selected siblings
964  do
965  {
966  m_aDndOutlinesSelected.push_back(m_xTreeView->make_iterator(xEntry.get()));
967  }
968  while (m_xTreeView->iter_next_sibling(*xEntry) && m_xTreeView->is_selected(*xEntry));
969  bDisallow = false;
970  }
971 
972  if (!bDisallow)
973  m_xTreeView->enable_drag_source(xContainer, nDragMode);
974  return bDisallow;
975 }
976 
978  : DropTargetHelper(rTreeView.get_widget().get_drop_target())
979  , m_rTreeView(rTreeView)
980 {
981 }
982 
984 {
985  sal_Int8 nAccept = m_rTreeView.AcceptDrop(rEvt);
986 
987  if (nAccept != DND_ACTION_NONE)
988  {
989  // to enable the autoscroll when we're close to the edges
991  rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
992  }
993 
994  return nAccept;
995 }
996 
998 {
999  return m_xTreeView->get_drag_source() == m_xTreeView.get();
1000 }
1001 
1002 // QueryDrop will be executed in the navigator
1004 {
1005  sal_Int8 nRet = DND_ACTION_NONE;
1006  if( m_bIsRoot )
1007  {
1008  if( m_bIsOutlineMoveable )
1009  nRet = rEvt.mnAction;
1010  }
1011  else if (!IsInDrag())
1012  nRet = GetParentWindow()->AcceptDrop();
1013  return nRet;
1014 }
1015 
1016 // Drop will be executed in the navigator
1017 static void* lcl_GetOutlineKey(SwContentTree& rTree, SwOutlineContent const * pContent)
1018 {
1019  void* key = nullptr;
1020  if (pContent)
1021  {
1022  SwWrtShell* pShell = rTree.GetWrtShell();
1023  auto const nPos = pContent->GetOutlinePos();
1024 
1025  key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
1026  }
1027  return key;
1028 }
1029 
1031 {
1032  return m_rTreeView.ExecuteDrop(rEvt);
1033 }
1034 
1036 {
1037  std::unique_ptr<weld::TreeIter> xDropEntry(m_xTreeView->make_iterator());
1038  if (!m_xTreeView->get_dest_row_at_pos(rEvt.maPosPixel, xDropEntry.get(), true))
1039  xDropEntry.reset();
1040 
1042  {
1043  if (xDropEntry && lcl_IsContent(*xDropEntry, *m_xTreeView))
1044  {
1045  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xDropEntry).toInt64())));
1046  SwOutlineContent* pOutlineContent = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xDropEntry).toInt64());
1047  assert(pOutlineContent);
1048 
1049  void* key = lcl_GetOutlineKey(*this, pOutlineContent);
1050  assert(key);
1051  if (!mOutLineNodeMap[key])
1052  {
1053  while (m_xTreeView->iter_has_child(*xDropEntry))
1054  {
1055  std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator(xDropEntry.get()));
1056  bool bChildEntry = m_xTreeView->iter_children(*xChildEntry);
1057  while (bChildEntry)
1058  {
1059  m_xTreeView->copy_iterator(*xChildEntry, *xDropEntry);
1060  bChildEntry = m_xTreeView->iter_next_sibling(*xChildEntry);
1061  }
1062  }
1063  }
1064  }
1065 
1066  SwOutlineNodes::size_type nTargetPos = 0;
1067  if (!xDropEntry)
1068  {
1069  // dropped in blank space -> move to bottom
1071  }
1072  else if (!lcl_IsContent(*xDropEntry, *m_xTreeView))
1073  {
1074  // dropped on "heading" parent -> move to start
1075  nTargetPos = SwOutlineNodes::npos;
1076  }
1077  else
1078  {
1079  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xDropEntry).toInt64())));
1080  nTargetPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xDropEntry).toInt64())->GetOutlinePos();
1081  }
1082 
1083  if( MAXLEVEL > m_nOutlineLevel && // Not all layers are displayed.
1084  nTargetPos != SwOutlineNodes::npos)
1085  {
1086  std::unique_ptr<weld::TreeIter> xNext(m_xTreeView->make_iterator(xDropEntry.get()));
1087  bool bNext = m_xTreeView->iter_next(*xNext);
1088  if (bNext)
1089  {
1090  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xNext).toInt64())));
1091  nTargetPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xNext).toInt64())->GetOutlinePos() - 1;
1092  }
1093  else
1095  }
1096 
1097  // remove the drop highlight before we change the contents of the tree so we don't
1098  // try and dereference a removed entry in post-processing drop
1099  m_xTreeView->unset_drag_dest_row();
1100  MoveOutline(nTargetPos);
1101 
1102  }
1103  return IsInDrag() ? DND_ACTION_NONE : GetParentWindow()->ExecuteDrop(rEvt);
1104 }
1105 
1106 namespace
1107 {
1108  bool IsAllExpanded(const weld::TreeView& rContentTree, const weld::TreeIter& rEntry)
1109  {
1110  if (!rContentTree.get_row_expanded(rEntry))
1111  return false;
1112 
1113  if (!rContentTree.iter_has_child(rEntry))
1114  return false;
1115 
1116  std::unique_ptr<weld::TreeIter> xChild(rContentTree.make_iterator(&rEntry));
1117  (void)rContentTree.iter_children(*xChild);
1118 
1119  do
1120  {
1121  if (rContentTree.iter_has_child(*xChild) || rContentTree.get_children_on_demand(*xChild))
1122  {
1123  if (!IsAllExpanded(rContentTree, *xChild))
1124  return false;
1125  }
1126  }
1127  while (rContentTree.iter_next_sibling(*xChild));
1128  return true;
1129  }
1130 
1131  void ExpandOrCollapseAll(weld::TreeView& rContentTree, weld::TreeIter& rEntry)
1132  {
1133  bool bExpand = !IsAllExpanded(rContentTree, rEntry);
1134  bExpand ? rContentTree.expand_row(rEntry) : rContentTree.collapse_row(rEntry);
1135  int nRefDepth = rContentTree.get_iter_depth(rEntry);
1136  while (rContentTree.iter_next(rEntry) && rContentTree.get_iter_depth(rEntry) > nRefDepth)
1137  {
1138  if (rContentTree.iter_has_child(rEntry))
1139  bExpand ? rContentTree.expand_row(rEntry) : rContentTree.collapse_row(rEntry);
1140  }
1141  }
1142 }
1143 
1144 // Handler for Dragging and ContextMenu
1146 {
1147  if (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry))
1148  {
1149  rPop.set_label(OString::number(800), IsAllExpanded(rContentTree, rEntry) ? SwResId(STR_COLLAPSEALL) : SwResId(STR_EXPANDALL));
1150  return false;
1151  }
1152  return true;
1153 }
1154 
1156 {
1157  rPop.set_sensitive(OString::number(1512), false);
1158  rPop.set_sensitive(OString::number(1513), false);
1159  rPop.set_sensitive(OString::number(1514), false);
1160 
1162  return;
1163 
1164  // todo: multi selection
1165  if (rContentTree.count_selected_rows() > 1)
1166  return;
1167 
1168  const SwNodes& rNodes = pThis->GetWrtShell()->GetNodes();
1169  const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
1170  size_t nOutlinePos = weld::GetAbsPos(rContentTree, rEntry);
1171 
1172  bool bIsRoot = lcl_IsContentType(rEntry, rContentTree);
1173 
1174  if (!bIsRoot)
1175  --nOutlinePos;
1176 
1177  if (nOutlinePos >= rOutlineNodes.size())
1178  return;
1179 
1180  int nFirstLevel = pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
1181  {
1182  // determine if any concerned outline node has content
1183  bool bHasContent(false);
1184  size_t nPos = nOutlinePos;
1185  SwNode* pSttNd = rOutlineNodes[nPos];
1186  SwNode* pEndNd = &rNodes.GetEndOfContent();
1187  if (rOutlineNodes.size() > nPos + 1)
1188  pEndNd = rOutlineNodes[nPos + 1];
1189 
1190  // selected
1191  SwNodeIndex aIdx(*pSttNd);
1192  if (rNodes.GoNext(&aIdx) != pEndNd)
1193  bHasContent = true;
1194 
1195  // descendants
1196  if (!bHasContent && (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry)))
1197  {
1198  while (++nPos < rOutlineNodes.size() &&
1199  (bIsRoot || pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nFirstLevel))
1200  {
1201  pSttNd = rOutlineNodes[nPos];
1202  pEndNd = &rNodes.GetEndOfContent();
1203  if (rOutlineNodes.size() > nPos + 1)
1204  pEndNd = rOutlineNodes[nPos + 1];
1205 
1206  // test for content in outline node
1207  aIdx.Assign(*pSttNd);
1208  if (rNodes.GoNext(&aIdx) != pEndNd)
1209  {
1210  bHasContent = true;
1211  break;
1212  }
1213  }
1214  }
1215 
1216  if (!bHasContent)
1217  return; // no content in any of the concerned outline nodes
1218  }
1219 
1220  // determine for subs if all are folded or unfolded or if they are mixed
1221  if (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry))
1222  {
1223  // skip no content nodes
1224  // we know there is content from results above so this is presumably safe
1225  size_t nPos = nOutlinePos;
1226  while (true)
1227  {
1228  SwNode* pSttNd = rOutlineNodes[nPos];
1229  SwNode* pEndNd = rOutlineNodes.back();
1230  if (!bIsRoot && rOutlineNodes.size() > nPos + 1)
1231  pEndNd = rOutlineNodes[nPos + 1];
1232 
1233  SwNodeIndex aIdx(*pSttNd);
1234  if (rNodes.GoNext(&aIdx) != pEndNd)
1235  break;
1236  nPos++;
1237  }
1238 
1239  bool bHasFolded(pThis->GetWrtShell()->IsOutlineContentFolded(nPos));
1240  bool bHasUnfolded(!bHasFolded);
1241 
1242  while ((++nPos < pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineNodesCount()) &&
1243  (bIsRoot || pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nFirstLevel))
1244  {
1245 
1246  SwNode* pSttNd = rOutlineNodes[nPos];
1247  SwNode* pEndNd = &rNodes.GetEndOfContent();
1248  if (rOutlineNodes.size() > nPos + 1)
1249  pEndNd = rOutlineNodes[nPos + 1];
1250 
1251  SwNodeIndex aIdx(*pSttNd);
1252  if (rNodes.GoNext(&aIdx) == pEndNd)
1253  continue; // skip if no content
1254 
1255  if (pThis->GetWrtShell()->IsOutlineContentFolded(nPos))
1256  bHasFolded = true;
1257  else
1258  bHasUnfolded = true;
1259 
1260  if (bHasFolded && bHasUnfolded)
1261  break; // mixed so no need to continue
1262  }
1263 
1264  rPop.set_sensitive(OString::number(1513), bHasUnfolded);
1265  rPop.set_sensitive(OString::number(1514), bHasFolded);
1266  }
1267 
1268  bIsRoot ? rPop.remove(OString::number(1512)) : rPop.set_sensitive(OString::number(1512), true);
1269 }
1270 
1271 IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
1272 {
1273  if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
1274  return false;
1275 
1276  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/swriter/ui/navigatorcontextmenu.ui"));
1277  std::unique_ptr<weld::Menu> xPop = xBuilder->weld_menu("navmenu");
1278 
1279  bool bOutline(false);
1280  std::unique_ptr<weld::Menu> xSubPop1 = xBuilder->weld_menu("outlinelevel");
1281  std::unique_ptr<weld::Menu> xSubPop2 = xBuilder->weld_menu("dragmodemenu");
1282  std::unique_ptr<weld::Menu> xSubPop3 = xBuilder->weld_menu("displaymenu");
1283  std::unique_ptr<weld::Menu> xSubPopOutlineTracking = xBuilder->weld_menu("outlinetracking");
1284 
1285  std::unique_ptr<weld::Menu> xSubPopOutlineContent = xBuilder->weld_menu("outlinecontent");
1286  xSubPopOutlineContent->append(OUString::number(1512), SwResId(STR_OUTLINE_CONTENT_VISIBILITY_TOGGLE));
1287  xSubPopOutlineContent->append(OUString::number(1513), SwResId(STR_OUTLINE_CONTENT_VISIBILITY_HIDE_ALL));
1288  xSubPopOutlineContent->append(OUString::number(1514), SwResId(STR_OUTLINE_CONTENT_VISIBILITY_SHOW_ALL));
1289 
1290  for(int i = 1; i <= 3; ++i)
1291  xSubPopOutlineTracking->append_radio(OUString::number(i + 10), m_aContextStrings[IDX_STR_OUTLINE_TRACKING + i]);
1292  xSubPopOutlineTracking->set_active(OString::number(10 + m_nOutlineTracking), true);
1293 
1294  for (int i = 1; i <= MAXLEVEL; ++i)
1295  xSubPop1->append_radio(OUString::number(i + 100), OUString::number(i));
1296  xSubPop1->set_active(OString::number(100 + m_nOutlineLevel), true);
1297 
1298  for (int i=0; i < 3; ++i)
1299  xSubPop2->append_radio(OUString::number(i + 201), m_aContextStrings[IDX_STR_HYPERLINK + i]);
1300  xSubPop2->set_active(OString::number(201 + static_cast<int>(GetParentWindow()->GetRegionDropMode())), true);
1301 
1302  // Insert the list of the open files
1303  sal_uInt16 nId = 301;
1304  const SwView* pActiveView = ::GetActiveView();
1305  SwView *pView = SwModule::GetFirstView();
1306  while (pView)
1307  {
1308  OUString sInsert = pView->GetDocShell()->GetTitle();
1309  if (pView == pActiveView)
1310  {
1311  sInsert += "(" +
1312  m_aContextStrings[IDX_STR_ACTIVE] +
1313  ")";
1314  }
1315  xSubPop3->append_radio(OUString::number(nId), sInsert);
1316  if (State::CONSTANT == m_eState && m_pActiveShell == &pView->GetWrtShell())
1317  xSubPop3->set_active(OString::number(nId), true);
1318  pView = SwModule::GetNextView(pView);
1319  nId++;
1320  }
1321  xSubPop3->append_radio(OUString::number(nId++), m_aContextStrings[IDX_STR_ACTIVE_VIEW]);
1322  if (m_pHiddenShell)
1323  {
1324  OUString sHiddenEntry = m_pHiddenShell->GetView().GetDocShell()->GetTitle() +
1325  " ( " +
1326  m_aContextStrings[IDX_STR_HIDDEN] +
1327  " )";
1328  xSubPop3->append_radio(OUString::number(nId), sHiddenEntry);
1329  }
1330 
1331  if (State::ACTIVE == m_eState)
1332  xSubPop3->set_active(OString::number(--nId), true);
1333  else if (State::HIDDEN == m_eState)
1334  xSubPop3->set_active(OString::number(nId), true);
1335 
1336  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1337  if (!m_xTreeView->get_selected(xEntry.get()))
1338  xEntry.reset();
1339 
1340  if (!xEntry || !lcl_IsContent(*xEntry, *m_xTreeView))
1341  xPop->remove(OString::number(900)); // go to
1342 
1343  bool bRemovePostItEntries = true;
1344  bool bRemoveIndexEntries = true;
1345  bool bRemoveEditEntry = true;
1346  bool bRemoveUnprotectEntry = true;
1347  bool bRemoveDeleteEntry = true;
1348  bool bRemoveRenameEntry = true;
1349  bool bRemoveSelectEntry = true;
1350  bool bRemoveToggleExpandEntry = true;
1351  bool bRemoveChapterEntries = true;
1352  bool bRemoveSendOutlineEntry = true;
1353 
1354  // Edit only if the shown content is coming from the current view.
1355  if ((State::ACTIVE == m_eState || m_pActiveShell == pActiveView->GetWrtShellPtr())
1356  && xEntry && lcl_IsContent(*xEntry, *m_xTreeView))
1357  {
1358  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
1359  const SwContentType* pContType = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetParent();
1360  const ContentTypeId nContentType = pContType->GetType();
1361  const bool bReadonly = m_pActiveShell->GetView().GetDocShell()->IsReadOnly();
1362  const bool bVisible = !reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->IsInvisible();
1363  const bool bProtected = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->IsProtect();
1364  const bool bProtectBM = (ContentTypeId::BOOKMARK == nContentType)
1365  && m_pActiveShell->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS);
1366  const bool bEditable = pContType->IsEditable() &&
1367  ((bVisible && !bProtected && !bProtectBM) || ContentTypeId::REGION == nContentType);
1368  const bool bDeletable = pContType->IsDeletable() &&
1369  ((bVisible && !bProtected && !bProtectBM) || ContentTypeId::REGION == nContentType);
1370  const bool bRenamable = bEditable && !bReadonly &&
1371  (ContentTypeId::TABLE == nContentType ||
1372  ContentTypeId::FRAME == nContentType ||
1373  ContentTypeId::GRAPHIC == nContentType ||
1374  ContentTypeId::OLE == nContentType ||
1375  (ContentTypeId::BOOKMARK == nContentType && !bProtectBM) ||
1376  ContentTypeId::REGION == nContentType ||
1377  ContentTypeId::INDEX == nContentType ||
1378  ContentTypeId::DRAWOBJECT == nContentType);
1379 
1380  if(ContentTypeId::OUTLINE == nContentType)
1381  {
1382  bOutline = true;
1383  lcl_SetOutlineContentEntriesSensitivities(this, *m_xTreeView, *xEntry, *xSubPopOutlineContent);
1384  bRemoveToggleExpandEntry = lcl_InsertExpandCollapseAllItem(*m_xTreeView, *xEntry, *xPop);
1385  if (!bReadonly)
1386  {
1387  bRemoveSelectEntry = false;
1388  bRemoveChapterEntries = false;
1389  }
1390  }
1391  else if (!bReadonly && (bEditable || bDeletable))
1392  {
1393  if(ContentTypeId::INDEX == nContentType)
1394  {
1395  bRemoveIndexEntries = false;
1396 
1397  const SwTOXBase* pBase = reinterpret_cast<SwTOXBaseContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetTOXBase();
1398  if (!pBase->IsTOXBaseInReadonly())
1399  bRemoveEditEntry = false;
1400 
1401  xPop->set_active(OString::number(405), SwEditShell::IsTOXBaseReadonly(*pBase));
1402  bRemoveDeleteEntry = false;
1403  }
1404  else if(ContentTypeId::TABLE == nContentType)
1405  {
1406  bRemoveSelectEntry = false;
1407  bRemoveEditEntry = false;
1408  bRemoveUnprotectEntry = false;
1409  bool bFull = false;
1410  OUString sTableName = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetName();
1411  bool bProt = m_pActiveShell->HasTableAnyProtection( &sTableName, &bFull );
1412  xPop->set_sensitive(OString::number(403), !bFull);
1413  xPop->set_sensitive(OString::number(404), bProt);
1414  bRemoveDeleteEntry = false;
1415  }
1416  else if(ContentTypeId::DRAWOBJECT == nContentType)
1417  {
1418  bRemoveDeleteEntry = false;
1419  }
1420  else if(ContentTypeId::REGION == nContentType)
1421  {
1422  bRemoveSelectEntry = false;
1423  bRemoveEditEntry = false;
1424  }
1425  else
1426  {
1427  if (bEditable && bDeletable)
1428  {
1429  bRemoveEditEntry = false;
1430  bRemoveDeleteEntry = false;
1431  }
1432  else if (bEditable)
1433  bRemoveEditEntry = false;
1434  else if (bDeletable)
1435  {
1436  bRemoveDeleteEntry = false;
1437  }
1438  }
1439  //Rename object
1440  if (bRenamable)
1441  bRemoveRenameEntry = false;
1442  }
1443  }
1444  else if (xEntry)
1445  {
1446  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
1447  SwContentType* pType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xEntry).toInt64());
1448  if (ContentTypeId::OUTLINE == pType->GetType())
1449  {
1450  bOutline = true;
1451  lcl_SetOutlineContentEntriesSensitivities(this, *m_xTreeView, *xEntry, *xSubPopOutlineContent);
1452  bRemoveToggleExpandEntry = lcl_InsertExpandCollapseAllItem(*m_xTreeView, *xEntry, *xPop);
1453  bRemoveSendOutlineEntry = false;
1454  }
1455  if ( (pType->GetType() == ContentTypeId::POSTIT) && (!m_pActiveShell->GetView().GetDocShell()->IsReadOnly()) && ( pType->GetMemberCount() > 0) )
1456  bRemovePostItEntries = false;
1457  }
1458 
1459  if (bRemoveToggleExpandEntry)
1460  {
1461  xPop->remove("separator3");
1462  xPop->remove(OString::number(800));
1463  }
1464 
1465  if (bRemoveSelectEntry)
1466  xPop->remove(OString::number(805));
1467 
1468  if (bRemoveChapterEntries)
1469  {
1470  xPop->remove("separator2");
1471  xPop->remove(OString::number(806));
1472  xPop->remove(OString::number(801));
1473  xPop->remove(OString::number(802));
1474  xPop->remove(OString::number(803));
1475  xPop->remove(OString::number(804));
1476  }
1477 
1478  if (bRemoveSendOutlineEntry)
1479  xPop->remove(OString::number(700));
1480 
1481  if (bRemovePostItEntries)
1482  {
1483  xPop->remove(OString::number(600));
1484  xPop->remove(OString::number(601));
1485  xPop->remove(OString::number(602));
1486  }
1487 
1488  if (bRemoveDeleteEntry)
1489  xPop->remove(OString::number(501));
1490 
1491  if (bRemoveRenameEntry)
1492  xPop->remove(OString::number(502));
1493 
1494  if (bRemoveIndexEntries)
1495  {
1496  xPop->remove(OString::number(401));
1497  xPop->remove(OString::number(402));
1498  xPop->remove(OString::number(405));
1499  }
1500 
1501  if (bRemoveUnprotectEntry)
1502  xPop->remove(OString::number(404));
1503 
1504  if (bRemoveEditEntry)
1505  xPop->remove(OString::number(403));
1506 
1507  if (bRemoveToggleExpandEntry &&
1508  bRemoveSelectEntry &&
1509  bRemoveChapterEntries &&
1510  bRemoveSendOutlineEntry &&
1511  bRemovePostItEntries &&
1512  bRemoveDeleteEntry &&
1513  bRemoveRenameEntry &&
1514  bRemoveIndexEntries &&
1515  bRemoveUnprotectEntry &&
1516  bRemoveEditEntry)
1517  {
1518  xPop->remove("separator1");
1519  }
1520 
1521  if (!bOutline)
1522  {
1523  xSubPop1.reset();
1524  xPop->remove(OString::number(1)); // outline level menu
1525  xSubPopOutlineTracking.reset();
1526  xPop->remove(OString::number(4)); // outline tracking menu
1527  }
1528  if (!bOutline
1529  || !m_pActiveShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()
1530  || m_pActiveShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount() == 0)
1531  {
1532  xSubPopOutlineContent.reset();
1533  xPop->remove(OString::number(5)); // outline content menu
1534  xPop->remove("separator1511");
1535  }
1536 
1537  OString sCommand = xPop->popup_at_rect(m_xTreeView.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1)));
1538  if (!sCommand.isEmpty())
1539  ExecuteContextMenuAction(sCommand);
1540 
1541  return true;
1542 }
1543 
1544 void SwContentTree::insert(const weld::TreeIter* pParent, const OUString& rStr, const OUString& rId,
1545  bool bChildrenOnDemand, weld::TreeIter* pRet)
1546 {
1547  m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, bChildrenOnDemand, pRet);
1548  ++m_nEntryCount;
1549 }
1550 
1552 {
1553  if (m_xTreeView->iter_has_child(rIter))
1554  {
1555  std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rIter);
1556  (void)m_xTreeView->iter_children(*xChild);
1557  remove(*xChild);
1558  }
1559  m_xTreeView->remove(rIter);
1560  --m_nEntryCount;
1561 }
1562 
1563 // Content will be integrated into the Box only on demand.
1565 {
1566  bool bChild = m_xTreeView->iter_has_child(rParent);
1567  if (bChild || !m_xTreeView->get_children_on_demand(rParent))
1568  return bChild;
1569 
1570  // Is this a content type?
1571  if (lcl_IsContentType(rParent, *m_xTreeView))
1572  {
1573  std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator();
1574 
1575  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(rParent).toInt64())));
1576  SwContentType* pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rParent).toInt64());
1577 
1578  const size_t nCount = pCntType->GetMemberCount();
1579  // Add for outline plus/minus
1580  if (pCntType->GetType() == ContentTypeId::OUTLINE)
1581  {
1582  for(size_t i = 0; i < nCount; ++i)
1583  {
1584  const SwContent* pCnt = pCntType->GetMember(i);
1585  if(pCnt)
1586  {
1587  const auto nLevel = static_cast<const SwOutlineContent*>(pCnt)->GetOutlineLevel();
1588  OUString sEntry = pCnt->GetName();
1589  if(sEntry.isEmpty())
1590  sEntry = m_sSpace;
1591  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
1592  if (!bChild || (nLevel == 0))
1593  {
1594  insert(&rParent, sEntry, sId, false, xChild.get());
1595  m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
1596  m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 - m_xTreeView->get_iter_depth(*xChild));
1597  bChild = true;
1598  }
1599  else
1600  {
1601  //back search parent.
1602  if(static_cast<const SwOutlineContent*>(pCntType->GetMember(i-1))->GetOutlineLevel() < nLevel)
1603  {
1604  insert(xChild.get(), sEntry, sId, false, xChild.get());
1605  m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
1606  m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 - m_xTreeView->get_iter_depth(*xChild));
1607  bChild = true;
1608  }
1609  else
1610  {
1611  bChild = m_xTreeView->iter_previous(*xChild);
1612  assert(!bChild || lcl_IsContentType(*xChild, *m_xTreeView) || dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xChild).toInt64())));
1613  while (bChild &&
1614  lcl_IsContent(*xChild, *m_xTreeView) &&
1615  (reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xChild).toInt64())->GetOutlineLevel() >= nLevel)
1616  )
1617  {
1618  bChild = m_xTreeView->iter_previous(*xChild);
1619  }
1620  if (bChild)
1621  {
1622  insert(xChild.get(), sEntry, sId, false, xChild.get());
1623  m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
1624  m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 - m_xTreeView->get_iter_depth(*xChild));
1625  }
1626  }
1627  }
1628  }
1629  }
1630  }
1631  else
1632  {
1633  bool bRegion = pCntType->GetType() == ContentTypeId::REGION;
1634  for(size_t i = 0; i < nCount; ++i)
1635  {
1636  const SwContent* pCnt = pCntType->GetMember(i);
1637  if (pCnt)
1638  {
1639  OUString sEntry = pCnt->GetName();
1640  if (sEntry.isEmpty())
1641  sEntry = m_sSpace;
1642  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
1643  insert(&rParent, sEntry, sId, false, xChild.get());
1644  m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
1645  if (bRegion)
1646  m_xTreeView->set_extra_row_indent(*xChild, static_cast<const SwRegionContent*>(pCnt)->GetRegionLevel());
1647  bChild = true;
1648  }
1649  }
1650  }
1651  }
1652 
1653  return bChild;
1654 }
1655 
1657 {
1658  SdrObject *pRetObj = nullptr;
1659  switch(pCnt->GetParent()->GetType())
1660  {
1662  {
1663  SdrView* pDrawView = m_pActiveShell->GetDrawView();
1664  if (pDrawView)
1665  {
1667  SdrPage* pPage = pDrawModel->GetPage(0);
1668  const size_t nCount = pPage->GetObjCount();
1669 
1670  for( size_t i=0; i<nCount; ++i )
1671  {
1672  SdrObject* pTemp = pPage->GetObj(i);
1673  if( pTemp->GetName() == pCnt->GetName())
1674  {
1675  pRetObj = pTemp;
1676  break;
1677  }
1678  }
1679  }
1680  break;
1681  }
1682  default:
1683  pRetObj = nullptr;
1684  }
1685  return pRetObj;
1686 }
1687 
1688 void SwContentTree::Expand(const weld::TreeIter& rParent, std::vector<std::unique_ptr<weld::TreeIter>>* pNodesToExpand)
1689 {
1690  if (!(m_xTreeView->iter_has_child(rParent) || m_xTreeView->get_children_on_demand(rParent)))
1691  return;
1692 
1693  if (!m_bIsRoot
1694  || (lcl_IsContentType(rParent, *m_xTreeView) &&
1695  reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rParent).toInt64())->GetType() == ContentTypeId::OUTLINE)
1697  {
1698  if (lcl_IsContentType(rParent, *m_xTreeView))
1699  {
1700  SwContentType* pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rParent).toInt64());
1701  const sal_Int32 nOr = 1 << static_cast<int>(pCntType->GetType()); //linear -> Bitposition
1702  if (State::HIDDEN != m_eState)
1703  {
1704  m_nActiveBlock |= nOr;
1706  }
1707  else
1708  m_nHiddenBlock |= nOr;
1709  if (pCntType->GetType() == ContentTypeId::OUTLINE)
1710  {
1711  std::map< void*, bool > aCurrOutLineNodeMap;
1712 
1713  SwWrtShell* pShell = GetWrtShell();
1714  bool bParentHasChild = RequestingChildren(rParent);
1715  if (pNodesToExpand)
1716  pNodesToExpand->emplace_back(m_xTreeView->make_iterator(&rParent));
1717  if (bParentHasChild)
1718  {
1719  std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rParent));
1720  bool bChild = m_xTreeView->iter_next(*xChild);
1721  while (bChild && lcl_IsContent(*xChild, *m_xTreeView))
1722  {
1723  if (m_xTreeView->iter_has_child(*xChild))
1724  {
1725  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xChild).toInt64())));
1726  auto const nPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xChild).toInt64())->GetOutlinePos();
1727  void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
1728  aCurrOutLineNodeMap.emplace( key, false );
1729  std::map<void*, bool>::iterator iter = mOutLineNodeMap.find( key );
1730  if( iter != mOutLineNodeMap.end() && mOutLineNodeMap[key])
1731  {
1732  aCurrOutLineNodeMap[key] = true;
1733  RequestingChildren(*xChild);
1734  if (pNodesToExpand)
1735  pNodesToExpand->emplace_back(m_xTreeView->make_iterator(xChild.get()));
1736  m_xTreeView->set_children_on_demand(*xChild, false);
1737  }
1738  }
1739  bChild = m_xTreeView->iter_next(*xChild);
1740  }
1741  }
1742  mOutLineNodeMap = aCurrOutLineNodeMap;
1743  return;
1744  }
1745  }
1746  else
1747  {
1748  if (lcl_IsContent(rParent, *m_xTreeView))
1749  {
1750  SwWrtShell* pShell = GetWrtShell();
1751  // paranoid assert now that outline type is checked
1752  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(rParent).toInt64())));
1753  auto const nPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rParent).toInt64())->GetOutlinePos();
1754  void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
1755  mOutLineNodeMap[key] = true;
1756  }
1757  }
1758  }
1759 
1760  RequestingChildren(rParent);
1761  if (pNodesToExpand)
1762  pNodesToExpand->emplace_back(m_xTreeView->make_iterator(&rParent));
1763 }
1764 
1765 IMPL_LINK(SwContentTree, ExpandHdl, const weld::TreeIter&, rParent, bool)
1766 {
1767  Expand(rParent, nullptr);
1768  return true;
1769 }
1770 
1771 IMPL_LINK(SwContentTree, CollapseHdl, const weld::TreeIter&, rParent, bool)
1772 {
1773  if (!m_xTreeView->iter_has_child(rParent) || m_xTreeView->get_children_on_demand(rParent))
1774  return true;
1775 
1776  if (lcl_IsContentType(rParent, *m_xTreeView))
1777  {
1778  if (m_bIsRoot)
1779  {
1780  // collapse to children of root node
1781  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(&rParent));
1782  if (m_xTreeView->iter_children(*xEntry))
1783  {
1784  do
1785  {
1786  m_xTreeView->collapse_row(*xEntry);
1787  }
1788  while (m_xTreeView->iter_next(*xEntry));
1789  }
1790  return false; // return false to notify caller not to do collapse
1791  }
1792  SwContentType* pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rParent).toInt64());
1793  const sal_Int32 nAnd = ~(1 << static_cast<int>(pCntType->GetType()));
1794  if (State::HIDDEN != m_eState)
1795  {
1796  m_nActiveBlock &= nAnd;
1797  m_pConfig->SetActiveBlock(m_nActiveBlock);
1798  }
1799  else
1800  m_nHiddenBlock &= nAnd;
1801  }
1802  else if (lcl_IsContent(rParent, *m_xTreeView))
1803  {
1804  SwWrtShell* pShell = GetWrtShell();
1805  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(rParent).toInt64())));
1806  auto const nPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rParent).toInt64())->GetOutlinePos();
1807  void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
1808  mOutLineNodeMap[key] = false;
1809  }
1810 
1811  return true;
1812 }
1813 
1814 // Also on double click will be initially opened only.
1815 IMPL_LINK_NOARG(SwContentTree, ContentDoubleClickHdl, weld::TreeView&, bool)
1816 {
1817  bool bConsumed = false;
1818 
1819  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1820  bool bEntry = m_xTreeView->get_cursor(xEntry.get());
1821  // Is it a content type?
1822  OSL_ENSURE(bEntry, "no current entry!");
1823  if (bEntry)
1824  {
1825  if (lcl_IsContentType(*xEntry, *m_xTreeView) && !m_xTreeView->iter_has_child(*xEntry))
1826  {
1827  RequestingChildren(*xEntry);
1828  m_xTreeView->set_children_on_demand(*xEntry, false);
1829  }
1830  else if (!lcl_IsContentType(*xEntry, *m_xTreeView) && (State::HIDDEN != m_eState))
1831  {
1832  if (State::CONSTANT == m_eState)
1833  {
1834  m_pActiveShell->GetView().GetViewFrame()->GetWindow().ToTop();
1835  }
1836  //Jump to content type:
1837  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
1838  SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64());
1839  assert(pCnt && "no UserData");
1840  GotoContent(pCnt);
1841  const ContentTypeId nActType = pCnt->GetParent()->GetType();
1842  if (nActType == ContentTypeId::FRAME)
1843  m_pActiveShell->EnterStdMode();
1844  // fdo#36308 don't expand outlines on double-click
1845  bConsumed = nActType == ContentTypeId::OUTLINE;
1846  }
1847  }
1848 
1849  return bConsumed; // false/true == allow/disallow more to be done, i.e. expand/collapse children
1850 }
1851 
1852 namespace
1853 {
1854  OUString GetImageIdForContentTypeId(ContentTypeId eType)
1855  {
1856  OUString sResId;
1857 
1858  switch (eType)
1859  {
1861  sResId = RID_BMP_NAVI_OUTLINE;
1862  break;
1863  case ContentTypeId::TABLE:
1864  sResId = RID_BMP_NAVI_TABLE;
1865  break;
1866  case ContentTypeId::FRAME:
1867  sResId = RID_BMP_NAVI_FRAME;
1868  break;
1870  sResId = RID_BMP_NAVI_GRAPHIC;
1871  break;
1872  case ContentTypeId::OLE:
1873  sResId = RID_BMP_NAVI_OLE;
1874  break;
1876  sResId = RID_BMP_NAVI_BOOKMARK;
1877  break;
1878  case ContentTypeId::REGION:
1879  sResId = RID_BMP_NAVI_REGION;
1880  break;
1882  sResId = RID_BMP_NAVI_URLFIELD;
1883  break;
1885  sResId = RID_BMP_NAVI_REFERENCE;
1886  break;
1887  case ContentTypeId::INDEX:
1888  sResId = RID_BMP_NAVI_INDEX;
1889  break;
1890  case ContentTypeId::POSTIT:
1891  sResId = RID_BMP_NAVI_POSTIT;
1892  break;
1894  sResId = RID_BMP_NAVI_DRAWOBJECT;
1895  break;
1897  SAL_WARN("sw.ui", "ContentTypeId::UNKNOWN has no bitmap preview");
1898  break;
1899  }
1900 
1901  return sResId;
1902  };
1903 }
1904 
1906 {
1907  return weld::GetAbsPos(*m_xTreeView, rIter);
1908 }
1909 
1911 {
1912  return m_nEntryCount;
1913 }
1914 
1915 size_t SwContentTree::GetChildCount(const weld::TreeIter& rParent) const
1916 {
1917  if (!m_xTreeView->iter_has_child(rParent))
1918  return 0;
1919 
1920  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rParent));
1921 
1922  size_t nCount = 0;
1923  auto nRefDepth = m_xTreeView->get_iter_depth(*xParent);
1924  auto nActDepth = nRefDepth;
1925  do
1926  {
1927  if (!m_xTreeView->iter_next(*xParent))
1928  xParent.reset();
1929  else
1930  nActDepth = m_xTreeView->get_iter_depth(*xParent);
1931  nCount++;
1932  } while(xParent && nRefDepth < nActDepth);
1933 
1934  nCount--;
1935  return nCount;
1936 }
1937 
1938 std::unique_ptr<weld::TreeIter> SwContentTree::GetEntryAtAbsPos(size_t nAbsPos) const
1939 {
1940  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1941  if (!m_xTreeView->get_iter_first(*xEntry))
1942  xEntry.reset();
1943 
1944  while (nAbsPos && xEntry)
1945  {
1946  if (!m_xTreeView->iter_next(*xEntry))
1947  xEntry.reset();
1948  nAbsPos--;
1949  }
1950  return xEntry;
1951 }
1952 
1953 void SwContentTree::Display( bool bActive )
1954 {
1955  // First read the selected entry to select it later again if necessary
1956  // -> the user data here are no longer valid!
1957  std::unique_ptr<weld::TreeIter> xOldSelEntry(m_xTreeView->make_iterator());
1958  if (!m_xTreeView->get_selected(xOldSelEntry.get()))
1959  xOldSelEntry.reset();
1960  OUString sEntryName; // Name of the entry
1961  size_t nEntryRelPos = 0; // relative position to their parent
1962  size_t nOldEntryCount = GetEntryCount();
1963  sal_Int32 nOldScrollPos = 0;
1964  if (xOldSelEntry)
1965  {
1967 
1968  nOldScrollPos = m_xTreeView->vadjustment_get_value();
1969  sEntryName = m_xTreeView->get_text(*xOldSelEntry);
1970  std::unique_ptr<weld::TreeIter> xParentEntry = m_xTreeView->make_iterator(xOldSelEntry.get());
1971  while (m_xTreeView->get_iter_depth(*xParentEntry))
1972  m_xTreeView->iter_parent(*xParentEntry);
1973  if (m_xTreeView->get_iter_depth(*xOldSelEntry))
1974  nEntryRelPos = GetAbsPos(*xOldSelEntry) - GetAbsPos(*xParentEntry);
1975  }
1976 
1977  clear();
1978 
1979  if (!bActive)
1981  else if (State::HIDDEN == m_eState)
1983  SwWrtShell* pShell = GetWrtShell();
1984  const bool bReadOnly = !pShell || pShell->GetView().GetDocShell()->IsReadOnly();
1985  if(bReadOnly != m_bIsLastReadOnly)
1986  {
1987  m_bIsLastReadOnly = bReadOnly;
1988  bool bDisable = pShell == nullptr || bReadOnly;
1989  SwNavigationPI* pNavi = GetParentWindow();
1990  pNavi->m_xContent3ToolBox->set_item_sensitive("chapterup", !bDisable);
1991  pNavi->m_xContent3ToolBox->set_item_sensitive("chapterdown", !bDisable);
1992  pNavi->m_xContent3ToolBox->set_item_sensitive("promote", !bDisable);
1993  pNavi->m_xContent3ToolBox->set_item_sensitive("demote", !bDisable);
1994  pNavi->m_xContent2ToolBox->set_item_sensitive("reminder", !bDisable);
1995  }
1996 
1997  if (pShell)
1998  {
1999  std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
2000  std::unique_ptr<weld::TreeIter> xSelEntry;
2001  // all content navigation view
2003  {
2004  m_xTreeView->freeze();
2005 
2006  std::vector<std::unique_ptr<weld::TreeIter>> aNodesToExpand;
2007 
2008  for( ContentTypeId nCntType : o3tl::enumrange<ContentTypeId>() )
2009  {
2010  std::unique_ptr<SwContentType>& rpContentT = bActive ?
2011  m_aActiveContentArr[nCntType] :
2012  m_aHiddenContentArr[nCntType];
2013  if(!rpContentT)
2014  rpContentT.reset(new SwContentType(pShell, nCntType, m_nOutlineLevel ));
2015 
2016  OUString sEntry = rpContentT->GetName();
2017  OUString aImage(GetImageIdForContentTypeId(nCntType));
2018  bool bChOnDemand = 0 != rpContentT->GetMemberCount();
2019  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(rpContentT.get())));
2020  insert(nullptr, sEntry, sId, bChOnDemand, xEntry.get());
2021  m_xTreeView->set_image(*xEntry, aImage);
2022 
2023  m_xTreeView->set_sensitive(*xEntry, bChOnDemand);
2024 
2025  if (nCntType == m_nLastSelType)
2026  xSelEntry = m_xTreeView->make_iterator(xEntry.get());
2027  sal_Int32 nExpandOptions = (State::HIDDEN == m_eState)
2028  ? m_nHiddenBlock
2029  : m_nActiveBlock;
2030  if (nExpandOptions & (1 << static_cast<int>(nCntType)))
2031  {
2032  // fill contents of to-be expanded entries while frozen
2033  Expand(*xEntry, &aNodesToExpand);
2034  m_xTreeView->set_children_on_demand(*xEntry, false);
2035  }
2036  }
2037 
2038  m_xTreeView->thaw();
2039 
2040  // restore visual expanded tree state
2041  for (const auto& rNode : aNodesToExpand)
2042  m_xTreeView->expand_row(*rNode);
2043 
2044  (void)m_xTreeView->get_iter_first(*xEntry);
2046  {
2047  sal_Int32 nExpandOptions = (State::HIDDEN == m_eState)
2048  ? m_nHiddenBlock
2049  : m_nActiveBlock;
2050  if (nExpandOptions & (1 << static_cast<int>(nCntType)))
2051  {
2052  if (nEntryRelPos && nCntType == m_nLastSelType)
2053  {
2054  // reselect the entry
2055  std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
2056  std::unique_ptr<weld::TreeIter> xTemp;
2057  sal_uLong nPos = 1;
2058  while (m_xTreeView->iter_next(*xChild))
2059  {
2060  // The old text will be slightly favored
2061  if (sEntryName == m_xTreeView->get_text(*xChild) ||
2062  nPos == nEntryRelPos)
2063  {
2064  m_xTreeView->copy_iterator(*xChild, *xSelEntry);
2065  break;
2066  }
2067  xTemp = m_xTreeView->make_iterator(xChild.get());
2068  nPos++;
2069  }
2070  if (!xSelEntry || lcl_IsContentType(*xSelEntry, *m_xTreeView))
2071  xSelEntry = std::move(xTemp);
2072  }
2073  }
2074 
2075  (void)m_xTreeView->iter_next_sibling(*xEntry);
2076  }
2077 
2078  if (!xSelEntry)
2079  {
2080  nOldScrollPos = 0;
2081  xSelEntry = m_xTreeView->make_iterator();
2082  if (!m_xTreeView->get_iter_first(*xSelEntry))
2083  xSelEntry.reset();
2084  }
2085 
2086  if (xSelEntry)
2087  {
2088  m_xTreeView->set_cursor(*xSelEntry);
2089  Select();
2090  }
2091  }
2092  // root content navigation view
2093  else
2094  {
2095  m_xTreeView->freeze();
2096 
2097  std::unique_ptr<SwContentType>& rpRootContentT = bActive ?
2100  if(!rpRootContentT)
2101  rpRootContentT.reset(new SwContentType(pShell, m_nRootType, m_nOutlineLevel ));
2102  OUString aImage(GetImageIdForContentTypeId(m_nRootType));
2103  bool bChOnDemand = m_nRootType == ContentTypeId::OUTLINE;
2104  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(rpRootContentT.get())));
2105  insert(nullptr, rpRootContentT->GetName(), sId, bChOnDemand, xEntry.get());
2106  m_xTreeView->set_image(*xEntry, aImage);
2107 
2108  if (!bChOnDemand)
2109  {
2110  bool bRegion = rpRootContentT->GetType() == ContentTypeId::REGION;
2111 
2112  std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator();
2113  for (size_t i = 0; i < rpRootContentT->GetMemberCount(); ++i)
2114  {
2115  const SwContent* pCnt = rpRootContentT->GetMember(i);
2116  if (pCnt)
2117  {
2118  OUString sEntry = pCnt->GetName();
2119  if(sEntry.isEmpty())
2120  sEntry = m_sSpace;
2121  OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
2122  insert(xEntry.get(), sEntry, sSubId, false, xChild.get());
2123  m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
2124  if (bRegion)
2125  m_xTreeView->set_extra_row_indent(*xChild, static_cast<const SwRegionContent*>(pCnt)->GetRegionLevel());
2126  }
2127  }
2128  }
2129  else
2130  {
2131  RequestingChildren(*xEntry);
2132  m_xTreeView->set_children_on_demand(*xEntry, false);
2133  }
2134 
2135  m_xTreeView->set_sensitive(*xEntry, m_xTreeView->iter_has_child(*xEntry));
2136 
2137  m_xTreeView->thaw();
2138 
2139  m_xTreeView->expand_row(*xEntry);
2140 
2141  // reselect the entry
2142  if (nEntryRelPos)
2143  {
2144  std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
2145  sal_uLong nPos = 1;
2146  while (m_xTreeView->iter_next(*xChild))
2147  {
2148  // The old text will be slightly favored
2149  if (sEntryName == m_xTreeView->get_text(*xChild) || nPos == nEntryRelPos)
2150  {
2151  xSelEntry = std::move(xChild);
2152  break;
2153  }
2154  nPos++;
2155  }
2156  if (xSelEntry)
2157  {
2158  m_xTreeView->set_cursor(*xSelEntry); // unselect all entries, make pSelEntry visible, and select
2159  Select();
2160  }
2161  }
2162  else
2163  {
2164  m_xTreeView->set_cursor(*xEntry);
2165  Select();
2166  }
2167  }
2168  }
2169 
2170  if (!m_bIgnoreViewChange && GetEntryCount() == nOldEntryCount)
2171  {
2172  m_xTreeView->vadjustment_set_value(nOldScrollPos);
2173  }
2174 }
2175 
2177 {
2178  m_xTreeView->freeze();
2179  m_xTreeView->clear();
2180  m_nEntryCount = 0;
2181  m_xTreeView->thaw();
2182 }
2183 
2185  sal_Int8& rDragMode )
2186 {
2187  bool bRet = false;
2188  SwWrtShell* pWrtShell = GetWrtShell();
2189  OSL_ENSURE(pWrtShell, "no Shell!");
2190 
2191  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2192  bool bEntry = m_xTreeView->get_cursor(xEntry.get());
2193  if (!bEntry || lcl_IsContentType(*xEntry, *m_xTreeView) || !pWrtShell)
2194  return false;
2195  OUString sEntry;
2196  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2197  SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64());
2198 
2199  const ContentTypeId nActType = pCnt->GetParent()->GetType();
2200  OUString sUrl;
2201  bool bOutline = false;
2202  OUString sOutlineText;
2203  switch( nActType )
2204  {
2206  {
2207  const SwOutlineNodes::size_type nPos = static_cast<SwOutlineContent*>(pCnt)->GetOutlinePos();
2208  OSL_ENSURE(nPos < pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount(),
2209  "outlinecnt changed");
2210 
2211  // make sure outline may actually be copied
2212  if( pWrtShell->IsOutlineCopyable( nPos ) )
2213  {
2214  const SwNumRule* pOutlRule = pWrtShell->GetOutlineNumRule();
2215  const SwTextNode* pTextNd =
2216  pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNode(nPos);
2217  if (pTextNd && pOutlRule && pTextNd->IsNumbered(pWrtShell->GetLayout()))
2218  {
2219  SwNumberTree::tNumberVector aNumVector =
2220  pTextNd->GetNumberVector(pWrtShell->GetLayout());
2221  for( int nLevel = 0;
2222  nLevel <= pTextNd->GetActualListLevel();
2223  nLevel++ )
2224  {
2225  const SwNumberTree::tSwNumTreeNumber nVal = aNumVector[nLevel] + 1;
2226  sEntry += OUString::number( nVal - pOutlRule->Get(nLevel).GetStart() ) + ".";
2227  }
2228  }
2229  sEntry += pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout(), false);
2230  sOutlineText = pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout());
2231  m_bIsOutlineMoveable = static_cast<SwOutlineContent*>(pCnt)->IsMoveable();
2232  bOutline = true;
2233  }
2234  }
2235  break;
2236  case ContentTypeId::POSTIT:
2237  case ContentTypeId::INDEX:
2239  // cannot be inserted, neither as URL nor as section
2240  break;
2242  sUrl = static_cast<SwURLFieldContent*>(pCnt)->GetURL();
2243  [[fallthrough]];
2244  case ContentTypeId::OLE:
2247  break;
2248  else
2249  rDragMode &= ~( DND_ACTION_MOVE | DND_ACTION_LINK );
2250  [[fallthrough]];
2251  default:
2252  sEntry = m_xTreeView->get_text(*xEntry);
2253  }
2254 
2255  if(!sEntry.isEmpty())
2256  {
2257  const SwDocShell* pDocShell = pWrtShell->GetView().GetDocShell();
2258  if(sUrl.isEmpty())
2259  {
2260  if(pDocShell->HasName())
2261  {
2262  SfxMedium* pMedium = pDocShell->GetMedium();
2263  sUrl = pMedium->GetURLObject().GetURLNoMark();
2264  // only if a primarily link shall be integrated.
2265  bRet = true;
2266  }
2267  else if ( nActType == ContentTypeId::REGION || nActType == ContentTypeId::BOOKMARK )
2268  {
2269  // For field and bookmarks a link is also allowed
2270  // without a filename into its own document.
2271  bRet = true;
2272  }
2273  else if (State::CONSTANT == m_eState &&
2274  ( !::GetActiveView() ||
2275  m_pActiveShell != ::GetActiveView()->GetWrtShellPtr()))
2276  {
2277  // Urls of inactive views cannot dragged without
2278  // file names, also.
2279  bRet = false;
2280  }
2281  else
2282  {
2284  rDragMode = DND_ACTION_MOVE;
2285  }
2286 
2287  const OUString& rToken = pCnt->GetParent()->GetTypeToken();
2288  sUrl += "#" + sEntry;
2289  if(!rToken.isEmpty())
2290  {
2291  sUrl += OUStringChar(cMarkSeparator) + rToken;
2292  }
2293  }
2294  else
2295  bRet = true;
2296 
2297  if( bRet )
2298  {
2299  // In Outlines of heading text must match
2300  // the real number into the description.
2301  if(bOutline)
2302  sEntry = sOutlineText;
2303 
2304  {
2305  NaviContentBookmark aBmk( sUrl, sEntry,
2306  GetParentWindow()->GetRegionDropMode(),
2307  pDocShell);
2308  aBmk.Copy( rTransfer );
2309  }
2310 
2311  // An INetBookmark must a be delivered to foreign DocShells
2312  if( pDocShell->HasName() )
2313  {
2314  INetBookmark aBkmk( sUrl, sEntry );
2315  rTransfer.CopyINetBookmark( aBkmk );
2316  }
2317  }
2318  }
2319  return bRet;
2320 }
2321 
2323 {
2324  if(!m_bIsRoot)
2325  {
2326  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2327  bool bEntry = m_xTreeView->get_cursor(xEntry.get());
2328  const SwContentType* pCntType;
2329  if (bEntry)
2330  {
2331  if (lcl_IsContentType(*xEntry, *m_xTreeView))
2332  {
2333  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2334  pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xEntry).toInt64());
2335  }
2336  else
2337  {
2338  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2339  pCntType = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetParent();
2340  }
2341  m_nRootType = pCntType->GetType();
2342  m_bIsRoot = true;
2345  {
2346  m_xTreeView->set_selection_mode(SelectionMode::Multiple);
2347  }
2348  }
2349  }
2350  else
2351  {
2352  m_xTreeView->set_selection_mode(SelectionMode::Single);
2354  m_bIsRoot = false;
2357  }
2360  pBox->set_item_active("root", m_bIsRoot);
2361 }
2362 
2364 {
2365  bool bContentChanged = false;
2366 
2367 // - Run through the local array and the Treelistbox in parallel.
2368 // - Are the records not expanded, they are discarded only in the array
2369 // and the content type will be set as the new UserData.
2370 // - Is the root mode is active only this will be updated.
2371 
2372 // Valid for the displayed content types is:
2373 // the Memberlist will be erased and the membercount will be updated
2374 // If content will be checked, the memberlists will be replenished
2375 // at the same time. Once a difference occurs it will be only replenished
2376 // no longer checked. Finally, the box is filled again.
2377 
2378  // bVisibilityChanged gets set to true if some element, like a section,
2379  // changed visibility and should have its name rerendered with a new
2380  // grayed-out state
2381  bool bVisibilityChanged = false;
2382 
2383  if (State::HIDDEN == m_eState)
2384  {
2386  {
2387  if(m_aActiveContentArr[i])
2388  m_aActiveContentArr[i]->Invalidate();
2389  }
2390  }
2391  // root content navigation view
2392  else if(m_bIsRoot)
2393  {
2394  std::unique_ptr<weld::TreeIter> xRootEntry(m_xTreeView->make_iterator());
2395  if (!m_xTreeView->get_iter_first(*xRootEntry))
2396  bContentChanged = true;
2397  else
2398  {
2399  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xRootEntry).toInt64())));
2400  const ContentTypeId nType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xRootEntry).toInt64())->GetType();
2401  SwContentType* pArrType = m_aActiveContentArr[nType].get();
2402  if (!pArrType)
2403  bContentChanged = true;
2404  else
2405  {
2406  // start check if first selected outline level has changed
2407  bool bCheckChanged = m_nRootType == ContentTypeId::OUTLINE && !m_xTreeView->has_focus();
2408  if (bCheckChanged)
2409  {
2410  std::unique_ptr<weld::TreeIter> xFirstSel(m_xTreeView->make_iterator());
2411  bool bFirstSel = m_xTreeView->get_selected(xFirstSel.get());
2412  if (bFirstSel && lcl_IsContent(*xFirstSel, *m_xTreeView))
2413  {
2414  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xFirstSel).toInt64())));
2415  const auto nSelLevel = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xFirstSel).toInt64())->GetOutlineLevel();
2416  SwWrtShell* pSh = GetWrtShell();
2417  const SwOutlineNodes::size_type nOutlinePos = pSh->GetOutlinePos(MAXLEVEL);
2418  if (nOutlinePos != SwOutlineNodes::npos && pSh->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos) != nSelLevel)
2419  bContentChanged = true;
2420  }
2421  }
2422  // end check if first selected outline level has changed
2423 
2424  pArrType->Init(&bVisibilityChanged);
2425  pArrType->FillMemberList();
2426  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pArrType)));
2427  m_xTreeView->set_id(*xRootEntry, sId);
2428  if (!bContentChanged)
2429  {
2430  const size_t nChildCount = GetChildCount(*xRootEntry);
2431  if (nChildCount != pArrType->GetMemberCount())
2432  bContentChanged = true;
2433  else
2434  {
2435  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(xRootEntry.get()));
2436  for (size_t j = 0; j < nChildCount; ++j)
2437  {
2438  m_xTreeView->iter_next(*xEntry);
2439  const SwContent* pCnt = pArrType->GetMember(j);
2440  OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
2441  m_xTreeView->set_id(*xEntry, sSubId);
2442  OUString sEntryText = m_xTreeView->get_text(*xEntry);
2443  if( sEntryText != pCnt->GetName() &&
2444  !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
2445  bContentChanged = true;
2446  }
2447  }
2448  }
2449  }
2450  }
2451  }
2452  // all content navigation view
2453  else
2454  {
2455  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2456  bool bEntry = m_xTreeView->get_iter_first(*xEntry);
2457  while (bEntry)
2458  {
2459  bool bNext = true; // at least a next must be
2460  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2461  SwContentType* pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xEntry).toInt64());
2462  const size_t nCntCount = pCntType->GetMemberCount();
2463  const ContentTypeId nType = pCntType->GetType();
2464  SwContentType* pArrType = m_aActiveContentArr[nType].get();
2465  if (!pArrType)
2466  bContentChanged = true;
2467  else
2468  {
2469  pArrType->Init(&bVisibilityChanged);
2470  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pArrType)));
2471  m_xTreeView->set_id(*xEntry, sId);
2472  if (m_xTreeView->get_row_expanded(*xEntry))
2473  {
2474  bool bLevelOrVisibilityChanged = false;
2475  // bLevelOrVisibilityChanged is set if outlines have changed their level
2476  // or if the visibility of objects (frames, sections, tables) has changed
2477  // i.e. in header/footer
2478  pArrType->FillMemberList(&bLevelOrVisibilityChanged);
2479  const size_t nChildCount = GetChildCount(*xEntry);
2480  if (bLevelOrVisibilityChanged)
2481  {
2482  if (nType == ContentTypeId::OUTLINE)
2483  bContentChanged = true;
2484  else
2485  bVisibilityChanged = true;
2486  }
2487 
2488  if(nChildCount != pArrType->GetMemberCount())
2489  bContentChanged = true;
2490  else
2491  {
2492  for(size_t j = 0; j < nChildCount; ++j)
2493  {
2494  bEntry = m_xTreeView->iter_next(*xEntry);
2495  bNext = false;
2496  const SwContent* pCnt = pArrType->GetMember(j);
2497  OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
2498  m_xTreeView->set_id(*xEntry, sSubId);
2499  OUString sEntryText = m_xTreeView->get_text(*xEntry);
2500  if( sEntryText != pCnt->GetName() &&
2501  !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
2502  bContentChanged = true;
2503  }
2504  }
2505  }
2506  // not expanded and has children
2507  else if (m_xTreeView->iter_has_child(*xEntry))
2508  {
2509  // was the entry once opened, then must also the
2510  // invisible records be examined.
2511  // At least the user data must be updated.
2512  bool bLevelOrVisibilityChanged = false;
2513  // bLevelOrVisibilityChanged is set if outlines have changed their level
2514  // or if the visibility of objects (frames, sections, tables) has changed
2515  // i.e. in header/footer
2516  pArrType->FillMemberList(&bLevelOrVisibilityChanged);
2517  bool bRemoveChildren = false;
2518  const size_t nChildCount = GetChildCount(*xEntry);
2519  if (nChildCount != pArrType->GetMemberCount())
2520  {
2521  bRemoveChildren = true;
2522  }
2523  else
2524  {
2525  std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
2526  (void)m_xTreeView->iter_children(*xChild);
2527  for (size_t j = 0; j < nChildCount; ++j)
2528  {
2529  const SwContent* pCnt = pArrType->GetMember(j);
2530  OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
2531  m_xTreeView->set_id(*xChild, sSubId);
2532  OUString sEntryText = m_xTreeView->get_text(*xChild);
2533  if( sEntryText != pCnt->GetName() &&
2534  !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
2535  bRemoveChildren = true;
2536  (void)m_xTreeView->iter_next(*xChild);
2537  }
2538  }
2539  if (bRemoveChildren)
2540  {
2541  std::unique_ptr<weld::TreeIter> xRemove(m_xTreeView->make_iterator(xEntry.get()));
2542  while (m_xTreeView->iter_children(*xRemove))
2543  {
2544  remove(*xRemove);
2545  m_xTreeView->copy_iterator(*xEntry, *xRemove);
2546  }
2547  }
2548  m_xTreeView->set_children_on_demand(*xEntry, !nChildCount);
2549  }
2550  else if((nCntCount != 0)
2551  != (pArrType->GetMemberCount()!=0))
2552  {
2553  bContentChanged = true;
2554  }
2555  }
2556  // The Root-Entry has to be found now
2557  while (bEntry && (bNext || m_xTreeView->get_iter_depth(*xEntry)))
2558  {
2559  bEntry = m_xTreeView->iter_next(*xEntry);
2560  bNext = false;
2561  }
2562  }
2563  }
2564 
2565  if (!bContentChanged && bVisibilityChanged)
2566  m_aUpdTimer.Start();
2567 
2568  return bContentChanged || bVisibilityChanged;
2569 }
2570 
2572 {
2573  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2574  if (m_xTreeView->get_selected(xEntry.get()))
2575  {
2576  while (m_xTreeView->get_iter_depth(*xEntry))
2577  m_xTreeView->iter_parent(*xEntry);
2578  sal_Int64 nId = m_xTreeView->get_id(*xEntry).toInt64();
2579  if (nId && lcl_IsContentType(*xEntry, *m_xTreeView))
2580  {
2581  assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(nId)));
2582  m_nLastSelType = reinterpret_cast<SwContentType*>(nId)->GetType();
2583  }
2584  }
2585 }
2586 
2588 {
2590 
2591  // If clear is called by TimerUpdate:
2592  // Only for root can the validity of the UserData be guaranteed.
2593  m_xTreeView->all_foreach([this](weld::TreeIter& rEntry){
2594  m_xTreeView->set_id(rEntry, "");
2595  return false;
2596  });
2597 }
2598 
2600 {
2601  m_pHiddenShell = pSh;
2605  {
2606  m_aHiddenContentArr[i].reset();
2607  }
2608  Display(false);
2609 
2611 }
2612 
2614 {
2615  bool bClear = m_pActiveShell != pSh;
2616  if (State::ACTIVE == m_eState && bClear)
2617  {
2618  if (m_pActiveShell)
2620  m_pActiveShell = pSh;
2622  clear();
2623  }
2624  else if (State::CONSTANT == m_eState)
2625  {
2626  if (m_pActiveShell)
2628  m_pActiveShell = pSh;
2630  bClear = true;
2631  }
2632  // Only if it is the active view, the array will be deleted and
2633  // the screen filled new.
2634  if (State::ACTIVE == m_eState && bClear)
2635  {
2636  if (m_pActiveShell)
2640  {
2641  m_aActiveContentArr[i].reset();
2642  }
2643  Display(true);
2644  }
2645 }
2646 
2648 {
2649  if (m_pActiveShell)
2651  m_pActiveShell = pSh;
2653  StartListening(*m_pActiveShell->GetView().GetDocShell());
2656  {
2657  m_aActiveContentArr[i].reset();
2658  }
2659  Display(true);
2660 }
2661 
2663 {
2664  SfxViewEventHint const*const pVEHint(dynamic_cast<SfxViewEventHint const*>(&rHint));
2665  SwXTextView* pDyingShell = nullptr;
2666  if (m_pActiveShell && pVEHint && pVEHint->GetEventName() == "OnViewClosed")
2667  pDyingShell = dynamic_cast<SwXTextView*>(pVEHint->GetController().get());
2668  if (pDyingShell && pDyingShell->GetView() == &m_pActiveShell->GetView())
2669  {
2670  SetActiveShell(nullptr); // our view is dying, clear our pointers to it
2671  }
2672  else
2673  {
2674  SfxListener::Notify(rBC, rHint);
2675  }
2676  switch (rHint.GetId())
2677  {
2678  case SfxHintId::DocChanged:
2679  if (!m_bIgnoreViewChange)
2680  {
2681  m_bViewHasChanged = true;
2682  TimerUpdate(&m_aUpdTimer);
2683  }
2684  break;
2685  case SfxHintId::ModeChanged:
2686  if (SwWrtShell* pShell = GetWrtShell())
2687  {
2688  const bool bReadOnly = pShell->GetView().GetDocShell()->IsReadOnly();
2689  if (bReadOnly != m_bIsLastReadOnly)
2690  {
2691  m_bIsLastReadOnly = bReadOnly;
2692 
2693  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2694  if (m_xTreeView->get_cursor(xEntry.get()))
2695  {
2696  m_xTreeView->select(*xEntry);
2697  Select();
2698  }
2699  else
2700  m_xTreeView->unselect_all();
2701  }
2702  }
2703  break;
2704  default:
2705  break;
2706  }
2707 }
2708 
2709 void SwContentTree::ExecCommand(const OString& rCmd, bool bOutlineWithChildren)
2710 {
2711  const bool bUp = rCmd == "chapterup";
2712  const bool bUpDown = bUp || rCmd == "chapterdown";
2713  const bool bLeft = rCmd == "promote";
2714  const bool bLeftRight = bLeft || rCmd == "demote";
2715  if (!bUpDown && !bLeftRight)
2716  return;
2717  if (GetWrtShell()->GetView().GetDocShell()->IsReadOnly() ||
2718  (State::ACTIVE != m_eState &&
2719  (State::CONSTANT != m_eState || m_pActiveShell != GetParentWindow()->GetCreateView()->GetWrtShellPtr())))
2720  {
2721  return;
2722  }
2723 
2724  m_bIgnoreViewChange = true;
2725 
2726  SwWrtShell *const pShell = GetWrtShell();
2727  sal_Int8 nActOutlineLevel = m_nOutlineLevel;
2728  SwOutlineNodes::size_type nActPos = pShell->GetOutlinePos(nActOutlineLevel);
2729 
2730  std::vector<SwTextNode*> selectedOutlineNodes;
2731  std::vector<std::unique_ptr<weld::TreeIter>> selected;
2732 
2733  m_xTreeView->selected_foreach([this, pShell, &bLeftRight, &bOutlineWithChildren, &selected, &selectedOutlineNodes](weld::TreeIter& rEntry){
2734  // it's possible to select the root node too which is a really bad idea
2735  bool bSkip = lcl_IsContentType(rEntry, *m_xTreeView);
2736  // filter out children of selected parents so they don't get promoted
2737  // or moved twice (except if there is Ctrl modifier, since in that
2738  // case children are re-parented)
2739  if ((bLeftRight || bOutlineWithChildren) && !selected.empty())
2740  {
2741  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
2742  for (bool bParent = m_xTreeView->iter_parent(*xParent); bParent; bParent = m_xTreeView->iter_parent(*xParent))
2743  {
2744  if (m_xTreeView->iter_compare(*selected.back(), *xParent) == 0)
2745  {
2746  bSkip = true;
2747  break;
2748  }
2749  }
2750  }
2751  if (!bSkip)
2752  {
2753  selected.emplace_back(m_xTreeView->make_iterator(&rEntry));
2754  const SwNodes& rNodes = pShell->GetNodes();
2755  const size_t nPos = GetAbsPos(rEntry) - 1;
2756  if (nPos < rNodes.GetOutLineNds().size())
2757  {
2758  SwNode* pNode = rNodes.GetOutLineNds()[ nPos ];
2759  if (pNode)
2760  {
2761  selectedOutlineNodes.push_back(pNode->GetTextNode());
2762  }
2763  }
2764  }
2765  return false;
2766  });
2767 
2768  if (bUpDown && !bUp)
2769  { // to move down, start at the end!
2770  std::reverse(selected.begin(), selected.end());
2771  }
2772 
2773  SwOutlineNodes::difference_type nDirLast = bUp ? -1 : 1;
2774  bool bStartedAction = false;
2775  std::vector<SwNode*> aFoldedOutlineNdsArray;
2776  for (auto const& pCurrentEntry : selected)
2777  {
2778  assert(pCurrentEntry && lcl_IsContent(*pCurrentEntry, *m_xTreeView));
2779  if (lcl_IsContent(*pCurrentEntry, *m_xTreeView))
2780  {
2781  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*pCurrentEntry).toInt64())));
2783  reinterpret_cast<SwContent*>(m_xTreeView->get_id(*pCurrentEntry).toInt64())->GetParent()->GetType()
2785  {
2786  nActPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*pCurrentEntry).toInt64())->GetOutlinePos();
2787  }
2788  }
2789  if (nActPos == SwOutlineNodes::npos || (bUpDown && !pShell->IsOutlineMovable(nActPos)))
2790  {
2791  continue;
2792  }
2793 
2794  if (!bStartedAction)
2795  {
2796  pShell->StartAllAction();
2797  if (bUpDown)
2798  {
2800  {
2801  // unfold all folded outline content
2802  SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds();
2803  for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos)
2804  {
2805  SwNode* pNd = rOutlineNds[nPos];
2806  if (pNd->IsTextNode()) // should always be true
2807  {
2808  bool bOutlineContentVisibleAttr = true;
2809  pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
2810  if (!bOutlineContentVisibleAttr)
2811  {
2812  aFoldedOutlineNdsArray.push_back(pNd);
2814  }
2815  }
2816  }
2817  }
2818  }
2819  pShell->StartUndo(bLeftRight ? SwUndoId::OUTLINE_LR : SwUndoId::OUTLINE_UD);
2820  bStartedAction = true;
2821  }
2822  pShell->GotoOutline( nActPos); // If text selection != box selection
2823  pShell->Push();
2824  pShell->MakeOutlineSel(nActPos, nActPos, bOutlineWithChildren);
2825  if (bUpDown)
2826  {
2827  const size_t nEntryAbsPos(GetAbsPos(*pCurrentEntry));
2828  SwOutlineNodes::difference_type nDir = bUp ? -1 : 1;
2829  if (!bOutlineWithChildren && ((nDir == -1 && nActPos > 0) ||
2830  (nDir == 1 && nEntryAbsPos < GetEntryCount() - 2)))
2831  {
2832  pShell->MoveOutlinePara( nDir );
2833  // Set cursor back to the current position
2834  pShell->GotoOutline( nActPos + nDir);
2835  }
2836  else if (bOutlineWithChildren)
2837  {
2838  SwOutlineNodes::size_type nActEndPos = nActPos;
2839  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pCurrentEntry.get()));
2840  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*pCurrentEntry).toInt64())));
2841  const auto nActLevel = reinterpret_cast<SwOutlineContent*>(
2842  m_xTreeView->get_id(*pCurrentEntry).toInt64())->GetOutlineLevel();
2843  bool bEntry = m_xTreeView->iter_next(*xEntry);
2844  while (bEntry && lcl_IsContent(*xEntry, *m_xTreeView))
2845  {
2846  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2847  if (nActLevel >= reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlineLevel())
2848  break;
2849  nActEndPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlinePos();
2850  bEntry = m_xTreeView->iter_next(*xEntry);
2851  }
2852  if (nDir == 1) // move down
2853  {
2854  std::unique_ptr<weld::TreeIter> xNextSibling(m_xTreeView->make_iterator(pCurrentEntry.get()));
2855  if (m_xTreeView->iter_next_sibling(*xNextSibling) && m_xTreeView->is_selected(*xNextSibling))
2856  nDir = nDirLast;
2857  else
2858  {
2859  // If the last entry is to be moved we're done
2860  if (bEntry && lcl_IsContent(*xEntry, *m_xTreeView))
2861  {
2862  // xEntry now points to the entry following the last
2863  // selected entry.
2864  SwOutlineNodes::size_type nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlinePos();
2865  // here needs to found the next entry after next.
2866  // The selection must be inserted in front of that.
2867  while (bEntry)
2868  {
2869  bEntry = m_xTreeView->iter_next(*xEntry);
2870  assert(!bEntry || !lcl_IsContent(*xEntry, *m_xTreeView)||
2871  dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2872  // nDest++ may only executed if bEntry
2873  if (bEntry)
2874  {
2875  if (!lcl_IsContent(*xEntry, *m_xTreeView))
2876  break;
2877  else if (nActLevel >= reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlineLevel())
2878  {
2879  // nDest needs adjusted if there are selected entries (including ancestral lineage)
2880  // immediately before the current moved entry.
2881  std::unique_ptr<weld::TreeIter> xTmp(m_xTreeView->make_iterator(xEntry.get()));
2882  bool bTmp = m_xTreeView->iter_previous(*xTmp);
2883  while (bTmp && lcl_IsContent(*xTmp, *m_xTreeView) &&
2884  nActLevel < reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlineLevel())
2885  {
2886  while (bTmp && lcl_IsContent(*xTmp, *m_xTreeView) && !m_xTreeView->is_selected(*xTmp) &&
2887  nActLevel < reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlineLevel())
2888  {
2889  bTmp = m_xTreeView->iter_parent(*xTmp);
2890  }
2891  if (!bTmp || !m_xTreeView->is_selected(*xTmp))
2892  break;
2893  bTmp = m_xTreeView->iter_previous(*xTmp);
2894  nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlinePos();
2895  }
2896  std::unique_ptr<weld::TreeIter> xPrevSibling(m_xTreeView->make_iterator(xEntry.get()));
2897  if (!m_xTreeView->iter_previous_sibling(*xPrevSibling) || !m_xTreeView->is_selected(*xPrevSibling))
2898  break;
2899  }
2900  else
2901  {
2902  nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlinePos();
2903  }
2904  }
2905  }
2906  nDirLast = nDir = nDest - nActEndPos;
2907  // If no entry was found that allows insertion before
2908  // it, we just move it to the end.
2909  }
2910  else
2911  nDirLast = nDir = 0;
2912  }
2913  }
2914  else // move up
2915  {
2916  std::unique_ptr<weld::TreeIter> xPrevSibling(m_xTreeView->make_iterator(pCurrentEntry.get()));
2917  if (m_xTreeView->iter_previous_sibling(*xPrevSibling) && m_xTreeView->is_selected(*xPrevSibling))
2918  nDir = nDirLast;
2919  else
2920  {
2921  SwOutlineNodes::size_type nDest = nActPos;
2922  bEntry = true;
2923  m_xTreeView->copy_iterator(*pCurrentEntry, *xEntry);
2924  while (bEntry && nDest)
2925  {
2926  bEntry = m_xTreeView->iter_previous(*xEntry);
2927  assert(!bEntry || !lcl_IsContent(*xEntry, *m_xTreeView) ||
2928  dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
2929  if (bEntry && lcl_IsContent(*xEntry, *m_xTreeView))
2930  {
2931  nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlinePos();
2932  }
2933  else
2934  {
2935  nDest = 0; // presumably?
2936  }
2937  if (bEntry)
2938  {
2939  if (!lcl_IsContent(*xEntry, *m_xTreeView))
2940  break;
2941  else if (nActLevel >= reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetOutlineLevel())
2942  {
2943  // nDest needs adjusted if there are selected entries immediately
2944  // after the level change.
2945  std::unique_ptr<weld::TreeIter> xTmp(m_xTreeView->make_iterator(xEntry.get()));
2946  bool bTmp = m_xTreeView->iter_next(*xTmp);
2947  while (bTmp && lcl_IsContent(*xTmp, *m_xTreeView) &&
2948  nActLevel < reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlineLevel() &&
2949  m_xTreeView->is_selected(*xTmp))
2950  {
2951  nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlinePos();
2952  const auto nLevel = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlineLevel();
2953  // account for selected entries' descendent lineage
2954  bTmp = m_xTreeView->iter_next(*xTmp);
2955  while (bTmp && lcl_IsContent(*xTmp, *m_xTreeView) &&
2956  nLevel < reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlineLevel())
2957  {
2958  nDest = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xTmp).toInt64())->GetOutlinePos();
2959  bTmp = m_xTreeView->iter_next(*xTmp);
2960  }
2961  }
2962  break;
2963  }
2964  }
2965  }
2966  nDirLast = nDir = nDest - nActPos;
2967  }
2968  }
2969  if (nDir)
2970  {
2971  pShell->MoveOutlinePara( nDir );
2972  // Set cursor back to the current position
2973  pShell->GotoOutline(nActPos + nDir);
2974  }
2975  }
2976  }
2977  else
2978  {
2979  if (!pShell->IsProtectedOutlinePara())
2980  pShell->OutlineUpDown(bLeft ? -1 : 1);
2981  }
2982 
2983  pShell->ClearMark();
2984  pShell->Pop(SwCursorShell::PopMode::DeleteCurrent); // Cursor is now back at the current heading.
2985  }
2986 
2987  if (bStartedAction)
2988  {
2989  pShell->EndUndo();
2990  if (bUpDown)
2991  {
2993  {
2994  // fold all outlines that were folded before chapter promote/demote
2995  for (SwNode* pNd : aFoldedOutlineNdsArray)
2996  pShell->ToggleOutlineContentVisibility(pNd, true);
2997  }
2998  }
2999  pShell->EndAllAction();
3002 
3003  // clear all selections to prevent the Display function from trying to reselect selected entries
3004  m_xTreeView->unselect_all();
3005  Display(true);
3006 
3007  // reselect entries
3008  const SwOutlineNodes::size_type nCurrPos = pShell->GetOutlinePos(MAXLEVEL);
3009  std::unique_ptr<weld::TreeIter> xListEntry(m_xTreeView->make_iterator());
3010  bool bListEntry = m_xTreeView->get_iter_first(*xListEntry);
3011  while ((bListEntry = m_xTreeView->iter_next(*xListEntry)) && lcl_IsContent(*xListEntry, *m_xTreeView))
3012  {
3013  assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xListEntry).toInt64())));
3014  if (reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xListEntry).toInt64())->GetOutlinePos() == nCurrPos)
3015  {
3016  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(xListEntry.get()));
3017  if (m_xTreeView->iter_parent(*xParent) && !m_xTreeView->get_row_expanded(*xParent))
3018  m_xTreeView->expand_row(*xParent);
3019  m_xTreeView->set_cursor(*xListEntry); // unselect all entries, make entry visible, set focus, and select
3020  Select();
3021  break;
3022  }
3023  }
3024 
3025  if (m_bIsRoot)
3026  {
3027  const SwOutlineNodes& rOutLineNds = pShell->GetNodes().GetOutLineNds();
3028  for (SwTextNode* pNode : selectedOutlineNodes)
3029  {
3030  SwOutlineNodes::const_iterator aFndIt = rOutLineNds.find(pNode);
3031  if(aFndIt == rOutLineNds.end())
3032  continue;
3033  const size_t nFndPos = aFndIt - rOutLineNds.begin();
3034  std::unique_ptr<weld::TreeIter> xEntry = GetEntryAtAbsPos(nFndPos + 1);
3035  if (xEntry)
3036  {
3037  m_xTreeView->select(*xEntry);
3038  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(xEntry.get()));
3039  if (m_xTreeView->iter_parent(*xParent) && !m_xTreeView->get_row_expanded(*xParent))
3040  m_xTreeView->expand_row(*xParent);
3041  }
3042  }
3043  }
3044  }
3045  m_bIgnoreViewChange = false;
3046 }
3047 
3049 {
3050  m_xTreeView->show();
3051  m_aUpdTimer.Start();
3052 }
3053 
3055 {
3056  // folded together will not be idled
3057  m_aUpdTimer.Stop();
3058  m_xTreeView->hide();
3059 }
3060 
3062 IMPL_LINK_NOARG(SwContentTree, TimerUpdate, Timer *, void)
3063 {
3064  // No update while focus is not in document.
3065  // No update while drag and drop.
3066  // Query view because the Navigator is cleared too late.
3067  SwView* pView = GetParentWindow()->GetCreateView();
3068  if(pView && pView->GetWrtShellPtr() && pView->GetWrtShellPtr()->GetWin() &&
3069  (pView->GetWrtShellPtr()->GetWin()->HasFocus() || m_bViewHasChanged) &&
3070  !IsInDrag() && !pView->GetWrtShellPtr()->ActionPend())
3071  {
3072  m_bViewHasChanged = false;
3073  m_bIsIdleClear = false;
3074  SwWrtShell* pActShell = pView->GetWrtShellPtr();
3075  if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell))
3076  {
3077  SetActiveShell(pActShell);
3078  GetParentWindow()->UpdateListBox();
3079  }
3080 
3081  if (State::ACTIVE == m_eState && pActShell != GetWrtShell())
3082  {
3083  SetActiveShell(pActShell);
3084  }
3085  else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) &&
3086  HasContentChanged())
3087  {
3088  FindActiveTypeAndRemoveUserData();
3089  Display(true);
3090  }
3091 
3092  // track document outline position at cursor
3093  if (m_nOutlineTracking == 3) // no outline tracking
3094  return;
3095 
3096  const SwOutlineNodes::size_type nActPos = GetWrtShell()->GetOutlinePos(MAXLEVEL); // find out where the cursor is
3097  if (nActPos == SwOutlineNodes::npos)
3098  return;
3099 
3100  // only track if selection is already an outline
3101  std::unique_ptr<weld::TreeIter> xFirstSelected(m_xTreeView->make_iterator());
3102  if (!m_xTreeView->get_selected(xFirstSelected.get()))
3103  xFirstSelected.reset();
3104  if (xFirstSelected && lcl_IsContent(*xFirstSelected, *m_xTreeView) &&
3105  reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xFirstSelected).toInt64())->GetParent()->GetType() != ContentTypeId::OUTLINE)
3106  return;
3107  if (xFirstSelected && lcl_IsContentType(*xFirstSelected, *m_xTreeView) &&
3108  reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xFirstSelected).toInt64())->GetType() != ContentTypeId::OUTLINE)
3109  return;
3110 
3111  int nSelectedRows = m_xTreeView->count_selected_rows();
3112 
3113  // find the outline in the tree and select it
3114  m_xTreeView->all_foreach([this, nSelectedRows, nActPos, &xFirstSelected](weld::TreeIter& rEntry){
3115  bool bRet = false;
3116 
3117  if (lcl_IsContent(rEntry, *m_xTreeView) &&
3118  reinterpret_cast<SwContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetParent()->GetType() == ContentTypeId::OUTLINE)
3119  {
3120  // might have been scrolled out of view by the user so leave it that way
3121  if (reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos() == nActPos)
3122  {
3123  // only select if not already selected or tree has multiple entries selected
3124  if (nSelectedRows != 1 || m_xTreeView->iter_compare(rEntry, *xFirstSelected) != 0)
3125  {
3126  if (m_nOutlineTracking == 2) // focused outline tracking
3127  {
3128  // collapse to children of root node
3129  std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator());
3130  if (m_xTreeView->get_iter_first(*xChildEntry) && m_xTreeView->iter_children(*xChildEntry))
3131  {
3132  do
3133  {
3134  if (reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xChildEntry).toInt64())->GetParent()->GetType() == ContentTypeId::OUTLINE)
3135  m_xTreeView->collapse_row(*xChildEntry);
3136  else
3137  break;
3138  }
3139  while (m_xTreeView->iter_next(*xChildEntry));
3140  }
3141  }
3142  m_xTreeView->set_cursor(rEntry); // unselect all entries, make pEntry visible, and select
3143  Select();
3144  }
3145  bRet = true;
3146  }
3147  }
3148  else
3149  {
3150  // use of this break assumes outline content type is first in tree
3151  if (lcl_IsContentType(rEntry, *m_xTreeView) &&
3152  reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rEntry).toInt64())->GetType() != ContentTypeId::OUTLINE)
3153  bRet = true;
3154  }
3155 
3156  return bRet;
3157  });
3158  }
3159  else if (!pView && State::ACTIVE == m_eState && !m_bIsIdleClear)
3160  {
3161  if(m_pActiveShell)
3162  {
3163  SetActiveShell(nullptr);
3164  }
3165  clear();
3166  m_bIsIdleClear = true;
3167  }
3168 }
3169 
3171 {
3172  SwWrtShell *const pShell = GetWrtShell();
3173  pShell->StartAllAction();
3174  std::vector<SwNode*> aFoldedOutlineNdsArray;
3175 
3177  {
3178  // unfold all folded outline content
3179  SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds();
3180  for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos)
3181  {
3182  SwNode* pNd = rOutlineNds[nPos];
3183  if (pNd->IsTextNode()) // should always be true
3184  {
3185  bool bOutlineContentVisibleAttr = true;
3186  pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
3187  if (!bOutlineContentVisibleAttr)
3188  {
3189  aFoldedOutlineNdsArray.push_back(pNd);
3191  }
3192  }
3193  }
3194  }
3196 
3198  SwOutlineNodes::size_type nPrevTargetPosOrOffset = SwOutlineNodes::npos;
3199 
3200  bool bFirstMove = true;
3201 
3202  for (const auto& source : m_aDndOutlinesSelected)
3203  {
3204  SwOutlineNodes::size_type nSourcePos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*source).toInt64())->GetOutlinePos();
3205 
3206  // Done on the first selection move
3207  if (bFirstMove) // only do once
3208  {
3209  if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos)
3210  {
3211  // Up moves
3212  // The first up move sets the up move amount for the remaining selected outlines to be moved
3213  if (nTargetPos != SwOutlineNodes::npos)
3214  nPrevTargetPosOrOffset = nSourcePos - nTargetPos;
3215  else
3216  nPrevTargetPosOrOffset = nSourcePos + 1;
3217  }
3218  else if (nSourcePos < nTargetPos)
3219  {
3220  // Down moves
3221  // The first down move sets the source and target positions for the remaining selected outlines to be moved
3222  nPrevSourcePos = nSourcePos;
3223  nPrevTargetPosOrOffset = nTargetPos;
3224  }
3225  bFirstMove = false;
3226  }
3227  else
3228  {
3229  if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos)
3230  {
3231  // Move up
3232  nTargetPos = nSourcePos - nPrevTargetPosOrOffset;
3233  }
3234  else if (nSourcePos < nTargetPos)
3235  {
3236  // Move down
3237  nSourcePos = nPrevSourcePos;
3238  nTargetPos = nPrevTargetPosOrOffset;
3239  }
3240  }
3241  GetParentWindow()->MoveOutline(nSourcePos, nTargetPos);
3242  }
3243 
3244  pShell->EndUndo();
3246  {
3247  // fold all outlines that were folded before chapter promote/demote
3248  for (SwNode* pNd : aFoldedOutlineNdsArray)
3249  pShell->ToggleOutlineContentVisibility(pNd, true);
3250  }
3251  pShell->EndAllAction();
3253  Display(true);
3254  m_aDndOutlinesSelected.clear();
3255 }
3256 
3257 // Update immediately
3259 {
3260  SwView* pActView = GetParentWindow()->GetCreateView();
3261  if(pActView)
3262  {
3263  SwWrtShell* pActShell = pActView->GetWrtShellPtr();
3264  if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell))
3265  {
3266  SetActiveShell(pActShell);
3267  }
3268 
3269  if (State::ACTIVE == m_eState && pActShell != GetWrtShell())
3270  SetActiveShell(pActShell);
3271  else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) &&
3272  HasContentChanged())
3273  {
3274  Display(true);
3275  }
3276  }
3277  else if (State::ACTIVE == m_eState)
3278  clear();
3279 }
3280 
3281 IMPL_LINK(SwContentTree, KeyInputHdl, const KeyEvent&, rEvent, bool)
3282 {
3283  bool bConsumed = true;
3284 
3285  const vcl::KeyCode aCode = rEvent.GetKeyCode();
3286  if (aCode.GetCode() == KEY_MULTIPLY && aCode.IsMod1())
3287  {
3288  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3289  if (m_xTreeView->get_selected(xEntry.get()))
3290  ExpandOrCollapseAll(*m_xTreeView, *xEntry);
3291  }
3292  else if (aCode.GetCode() == KEY_RETURN)
3293  {
3294  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3295  if (m_xTreeView->get_selected(xEntry.get()))
3296  {
3297  switch(aCode.GetModifier())
3298  {
3299  case KEY_MOD2:
3300  // Switch boxes
3301  GetParentWindow()->ToggleTree();
3302  break;
3303  case KEY_MOD1:
3304  // Switch RootMode
3305  ToggleToRoot();
3306  break;
3307  case 0:
3308  if (lcl_IsContentType(*xEntry, *m_xTreeView))
3309  {
3310  m_xTreeView->get_row_expanded(*xEntry) ? m_xTreeView->collapse_row(*xEntry)
3311  : m_xTreeView->expand_row(*xEntry);
3312  }
3313  else
3314  ContentDoubleClickHdl(*m_xTreeView);
3315  break;
3316  }
3317  }
3318  }
3319  else if(aCode.GetCode() == KEY_DELETE && 0 == aCode.GetModifier())
3320  {
3321  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3322  if (m_xTreeView->get_selected(xEntry.get()) && lcl_IsContent(*xEntry, *m_xTreeView))
3323  {
3324  assert(dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
3325  if (reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64())->GetParent()->IsDeletable() &&
3326  !m_pActiveShell->GetView().GetDocShell()->IsReadOnly())
3327  {
3328  EditEntry(*xEntry, EditEntryMode::DELETE);
3329  }
3330  }
3331  }
3332  //Make KEY_SPACE has same function as DoubleClick ,
3333  //and realize multi-selection .
3334  else if (aCode.GetCode() == KEY_SPACE && 0 == aCode.GetModifier())
3335  {
3336  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3337  if (m_xTreeView->get_cursor(xEntry.get()))
3338  {
3339  if (State::HIDDEN != m_eState)
3340  {
3341  if (State::CONSTANT == m_eState)
3342  {
3343  m_pActiveShell->GetView().GetViewFrame()->GetWindow().ToTop();
3344  }
3345 
3346  SwContent* pCnt = dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64()));
3347 
3348  if (pCnt && pCnt->GetParent()->GetType() == ContentTypeId::DRAWOBJECT)
3349  {
3350  SdrView* pDrawView = m_pActiveShell->GetDrawView();
3351  if (pDrawView)
3352  {
3353  pDrawView->SdrEndTextEdit();
3354 
3355  SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
3356  SdrPage* pPage = pDrawModel->GetPage(0);
3357  const size_t nCount = pPage->GetObjCount();
3358  bool hasObjectMarked = false;
3359 
3360  if (SdrObject* pObject = GetDrawingObjectsByContent(pCnt))
3361  {
3362  SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/);
3363  if( pPV )
3364  {
3365  bool bUnMark = pDrawView->IsObjMarked(pObject);
3366  pDrawView->MarkObj( pObject, pPV, bUnMark);
3367 
3368  }
3369  }
3370  for( size_t i=0; i<nCount; ++i )
3371  {
3372  SdrObject* pTemp = pPage->GetObj(i);
3373  bool bMark = pDrawView->IsObjMarked(pTemp);
3374  switch( pTemp->GetObjIdentifier() )
3375  {
3376  case OBJ_GRUP:
3377  case OBJ_TEXT:
3378  case OBJ_LINE:
3379  case OBJ_RECT:
3380  case OBJ_CIRC:
3381  case OBJ_SECT:
3382  case OBJ_CARC:
3383  case OBJ_CCUT:
3384  case OBJ_POLY:
3385  case OBJ_PLIN:
3386  case OBJ_PATHLINE:
3387  case OBJ_PATHFILL:
3388  case OBJ_FREELINE:
3389  case OBJ_FREEFILL:
3390  case OBJ_PATHPOLY:
3391  case OBJ_PATHPLIN:
3392  case OBJ_CAPTION:
3393  case OBJ_CUSTOMSHAPE:
3394  if( bMark )
3395  hasObjectMarked = true;
3396  break;
3397  default:
3398  if ( bMark )
3399  {
3400  SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/);
3401  if (pPV)
3402  {
3403  pDrawView->MarkObj(pTemp, pPV, true);
3404  }
3405  }
3406  }
3407  //mod end
3408  }
3409  if ( !hasObjectMarked )
3410  {
3411  SwEditWin& rEditWindow = m_pActiveShell->GetView().GetEditWin();
3412  vcl::KeyCode tempKeycode( KEY_ESCAPE );
3413  KeyEvent rKEvt( 0 , tempKeycode );
3414  static_cast<vcl::Window*>(&rEditWindow)->KeyInput( rKEvt );
3415  }
3416  }
3417  }
3418 
3419  m_bViewHasChanged = true;
3420  }
3421  }
3422  }
3423  else
3424  {
3425  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3426  if (m_xTreeView->get_cursor(xEntry.get()))
3427  {
3428  SwContent* pCnt = dynamic_cast<SwContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64()));
3429  if (pCnt && pCnt->GetParent()->GetType() == ContentTypeId::OUTLINE)
3430  {
3431  if (m_bIsRoot && aCode.GetCode() == KEY_LEFT && aCode.GetModifier() == 0)
3432  {
3433  m_xTreeView->unselect_all();
3434  bConsumed = false;
3435  }
3436  else if (aCode.IsMod1())
3437  {
3438  if (aCode.GetCode() == KEY_LEFT)
3439  ExecCommand("promote", !aCode.IsShift());
3440  else if (aCode.GetCode() == KEY_RIGHT)
3441  ExecCommand("demote", !aCode.IsShift());
3442  else if (aCode.GetCode() == KEY_UP)
3443  ExecCommand("chapterup", !aCode.IsShift());
3444  else if (aCode.GetCode() == KEY_DOWN)
3445  ExecCommand("chapterdown", !aCode.IsShift());
3446  else
3447  bConsumed = false;
3448  }
3449  else
3450  bConsumed = false;
3451  }
3452  else
3453  bConsumed = false;
3454  }
3455  else
3456  bConsumed = false;
3457  }
3458  return bConsumed;
3459 }
3460 
3461 IMPL_LINK(SwContentTree, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
3462 {
3464  bool bContent = false;
3465  void* pUserData = reinterpret_cast<void*>(m_xTreeView->get_id(rEntry).toInt64());
3466  if (lcl_IsContentType(rEntry, *m_xTreeView))
3467  {
3468  assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pUserData)));
3469  nType = static_cast<SwContentType*>(pUserData)->GetType();
3470  }
3471  else
3472  {
3473  assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pUserData)));
3474  nType = static_cast<SwContent*>(pUserData)->GetParent()->GetType();
3475  bContent = true;
3476  }
3477  OUString sEntry;
3478  if(bContent)
3479  {
3480  switch( nType )
3481  {
3483  assert(dynamic_cast<SwURLFieldContent*>(static_cast<SwTypeNumber*>(pUserData)));
3484  sEntry = static_cast<SwURLFieldContent*>(pUserData)->GetURL();
3485  break;
3486 
3487  case ContentTypeId::POSTIT:
3488  assert(dynamic_cast<SwPostItContent*>(static_cast<SwTypeNumber*>(pUserData)));
3489  sEntry = static_cast<SwPostItContent*>(pUserData)->GetName();
3490  break;
3492  assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pUserData)));
3493  sEntry = static_cast<SwOutlineContent*>(pUserData)->GetName();
3494  break;
3496  assert(dynamic_cast<SwGraphicContent*>(static_cast<SwTypeNumber*>(pUserData)));
3497  sEntry = static_cast<SwGraphicContent*>(pUserData)->GetLink();
3498  break;
3499  case ContentTypeId::REGION:
3500  {
3501  assert(dynamic_cast<SwRegionContent*>(static_cast<SwTypeNumber*>(pUserData)));
3502  sEntry = static_cast<SwRegionContent*>(pUserData)->GetName();
3503  const SwSectionFormats& rFormats = GetWrtShell()->GetDoc()->GetSections();
3504  for (SwSectionFormats::size_type n = rFormats.size(); n;)
3505  {
3506  const SwNodeIndex* pIdx = nullptr;
3507  const SwSectionFormat* pFormat = rFormats[--n];
3508  const SwSection* pSect;
3509  if (nullptr != (pSect = pFormat->GetSection()) &&
3510  pSect->GetSectionName() == sEntry &&
3511  nullptr != (pIdx = pFormat->GetContent().GetContentIdx()) &&
3512  pIdx->GetNode().GetNodes().IsDocNodes())
3513  {
3514  SwDocStat aDocStat;
3515  SwPaM aPaM(*pIdx, *pIdx->GetNode().EndOfSectionNode());
3516  SwDoc::CountWords(aPaM, aDocStat);
3517  sEntry = SwResId(STR_REGION_DEFNAME) + ": " + sEntry + "\n" +
3518  SwResId(FLD_STAT_WORD) + ": " + OUString::number(aDocStat.nWord) + "\n" +
3519  SwResId(FLD_STAT_CHAR) + ": " + OUString::number(aDocStat.nChar);
3520  break;
3521  }
3522  }
3523  }
3524  break;
3525  default: break;
3526  }
3527  if(static_cast<SwContent*>(pUserData)->IsInvisible())
3528  {
3529  if(!sEntry.isEmpty())
3530  sEntry += ", ";
3531  sEntry += m_sInvisible;
3532  }
3533  }
3534  else
3535  {
3536  const size_t nMemberCount = static_cast<SwContentType*>(pUserData)->GetMemberCount();
3537  sEntry = OUString::number(nMemberCount) + " " +
3538  (nMemberCount == 1
3539  ? static_cast<SwContentType*>(pUserData)->GetSingleName()
3540  : static_cast<SwContentType*>(pUserData)->GetName());
3541  }
3542 
3543  return sEntry;
3544 }
3545 
3546 void SwContentTree::ExecuteContextMenuAction(const OString& rSelectedPopupEntry)
3547 {
3548  std::unique_ptr<weld::TreeIter> xFirst(m_xTreeView->make_iterator());
3549  if (!m_xTreeView->get_selected(xFirst.get()))
3550  xFirst.reset();
3551 
3552  auto nSelectedPopupEntry = rSelectedPopupEntry.toUInt32();
3553  switch (nSelectedPopupEntry)
3554  {
3555  case 1512: // fold or unfold outline content of selected entry
3556  case 1513: // fold outline content of selected entry and descendants
3557  case 1514: // unfold outline content of selected entry and descendants
3558  {
3560  m_bIgnoreViewChange = true;
3561  SwOutlineContent* pCntFirst = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xFirst).toInt64());
3562  if (nSelectedPopupEntry == 1512)
3563  {
3565  }
3566  else
3567  {
3568  // with subs
3570  if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry
3571  nPos = SwOutlineNodes::npos;
3573  int nLevel = -1;
3574  if (nPos != SwOutlineNodes::npos) // not root
3576  else
3577  nPos = 0;
3578  bool bFold(nSelectedPopupEntry == 1514);
3579  do
3580  {
3581  if (m_pActiveShell->IsOutlineContentFolded(nPos) == bFold)
3583  } while (++nPos < nOutlineNodesCount
3584  && (nLevel == -1 || m_pActiveShell->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel));
3585  }
3586  if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry
3587  m_pActiveShell->GotoPage(1, true);
3588  else
3589  GotoContent(pCntFirst);
3590  grab_focus();
3591  m_bIgnoreViewChange = false;
3592  }
3593  break;
3594  case 11:
3595  case 12:
3596  case 13:
3597  nSelectedPopupEntry -= 10;
3598  if(m_nOutlineTracking != nSelectedPopupEntry)
3599  m_nOutlineTracking = nSelectedPopupEntry;
3600  break;
3601  //Outlinelevel
3602  case 101:
3603  case 102:
3604  case 103:
3605  case 104:
3606  case 105:
3607  case 106:
3608  case 107:
3609  case 108:
3610  case 109:
3611  case 110:
3612  nSelectedPopupEntry -= 100;
3613  if(m_nOutlineLevel != nSelectedPopupEntry )
3614  SetOutlineLevel(static_cast<sal_Int8>(nSelectedPopupEntry));
3615  break;
3616  case 201:
3617  case 202:
3618  case 203:
3619  GetParentWindow()->SetRegionDropMode(static_cast<RegionMode>(nSelectedPopupEntry - 201));
3620  break;
3621  case 401:
3622  case 402:
3623  EditEntry(*xFirst, nSelectedPopupEntry == 401 ? EditEntryMode::RMV_IDX : EditEntryMode::UPD_IDX);
3624  break;
3625  // Edit entry
3626  case 403:
3627  EditEntry(*xFirst, EditEntryMode::EDIT);
3628  break;
3629  case 404:
3631  break;
3632  case 405 :
3633  {
3634  const SwTOXBase* pBase = reinterpret_cast<SwTOXBaseContent*>(m_xTreeView->get_id(*xFirst).toInt64())
3635  ->GetTOXBase();
3637  }
3638  break;
3639  case 4:
3640  break;
3641  case 501:
3642  EditEntry(*xFirst, EditEntryMode::DELETE);
3643  break;
3644  case 502 :
3645  EditEntry(*xFirst, EditEntryMode::RENAME);
3646  break;
3647  case 600:
3649  break;
3650  case 601:
3652  break;
3653  case 602:
3654  {
3657  break;
3658  }
3659  case 700:
3660  {
3662  break;
3663  }
3664  case 800:
3665  ExpandOrCollapseAll(*m_xTreeView, *xFirst);
3666  break;
3667  case 801:
3668  ExecCommand("chapterup", true);
3669  break;
3670  case 802:
3671  ExecCommand("chapterdown", true);
3672  break;
3673  case 803:
3674  ExecCommand("promote", true);
3675  break;
3676  case 804:
3677  ExecCommand("demote", true);
3678  break;
3679  case 805:
3680  {
3684  SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xFirst).toInt64());
3685  const ContentTypeId eTypeId = pCnt->GetParent()->GetType();
3686  if (eTypeId == ContentTypeId::OUTLINE)
3687  {
3688  m_xTreeView->selected_foreach([this](weld::TreeIter& rEntry){
3690  SwOutlineNodes::size_type nActPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos();
3691  m_pActiveShell->MakeOutlineSel(nActPos, nActPos, !m_xTreeView->get_row_expanded(rEntry), false); // select children if not expanded
3693  return false;
3694  });
3695  }
3696  else if (eTypeId == ContentTypeId::TABLE)
3697  {
3698  m_pActiveShell->GotoTable(pCnt->GetName());
3700  }
3701  else if (eTypeId == ContentTypeId::REGION)
3702  {
3704  m_pActiveShell->GotoRegion(pCnt->GetName());
3710  }
3712  }
3713  break;
3714  case 806:
3715  // Delete outline selections
3716  EditEntry(*xFirst, EditEntryMode::DELETE);
3717  break;
3718  case 900:
3719  {
3720  SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xFirst).toInt64());
3721  GotoContent(pCnt);
3722  }
3723  break;
3724  //Display
3725  default:
3726  if(nSelectedPopupEntry > 300 && nSelectedPopupEntry < 400)
3727  {
3728  nSelectedPopupEntry -= 300;
3729  SwView *pView = SwModule::GetFirstView();
3730  while (pView)
3731  {
3732  nSelectedPopupEntry --;
3733  if(nSelectedPopupEntry == 0)
3734  {
3735  SetConstantShell(&pView->GetWrtShell());
3736  break;
3737  }
3738  pView = SwModule::GetNextView(pView);
3739  }
3740  if(nSelectedPopupEntry)
3741  {
3742  m_bViewHasChanged = nSelectedPopupEntry == 1;
3743  m_eState = (nSelectedPopupEntry == 1) ? State::ACTIVE : State::HIDDEN;
3744  Display(nSelectedPopupEntry == 1);
3745  }
3746  }
3747  }
3749 }
3750 
3752 {
3755  auto nChapters(0);
3756 
3757  m_xTreeView->selected_foreach([this, &nChapters](weld::TreeIter& rEntry){
3758  ++nChapters;
3759  if (m_xTreeView->iter_has_child(rEntry) &&
3760  !m_xTreeView->get_row_expanded(rEntry)) // only count children if not expanded
3761  {
3762  nChapters += m_xTreeView->iter_n_children(rEntry);
3763  }
3765  SwOutlineNodes::size_type nActPos = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos();
3766  m_pActiveShell->MakeOutlineSel(nActPos, nActPos, !m_xTreeView->get_row_expanded(rEntry), false); // select children if not expanded
3768  return false;
3769  });
3771  SwRewriter aRewriter;
3772  aRewriter.AddRule(UndoArg1, SwResId(STR_CHAPTERS, nChapters));
3779 }
3780 
3782 {
3783  m_nOutlineLevel = nSet;
3785  std::unique_ptr<SwContentType>& rpContentT = (State::ACTIVE == m_eState)
3788  if(rpContentT)
3789  {
3790  rpContentT->SetOutlineLevel(m_nOutlineLevel);
3791  rpContentT->Init();
3792  }
3794 }
3795 
3796 // Mode Change: Show dropped Doc
3798 {
3799  if(m_pHiddenShell)
3800  {
3802  Display(false);
3803  }
3804 }
3805 
3806 // Mode Change: Show active view
3808 {
3810  Display(true);
3812 }
3813 
3815 {
3816  Select();
3817 }
3818 
3819 // Here the buttons for moving outlines are en-/disabled.
3821 {
3822  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3823  if (!m_xTreeView->get_selected(xEntry.get()))
3824  return;
3825 
3826  bool bEnable = false;
3827  std::unique_ptr<weld::TreeIter> xParentEntry(m_xTreeView->make_iterator(xEntry.get()));
3828  bool bParentEntry = m_xTreeView->iter_parent(*xParentEntry);
3829  while (bParentEntry && (!lcl_IsContentType(*xParentEntry, *m_xTreeView)))
3830  bParentEntry = m_xTreeView->iter_parent(*xParentEntry);
3831  if (!m_bIsLastReadOnly)
3832  {
3833  if (!m_xTreeView->get_visible())
3834  bEnable = true;
3835  else if (bParentEntry)
3836  {
3838  (lcl_IsContent(*xEntry, *m_xTreeView) &&
3839  reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xParentEntry).toInt64())->GetType() == ContentTypeId::OUTLINE))
3840  {
3841  bEnable = true;
3842  }
3843  }
3844  }
3845  SwNavigationPI* pNavi = GetParentWindow();
3846  pNavi->m_xContent3ToolBox->set_item_sensitive("chapterup", bEnable);
3847  pNavi->m_xContent3ToolBox->set_item_sensitive("chapterdown", bEnable);
3848  pNavi->m_xContent3ToolBox->set_item_sensitive("promote", bEnable);
3849  pNavi->m_xContent3ToolBox->set_item_sensitive("demote", bEnable);
3850 }
3851 
3853 {
3854  m_nRootType = nType;
3855  m_bIsRoot = true;
3857 }
3858 
3859 OUString SwContentType::RemoveNewline(const OUString& rEntry)
3860 {
3861  if (rEntry.isEmpty())
3862  return rEntry;
3863 
3864  OUStringBuffer aEntry(rEntry);
3865  for (sal_Int32 i = 0; i < rEntry.getLength(); ++i)
3866  if(aEntry[i] == 10 || aEntry[i] == 13)
3867  aEntry[i] = 0x20;
3868 
3869  return aEntry.makeStringAndClear();
3870 }
3871 
3873 {
3874  SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(rEntry).toInt64());
3875  GotoContent(pCnt);
3876  const ContentTypeId nType = pCnt->GetParent()->GetType();
3877  sal_uInt16 nSlot = 0;
3878 
3879  uno::Reference< container::XNameAccess > xNameAccess, xSecond, xThird;
3880  switch(nType)
3881  {
3882  case ContentTypeId::OUTLINE :
3883  if(nMode == EditEntryMode::DELETE)
3884  {
3886  }
3887  break;
3888 
3889  case ContentTypeId::TABLE :
3890  if(nMode == EditEntryMode::UNPROTECT_TABLE)
3891  {
3893  GetDoc()->UnProtectCells( pCnt->GetName());
3894  }
3895  else if(nMode == EditEntryMode::DELETE)
3896  {
3898  OUString sTable = SwResId(STR_TABLE_NAME);
3899  SwRewriter aRewriterTableName;
3900  aRewriterTableName.AddRule(UndoArg1, SwResId(STR_START_QUOTE));
3901  aRewriterTableName.AddRule(UndoArg2, pCnt->GetName());
3902  aRewriterTableName.AddRule(UndoArg3, SwResId(STR_END_QUOTE));
3903  sTable = aRewriterTableName.Apply(sTable);
3904 
3905  SwRewriter aRewriter;
3906  aRewriter.AddRule(UndoArg1, sTable);
3912  }
3913  else if(nMode == EditEntryMode::RENAME)
3914  {
3915  uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
3916  uno::Reference< text::XTextTablesSupplier > xTables(xModel, uno::UNO_QUERY);
3917  xNameAccess = xTables->getTextTables();
3918  }
3919  else
3920  nSlot = FN_FORMAT_TABLE_DLG;
3921  break;
3922 
3923  case ContentTypeId::GRAPHIC :
3924  if(nMode == EditEntryMode::DELETE)
3925  {
3927  }
3928  else if(nMode == EditEntryMode::RENAME)
3929  {
3930  uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
3931  uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
3932  xNameAccess = xGraphics->getGraphicObjects();
3933  uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
3934  xSecond = xFrames->getTextFrames();
3935  uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
3936  xThird = xObjs->getEmbeddedObjects();
3937  }
3938  else
3939  nSlot = FN_FORMAT_GRAFIC_DLG;
3940  break;
3941 
3942  case ContentTypeId::FRAME :
3943  case ContentTypeId::OLE :
3944  if(nMode == EditEntryMode::DELETE)
3945  {
3947  }
3948  else if(nMode == EditEntryMode::RENAME)
3949  {
3950  uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
3951  uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
3952  uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
3953  if(ContentTypeId::FRAME == nType)
3954  {
3955  xNameAccess = xFrames->getTextFrames();
3956  xSecond = xObjs->getEmbeddedObjects();
3957  }
3958  else
3959  {
3960  xNameAccess = xObjs->getEmbeddedObjects();
3961  xSecond = xFrames->getTextFrames();
3962  }
3963  uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
3964  xThird = xGraphics->getGraphicObjects();
3965  }
3966  else
3967  nSlot = FN_FORMAT_FRAME_DLG;
3968  break;
3971  if(nMode == EditEntryMode::DELETE)
3972  {
3974  pMarkAccess->deleteMark( pMarkAccess->findMark(pCnt->GetName()) );
3975  }
3976  else if(nMode == EditEntryMode::RENAME)
3977  {
3978  uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
3979  uno::Reference< text::XBookmarksSupplier > xBkms(xModel, uno::UNO_QUERY);
3980  xNameAccess = xBkms->getBookmarks();
3981  }
3982  else
3983  nSlot = FN_INSERT_BOOKMARK;
3984  break;
3985 
3986  case ContentTypeId::REGION :
3987  if(nMode == EditEntryMode::RENAME)
3988  {
3989  uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
3990  uno::Reference< text::XTextSectionsSupplier > xSects(xModel, uno::UNO_QUERY);
3991  xNameAccess = xSects->getTextSections();
3992  }
3993  else
3994  nSlot = FN_EDIT_REGION;
3995  break;
3996 
3998  if (nMode == EditEntryMode::DELETE)
3999  nSlot = SID_REMOVE_HYPERLINK;
4000  else
4001  nSlot = SID_EDIT_HYPERLINK;
4002  break;
4004  nSlot = FN_EDIT_FIELD;
4005  break;
4006 
4007  case ContentTypeId::POSTIT:
4009  if(nMode == EditEntryMode::DELETE)
4010  {
4013  }
4014  else
4015  {
4016  nSlot = FN_POSTIT;
4017  }
4018  break;
4019  case ContentTypeId::INDEX:
4020  {
4021  const SwTOXBase* pBase = static_cast<SwTOXBaseContent*>(pCnt)->GetTOXBase();
4022  switch(nMode)
4023  {
4024  case EditEntryMode::EDIT:
4025  if(pBase)
4026  {
4027  SwPtrItem aPtrItem( FN_INSERT_MULTI_TOX, const_cast<SwTOXBase *>(pBase));
4030  SfxCallMode::ASYNCHRON, { &aPtrItem });
4031 
4032  }
4033  break;
4035  case EditEntryMode::DELETE:
4036  {
4037  if( pBase )
4038  m_pActiveShell->DeleteTOX(*pBase, EditEntryMode::DELETE == nMode);
4039  }
4040  break;
4042  case EditEntryMode::RENAME:
4043  {
4045  Reference< XDocumentIndexesSupplier > xIndexes(xModel, UNO_QUERY);
4046  Reference< XIndexAccess> xIdxAcc(xIndexes->getDocumentIndexes());
4047  Reference< XNameAccess >xLocalNameAccess(xIdxAcc, UNO_QUERY);
4048  if(EditEntryMode::RENAME == nMode)
4049  xNameAccess = xLocalNameAccess;
4050  else if(xLocalNameAccess.is() && xLocalNameAccess->hasByName(pBase->GetTOXName()))
4051  {
4052  Any aIdx = xLocalNameAccess->getByName(pBase->GetTOXName());
4053  Reference< XDocumentIndex> xIdx;
4054  if(aIdx >>= xIdx)
4055  xIdx->update();
4056  }
4057  }
4058  break;
4059  default: break;
4060  }
4061  }
4062  break;
4064  if(EditEntryMode::DELETE == nMode)
4065  nSlot = SID_DELETE;
4066  else if(nMode == EditEntryMode::RENAME)
4067  nSlot = FN_NAME_SHAPE;
4068  break;
4069  default: break;
4070  }
4071  if(nSlot)
4073  GetDispatcher()->Execute(nSlot, SfxCallMode::ASYNCHRON);
4074  else if(xNameAccess.is())
4075  {
4076  uno::Any aObj = xNameAccess->getByName(pCnt->GetName());
4077  uno::Reference< uno::XInterface > xTmp;
4078  aObj >>= xTmp;
4079  uno::Reference< container::XNamed > xNamed(xTmp, uno::UNO_QUERY);
4082  if(xSecond.is())
4083  pDlg->SetAlternativeAccess( xSecond, xThird);
4084 
4085  OUString sForbiddenChars;
4086  if(ContentTypeId::BOOKMARK == nType)
4087  {
4088  sForbiddenChars = "/\\@:*?\";,.#";
4089  }
4090  else if(ContentTypeId::TABLE == nType)
4091  {
4092  sForbiddenChars = " .<>";
4093  }
4094  pDlg->SetForbiddenChars(sForbiddenChars);
4095  pDlg->Execute();
4096  }
4097  if(EditEntryMode::DELETE == nMode)
4098  {
4099  m_bViewHasChanged = true;
4101  TimerUpdate(&m_aUpdTimer);
4102  grab_focus();
4103  }
4104 }
4105 
4107 {
4109 
4110  bool bSel = false;
4111  switch(pCnt->GetParent()->GetType())
4112  {
4113  case ContentTypeId::OUTLINE :
4114  {
4115  m_pActiveShell->GotoOutline(static_cast<const SwOutlineContent*>(pCnt)->GetOutlinePos());
4116  }
4117  break;
4118  case ContentTypeId::TABLE :
4119  {
4120  m_pActiveShell->GotoTable(pCnt->GetName());
4121  }
4122  break;
4123  case ContentTypeId::FRAME :
4124  case ContentTypeId::GRAPHIC :
4125  case ContentTypeId::OLE :
4126  {
4127  if(m_pActiveShell->GotoFly(pCnt->GetName()))
4128  bSel = true;
4129  }
4130  break;
4132  {
4133  m_pActiveShell->GotoMark(pCnt->GetName());
4134  }
4135  break;
4136  case ContentTypeId::REGION :
4137  {
4138  m_pActiveShell->GotoRegion(pCnt->GetName());
4139  }
4140  break;
4142  {
4144  *static_cast<const SwURLFieldContent*>(pCnt)->GetINetAttr() ))
4145  {
4146  m_pActiveShell->Right( CRSR_SKIP_CHARS, true, 1, false);
4147  m_pActiveShell->SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true );
4148  }
4149 
4150  }
4151  break;
4153  {
4155  }
4156  break;
4157  case ContentTypeId::INDEX:
4158  {
4159  const OUString& sName(pCnt->GetName());
4162  }
4163  break;
4164  case ContentTypeId::POSTIT:
4166  m_pActiveShell->GotoFormatField(*static_cast<const SwPostItContent*>(pCnt)->GetPostIt());
4167  break;
4169  {
4171  SdrView* pDrawView = m_pActiveShell->GetDrawView();
4172  if (pDrawView)
4173  {
4174  pDrawView->SdrEndTextEdit();
4175  pDrawView->UnmarkAll();
4177  SdrPage* pPage = _pModel->GetPage(0);
4178  const size_t nCount = pPage->GetObjCount();
4179  for( size_t i=0; i<nCount; ++i )
4180  {
4181  SdrObject* pTemp = pPage->GetObj(i);
4182  if (pTemp->GetName() == pCnt->GetName())
4183  {
4184  SdrPageView* pPV = pDrawView->GetSdrPageView();
4185  if( pPV )
4186  {
4187  pDrawView->MarkObj( pTemp, pPV );
4188  }
4189  }
4190  }
4193  bSel = true;
4194  }
4195  }
4196  break;
4197  default: break;
4198  }
4199  if(bSel)
4200  {
4203  }
4204  SwView& rView = m_pActiveShell->GetView();
4205  rView.StopShellTimer();
4206  rView.GetPostItMgr()->SetActiveSidebarWin(nullptr);
4207  rView.GetEditWin().GrabFocus();
4208 
4209  // force scroll to cursor position when navigating to inactive document
4210  if(!bSel)
4211  {
4212  Point rPoint = m_pActiveShell->GetCursorDocPos();
4213  rPoint.setX(0);
4214  rView.SetVisArea(rPoint);
4215  }
4216 }
4217 
4218 // Now even the matching text::Bookmark
4220  :
4221  nDocSh(0),
4222  nDefDrag( RegionMode::NONE )
4223 {
4224 }
4225 
4227  const OUString& rDesc,
4228  RegionMode nDragType,
4229  const SwDocShell* pDocSh ) :
4230  aUrl( rUrl ),
4231  aDescr(rDesc),
4232  nDocSh(reinterpret_cast<sal_IntPtr>(pDocSh)),
4233  nDefDrag( nDragType )
4234 {
4235 }
4236 
4238 {
4239  rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding();
4240 
4241  OString sStrBuf(OUStringToOString(aUrl, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) +
4242  OUStringToOString(aDescr, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) +
4243  OString::number(static_cast<int>(nDefDrag)) + OStringChar(NAVI_BOOKMARK_DELIM) +
4244  OString::number(nDocSh));
4245  rData.CopyByteString(SotClipboardFormatId::SONLK, sStrBuf);
4246 }
4247 
4249 {
4250  OUString sStr;
4251  bool bRet = rData.GetString( SotClipboardFormatId::SONLK, sStr );
4252  if( bRet )
4253  {
4254  sal_Int32 nPos = 0;
4255  aUrl = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos );
4256  aDescr = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos );
4257  nDefDrag= static_cast<RegionMode>( sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ).toInt32() );
4258  nDocSh = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ).toInt32();
4259  }
4260  return bRet;
4261 }
4262 
4264 {
4265  return m_xDialog;
4266 }
4267 
4268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const char * STR_CONTENT_TYPE_ARY[]
Definition: content.cxx:212
SfxViewFrame * GetViewFrame() const
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
void StopShellTimer()
Definition: view.cxx:1750
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:66
void FillMemberList(bool *pbLevelChanged=nullptr)
Fill the List of contents.
Definition: content.cxx:521
bool RequestingChildren(const weld::TreeIter &rParent)
Definition: content.cxx:1564
void Init(bool *pbInvalidateWindow=nullptr)
Definition: content.cxx:282
void DeleteOutlineSelections()
Definition: content.cxx:3751
ContentTypeId
Definition: swcont.hxx:28
virtual bool IsProtect() const override
Definition: content.cxx:199
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
bool Right(sal_uInt16 nMode, bool bSelect, sal_uInt16 nCount, bool bBasicCall, bool bVisual=false)
Definition: move.cxx:123
void KillPams()
Definition: crsrsh.cxx:1020
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1566
const Value & back() const
OUString sText
Definition: editsh.hxx:119
void CopyINetBookmark(const INetBookmark &rBkmk)
virtual void set_sensitive(const OString &rIdent, bool bSensitive)=0
bool bVisible
size_t GetTableFrameFormatCount(bool bUsed=false) const
TABLE.
Definition: edfmt.cxx:101
#define FN_EDIT_REGION
Definition: cmdid.h:108
OUString m_sTypeToken
Definition: content.hxx:145
Marks a position in the document model.
Definition: pam.hxx:35
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2087
OBJ_CUSTOMSHAPE
virtual int count_selected_rows() const =0
constexpr sal_uInt16 KEY_MOD1
SdrView * GetDrawView()
Definition: vnew.cxx:375
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:189
const OUStringLiteral IsReadOnly("IsReadOnly")
size_t GetChildCount(const weld::TreeIter &rParent) const
Definition: content.cxx:1915
ContentTypeId m_nRootType
Definition: conttree.hxx:107
OUString GetTitle(sal_uInt16 nMaxLen=0) const
SwView * GetActiveView()
Definition: swmodul1.cxx:116
SwContentTreeDropTarget(SwContentTree &rTreeView)
Definition: content.cxx:977
void SetRegionDropMode(RegionMode nNewMode)
Definition: navipi.cxx:976
size_t GetAbsPos(const weld::TreeView &rTreeView, const weld::TreeIter &rIter)
void SetHiddenShell(SwWrtShell *pSh)
After a file is dropped on the Navigator, the new shell will be set.
Definition: content.cxx:2599
bool IsProtect() const
Definition: atrfld.cxx:400
virtual OUString getOutlineText(const tSortedOutlineNodeList::size_type nIdx, SwRootFrame const *pLayout, const bool bWithNumber=true, const bool bWithSpacesForLevel=false, const bool bWithFootnote=true) const =0
OUString m_aContextStrings[CONTEXT_COUNT+1]
Definition: conttree.hxx:95
signed char sal_Int8
void ShowActualView()
Definition: content.cxx:3807
std::vector< SwNode * >::difference_type difference_type
SwWrtShell * m_pHiddenShell
Definition: conttree.hxx:98
const SwView & GetView() const
Definition: edtwin.hxx:243
void ExecCommand(const OString &rCmd, bool bModifier)
Execute commands of the Navigator.
Definition: content.cxx:2709
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2610
OBJ_TEXT
SfxDispatcher * GetDispatcher()
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
const_iterator begin() const
Definition: PostItMgr.hxx:178
IMPL_LINK(SwContentTree, DragBeginHdl, bool &, rUnsetDragIcon, bool)
Definition: content.cxx:926
bool HasContentChanged()
Check if the displayed content is valid.
Definition: content.cxx:2363
sal_uIntPtr sal_uLong
void SetOutlineLevel(sal_Int32 nSet)
Definition: navicfg.hxx:57
void UpdateLastSelType()
Definition: content.cxx:2571
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2686
bool Pop(SwCursorShell::PopMode=SwCursorShell::PopMode::DeleteStack)
Definition: wrtsh1.cxx:1718
void Select()
Definition: content.cxx:3820
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
sal_Int64 n
SwContentTree(std::unique_ptr< weld::TreeView > xTreeView, SwNavigationPI *pDialog)
Definition: content.cxx:865
Provides access to the marks of a document.
SdrObject * GetObj(size_t nNum) const
OBJ_PATHPOLY
#define FN_FORMAT_TABLE_DLG
Definition: cmdid.h:319
size_t GetObjCount() const
sal_uLong nChar
Definition: docstat.hxx:37
void GotoFormatField(const SwFormatField &rField)
Definition: move.cxx:664
bool addEntry(const SwPosition &rPos)
Definition: navmgr.cxx:170
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false)
sal_Int16 nId
bool GotoINetAttr(const SwTextINetFormat &rAttr)
Definition: move.cxx:603
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
const_iterator find(const Value &x) const
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2583
#define DND_ACTION_COPYMOVE
sal_uInt16 GetCode() const
SwNode & GetNode() const
Definition: ndindex.hxx:119
void SetActiveSidebarWin(sw::annotation::SwAnnotationWin *p)
Definition: PostItMgr.cxx:2134
void CopyByteString(SotClipboardFormatId nFormatId, const OString &rStr)
void EnterStdMode()
Definition: select.cxx:550
SwEditWin & GetEditWin()
Definition: view.hxx:401
static void lcl_SetOutlineContentEntriesSensitivities(SwContentTree *pThis, weld::TreeView &rContentTree, weld::TreeIter &rEntry, weld::Menu &rPop)
Definition: content.cxx:1155
sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt)
Definition: navipi.cxx:935
VclPtr< SwNavigationPI > m_xDialog
Definition: conttree.hxx:89
bool IsTOXBaseInReadonly() const
Definition: doctxm.cxx:2013
OBJ_POLY
const SwDoc & GetDoc() const
Definition: drawdoc.hxx:35
constexpr sal_uInt16 KEY_SPACE
bool bReadOnly
OBJ_FREEFILL
#define FN_FORMAT_GRAFIC_DLG
Definition: cmdid.h:318
EmbeddedObjectRef * pObject
sal_uInt8 GetOutlineLevel() const
Definition: conttree.hxx:210
void EndAllAction()
Definition: edws.cxx:97
void HideTree()
Definition: content.cxx:3054
virtual bool GetInfo(SfxPoolItem &) const override
Definition: calbck.cxx:206
#define FN_EDIT_FIELD
Definition: cmdid.h:70
bool GotoTable(const OUString &rName)
Definition: move.cxx:655
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4109
OBJ_PLIN
SfxHintId GetId() const
weld::TreeView & get_widget()
Definition: conttree.hxx:266
OBJ_RECT
constexpr sal_uInt16 KEY_UP
static bool IsTOXBaseReadonly(const SwTOXBase &rTOXBase)
Definition: edtox.cxx:91
void EditEntry(const weld::TreeIter &rEntry, EditEntryMode nMode)
Definition: content.cxx:3872
void UpdateListBox()
Definition: navipi.cxx:794
bool IsProtect() const
Definition: txtatr2.cxx:184
void SetVisArea(const tools::Rectangle &, bool bUpdateScrollbar=true)
Definition: viewport.cxx:195
void ExecuteContextMenuAction(const OString &rSelectedPopupEntry)
Definition: content.cxx:3546
bool DelRight()
Definition: delete.cxx:292
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const =0
SwWrtShell & GetWrtShell() const
Definition: view.hxx:398
bool MakeOutlineSel(SwOutlineNodes::size_type nSttPos, SwOutlineNodes::size_type nEndPos, bool bWithChildren, bool bKillPams=true)
Definition: crstrvl.cxx:1158
void GetINetAttrs(SwGetINetAttrs &rArr)
Definition: editsh.cxx:687
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:154
Array of Undo-history.
Definition: docary.hxx:197
#define DND_ACTION_MOVE
SwNavigationMgr & GetNavigationMgr()
Definition: wrtsh.hxx:470
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_CONTENT_VISIBLE(183)
sal_uInt16 GetRefMarks(std::vector< OUString > *=nullptr) const
get the names of all references in a Doc
Definition: editsh.cxx:447
bool IsOutlineContentFolded(const size_t nPos)
Definition: wrtsh1.cxx:1995
Used by the UI to modify the document model.
Definition: wrtsh.hxx:90
ContentTypeId GetType() const
Definition: content.hxx:164
sal_uInt8 m_nOutlineLevel
Definition: conttree.hxx:109
static const char * STR_CONTEXT_ARY[]
Definition: content.cxx:844
OBJ_PATHPLIN
std::vector< SwFrameFormat const * > GetFlyFrameFormats(FlyCntType eType, bool bIgnoreTextBoxes)
Definition: feshview.cxx:2577
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
void FindActiveTypeAndRemoveUserData()
Before any data will be deleted, the last active entry has to be found.
Definition: content.cxx:2587
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
bool GotoFly(const OUString &rName, FlyCntType eType=FLYCNTTYPE_ALL, bool bSelFrame=true)
Definition: move.cxx:594
const SwView & GetView() const
Definition: wrtsh.hxx:428
bool GotoNextTOXBase(const OUString *pName=nullptr)
Definition: move.cxx:646
void ToggleOutlineContentVisibility(SwNode *pNd, bool bForceFold=false)
Definition: wrtsh1.cxx:2013
virtual const_iterator_t findMark(const OUString &rMark) const =0
Finds a mark by name.
void Top(const long nTop)
Definition: swrect.hxx:204
OBJ_CAPTION
#define FN_TABLE_SELECT_ALL
Definition: cmdid.h:358
SwContentType(SwWrtShell *pParent, ContentTypeId nType, sal_uInt8 nLevel)
Definition: content.cxx:267
std::unique_ptr< weld::TreeIter > GetEntryAtAbsPos(size_t nAbsPos) const
Definition: content.cxx:1938
SwView * GetView()
Definition: unotxvw.hxx:135
#define FN_INSERT_BOOKMARK
Definition: cmdid.h:193
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void LeaveAddMode()
Definition: select.cxx:640
bool IsProtectedOutlinePara() const
Definition: ednumber.cxx:581
bool IsOutlineMovable(SwOutlineNodes::size_type nIdx) const
May an outline be moved or copied? Check whether it's in text body, not in table, and not read-only (...
Definition: ednumber.cxx:651
ContentTypeId m_nContentType
Definition: content.hxx:147
virtual void set_label(const OString &rIdent, const OUString &rLabel)=0
const OUString & GetName() const
Definition: format.hxx:111
std::vector< SwGetINetAttr > SwGetINetAttrs
Definition: editsh.hxx:126
bool Paste(TransferableDataHelper &rData)
Definition: content.cxx:4248
sal_Int32 GetActiveBlock() const
Definition: navicfg.hxx:74
int nCount
bool GotoPrevTOXBase(const OUString *=nullptr)
jump to previous index
Definition: crstrvl.cxx:315
#define DND_ACTION_NONE
const SwTOXBase * GetTOX(sal_uInt16 nPos) const
Definition: edtox.cxx:225
TreeListBox for content indicator.
Definition: conttree.hxx:84
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
SwMoveFnCollection const & fnRegionEnd
Definition: paminit.cxx:56
virtual OUString get_id(int pos) const =0
OBJ_PATHLINE
size_t GetMemberCount() const
Definition: content.hxx:162
static bool lcl_InsertExpandCollapseAllItem(weld::TreeView &rContentTree, weld::TreeIter &rEntry, weld::Menu &rPop)
Definition: content.cxx:1145
sal_uInt16 GetModifier() const
SwContent(const SwContentType *pCnt, const OUString &rName, long nYPos)
Definition: content.cxx:175
SwOutlineNodes::size_type GetOutlinePos() const
Definition: content.hxx:51
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
void GetGrfNms(OUString *pGrfName, OUString *pFltName, const SwFlyFrameFormat *=nullptr) const
Returns the name and the filter name of a graphic if the pointer is on a graphic. ...
Definition: editsh.cxx:304
const IDocumentMarkAccess * getIDocumentMarkAccess() const
Provides access to the document bookmark interface.
Definition: viewsh.cxx:2587
UNKNOWN
void SetOutlineLevel(sal_uInt8 nSet)
Definition: content.cxx:3781
void MoveOutline(SwOutlineNodes::size_type nTargetPos)
Definition: content.cxx:3170
void UnmarkAll()
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2589
OBJ_SECT
size_type size() const
sal_Int8 AcceptDrop()
Definition: navipi.cxx:920
css::uno::Reference< css::frame::XModel > GetBaseModel() const
const SwSectionFormat & GetSectionFormat(size_t nFormat) const
Definition: edsect.cxx:141
const char * sName
sal_Int32 m_nActiveBlock
Definition: conttree.hxx:104
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
void ToggleToRoot()
Switch the display to Root.
Definition: content.cxx:2322
sal_Int32 m_nHiddenBlock
Definition: conttree.hxx:105
const SwWrtShell * GetActiveWrtShell() const
Definition: conttree.hxx:223
SwOutlineNodes::size_type GetOutlinePos(sal_uInt8 nLevel=UCHAR_MAX)
search "outline position" before previous outline node at given level
Definition: crstrvl.cxx:1135
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
const css::uno::Reference< css::frame::XController2 > & GetController() const
DocumentType eType
void SetActiveShell(SwWrtShell *pSh)
Document change - set new Shell.
Definition: content.cxx:2613
bool IsShowOutlineContentVisibilityButton() const
Definition: viewopt.hxx:298
virtual std::unique_ptr< ILazyDeleter > deleteMark(const IDocumentMarkAccess::const_iterator_t &ppMark)=0
Deletes a mark.
sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt)
Definition: content.cxx:1003
size_t GetFlyCount(FlyCntType eType, bool bIgnoreTextBoxes=false) const
Iterate over flys - for Basic-collections.
Definition: feshview.cxx:2567
constexpr sal_uInt16 KEY_DOWN
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:20
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const_iterator end() const
Definition: PostItMgr.hxx:179
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
void SetRootType(ContentTypeId nType)
Definition: content.cxx:3852
SwNavigationConfig * m_pConfig
Definition: conttree.hxx:100
void EndSelect()
Definition: select.cxx:424
virtual SwTextNode * getOutlineNode(const tSortedOutlineNodeList::size_type nIdx) const =0
virtual ~SwTypeNumber()
Definition: content.cxx:185
SwNavigationPI * GetParentWindow()
Definition: content.cxx:4263
void clear()
OBJ_LINE
virtual ~SwContentType() override
Definition: content.cxx:500
void SetTextFormatColl(SwTextFormatColl *, const bool bResetListAttrs=false)
Add 2nd optional parameter - see also
Definition: edfcol.cxx:2180
Style of a layout element.
Definition: frmfmt.hxx:57
void SetRootType(ContentTypeId nSet)
Definition: navicfg.hxx:48
RegionMode GetRegionDropMode() const
Definition: navipi.hxx:148
virtual SwPaM & GetCurrentShellCursor() override
Return the current shell cursor.
Definition: crsrsh.cxx:180
const SwContentType * GetParent() const
Definition: swcont.hxx:83
#define SW_MOD()
Definition: swmodule.hxx:255
virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter *pResult, bool bDnDMode)=0
static constexpr auto npos
Definition: ndarr.hxx:79
static OUString CleanEntry(const OUString &rEntry)
Definition: navipi.cxx:74
int i
#define HID_NAVIGATOR_TREELIST
Definition: helpids.h:36
uno_Any a
const OUString & GetSectionName() const
Definition: section.hxx:168
const SwPosition * GetPoint() const
Definition: pam.hxx:207
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:63
void EndAction(const bool bIdleEnd=false, const bool DoSetPosX=false)
Definition: crsrsh.cxx:239
OBJ_GRUP
virtual sal_uInt16 GetObjIdentifier() const
RegionMode
Definition: swcont.hxx:51
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
SwFrameFormat * GetFormat()
Definition: dcontact.hxx:112
OUString Apply(const OUString &rStr) const
Definition: SwRewriter.cxx:43
FlyCntType
Definition: flyenum.hxx:23
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2236
const SwTextINetFormat & rINetAttr
Definition: editsh.hxx:120
bool GetString(SotClipboardFormatId nFormat, OUString &rStr)
SwContentTree & m_rTreeView
Definition: conttree.hxx:74
virtual bool get_children_on_demand(const TreeIter &rIter) const =0
virtual bool IsVisible() const
Definition: tox.hxx:563
void Expand(const weld::TreeIter &rParent, std::vector< std::unique_ptr< weld::TreeIter >> *pNodesToExpand)
Definition: content.cxx:1688
bool ActionPend() const
Definition: viewsh.hxx:197
virtual bool iter_has_child(const TreeIter &rIter) const =0
const SvxPageUsage aArr[]
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
virtual void collapse_row(const TreeIter &rIter)=0
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Content type, knows it's contents and the WrtShell.
Definition: content.hxx:138
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
#define CTYPE_CNT
Definition: content.cxx:94
RegionMode nDefDrag
Definition: navicont.hxx:39
sal_uInt16 GetTOXCount() const
Definition: edtox.cxx:211
virtual bool iter_next(TreeIter &rIter) const =0
virtual bool IsProtect() const
Definition: content.cxx:189
size_t size() const
Definition: docary.hxx:84
enum SwContentTree::State m_eState
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:29
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
bool m_bViewHasChanged
Definition: conttree.hxx:119
virtual ~SwGraphicContent() override
Definition: content.cxx:204
virtual void Start() override
static SwView * GetFirstView()
Definition: swmodul1.cxx:122
const SwTextINetFormat * pINetAttr
Definition: content.hxx:74
std::unique_ptr< weld::Toolbar > m_xContent3ToolBox
Definition: navipi.hxx:61
size
bool GetAttrOutlineContentVisible(bool &bOutlineContentVisibleAttr)
GetAttrOutlineContentVisible.
Definition: ndtxt.cxx:4040
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
Display
Marks a node in the document model.
Definition: ndindex.hxx:31
void Hide(const OUString &rAuthor)
Definition: PostItMgr.cxx:1680