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