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>
22#include <svl/urlbmk.hxx>
23#include <osl/thread.h>
24#include <sal/log.hxx>
25#include <tools/urlobj.hxx>
26#include <sfx2/docfile.hxx>
27#include <sfx2/dispatch.hxx>
28#include <sfx2/event.hxx>
29#include <sfx2/viewfrm.hxx>
30#include <o3tl/enumrange.hxx>
32#include <utility>
33#include <vcl/commandevent.hxx>
34#include <vcl/weldutils.hxx>
35#include <sot/formats.hxx>
36#include <o3tl/string_view.hxx>
37#include <uiitems.hxx>
38#include <fmtanchr.hxx>
39#include <fmtinfmt.hxx>
40#include <txtinet.hxx>
41#include <fmtfld.hxx>
42#include <swmodule.hxx>
43#include <wrtsh.hxx>
44#include <view.hxx>
45#include <docsh.hxx>
46#include <drawdoc.hxx>
47#include <content.hxx>
48#include <frmatr.hxx>
49#include <frmfmt.hxx>
50#include <fldbas.hxx>
51#include <IMark.hxx>
52#include <section.hxx>
53#include <tox.hxx>
54#include <navipi.hxx>
55#include <navicont.hxx>
56#include <navicfg.hxx>
57#include <edtwin.hxx>
58#include <doc.hxx>
62#include <unotxvw.hxx>
63#include <cmdid.h>
64#include <helpids.h>
65#include <strings.hrc>
66#include <com/sun/star/text/XTextSectionsSupplier.hpp>
67#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
68#include <com/sun/star/text/XTextTablesSupplier.hpp>
69#include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
70#include <com/sun/star/text/XDocumentIndex.hpp>
71#include <com/sun/star/text/XBookmarksSupplier.hpp>
72#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
73#include <com/sun/star/text/XTextFramesSupplier.hpp>
74#include <com/sun/star/ui/XSidebarProvider.hpp>
75#include <com/sun/star/ui/XDecks.hpp>
76#include <com/sun/star/ui/XDeck.hpp>
77#include <com/sun/star/ui/XPanels.hpp>
78#include <com/sun/star/ui/XPanel.hpp>
79#include <svx/svdpage.hxx>
80#include <svx/svdview.hxx>
81#include <SwRewriter.hxx>
82#include <hints.hxx>
83#include <numrule.hxx>
84#include <swundo.hxx>
85#include <ndtxt.hxx>
86#include <PostItMgr.hxx>
87#include <postithelper.hxx>
88
89#include <swabstdlg.hxx>
90#include <bitmaps.hlst>
91
92#include <AnnotationWin.hxx>
93#include <memory>
94
95#include <fmtcntnt.hxx>
96#include <docstat.hxx>
97
98#include <viewopt.hxx>
99
101#include <txtfld.hxx>
102#include <fldmgr.hxx>
103
104#include <frameformats.hxx>
105
106#include <ftnidx.hxx>
107#include <txtftn.hxx>
108#include <fmtftn.hxx>
109
110#include <txtannotationfld.hxx>
111#include <txtfrm.hxx>
112#include <txtrfmrk.hxx>
116#include <svx/sdrpaintwindow.hxx>
117#include <node2lay.hxx>
118
119#define CTYPE_CNT 0
120#define CTYPE_CTT 1
121
122using namespace ::com::sun::star;
123using namespace ::com::sun::star::text;
124using namespace ::com::sun::star::uno;
125using namespace ::com::sun::star::container;
126
127namespace {
128
129/*
130 Symbolic name representations of numeric values used for the Outline Content Visibility popup
131 menu item ids. The numbers are chosen arbitrarily to not over overlap other menu item ids.
132 see: SwContentTree::ExecuteContextMenuAction, navigatorcontextmenu.ui
133
134 1512 toggle outline content visibility of the selected outline entry
135 1513 make the outline content of the selected outline entry and children not visible
136 1514 make the outline content of the selected entry and children visible
137*/
138const sal_uInt32 TOGGLE_OUTLINE_CONTENT_VISIBILITY = 1512;
139const sal_uInt32 HIDE_OUTLINE_CONTENT_VISIBILITY = 1513;
140const sal_uInt32 SHOW_OUTLINE_CONTENT_VISIBILITY = 1514;
141
142constexpr char NAVI_BOOKMARK_DELIM = '\x01';
143
144}
145
147 : public o3tl::sorted_vector<std::unique_ptr<SwContent>, o3tl::less_uniqueptr_to<SwContent>,
148 o3tl::find_partialorder_ptrequals>
149{
150};
151
152namespace
153{
154 std::map<OUString, std::map<void*, bool>> lcl_DocOutLineExpandStateMap;
155
156 bool lcl_IsContent(const weld::TreeIter& rEntry, const weld::TreeView& rTreeView)
157 {
158 return weld::fromId<const SwTypeNumber*>(rTreeView.get_id(rEntry))->GetTypeId() == CTYPE_CNT;
159 }
160
161 bool lcl_IsContentType(const weld::TreeIter& rEntry, const weld::TreeView& rTreeView)
162 {
163 return weld::fromId<const SwTypeNumber*>(rTreeView.get_id(rEntry))->GetTypeId() == CTYPE_CTT;
164 }
165
166 bool lcl_IsLowerOutlineContent(const weld::TreeIter& rEntry, const weld::TreeView& rTreeView, sal_uInt8 nLevel)
167 {
168 return weld::fromId<const SwOutlineContent*>(rTreeView.get_id(rEntry))->GetOutlineLevel() < nLevel;
169 }
170
171 bool lcl_FindShell(SwWrtShell const * pShell)
172 {
173 bool bFound = false;
175 while (pView)
176 {
177 if(pShell == &pView->GetWrtShell())
178 {
179 bFound = true;
180 break;
181 }
182 pView = SwModule::GetNextView(pView);
183 }
184 return bFound;
185 }
186
187 bool lcl_IsUiVisibleBookmark(const ::sw::mark::IMark* pMark)
188 {
190 }
191
192 OUString lcl_GetFootnoteText(const SwTextFootnote& rTextFootnote)
193 {
194 SwNodeIndex aIdx(*rTextFootnote.GetStartNode(), 1);
195 SwContentNode* pCNd = aIdx.GetNode().GetTextNode();
196 if(!pCNd)
197 pCNd = aIdx.GetNodes().GoNext(&aIdx);
198 return pCNd->IsTextNode() ? static_cast<SwTextNode*>(pCNd)->GetText() : OUString();
199 }
200}
201
202// Content, contains names and reference at the content type.
203
204SwContent::SwContent(const SwContentType* pCnt, OUString aName, double nYPos) :
206 m_pParent(pCnt),
207 m_sContentName(std::move(aName)),
208 m_nYPosition(nYPos),
209 m_bInvisible(false)
210{
211}
212
213
215{
216}
217
219{
220 return false;
221}
222
224{
225 return m_pFormatField->IsProtect();
226}
227
229{
230 return m_pField->IsProtect();
231}
232
234{
235 return m_pINetAttr->IsProtect();
236}
237
239{
240}
241
243{
244}
245
247{
248 STR_CONTENT_TYPE_OUTLINE,
249 STR_CONTENT_TYPE_TABLE,
250 STR_CONTENT_TYPE_FRAME,
251 STR_CONTENT_TYPE_GRAPHIC,
252 STR_CONTENT_TYPE_OLE,
253 STR_CONTENT_TYPE_BOOKMARK,
254 STR_CONTENT_TYPE_REGION,
255 STR_CONTENT_TYPE_URLFIELD,
256 STR_CONTENT_TYPE_REFERENCE,
257 STR_CONTENT_TYPE_INDEX,
258 STR_CONTENT_TYPE_POSTIT,
259 STR_CONTENT_TYPE_DRAWOBJECT,
260 STR_CONTENT_TYPE_TEXTFIELD,
261 STR_CONTENT_TYPE_FOOTNOTE,
262 STR_CONTENT_TYPE_ENDNOTE
263};
264
266{
267 STR_CONTENT_TYPE_SINGLE_OUTLINE,
268 STR_CONTENT_TYPE_SINGLE_TABLE,
269 STR_CONTENT_TYPE_SINGLE_FRAME,
270 STR_CONTENT_TYPE_SINGLE_GRAPHIC,
271 STR_CONTENT_TYPE_SINGLE_OLE,
272 STR_CONTENT_TYPE_SINGLE_BOOKMARK,
273 STR_CONTENT_TYPE_SINGLE_REGION,
274 STR_CONTENT_TYPE_SINGLE_URLFIELD,
275 STR_CONTENT_TYPE_SINGLE_REFERENCE,
276 STR_CONTENT_TYPE_SINGLE_INDEX,
277 STR_CONTENT_TYPE_SINGLE_POSTIT,
278 STR_CONTENT_TYPE_SINGLE_DRAWOBJECT,
279 STR_CONTENT_TYPE_SINGLE_TEXTFIELD,
280 STR_CONTENT_TYPE_SINGLE_FOOTNOTE,
281 STR_CONTENT_TYPE_SINGLE_ENDNOTE
282};
283
284namespace
285{
286 bool checkVisibilityChanged(
287 const SwContentArr& rSwContentArrA,
288 const SwContentArr& rSwContentArrB)
289 {
290 if(rSwContentArrA.size() != rSwContentArrB.size())
291 {
292 return true;
293 }
294
295 for(size_t a(0); a < rSwContentArrA.size(); a++)
296 {
297 if(rSwContentArrA[a]->IsInvisible() != rSwContentArrB[a]->IsInvisible())
298 {
299 return true;
300 }
301 }
302
303 return false;
304 }
305// Gets "YPos" for content, i.e. a number used to sort content members in Navigator's list
306sal_Int32 getYPos(const SwNode& rNode)
307{
308 SwNodeOffset nIndex = rNode.GetIndex();
309 if (rNode.GetNodes().GetEndOfExtras().GetIndex() >= nIndex)
310 {
311 // Not a node of BodyText
312 // Are we in a fly?
313 if (const auto pFlyFormat = rNode.GetFlyFormat())
314 {
315 // Get node index of anchor
316 if (SwNode* pAnchorNode = pFlyFormat->GetAnchor().GetAnchorNode())
317 {
318 return getYPos(*pAnchorNode);
319 }
320 }
321 }
322 return sal_Int32(nIndex);
323}
324} // end of anonymous namespace
325
328 m_pWrtShell(pShell),
329 m_sContentTypeName(SwResId(STR_CONTENT_TYPE_ARY[static_cast<int>(nType)])),
330 m_sSingleContentTypeName(SwResId(STR_CONTENT_TYPE_SINGLE_ARY[static_cast<int>(nType)])),
331 m_nMemberCount(0),
332 m_nContentType(nType),
333 m_nOutlineLevel(nLevel),
334 m_bDataValid(false),
335 m_bEdit(false),
336 m_bDelete(true)
337{
338 switch(m_nContentType)
339 {
341 m_sTypeToken = "outline";
342 break;
344 m_sTypeToken = "table";
345 m_bEdit = true;
346 break;
348 m_sTypeToken = "frame";
349 m_bEdit = true;
350 break;
352 m_sTypeToken = "graphic";
353 m_bEdit = true;
354 break;
356 m_sTypeToken = "ole";
357 m_bEdit = true;
358 break;
360 m_bEdit = true;
361 m_bDelete = true;
362 break;
365 m_bEdit = true;
366 m_bDelete = false;
367 break;
369 {
370 const bool bProtectedBM = m_pWrtShell->getIDocumentSettingAccess().get(
372 m_bEdit = true;
373 m_bDelete = !bProtectedBM;
374 }
375 break;
377 m_sTypeToken = "region";
378 m_bEdit = true;
379 m_bDelete = false;
380 break;
382 m_bEdit = true;
383 m_bDelete = true;
384 break;
386 m_bEdit = false;
387 m_bDelete = true;
388 break;
390 m_bEdit = true;
391 m_bDelete = true;
392 break;
394 m_bEdit = true;
395 break;
397 m_sTypeToken = "drawingobject";
398 m_bEdit = true;
399 break;
400 default: break;
401 }
403}
404
406{
407}
408
410{
411 if(!m_bDataValid || !m_pMember)
412 {
414 }
415 if(nIndex < m_pMember->size())
416 return (*m_pMember)[nIndex].get();
417
418 return nullptr;
419}
420
422{
423 m_bDataValid = false;
424}
425
426void SwContentType::FillMemberList(bool* pbContentChanged)
427{
428 std::unique_ptr<SwContentArr> pOldMember;
429 size_t nOldMemberCount = 0;
430 if(m_pMember && pbContentChanged)
431 {
432 pOldMember = std::move(m_pMember);
433 nOldMemberCount = pOldMember->size();
434 m_pMember.reset( new SwContentArr );
435 *pbContentChanged = false;
436 }
437 else if(!m_pMember)
438 m_pMember.reset( new SwContentArr );
439 else
440 m_pMember->clear();
441 switch(m_nContentType)
442 {
444 {
445 const SwNodeOffset nEndOfExtrasIndex = m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex();
446 // provide for up to 99999 outline nodes in frames to be sorted in document layout order
447 double nOutlinesInFramesIndexAdjustment = 0.00001;
448 const SwOutlineNodes& rOutlineNodes(m_pWrtShell->GetNodes().GetOutLineNds());
449 const size_t nOutlineCount = rOutlineNodes.size();
450
451 for (size_t i = 0; i < nOutlineCount; ++i)
452 {
453 SwTextNode* pNode = rOutlineNodes[i]->GetTextNode();
454 const sal_uInt8 nLevel = pNode->GetAttrOutlineLevel() - 1;
455 if (nLevel >= m_nOutlineLevel || !pNode->getLayoutFrame(m_pWrtShell->GetLayout()))
456 continue;
457 double nYPos = m_bAlphabeticSort ? 0 : static_cast<double>(getYPos(*pNode));
458 if (nEndOfExtrasIndex >= pNode->GetIndex() && pNode->GetFlyFormat())
459 {
460 nYPos += nOutlinesInFramesIndexAdjustment;
461 nOutlinesInFramesIndexAdjustment += 0.00001;
462 }
463 OUString aEntry(comphelper::string::stripStart(
465 i, m_pWrtShell->GetLayout(), true, false, false), ' '));
466 aEntry = SwNavigationPI::CleanEntry(aEntry);
467 auto pCnt(std::make_unique<SwOutlineContent>(this, aEntry, i, nLevel,
468 m_pWrtShell->IsOutlineMovable(i), nYPos));
469 m_pMember->insert(std::move(pCnt));
470 }
471
472 // need to check level and equal entry number after creation due to possible outline
473 // nodes in frames, headers, footers
474 if (pOldMember)
475 {
476 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
477 if (pOldMember->size() != m_pMember->size())
478 {
479 *pbContentChanged = true;
480 break;
481 }
482 for (size_t i = 0; i < pOldMember->size(); i++)
483 {
484 if (static_cast<SwOutlineContent*>((*pOldMember)[i].get())->GetOutlineLevel() !=
485 static_cast<SwOutlineContent*>((*m_pMember)[i].get())->GetOutlineLevel())
486 {
487 *pbContentChanged = true;
488 break;
489 }
490 }
491 }
492 }
493 break;
495 {
496 const size_t nCount = m_pWrtShell->GetTableFrameFormatCount(true);
499 for(size_t n = 0, i = 0; i < nCount + n; ++i)
500 {
501 const SwTableFormat& rTableFormat = *(*pFrameFormats)[i];
502 if (rTableFormat.GetInfo(aGetHt)) // skip deleted tables
503 {
504 n++;
505 continue;
506 }
507 tools::Long nYPos = 0;
509 {
510 if (SwTable* pTable = SwTable::FindTable(&rTableFormat))
511 nYPos = getYPos(*pTable->GetTableNode());
512 }
513 auto pCnt = std::make_unique<SwContent>(this, rTableFormat.GetName(), nYPos);
514 if(!rTableFormat.IsVisible())
515 pCnt->SetInvisible();
516 m_pMember->insert(std::move(pCnt));
517 }
518
519 if (pOldMember)
520 {
521 // need to check visibility (and equal entry number) after
522 // creation due to a sorted list being used here (before,
523 // entries with same index were compared already at creation
524 // time what worked before a sorted list was used)
525 *pbContentChanged = checkVisibilityChanged(
526 *pOldMember,
527 *m_pMember);
528 }
529 }
530 break;
531 case ContentTypeId::OLE :
534 {
540 Point aNullPt;
541 size_t nCount = m_pWrtShell->GetFlyCount(eType, /*bIgnoreTextBoxes=*/true);
542 std::vector<SwFrameFormat const*> formats(m_pWrtShell->GetFlyFrameFormats(eType, /*bIgnoreTextBoxes=*/true));
543 SAL_WARN_IF(nCount != formats.size(), "sw.ui", "Count differs");
544 nCount = formats.size();
545 for (size_t i = 0; i < nCount; ++i)
546 {
547 SwFrameFormat const*const pFrameFormat = formats[i];
548 const OUString sFrameName = pFrameFormat->GetName();
549
550 SwContent* pCnt;
551 tools::Long nYPos =
552 m_bAlphabeticSort ? 0 : pFrameFormat->FindLayoutRect(false, &aNullPt).Top();
554 {
555 OUString sLink;
556 m_pWrtShell->GetGrfNms( &sLink, nullptr, static_cast<const SwFlyFrameFormat*>( pFrameFormat));
557 pCnt = new SwGraphicContent(this, sFrameName, INetURLObject::decode(sLink,
559 }
560 else
561 {
562 pCnt = new SwContent(this, sFrameName, nYPos);
563 }
564 if(!pFrameFormat->IsVisible())
565 pCnt->SetInvisible();
566 m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
567 }
568
569 if (pOldMember)
570 {
571 // need to check visibility (and equal entry number) after
572 // creation due to a sorted list being used here (before,
573 // entries with same index were compared already at creation
574 // time what worked before a sorted list was used)
575 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
576 *pbContentChanged = checkVisibilityChanged(
577 *pOldMember,
578 *m_pMember);
579 }
580 }
581 break;
583 {
584 tools::Long nYPos = 0;
586 for(IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
587 ppBookmark != pMarkAccess->getBookmarksEnd();
588 ++ppBookmark)
589 {
590 if(lcl_IsUiVisibleBookmark(*ppBookmark))
591 {
592 const OUString& rBkmName = (*ppBookmark)->GetName();
593 //nYPos from 0 -> text::Bookmarks will be sorted alphabetically
594 auto pCnt(std::make_unique<SwContent>(this, rBkmName,
595 m_bAlphabeticSort ? 0 : nYPos++));
596 m_pMember->insert(std::move(pCnt));
597 }
598 }
599 }
600 break;
602 {
603 std::vector<SwTextField*> aArr;
604 const SwFieldTypes& rFieldTypes =
606 const size_t nSize = rFieldTypes.size();
607 for (size_t i = 0; i < nSize; ++i)
608 {
609 const SwFieldType* pFieldType = rFieldTypes[i].get();
610 if (pFieldType->Which() == SwFieldIds::Postit)
611 continue;
612 std::vector<SwFormatField*> vFields;
613 pFieldType->GatherFields(vFields);
614 for (SwFormatField* pFormatField: vFields)
615 {
616 if (SwTextField* pTextField = pFormatField->GetTextField())
617 {
618 // fields in header footer don't behave well, skip them
619 if (m_pWrtShell->GetDoc()->IsInHeaderFooter(pTextField->GetTextNode()))
620 continue;
621 aArr.emplace_back(pTextField);
622 }
623 }
624 }
626 {
627 const SwNodeOffset nEndOfExtrasIndex = m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex();
628 bool bHasEntryInFly = false;
629
630 // use stable sort array to list fields in document model order
631 std::stable_sort(aArr.begin(), aArr.end(),
632 [](const SwTextField* a, const SwTextField* b){
633 SwPosition aPos(a->GetTextNode(), a->GetStart());
634 SwPosition bPos(b->GetTextNode(), b->GetStart());
635 return aPos < bPos;});
636
637 // determine if there is a text field in a fly frame
638 for (SwTextField* pTextField : aArr)
639 {
640 if (!bHasEntryInFly)
641 {
642 if (nEndOfExtrasIndex >= pTextField->GetTextNode().GetIndex())
643 {
644 // Not a node of BodyText
645 // Are we in a fly?
646 if (pTextField->GetTextNode().GetFlyFormat())
647 {
648 bHasEntryInFly = true;
649 break;
650 }
651 }
652 }
653 }
654
655 // When there are fields in fly frames do an additional sort using the fly frame
656 // anchor position to place field entries in order of document layout appearance.
657 if (bHasEntryInFly)
658 {
659 std::stable_sort(aArr.begin(), aArr.end(),
660 [nEndOfExtrasIndex](const SwTextField* a, const SwTextField* b){
661 SwTextNode& aTextNode = a->GetTextNode();
662 SwTextNode& bTextNode = b->GetTextNode();
663 SwPosition aPos(aTextNode, a->GetStart());
664 SwPosition bPos(bTextNode, b->GetStart());
665 // use anchor position for entries that are located in flys
666 if (nEndOfExtrasIndex >= aTextNode.GetIndex())
667 if (auto pFlyFormat = aTextNode.GetFlyFormat())
668 if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor())
669 aPos = *pPos;
670 if (nEndOfExtrasIndex >= bTextNode.GetIndex())
671 if (auto pFlyFormat = bTextNode.GetFlyFormat())
672 if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor())
673 bPos = *pPos;
674 return aPos < bPos;});
675 }
676 }
677 std::vector<OUString> aDocumentStatisticsSubTypesList;
678 tools::Long nYPos = 0;
679 for (SwTextField* pTextField : aArr)
680 {
681 const SwField* pField = pTextField->GetFormatField().GetField();
682 OUString sExpandField = pField->ExpandField(true, m_pWrtShell->GetLayout());
683 if (!sExpandField.isEmpty())
684 sExpandField = u" - " + sExpandField;
685 OUString sText;
687 {
688 if (aDocumentStatisticsSubTypesList.empty())
690 aDocumentStatisticsSubTypesList);
691 OUString sSubType;
692 if (pField->GetSubType() < aDocumentStatisticsSubTypesList.size())
693 sSubType = u" - " + aDocumentStatisticsSubTypesList[pField->GetSubType()];
694 sText = pField->GetDescription() + u" - " + pField->GetFieldName() + sSubType +
695 sExpandField;
696 }
697 else if (pField->GetTypeId() == SwFieldTypesEnum::GetRef)
698 {
699 assert(dynamic_cast<const SwGetRefField*>(pField));
700 const SwGetRefField* pRefField(static_cast<const SwGetRefField*>(pField));
701 if (pRefField->IsRefToHeadingCrossRefBookmark() ||
703 {
704 OUString sExpandedTextOfReferencedTextNode =
707 if (sExpandedTextOfReferencedTextNode.getLength() > 80)
708 {
709 sExpandedTextOfReferencedTextNode = OUString::Concat(
710 sExpandedTextOfReferencedTextNode.subView(0, 80)) + u"...";
711 }
712 sText = pField->GetDescription() + u" - "
713 + sExpandedTextOfReferencedTextNode + sExpandField;
714 }
715 else
716 {
717 OUString sFieldSubTypeOrName;
718 auto nSubType = pField->GetSubType();
719 if (nSubType == REF_FOOTNOTE)
720 sFieldSubTypeOrName = SwResId(STR_FLDREF_FOOTNOTE);
721 else if (nSubType == REF_ENDNOTE)
722 sFieldSubTypeOrName = SwResId(STR_FLDREF_ENDNOTE);
723 else
724 sFieldSubTypeOrName = pField->GetFieldName();
725 sText = pField->GetDescription() + u" - " + sFieldSubTypeOrName
726 + sExpandField;
727 }
728 }
729 else
730 sText = pField->GetDescription() + u" - " + pField->GetFieldName()
731 + sExpandField;
732 auto pCnt(std::make_unique<SwTextFieldContent>(this, sText,
733 &pTextField->GetFormatField(),
734 m_bAlphabeticSort ? 0 : nYPos++));
735 if (!pTextField->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))
736 pCnt->SetInvisible();
737 m_pMember->insert(std::move(pCnt));
738 }
739 }
740 break;
741 // We will separate footnotes and endnotes here.
744 {
745 const SwFootnoteIdxs& rFootnoteIdxs = m_pWrtShell->GetDoc()->GetFootnoteIdxs();
746 if (rFootnoteIdxs.size() == 0)
747 break;
748 // insert footnotes and endnotes
749 tools::Long nPos = 0;
750 for (const SwTextFootnote* pTextFootnote : rFootnoteIdxs)
751 {
752 if ((!pTextFootnote->GetFootnote().IsEndNote()
754 || (pTextFootnote->GetFootnote().IsEndNote()
756 {
757 const SwFormatFootnote& rFormatFootnote = pTextFootnote->GetFootnote();
758 const OUString& sText
759 = rFormatFootnote.GetViewNumStr(*m_pWrtShell->GetDoc(),
760 m_pWrtShell->GetLayout(), true)
761 + " " + lcl_GetFootnoteText(*pTextFootnote);
762 auto pCnt(std::make_unique<SwTextFootnoteContent>(
763 this, sText, pTextFootnote, ++nPos));
764 if (!pTextFootnote->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))
765 pCnt->SetInvisible();
766 m_pMember->insert(std::move(pCnt));
767 }
768 }
769 }
770 break;
772 {
774 for (size_t i = 0; i < nCount; ++i)
775 {
776 const SwSectionFormat* pFormat = &m_pWrtShell->GetSectionFormat(i);
777 if (!pFormat->IsInNodesArr())
778 continue;
779 const SwSection* pSection = pFormat->GetSection();
780 if (SectionType eTmpType = pSection->GetType();
781 eTmpType == SectionType::ToxContent || eTmpType == SectionType::ToxHeader)
782 continue;
783 const SwNodeIndex* pNodeIndex = pFormat->GetContent().GetContentIdx();
784 if (pNodeIndex)
785 {
786 const OUString& sSectionName = pSection->GetSectionName();
787
788 sal_uInt8 nLevel = 0;
789 SwSectionFormat* pParentFormat = pFormat->GetParent();
790 while(pParentFormat)
791 {
792 nLevel++;
793 pParentFormat = pParentFormat->GetParent();
794 }
795
796 std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, sSectionName,
797 nLevel, m_bAlphabeticSort ? 0 : getYPos(pNodeIndex->GetNode())));
798 if(!pFormat->IsVisible())
799 pCnt->SetInvisible();
800 m_pMember->insert(std::move(pCnt));
801 }
802
803 if (pOldMember)
804 {
805 // need to check visibility (and equal entry number) after
806 // creation due to a sorted list being used here (before,
807 // entries with same index were compared already at creation
808 // time what worked before a sorted list was used)
809 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
810 *pbContentChanged = checkVisibilityChanged(
811 *pOldMember,
812 *m_pMember);
813 }
814 }
815 }
816 break;
818 {
819 std::vector<OUString> aRefMarks;
820 m_pWrtShell->GetRefMarks( &aRefMarks );
821
822 tools::Long nYPos = 0;
823 for (const auto& rRefMark : aRefMarks)
824 {
825 m_pMember->insert(std::make_unique<SwContent>(this, rRefMark,
826 m_bAlphabeticSort ? 0 : nYPos++));
827 }
828 }
829 break;
831 {
834
836 {
837 for (auto& r : aArr)
838 {
839 auto pCnt(std::make_unique<SwURLFieldContent>(this, r.sText, INetURLObject::decode(
840 r.rINetAttr.GetINetFormat().GetValue(),
842 &r.rINetAttr, 0));
843 m_pMember->insert(std::move(pCnt));
844 }
845 break;
846 }
847
848 // use stable sort array to list hyperlinks in document order
849 const SwNodeOffset nEndOfExtrasIndex = m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex();
850 bool bHasEntryInFly = false;
851 std::vector<SwGetINetAttr*> aStableSortINetAttrsArray;
852
853 for (SwGetINetAttr& r : aArr)
854 {
855 aStableSortINetAttrsArray.emplace_back(&r);
856 if (!bHasEntryInFly)
857 {
858 if (nEndOfExtrasIndex >= r.rINetAttr.GetTextNode().GetIndex())
859 {
860 // Not a node of BodyText
861 // Are we in a fly?
862 if (r.rINetAttr.GetTextNode().GetFlyFormat())
863 bHasEntryInFly = true;
864 }
865 }
866 }
867
868 std::stable_sort(aStableSortINetAttrsArray.begin(), aStableSortINetAttrsArray.end(),
869 [](const SwGetINetAttr* a, const SwGetINetAttr* b){
870 SwPosition aSwPos(a->rINetAttr.GetTextNode(),
871 a->rINetAttr.GetStart());
872 SwPosition bSwPos(b->rINetAttr.GetTextNode(),
873 b->rINetAttr.GetStart());
874 return aSwPos < bSwPos;});
875
876 // When there are hyperlinks in text frames do an additional sort using the text frame
877 // anchor position to place entries in the order of document layout appearance.
878 if (bHasEntryInFly)
879 {
880 std::stable_sort(aStableSortINetAttrsArray.begin(), aStableSortINetAttrsArray.end(),
881 [nEndOfExtrasIndex](const SwGetINetAttr* a, const SwGetINetAttr* b){
882 const SwTextNode& aTextNode = a->rINetAttr.GetTextNode();
883 const SwTextNode& bTextNode = b->rINetAttr.GetTextNode();
884 SwPosition aPos(aTextNode, a->rINetAttr.GetStart());
885 SwPosition bPos(bTextNode, b->rINetAttr.GetStart());
886 // use anchor position for entries that are located in flys
887 if (nEndOfExtrasIndex >= aTextNode.GetIndex())
888 if (auto pFlyFormat = aTextNode.GetFlyFormat())
889 if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor())
890 aPos = *pPos;
891 if (nEndOfExtrasIndex >= bTextNode.GetIndex())
892 if (auto pFlyFormat = bTextNode.GetFlyFormat())
893 if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor())
894 bPos = *pPos;
895 return aPos < bPos;});
896 }
897
898 SwGetINetAttrs::size_type n = 0;
899 for (auto p : aStableSortINetAttrsArray)
900 {
901 auto pCnt = std::make_unique<SwURLFieldContent>(this, p->sText,
902 INetURLObject::decode(p->rINetAttr.GetINetFormat().GetValue(),
904 &p->rINetAttr, ++n);
905 m_pMember->insert(std::move(pCnt));
906 }
907 }
908 break;
910 {
911 const sal_uInt16 nCount = m_pWrtShell->GetTOXCount();
912
913 for ( sal_uInt16 nTox = 0; nTox < nCount; nTox++ )
914 {
915 const SwTOXBase* pBase = m_pWrtShell->GetTOX( nTox );
916 OUString sTOXNm( pBase->GetTOXName() );
917
918 SwContent* pCnt = new SwTOXBaseContent(
919 this, sTOXNm, m_bAlphabeticSort ? 0 : nTox, *pBase);
920
921 if(pBase && !pBase->IsVisible())
922 pCnt->SetInvisible();
923
924 m_pMember->insert( std::unique_ptr<SwContent>(pCnt) );
925 const size_t nPos = m_pMember->size() - 1;
926 if (pOldMember)
927 {
928 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
929 if (!*pbContentChanged && nOldMemberCount > nPos &&
930 (*pOldMember)[nPos]->IsInvisible() != pCnt->IsInvisible())
931 *pbContentChanged = true;
932 }
933 }
934 }
935 break;
937 {
939 if (aMgr)
940 {
941 tools::Long nYPos = 0;
942 for(SwPostItMgr::const_iterator i = aMgr->begin(); i != aMgr->end(); ++i)
943 {
944 if (const SwFormatField* pFormatField = dynamic_cast<const SwFormatField *>((*i)->GetBroadcaster())) // SwPostit
945 {
946 if (pFormatField->GetTextField() && pFormatField->IsFieldInDoc())
947 {
948 OUString sEntry = pFormatField->GetField()->GetPar2();
949 sEntry = RemoveNewline(sEntry);
950 std::unique_ptr<SwPostItContent> pCnt(new SwPostItContent(
951 this,
952 sEntry,
953 pFormatField,
954 nYPos));
955 if (!pFormatField->GetTextField()->GetTextNode().getLayoutFrame(
957 pCnt->SetInvisible();
958 if (pOldMember)
959 {
960 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
961 if (!*pbContentChanged &&
962 nOldMemberCount > o3tl::make_unsigned(nYPos) &&
963 (*pOldMember)[nYPos]->IsInvisible() != pCnt->IsInvisible())
964 *pbContentChanged = true;
965 }
966 m_pMember->insert(std::move(pCnt));
967 nYPos++;
968 }
969 }
970 }
971 }
972 }
973 break;
975 {
977 SwDrawModel* pModel = rIDDMA.GetDrawModel();
978 if(pModel)
979 {
980 SdrPage* pPage = pModel->GetPage(0);
981 const size_t nCount = pPage->GetObjCount();
982 for( size_t i=0; i<nCount; ++i )
983 {
984 SdrObject* pTemp = pPage->GetObj(i);
985 // #i51726# - all drawing objects can be named now
986 if (!pTemp->GetName().isEmpty())
987 {
988 tools::Long nYPos = LONG_MIN;
989 const bool bIsVisible = rIDDMA.IsVisibleLayerId(pTemp->GetLayer());
990 if (bIsVisible)
991 nYPos = m_bAlphabeticSort ? 0 : pTemp->GetLogicRect().Top();
992 auto pCnt(std::make_unique<SwContent>(this, pTemp->GetName(), nYPos));
993 if (!bIsVisible)
994 pCnt->SetInvisible();
995 m_pMember->insert(std::move(pCnt));
996 }
997 }
998
999 if (pOldMember)
1000 {
1001 // need to check visibility (and equal entry number) after
1002 // creation due to a sorted list being used here (before,
1003 // entries with same index were compared already at creation
1004 // time what worked before a sorted list was used)
1005 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
1006 *pbContentChanged = checkVisibilityChanged(
1007 *pOldMember,
1008 *m_pMember);
1009 }
1010 }
1011 }
1012 break;
1013 default: break;
1014 }
1015 m_nMemberCount = m_pMember->size();
1016 if (pOldMember)
1017 {
1018 assert(pbContentChanged && "pbContentChanged is always set if pOldMember is");
1019 if (!*pbContentChanged && pOldMember->size() != m_nMemberCount)
1020 *pbContentChanged = true;
1021 }
1022
1023 m_bDataValid = true;
1024}
1025
1026namespace {
1027
1028enum STR_CONTEXT_IDX
1029{
1030 IDX_STR_OUTLINE_LEVEL = 0,
1031 IDX_STR_DRAGMODE = 1,
1032 IDX_STR_HYPERLINK = 2,
1033 IDX_STR_LINK_REGION = 3,
1034 IDX_STR_COPY_REGION = 4,
1035 IDX_STR_DISPLAY = 5,
1036 IDX_STR_ACTIVE_VIEW = 6,
1037 IDX_STR_HIDDEN = 7,
1038 IDX_STR_ACTIVE = 8,
1039 IDX_STR_INACTIVE = 9,
1040 IDX_STR_EDIT_ENTRY = 10,
1041 IDX_STR_DELETE_ENTRY = 11,
1042 IDX_STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY = 12,
1043 IDX_STR_OUTLINE_TRACKING = 13,
1044 IDX_STR_OUTLINE_TRACKING_DEFAULT = 14,
1045 IDX_STR_OUTLINE_TRACKING_FOCUS = 15,
1046 IDX_STR_OUTLINE_TRACKING_OFF = 16
1047};
1048
1049}
1050
1052{
1053 STR_OUTLINE_LEVEL,
1054 STR_DRAGMODE,
1055 STR_HYPERLINK,
1056 STR_LINK_REGION,
1057 STR_COPY_REGION,
1058 STR_DISPLAY,
1059 STR_ACTIVE_VIEW,
1060 STR_HIDDEN,
1061 STR_ACTIVE,
1062 STR_INACTIVE,
1063 STR_EDIT_ENTRY,
1064 STR_DELETE_ENTRY,
1065 STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY,
1066 STR_OUTLINE_TRACKING,
1067 STR_OUTLINE_TRACKING_DEFAULT,
1068 STR_OUTLINE_TRACKING_FOCUS,
1069 STR_OUTLINE_TRACKING_OFF
1070};
1071
1072SwContentTree::SwContentTree(std::unique_ptr<weld::TreeView> xTreeView, SwNavigationPI* pDialog)
1073 : m_xTreeView(std::move(xTreeView))
1074 , m_aDropTargetHelper(*this)
1075 , m_pDialog(pDialog)
1076 , m_sSpace(OUString(" "))
1077 , m_aUpdTimer("SwContentTree m_aUpdTimer")
1078 , m_aOverlayObjectDelayTimer("SwContentTree m_aOverlayObjectDelayTimer")
1079 , m_sInvisible(SwResId(STR_INVISIBLE))
1080 , m_pHiddenShell(nullptr)
1081 , m_pActiveShell(nullptr)
1082 , m_pConfig(SW_MOD()->GetNavigationConfig())
1083 , m_nActiveBlock(0)
1084 , m_nHiddenBlock(0)
1085 , m_nEntryCount(0)
1086 , m_nRootType(ContentTypeId::UNKNOWN)
1087 , m_nLastSelType(ContentTypeId::UNKNOWN)
1088 , m_nOutlineLevel(MAXLEVEL)
1089 , m_eState(State::ACTIVE)
1090 , m_bIsRoot(false)
1091 , m_bIsIdleClear(false)
1092 , m_bIsLastReadOnly(false)
1093 , m_bIsOutlineMoveable(true)
1094 , m_bViewHasChanged(false)
1095{
1096 m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 30,
1097 m_xTreeView->get_text_height() * 14);
1098
1099 m_xTreeView->set_help_id(HID_NAVIGATOR_TREELIST);
1100
1101 m_xTreeView->connect_expanding(LINK(this, SwContentTree, ExpandHdl));
1102 m_xTreeView->connect_collapsing(LINK(this, SwContentTree, CollapseHdl));
1103 m_xTreeView->connect_row_activated(LINK(this, SwContentTree, ContentDoubleClickHdl));
1104 m_xTreeView->connect_changed(LINK(this, SwContentTree, SelectHdl));
1105 m_xTreeView->connect_focus_in(LINK(this, SwContentTree, FocusInHdl));
1106 m_xTreeView->connect_key_press(LINK(this, SwContentTree, KeyInputHdl));
1107 m_xTreeView->connect_popup_menu(LINK(this, SwContentTree, CommandHdl));
1108 m_xTreeView->connect_query_tooltip(LINK(this, SwContentTree, QueryTooltipHdl));
1109 m_xTreeView->connect_drag_begin(LINK(this, SwContentTree, DragBeginHdl));
1110 m_xTreeView->connect_mouse_move(LINK(this, SwContentTree, MouseMoveHdl));
1111 m_xTreeView->connect_mouse_press(LINK(this, SwContentTree, MousePressHdl));
1112
1114 {
1116 mTrackContentType[i] = true;
1117 m_aActiveContentArr[i] = nullptr;
1118 m_aHiddenContentArr[i] = nullptr;
1119 }
1120 for (int i = 0; i < CONTEXT_COUNT; ++i)
1121 {
1123 }
1125
1126 // Restore outline headings expand state (same session persistence only)
1127 if (SwView* pView = GetActiveView(); pView && pView->GetDocShell())
1128 {
1129 OUString sDocTitle = pView->GetDocShell()->GetTitle();
1130 if (lcl_DocOutLineExpandStateMap.find(sDocTitle) != lcl_DocOutLineExpandStateMap.end())
1131 mOutLineNodeMap = lcl_DocOutLineExpandStateMap[sDocTitle];
1132 }
1133
1134 m_aUpdTimer.SetInvokeHandler(LINK(this, SwContentTree, TimerUpdate));
1135 m_aUpdTimer.SetTimeout(1000);
1136 m_aOverlayObjectDelayTimer.SetInvokeHandler(LINK(this, SwContentTree, OverlayObjectDelayTimerHdl));
1138}
1139
1141{
1142 if (SwView* pView = GetActiveView(); pView && pView->GetDocShell())
1143 {
1144 OUString sDocTitle = pView->GetDocShell()->GetTitle();
1145 lcl_DocOutLineExpandStateMap[sDocTitle] = mOutLineNodeMap;
1146 }
1147 clear(); // If applicable erase content types previously.
1148 m_aUpdTimer.Stop();
1149 SetActiveShell(nullptr);
1150}
1151
1152IMPL_LINK(SwContentTree, MousePressHdl, const MouseEvent&, rMEvt, bool)
1153{
1154 m_bSelectTo = rMEvt.IsShift() && (m_pConfig->IsNavigateOnSelect() || rMEvt.GetClicks() == 2);
1155 return false;
1156}
1157
1158IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
1159{
1160 if (m_eState == State::HIDDEN)
1161 return false;
1162 if (std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1163 m_xTreeView->get_dest_row_at_pos(rMEvt.GetPosPixel(), xEntry.get(), false, false) &&
1164 !rMEvt.IsLeaveWindow())
1165 {
1166 if (!m_xOverlayCompareEntry)
1167 m_xOverlayCompareEntry.reset(m_xTreeView->make_iterator().release());
1168 else if (m_xTreeView->iter_compare(*xEntry, *m_xOverlayCompareEntry) == 0)
1169 return false; // The entry under the mouse has not changed.
1170 m_xTreeView->copy_iterator(*xEntry, *m_xOverlayCompareEntry);
1171 BringEntryToAttention(*xEntry);
1172 }
1173 else
1174 {
1175 if (m_xOverlayCompareEntry)
1176 m_xOverlayCompareEntry.reset();
1177 m_aOverlayObjectDelayTimer.Stop();
1178 if (m_xOverlayObject && m_xOverlayObject->getOverlayManager())
1179 {
1180 m_xOverlayObject->getOverlayManager()->remove(*m_xOverlayObject);
1181 m_xOverlayObject.reset();
1182 }
1183 }
1184 return false;
1185}
1186
1187// Drag&Drop methods
1188IMPL_LINK(SwContentTree, DragBeginHdl, bool&, rUnsetDragIcon, bool)
1189{
1190 rUnsetDragIcon = true;
1191
1192 bool bDisallow = true;
1193
1194 // don't allow if tree root is selected
1195 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1196 bool bEntry = m_xTreeView->get_selected(xEntry.get());
1197 if (!bEntry || lcl_IsContentType(*xEntry, *m_xTreeView))
1198 {
1199 return true; // disallow
1200 }
1201
1204
1205 if (FillTransferData(*xContainer, nDragMode))
1206 bDisallow = false;
1207
1208 if (m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE)
1209 {
1210 // Only move drag entry and continuous selected siblings:
1211 m_aDndOutlinesSelected.clear();
1212
1213 std::unique_ptr<weld::TreeIter> xScratch(m_xTreeView->make_iterator());
1214
1215 // Find first selected of continuous siblings
1216 while (true)
1217 {
1218 m_xTreeView->copy_iterator(*xEntry, *xScratch);
1219 if (!m_xTreeView->iter_previous_sibling(*xScratch))
1220 break;
1221 if (!m_xTreeView->is_selected(*xScratch))
1222 break;
1223 m_xTreeView->copy_iterator(*xScratch, *xEntry);
1224 }
1225 // Record continuous selected siblings
1226 do
1227 {
1228 m_aDndOutlinesSelected.push_back(m_xTreeView->make_iterator(xEntry.get()));
1229 }
1230 while (m_xTreeView->iter_next_sibling(*xEntry) && m_xTreeView->is_selected(*xEntry));
1231 bDisallow = false;
1232 }
1233
1234 if (!bDisallow)
1235 m_xTreeView->enable_drag_source(xContainer, nDragMode);
1236 return bDisallow;
1237}
1238
1240 : DropTargetHelper(rTreeView.get_widget().get_drop_target())
1241 , m_rTreeView(rTreeView)
1242{
1243}
1244
1246{
1247 sal_Int8 nAccept = m_rTreeView.AcceptDrop(rEvt);
1248
1249 if (nAccept != DND_ACTION_NONE)
1250 {
1251 // to enable the autoscroll when we're close to the edges
1253 rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
1254 }
1255
1256 return nAccept;
1257}
1258
1260{
1261 return m_xTreeView->get_drag_source() == m_xTreeView.get();
1262}
1263
1264// QueryDrop will be executed in the navigator
1266{
1268 if( m_bIsRoot )
1269 {
1271 nRet = rEvt.mnAction;
1272 }
1273 else if (!IsInDrag())
1274 nRet = GetParentWindow()->AcceptDrop();
1275 return nRet;
1276}
1277
1278// Drop will be executed in the navigator
1279static void* lcl_GetOutlineKey(SwContentTree& rTree, SwOutlineContent const * pContent)
1280{
1281 void* key = nullptr;
1282 if (pContent)
1283 {
1284 SwWrtShell* pShell = rTree.GetWrtShell();
1285 auto const nPos = pContent->GetOutlinePos();
1286
1287 key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
1288 }
1289 return key;
1290}
1291
1293{
1294 return m_rTreeView.ExecuteDrop(rEvt);
1295}
1296
1298{
1299 std::unique_ptr<weld::TreeIter> xDropEntry(m_xTreeView->make_iterator());
1300 if (!m_xTreeView->get_dest_row_at_pos(rEvt.maPosPixel, xDropEntry.get(), true))
1301 xDropEntry.reset();
1302
1304 {
1305 if (xDropEntry && lcl_IsContent(*xDropEntry, *m_xTreeView))
1306 {
1307 assert(dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xDropEntry))));
1308 SwOutlineContent* pOutlineContent = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*xDropEntry));
1309 assert(pOutlineContent);
1310
1311 void* key = lcl_GetOutlineKey(*this, pOutlineContent);
1312 assert(key);
1313 if (!mOutLineNodeMap[key])
1314 {
1315 while (m_xTreeView->iter_has_child(*xDropEntry))
1316 {
1317 std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator(xDropEntry.get()));
1318 bool bChildEntry = m_xTreeView->iter_children(*xChildEntry);
1319 while (bChildEntry)
1320 {
1321 m_xTreeView->copy_iterator(*xChildEntry, *xDropEntry);
1322 bChildEntry = m_xTreeView->iter_next_sibling(*xChildEntry);
1323 }
1324 }
1325 }
1326 }
1327
1328 SwOutlineNodes::size_type nTargetPos = 0;
1329 if (!xDropEntry)
1330 {
1331 // dropped in blank space -> move to bottom
1333 }
1334 else if (!lcl_IsContent(*xDropEntry, *m_xTreeView))
1335 {
1336 // dropped on "heading" parent -> move to start
1337 nTargetPos = SwOutlineNodes::npos;
1338 }
1339 else
1340 {
1341 assert(dynamic_cast<SwOutlineContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xDropEntry))));
1342 nTargetPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*xDropEntry))->GetOutlinePos();
1343 }
1344
1345 if( MAXLEVEL > m_nOutlineLevel && // Not all layers are displayed.
1346 nTargetPos != SwOutlineNodes::npos)
1347 {
1348 std::unique_ptr<weld::TreeIter> xNext(m_xTreeView->make_iterator(xDropEntry.get()));
1349 bool bNext = m_xTreeView->iter_next(*xNext);
1350 if (bNext)
1351 {
1352 assert(dynamic_cast<SwOutlineContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xNext))));
1353 nTargetPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*xNext))->GetOutlinePos() - 1;
1354 }
1355 else
1357 }
1358
1359 // remove the drop highlight before we change the contents of the tree so we don't
1360 // try and dereference a removed entry in post-processing drop
1361 m_xTreeView->unset_drag_dest_row();
1362 MoveOutline(nTargetPos);
1363
1364 }
1366}
1367
1368namespace
1369{
1370 bool IsAllExpanded(const weld::TreeView& rContentTree, const weld::TreeIter& rEntry)
1371 {
1372 if (!rContentTree.get_row_expanded(rEntry))
1373 return false;
1374
1375 if (!rContentTree.iter_has_child(rEntry))
1376 return false;
1377
1378 std::unique_ptr<weld::TreeIter> xChild(rContentTree.make_iterator(&rEntry));
1379 (void)rContentTree.iter_children(*xChild);
1380
1381 do
1382 {
1383 if (rContentTree.iter_has_child(*xChild) || rContentTree.get_children_on_demand(*xChild))
1384 {
1385 if (!IsAllExpanded(rContentTree, *xChild))
1386 return false;
1387 }
1388 }
1389 while (rContentTree.iter_next_sibling(*xChild));
1390 return true;
1391 }
1392
1393 void ExpandOrCollapseAll(weld::TreeView& rContentTree, weld::TreeIter& rEntry)
1394 {
1395 bool bExpand = !IsAllExpanded(rContentTree, rEntry);
1396 bExpand ? rContentTree.expand_row(rEntry) : rContentTree.collapse_row(rEntry);
1397 int nRefDepth = rContentTree.get_iter_depth(rEntry);
1398 while (rContentTree.iter_next(rEntry) && rContentTree.get_iter_depth(rEntry) > nRefDepth)
1399 {
1400 if (rContentTree.iter_has_child(rEntry))
1401 bExpand ? rContentTree.expand_row(rEntry) : rContentTree.collapse_row(rEntry);
1402 }
1403 }
1404}
1405
1406// Handler for Dragging and ContextMenu
1407static bool lcl_InsertExpandCollapseAllItem(const weld::TreeView& rContentTree, const weld::TreeIter& rEntry, weld::Menu& rPop)
1408{
1409 if (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry))
1410 {
1411 rPop.set_label(OUString::number(800), IsAllExpanded(rContentTree, rEntry) ? SwResId(STR_COLLAPSEALL) : SwResId(STR_EXPANDALL));
1412 return false;
1413 }
1414 return true;
1415}
1416
1417static void lcl_SetOutlineContentEntriesSensitivities(SwContentTree* pThis, const weld::TreeView& rContentTree, const weld::TreeIter& rEntry, weld::Menu& rPop)
1418{
1419 rPop.set_sensitive(OUString::number(TOGGLE_OUTLINE_CONTENT_VISIBILITY), false);
1420 rPop.set_sensitive(OUString::number(HIDE_OUTLINE_CONTENT_VISIBILITY), false);
1421 rPop.set_sensitive(OUString::number(SHOW_OUTLINE_CONTENT_VISIBILITY), false);
1422
1423 // todo: multi selection
1424 if (rContentTree.count_selected_rows() > 1)
1425 return;
1426
1427 bool bIsRoot = lcl_IsContentType(rEntry, rContentTree);
1428
1429 if (const SwWrtShell* pSh = pThis->GetActiveWrtShell())
1430 {
1431 if (pSh->GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
1432 {
1433 if (!bIsRoot)
1434 rPop.set_sensitive(OUString::number(TOGGLE_OUTLINE_CONTENT_VISIBILITY), true);
1435 return;
1436 }
1437 }
1438
1439 const SwNodes& rNodes = pThis->GetWrtShell()->GetNodes();
1440 const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
1441 size_t nOutlinePos = weld::GetAbsPos(rContentTree, rEntry);
1442
1443 if (!bIsRoot)
1444 --nOutlinePos;
1445
1446 if (nOutlinePos >= rOutlineNodes.size())
1447 return;
1448
1449 int nFirstLevel = pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
1450 {
1451 // determine if any concerned outline node has content
1452 bool bHasContent(false);
1453 size_t nPos = nOutlinePos;
1454 SwNode* pSttNd = rOutlineNodes[nPos];
1455 SwNode* pEndNd = &rNodes.GetEndOfContent();
1456 if (rOutlineNodes.size() > nPos + 1)
1457 pEndNd = rOutlineNodes[nPos + 1];
1458
1459 // selected
1460 SwNodeIndex aIdx(*pSttNd);
1461 if (rNodes.GoNext(&aIdx) != pEndNd)
1462 bHasContent = true;
1463
1464 // descendants
1465 if (!bHasContent && (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry)))
1466 {
1467 while (++nPos < rOutlineNodes.size() &&
1468 (bIsRoot || pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nFirstLevel))
1469 {
1470 pSttNd = rOutlineNodes[nPos];
1471 pEndNd = &rNodes.GetEndOfContent();
1472 if (rOutlineNodes.size() > nPos + 1)
1473 pEndNd = rOutlineNodes[nPos + 1];
1474
1475 // test for content in outline node
1476 aIdx.Assign(*pSttNd);
1477 if (rNodes.GoNext(&aIdx) != pEndNd)
1478 {
1479 bHasContent = true;
1480 break;
1481 }
1482 }
1483 }
1484
1485 if (!bHasContent)
1486 return; // no content in any of the concerned outline nodes
1487 }
1488
1489 // determine for subs if all are folded or unfolded or if they are mixed
1490 if (rContentTree.iter_has_child(rEntry) || rContentTree.get_children_on_demand(rEntry))
1491 {
1492 // skip no content nodes
1493 // we know there is content from results above so this is presumably safe
1494 size_t nPos = nOutlinePos;
1495 while (true)
1496 {
1497 SwNode* pSttNd = rOutlineNodes[nPos];
1498 SwNode* pEndNd = rOutlineNodes.back();
1499 if (!bIsRoot && rOutlineNodes.size() > nPos + 1)
1500 pEndNd = rOutlineNodes[nPos + 1];
1501
1502 SwNodeIndex aIdx(*pSttNd);
1503 if (rNodes.GoNext(&aIdx) != pEndNd)
1504 break;
1505 nPos++;
1506 }
1507
1508 bool bHasFolded(!pThis->GetWrtShell()->IsOutlineContentVisible(nPos));
1509 bool bHasUnfolded(!bHasFolded);
1510
1511 while ((++nPos < pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineNodesCount()) &&
1512 (bIsRoot || pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nFirstLevel))
1513 {
1514
1515 SwNode* pSttNd = rOutlineNodes[nPos];
1516 SwNode* pEndNd = &rNodes.GetEndOfContent();
1517 if (rOutlineNodes.size() > nPos + 1)
1518 pEndNd = rOutlineNodes[nPos + 1];
1519
1520 SwNodeIndex aIdx(*pSttNd);
1521 if (rNodes.GoNext(&aIdx) == pEndNd)
1522 continue; // skip if no content
1523
1525 bHasFolded = true;
1526 else
1527 bHasUnfolded = true;
1528
1529 if (bHasFolded && bHasUnfolded)
1530 break; // mixed so no need to continue
1531 }
1532
1533 rPop.set_sensitive(OUString::number(HIDE_OUTLINE_CONTENT_VISIBILITY), bHasUnfolded);
1534 rPop.set_sensitive(OUString::number(SHOW_OUTLINE_CONTENT_VISIBILITY), bHasFolded);
1535 }
1536
1537 rPop.set_sensitive(OUString::number(TOGGLE_OUTLINE_CONTENT_VISIBILITY), !bIsRoot);
1538}
1539
1540IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
1541{
1542 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
1543 return false;
1544
1545 grab_focus();
1546
1547 // select clicked entry or limit selection to root entry if needed
1548 if (std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1549 rCEvt.IsMouseEvent() && m_xTreeView->get_dest_row_at_pos(
1550 rCEvt.GetMousePosPixel(), xEntry.get(), false))
1551 {
1552 // if clicked entry is not currently selected then clear selections and select it
1553 if (!m_xTreeView->is_selected(*xEntry))
1554 m_xTreeView->set_cursor(*xEntry);
1555 // if root entry is selected then clear selections and select it
1556 else if (m_xTreeView->is_selected(0))
1557 m_xTreeView->set_cursor(0);
1558 }
1559
1560 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/swriter/ui/navigatorcontextmenu.ui"));
1561 std::unique_ptr<weld::Menu> xPop = xBuilder->weld_menu("navmenu");
1562
1563 bool bOutline(false);
1564 std::unique_ptr<weld::Menu> xSubPop1 = xBuilder->weld_menu("outlinelevel");
1565 std::unique_ptr<weld::Menu> xSubPop2 = xBuilder->weld_menu("dragmodemenu");
1566 std::unique_ptr<weld::Menu> xSubPop3 = xBuilder->weld_menu("displaymenu");
1567 std::unique_ptr<weld::Menu> xSubPopOutlineTracking = xBuilder->weld_menu("outlinetracking");
1568
1569 std::unique_ptr<weld::Menu> xSubPopOutlineContent = xBuilder->weld_menu("outlinecontent");
1570
1571 xSubPopOutlineContent->append(OUString::number(TOGGLE_OUTLINE_CONTENT_VISIBILITY),
1572 SwResId(STR_OUTLINE_CONTENT_VISIBILITY_TOGGLE));
1573 xSubPopOutlineContent->append(OUString::number(HIDE_OUTLINE_CONTENT_VISIBILITY),
1574 SwResId(STR_OUTLINE_CONTENT_VISIBILITY_HIDE_ALL));
1575 xSubPopOutlineContent->append(OUString::number(SHOW_OUTLINE_CONTENT_VISIBILITY),
1576 SwResId(STR_OUTLINE_CONTENT_VISIBILITY_SHOW_ALL));
1577
1578 for(int i = 1; i <= 3; ++i)
1579 xSubPopOutlineTracking->append_radio(OUString::number(i + 10), m_aContextStrings[IDX_STR_OUTLINE_TRACKING + i]);
1580 xSubPopOutlineTracking->set_active(OUString::number(10 + m_nOutlineTracking), true);
1581
1582 for (int i = 1; i <= MAXLEVEL; ++i)
1583 xSubPop1->append_radio(OUString::number(i + 100), OUString::number(i));
1584 xSubPop1->set_active(OUString::number(100 + m_nOutlineLevel), true);
1585
1586 for (int i=0; i < 3; ++i)
1587 xSubPop2->append_radio(OUString::number(i + 201), m_aContextStrings[IDX_STR_HYPERLINK + i]);
1588 xSubPop2->set_active(OUString::number(201 + static_cast<int>(GetParentWindow()->GetRegionDropMode())), true);
1589
1590 // Insert the list of the open files
1591 {
1592 sal_uInt16 nId = 301;
1593 SwView *pView = SwModule::GetFirstView();
1594 while (pView)
1595 {
1596 OUString sInsert = pView->GetDocShell()->GetTitle() + " (" +
1597 m_aContextStrings[pView == GetActiveView() ? IDX_STR_ACTIVE :
1598 IDX_STR_INACTIVE] + ")";
1599 xSubPop3->append_radio(OUString::number(nId), sInsert);
1600 if (State::CONSTANT == m_eState && m_pActiveShell == &pView->GetWrtShell())
1601 xSubPop3->set_active(OUString::number(nId), true);
1602 pView = SwModule::GetNextView(pView);
1603 nId++;
1604 }
1605 xSubPop3->append_radio(OUString::number(nId++), m_aContextStrings[IDX_STR_ACTIVE_VIEW]);
1606 if (m_pHiddenShell) // can have only one hidden shell
1607 {
1608 OUString sHiddenEntry = m_pHiddenShell->GetView().GetDocShell()->GetTitle() +
1609 " (" +
1610 m_aContextStrings[IDX_STR_HIDDEN] +
1611 ")";
1612 xSubPop3->append_radio(OUString::number(nId), sHiddenEntry);
1613 }
1614 if (State::ACTIVE == m_eState)
1615 xSubPop3->set_active(OUString::number(--nId), true);
1616 else if (State::HIDDEN == m_eState)
1617 xSubPop3->set_active(OUString::number(nId), true);
1618 }
1619
1620 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1621 if (!m_xTreeView->get_selected(xEntry.get()))
1622 xEntry.reset();
1623
1624 bool bRemoveGotoEntry = false;
1625 if (State::HIDDEN == m_eState || !xEntry || !lcl_IsContent(*xEntry, *m_xTreeView) ||
1626 weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->IsInvisible())
1627 bRemoveGotoEntry = true;
1628
1629 bool bRemovePostItEntries = true;
1630 bool bRemoveIndexEntries = true;
1631 bool bRemoveCopyEntry = true;
1632 bool bRemoveEditEntry = true;
1633 bool bRemoveUnprotectEntry = true;
1634 bool bRemoveDeleteChapterEntry = true,
1635 bRemoveDeleteTableEntry = true,
1636 bRemoveDeleteFrameEntry = true,
1637 bRemoveDeleteImageEntry = true,
1638 bRemoveDeleteOLEObjectEntry = true,
1639 bRemoveDeleteBookmarkEntry = true,
1640 bRemoveDeleteHyperlinkEntry = true,
1641 bRemoveDeleteReferenceEntry = true,
1642 bRemoveDeleteIndexEntry= true,
1643 bRemoveDeleteCommentEntry = true,
1644 bRemoveDeleteDrawingObjectEntry = true,
1645 bRemoveDeleteFieldEntry = true;
1646 bool bRemoveRenameEntry = true;
1647 bool bRemoveSelectEntry = true;
1648 bool bRemoveToggleExpandEntry = true;
1649 bool bRemoveChapterEntries = true;
1650 bool bRemoveSendOutlineEntry = true;
1651
1652 bool bRemoveTableTracking = true;
1653 bool bRemoveSectionTracking = true;
1654 bool bRemoveFrameTracking = true;
1655 bool bRemoveImageTracking = true;
1656 bool bRemoveOLEobjectTracking = true;
1657 bool bRemoveBookmarkTracking = true;
1658 bool bRemoveHyperlinkTracking = true;
1659 bool bRemoveReferenceTracking = true;
1660 bool bRemoveIndexTracking = true;
1661 bool bRemoveCommentTracking = true;
1662 bool bRemoveDrawingObjectTracking = true;
1663 bool bRemoveFieldTracking = true;
1664 bool bRemoveFootnoteTracking = true;
1665 bool bRemoveEndnoteTracking = true;
1666
1667 bool bRemoveSortEntry = true;
1668
1669 if (xEntry)
1670 {
1671 const SwContentType* pType;
1672 if (lcl_IsContentType(*xEntry, *m_xTreeView))
1673 pType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xEntry));
1674 else
1675 pType = weld::fromId<SwContent*>(
1676 m_xTreeView->get_id(*xEntry))->GetParent();
1677 const ContentTypeId nContentType = pType->GetType();
1678
1679 if (nContentType != ContentTypeId::FOOTNOTE && nContentType != ContentTypeId::ENDNOTE
1680 && nContentType != ContentTypeId::POSTIT)
1681 {
1682 bRemoveSortEntry = false;
1683 xPop->set_active("sort", pType->GetSortType());
1684 }
1685
1686 OUString aIdent;
1687 switch (nContentType)
1688 {
1690 aIdent = "tabletracking";
1691 bRemoveTableTracking = false;
1692 break;
1694 aIdent = "sectiontracking";
1695 bRemoveSectionTracking = false;
1696 break;
1698 aIdent = "frametracking";
1699 bRemoveFrameTracking = false;
1700 break;
1702 aIdent = "imagetracking";
1703 bRemoveImageTracking = false;
1704 break;
1705 case ContentTypeId::OLE:
1706 aIdent = "oleobjecttracking";
1707 bRemoveOLEobjectTracking = false;
1708 break;
1710 aIdent = "bookmarktracking";
1711 bRemoveBookmarkTracking = false;
1712 break;
1714 aIdent = "hyperlinktracking";
1715 bRemoveHyperlinkTracking = false;
1716 break;
1718 aIdent = "referencetracking";
1719 bRemoveReferenceTracking = false;
1720 break;
1722 aIdent = "indextracking";
1723 bRemoveIndexTracking = false;
1724 break;
1726 aIdent = "commenttracking";
1727 bRemoveCommentTracking = false;
1728 break;
1730 aIdent = "drawingobjecttracking";
1731 bRemoveDrawingObjectTracking = false;
1732 break;
1734 aIdent = "fieldtracking";
1735 bRemoveFieldTracking = false;
1736 break;
1738 aIdent = "footnotetracking";
1739 bRemoveFootnoteTracking = false;
1740 break;
1742 aIdent = "endnotetracking";
1743 bRemoveEndnoteTracking = false;
1744 break;
1745 default: break;
1746 }
1747 if (!aIdent.isEmpty())
1748 xPop->set_active(aIdent, mTrackContentType[nContentType]);
1749
1750 // Edit only if the shown content is coming from the current view.
1751 if (State::HIDDEN != m_eState &&
1752 (State::ACTIVE == m_eState || (GetActiveView() && m_pActiveShell == GetActiveView()->GetWrtShellPtr()))
1753 && lcl_IsContent(*xEntry, *m_xTreeView))
1754 {
1755 const bool bReadonly = m_pActiveShell->GetView().GetDocShell()->IsReadOnly();
1756 const bool bVisible = !weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->IsInvisible();
1757 const bool bProtected = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->IsProtect();
1758 const bool bProtectBM = (ContentTypeId::BOOKMARK == nContentType)
1759 && m_pActiveShell->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS);
1760 const bool bEditable = pType->IsEditable() &&
1761 ((bVisible && !bProtected) || ContentTypeId::REGION == nContentType);
1762 const bool bDeletable = pType->IsDeletable() &&
1763 ((bVisible && !bProtected && !bProtectBM) || ContentTypeId::REGION == nContentType);
1764 const bool bRenamable = bEditable && !bReadonly &&
1765 (ContentTypeId::TABLE == nContentType ||
1766 ContentTypeId::FRAME == nContentType ||
1767 ContentTypeId::GRAPHIC == nContentType ||
1768 ContentTypeId::OLE == nContentType ||
1769 (ContentTypeId::BOOKMARK == nContentType && !bProtectBM) ||
1770 ContentTypeId::REGION == nContentType ||
1771 ContentTypeId::INDEX == nContentType ||
1772 ContentTypeId::DRAWOBJECT == nContentType);
1773 // Choose which Delete entry to show.
1774 if (bDeletable)
1775 {
1776 switch (nContentType)
1777 {
1779 bRemoveDeleteChapterEntry = false;
1780 break;
1782 bRemoveDeleteTableEntry = false;
1783 break;
1785 bRemoveDeleteFrameEntry = false;
1786 break;
1788 bRemoveDeleteImageEntry = false;
1789 break;
1790 case ContentTypeId::OLE:
1791 bRemoveDeleteOLEObjectEntry = false;
1792 break;
1794 bRemoveDeleteBookmarkEntry = false;
1795 break;
1797 bRemoveDeleteHyperlinkEntry = false;
1798 break;
1800 bRemoveDeleteReferenceEntry = false;
1801 break;
1803 bRemoveDeleteIndexEntry = false;
1804 break;
1806 bRemoveDeleteCommentEntry = false;
1807 break;
1809 bRemoveDeleteDrawingObjectEntry = false;
1810 break;
1812 bRemoveDeleteFieldEntry = false;
1813 break;
1814 default: break;
1815 }
1816 }
1817 if (ContentTypeId::FOOTNOTE == nContentType || ContentTypeId::ENDNOTE == nContentType)
1818 {
1819 void* pUserData = weld::fromId<void*>(m_xTreeView->get_id(*xEntry));
1820 const SwTextFootnote* pFootnote =
1821 static_cast<const SwTextFootnoteContent*>(pUserData)->GetTextFootnote();
1822 if (!pFootnote)
1823 bRemoveGotoEntry = true;
1824 }
1825 else if(ContentTypeId::OUTLINE == nContentType)
1826 {
1827 bOutline = true;
1828 lcl_SetOutlineContentEntriesSensitivities(this, *m_xTreeView, *xEntry, *xSubPopOutlineContent);
1829 bRemoveToggleExpandEntry = lcl_InsertExpandCollapseAllItem(*m_xTreeView, *xEntry, *xPop);
1830 if (!bReadonly)
1831 {
1832 bRemoveSelectEntry = false;
1833 bRemoveChapterEntries = false;
1834 }
1835 bRemoveCopyEntry = false;
1836 }
1837 else if (!bReadonly && bEditable)
1838 {
1839 if(ContentTypeId::INDEX == nContentType)
1840 {
1841 bRemoveIndexEntries = false;
1842
1843 const SwTOXBase* pBase = weld::fromId<SwTOXBaseContent*>(m_xTreeView->get_id(*xEntry))->GetTOXBase();
1844 if (!pBase->IsTOXBaseInReadonly())
1845 bRemoveEditEntry = false;
1846
1847 xPop->set_active(OUString::number(405), SwEditShell::IsTOXBaseReadonly(*pBase));
1848 }
1849 else if(ContentTypeId::TABLE == nContentType)
1850 {
1851 bRemoveSelectEntry = false;
1852 bRemoveEditEntry = false;
1853 bRemoveUnprotectEntry = false;
1854 bool bFull = false;
1855 OUString sTableName = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->GetName();
1856 bool bProt = m_pActiveShell->HasTableAnyProtection( &sTableName, &bFull );
1857 xPop->set_sensitive(OUString::number(403), !bFull);
1858 xPop->set_sensitive(OUString::number(404), bProt);
1859 }
1860 else if(ContentTypeId::REGION == nContentType)
1861 {
1862 bRemoveSelectEntry = false;
1863 bRemoveEditEntry = false;
1864 }
1865 else if (bEditable)
1866 bRemoveEditEntry = false;
1867 //Rename object
1868 if (bRenamable)
1869 bRemoveRenameEntry = false;
1870 }
1871 }
1872 else
1873 {
1874 if (lcl_IsContentType(*xEntry, *m_xTreeView))
1875 pType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xEntry));
1876 else
1877 pType = weld::fromId<SwContent*>(
1878 m_xTreeView->get_id(*xEntry))->GetParent();
1879 if (pType)
1880 {
1881 if (ContentTypeId::OUTLINE == nContentType)
1882 {
1883 bOutline = true;
1884 if (State::HIDDEN != m_eState)
1885 {
1886 lcl_SetOutlineContentEntriesSensitivities(this, *m_xTreeView, *xEntry,
1887 *xSubPopOutlineContent);
1888 bRemoveSendOutlineEntry = false;
1889 }
1890 bRemoveToggleExpandEntry = lcl_InsertExpandCollapseAllItem(*m_xTreeView, *xEntry,
1891 *xPop);
1892 }
1893 else if (State::HIDDEN != m_eState &&
1894 nContentType == ContentTypeId::POSTIT &&
1895 !m_pActiveShell->GetView().GetDocShell()->IsReadOnly() &&
1896 pType->GetMemberCount() > 0)
1897 bRemovePostItEntries = false;
1898 }
1899 }
1900 }
1901
1902 if (bRemoveToggleExpandEntry)
1903 xPop->remove(OUString::number(800));
1904
1905 if (bRemoveGotoEntry)
1906 xPop->remove(OUString::number(900));
1907
1908 if (bRemoveSelectEntry)
1909 xPop->remove(OUString::number(805));
1910
1911 if (bRemoveChapterEntries)
1912 {
1913 xPop->remove(OUString::number(801));
1914 xPop->remove(OUString::number(802));
1915 xPop->remove(OUString::number(803));
1916 xPop->remove(OUString::number(804));
1917 }
1918
1919 if (bRemoveSendOutlineEntry)
1920 xPop->remove(OUString::number(700));
1921
1922 if (bRemovePostItEntries)
1923 {
1924 xPop->remove(OUString::number(600));
1925 xPop->remove(OUString::number(601));
1926 xPop->remove(OUString::number(602));
1927 }
1928
1929 if (bRemoveDeleteChapterEntry)
1930 xPop->remove("deletechapter");
1931 if (bRemoveDeleteTableEntry)
1932 xPop->remove("deletetable");
1933 if (bRemoveDeleteFrameEntry)
1934 xPop->remove("deleteframe");
1935 if (bRemoveDeleteImageEntry)
1936 xPop->remove("deleteimage");
1937 if (bRemoveDeleteOLEObjectEntry)
1938 xPop->remove("deleteoleobject");
1939 if (bRemoveDeleteBookmarkEntry)
1940 xPop->remove("deletebookmark");
1941 if (bRemoveDeleteHyperlinkEntry)
1942 xPop->remove("deletehyperlink");
1943 if (bRemoveDeleteReferenceEntry)
1944 xPop->remove("deletereference");
1945 if (bRemoveDeleteIndexEntry)
1946 xPop->remove("deleteindex");
1947 if (bRemoveDeleteCommentEntry)
1948 xPop->remove("deletecomment");
1949 if (bRemoveDeleteDrawingObjectEntry)
1950 xPop->remove("deletedrawingobject");
1951 if (bRemoveDeleteFieldEntry)
1952 xPop->remove("deletefield");
1953
1954 bool bRemoveDeleteEntry =
1955 bRemoveDeleteChapterEntry &&
1956 bRemoveDeleteTableEntry &&
1957 bRemoveDeleteFrameEntry &&
1958 bRemoveDeleteImageEntry &&
1959 bRemoveDeleteOLEObjectEntry &&
1960 bRemoveDeleteBookmarkEntry &&
1961 bRemoveDeleteHyperlinkEntry &&
1962 bRemoveDeleteReferenceEntry &&
1963 bRemoveDeleteIndexEntry &&
1964 bRemoveDeleteCommentEntry &&
1965 bRemoveDeleteDrawingObjectEntry &&
1966 bRemoveDeleteFieldEntry;
1967
1968 if (bRemoveRenameEntry)
1969 xPop->remove(OUString::number(502));
1970
1971 if (bRemoveIndexEntries)
1972 {
1973 xPop->remove(OUString::number(401));
1974 xPop->remove(OUString::number(402));
1975 xPop->remove(OUString::number(405));
1976 }
1977
1978 if (bRemoveUnprotectEntry)
1979 xPop->remove(OUString::number(404));
1980
1981 if (bRemoveEditEntry)
1982 xPop->remove(OUString::number(403));
1983
1984 if (bRemoveToggleExpandEntry &&
1985 bRemoveSendOutlineEntry)
1986 xPop->remove("separator1");
1987
1988 if (bRemoveCopyEntry)
1989 xPop->remove("copy");
1990
1991 if (bRemoveGotoEntry &&
1992 bRemoveCopyEntry &&
1993 bRemoveSelectEntry &&
1994 bRemoveDeleteEntry &&
1995 bRemoveChapterEntries &&
1996 bRemovePostItEntries &&
1997 bRemoveRenameEntry &&
1998 bRemoveIndexEntries &&
1999 bRemoveUnprotectEntry &&
2000 bRemoveEditEntry)
2001 xPop->remove("separator2");
2002
2003 if (!bOutline)
2004 {
2005 xSubPop1.reset();
2006 xPop->remove(OUString::number(1)); // outline level menu
2007 }
2008 if (!bOutline || State::HIDDEN == m_eState)
2009 {
2010 xSubPopOutlineTracking.reset();
2011 xPop->remove(OUString::number(4)); // outline tracking menu
2012 }
2013 if (!bOutline || State::HIDDEN == m_eState ||
2014 !m_pActiveShell->GetViewOptions()->IsShowOutlineContentVisibilityButton() ||
2015 m_pActiveShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount() == 0)
2016 {
2017 xSubPopOutlineContent.reset();
2018 xPop->remove(OUString::number(5)); // outline folding menu
2019 xPop->remove("separator3");
2020 }
2021
2022 if (bRemoveTableTracking)
2023 xPop->remove("tabletracking");
2024 if (bRemoveSectionTracking)
2025 xPop->remove("sectiontracking");
2026 if (bRemoveFrameTracking)
2027 xPop->remove("frametracking");
2028 if (bRemoveImageTracking)
2029 xPop->remove("imagetracking");
2030 if (bRemoveOLEobjectTracking)
2031 xPop->remove("oleobjecttracking");
2032 if (bRemoveBookmarkTracking)
2033 xPop->remove("bookmarktracking");
2034 if (bRemoveHyperlinkTracking)
2035 xPop->remove("hyperlinktracking");
2036 if (bRemoveReferenceTracking)
2037 xPop->remove("referencetracking");
2038 if (bRemoveIndexTracking)
2039 xPop->remove("indextracking");
2040 if (bRemoveCommentTracking)
2041 xPop->remove("commenttracking");
2042 if (bRemoveDrawingObjectTracking)
2043 xPop->remove("drawingobjecttracking");
2044 if (bRemoveFieldTracking)
2045 xPop->remove("fieldtracking");
2046 if (bRemoveFootnoteTracking)
2047 xPop->remove("footnotetracking");
2048 if (bRemoveEndnoteTracking)
2049 xPop->remove("endnotetracking");
2050 if (bRemoveSortEntry)
2051 xPop->remove("sort");
2052
2053 bool bSetSensitiveCollapseAllCategories = false;
2054 if (!m_bIsRoot && xEntry)
2055 {
2056 bool bEntry = m_xTreeView->get_iter_first(*xEntry);
2057 while (bEntry)
2058 {
2059 if (m_xTreeView->get_row_expanded(*xEntry))
2060 {
2061 bSetSensitiveCollapseAllCategories = true;
2062 break;
2063 }
2064 bEntry = m_xTreeView->iter_next_sibling(*xEntry);
2065 }
2066 }
2067 xPop->set_sensitive("collapseallcategories", bSetSensitiveCollapseAllCategories);
2068
2069 OUString sCommand = xPop->popup_at_rect(m_xTreeView.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1)));
2070 if (!sCommand.isEmpty())
2071 ExecuteContextMenuAction(sCommand);
2072
2073 return true;
2074}
2075
2077{
2078 assert(dynamic_cast<SwContentType*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(rParent))));
2079 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(rParent));
2080 bool bGraphic = pCntType->GetType() == ContentTypeId::GRAPHIC;
2081 bool bRegion = pCntType->GetType() == ContentTypeId::REGION;
2082 std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator();
2083 const size_t nCount = pCntType->GetMemberCount();
2084 for(size_t i = 0; i < nCount; ++i)
2085 {
2086 const SwContent* pCnt = pCntType->GetMember(i);
2087 if (pCnt)
2088 {
2089 OUString sEntry = pCnt->GetName();
2090 if (sEntry.isEmpty())
2091 sEntry = m_sSpace;
2092 OUString sId(weld::toId(pCnt));
2093 insert(&rParent, sEntry, sId, false, xChild.get());
2094 m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
2095 if (bGraphic && !static_cast<const SwGraphicContent*>(pCnt)->GetLink().isEmpty())
2096 m_xTreeView->set_image(*xChild, RID_BMP_NAVI_GRAPHIC_LINK);
2097 else if (bRegion)
2098 m_xTreeView->set_extra_row_indent(*xChild,
2099 static_cast<const SwRegionContent*>(pCnt)->GetRegionLevel());
2100 }
2101 }
2102}
2103
2104void SwContentTree::insert(const weld::TreeIter* pParent, const OUString& rStr, const OUString& rId,
2105 bool bChildrenOnDemand, weld::TreeIter* pRet)
2106{
2107 m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, bChildrenOnDemand, pRet);
2108 ++m_nEntryCount;
2109}
2110
2112{
2113 if (m_xTreeView->iter_has_child(rIter))
2114 {
2115 std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rIter);
2116 (void)m_xTreeView->iter_children(*xChild);
2117 remove(*xChild);
2118 }
2119 m_xTreeView->remove(rIter);
2120 --m_nEntryCount;
2121}
2122
2123// Content will be integrated into the Box only on demand.
2125{
2126 // Does the parent already have children or is it not a 'children on demand' node?
2127 if (m_xTreeView->iter_has_child(rParent) || !m_xTreeView->get_children_on_demand(rParent))
2128 return false;
2129
2130 // Is this a content type?
2131 if (lcl_IsContentType(rParent, *m_xTreeView))
2132 {
2133 std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator();
2134
2135 assert(dynamic_cast<SwContentType*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(rParent))));
2136 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(rParent));
2137
2138 const size_t nCount = pCntType->GetMemberCount();
2139 // Add for outline plus/minus
2140 if (pCntType->GetType() == ContentTypeId::OUTLINE)
2141 {
2142 std::vector<std::unique_ptr<weld::TreeIter>> aParentCandidates;
2143 for(size_t i = 0; i < nCount; ++i)
2144 {
2145 const SwContent* pCnt = pCntType->GetMember(i);
2146 if(pCnt)
2147 {
2148 const auto nLevel = static_cast<const SwOutlineContent*>(pCnt)->GetOutlineLevel();
2149 OUString sEntry = pCnt->GetName();
2150 if(sEntry.isEmpty())
2151 sEntry = m_sSpace;
2152 OUString sId(weld::toId(pCnt));
2153
2154 auto lambda = [nLevel, this](const std::unique_ptr<weld::TreeIter>& entry)
2155 {
2156 return lcl_IsLowerOutlineContent(*entry, *m_xTreeView, nLevel);
2157 };
2158
2159 // if there is a preceding outline node candidate with a lower outline level use
2160 // that as a parent, otherwise use the root node
2161 auto aFind = std::find_if(aParentCandidates.rbegin(), aParentCandidates.rend(), lambda);
2162 if (aFind != aParentCandidates.rend())
2163 insert(aFind->get(), sEntry, sId, false, xChild.get());
2164 else
2165 insert(&rParent, sEntry, sId, false, xChild.get());
2166 m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
2167 m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 - m_xTreeView->get_iter_depth(*xChild));
2168
2169 // remove any parent candidates equal to or higher than this node
2170 aParentCandidates.erase(std::remove_if(aParentCandidates.begin(), aParentCandidates.end(),
2171 std::not_fn(lambda)), aParentCandidates.end());
2172
2173 // add this node as a parent candidate for any following nodes at a higher outline level
2174 aParentCandidates.emplace_back(m_xTreeView->make_iterator(xChild.get()));
2175 }
2176 }
2177 }
2178 else
2179 InsertContent(rParent);
2180
2181 return nCount != 0;
2182 }
2183
2184 return false;
2185}
2186
2188{
2189 SdrObject *pRetObj = nullptr;
2190 switch(pCnt->GetParent()->GetType())
2191 {
2193 {
2194 SdrView* pDrawView = m_pActiveShell->GetDrawView();
2195 if (pDrawView)
2196 {
2198 SdrPage* pPage = pDrawModel->GetPage(0);
2199 const size_t nCount = pPage->GetObjCount();
2200
2201 for( size_t i=0; i<nCount; ++i )
2202 {
2203 SdrObject* pTemp = pPage->GetObj(i);
2204 if( pTemp->GetName() == pCnt->GetName())
2205 {
2206 pRetObj = pTemp;
2207 break;
2208 }
2209 }
2210 }
2211 break;
2212 }
2213 default:
2214 pRetObj = nullptr;
2215 }
2216 return pRetObj;
2217}
2218
2219void SwContentTree::Expand(const weld::TreeIter& rParent, std::vector<std::unique_ptr<weld::TreeIter>>* pNodesToExpand)
2220{
2221 if (!(m_xTreeView->iter_has_child(rParent) || m_xTreeView->get_children_on_demand(rParent)))
2222 return;
2223
2224 if (!m_bIsRoot
2225 || (lcl_IsContentType(rParent, *m_xTreeView) &&
2226 weld::fromId<SwContentType*>(m_xTreeView->get_id(rParent))->GetType() == ContentTypeId::OUTLINE)
2228 {
2229 if (lcl_IsContentType(rParent, *m_xTreeView))
2230 {
2231 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(rParent));
2232 const sal_Int32 nOr = 1 << static_cast<int>(pCntType->GetType()); //linear -> Bitposition
2233 if (State::HIDDEN != m_eState)
2234 {
2235 m_nActiveBlock |= nOr;
2237 }
2238 else
2239 m_nHiddenBlock |= nOr;
2240 if (pCntType->GetType() == ContentTypeId::OUTLINE)
2241 {
2242 std::map< void*, bool > aCurrOutLineNodeMap;
2243
2244 SwWrtShell* pShell = GetWrtShell();
2245 bool bParentHasChild = RequestingChildren(rParent);
2246 if (pNodesToExpand)
2247 pNodesToExpand->emplace_back(m_xTreeView->make_iterator(&rParent));
2248 if (bParentHasChild)
2249 {
2250 std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rParent));
2251 bool bChild = m_xTreeView->iter_next(*xChild);
2252 while (bChild && lcl_IsContent(*xChild, *m_xTreeView))
2253 {
2254 if (m_xTreeView->iter_has_child(*xChild))
2255 {
2256 assert(dynamic_cast<SwOutlineContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xChild))));
2257 auto const nPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*xChild))->GetOutlinePos();
2258 void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
2259 aCurrOutLineNodeMap.emplace( key, false );
2260 std::map<void*, bool>::iterator iter = mOutLineNodeMap.find( key );
2261 if( iter != mOutLineNodeMap.end() && mOutLineNodeMap[key])
2262 {
2263 aCurrOutLineNodeMap[key] = true;
2264 RequestingChildren(*xChild);
2265 if (pNodesToExpand)
2266 pNodesToExpand->emplace_back(m_xTreeView->make_iterator(xChild.get()));
2267 m_xTreeView->set_children_on_demand(*xChild, false);
2268 }
2269 }
2270 bChild = m_xTreeView->iter_next(*xChild);
2271 }
2272 }
2273 mOutLineNodeMap = aCurrOutLineNodeMap;
2274 return;
2275 }
2276 }
2277 else
2278 {
2279 if (lcl_IsContent(rParent, *m_xTreeView))
2280 {
2281 SwWrtShell* pShell = GetWrtShell();
2282 // paranoid assert now that outline type is checked
2283 assert(dynamic_cast<SwOutlineContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(rParent))));
2284 auto const nPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(rParent))->GetOutlinePos();
2285 void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
2286 mOutLineNodeMap[key] = true;
2287 }
2288 }
2289 }
2290
2291 RequestingChildren(rParent);
2292 if (pNodesToExpand)
2293 pNodesToExpand->emplace_back(m_xTreeView->make_iterator(&rParent));
2294}
2295
2296IMPL_LINK(SwContentTree, ExpandHdl, const weld::TreeIter&, rParent, bool)
2297{
2298 Expand(rParent, nullptr);
2299 return true;
2300}
2301
2302IMPL_LINK(SwContentTree, CollapseHdl, const weld::TreeIter&, rParent, bool)
2303{
2304 if (!m_xTreeView->iter_has_child(rParent) || m_xTreeView->get_children_on_demand(rParent))
2305 return true;
2306
2307 if (lcl_IsContentType(rParent, *m_xTreeView))
2308 {
2309 if (m_bIsRoot)
2310 {
2311 // collapse to children of root node
2312 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(&rParent));
2313 if (m_xTreeView->iter_children(*xEntry))
2314 {
2315 do
2316 {
2317 m_xTreeView->collapse_row(*xEntry);
2318 }
2319 while (m_xTreeView->iter_next(*xEntry));
2320 }
2321 return false; // return false to notify caller not to do collapse
2322 }
2323 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(rParent));
2324 const sal_Int32 nAnd = ~(1 << static_cast<int>(pCntType->GetType()));
2325 if (State::HIDDEN != m_eState)
2326 {
2327 m_nActiveBlock &= nAnd;
2328 m_pConfig->SetActiveBlock(m_nActiveBlock);
2329 }
2330 else
2331 m_nHiddenBlock &= nAnd;
2332 }
2333 else if (lcl_IsContent(rParent, *m_xTreeView))
2334 {
2335 SwWrtShell* pShell = GetWrtShell();
2336 assert(dynamic_cast<SwOutlineContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(rParent))));
2337 auto const nPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(rParent))->GetOutlinePos();
2338 void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos ));
2339 mOutLineNodeMap[key] = false;
2340 }
2341
2342 return true;
2343}
2344
2345// Also on double click will be initially opened only.
2346IMPL_LINK_NOARG(SwContentTree, ContentDoubleClickHdl, weld::TreeView&, bool)
2347{
2348 if (m_nRowActivateEventId)
2349 Application::RemoveUserEvent(m_nRowActivateEventId);
2350 // post the event to process row activate after mouse press event to be able to set key
2351 // modifier for selection feature (tdf#154211)
2352 m_nRowActivateEventId
2353 = Application::PostUserEvent(LINK(this, SwContentTree, AsyncContentDoubleClickHdl));
2354
2355 bool bConsumed = false;
2356
2357 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2358 if (m_xTreeView->get_cursor(xEntry.get()) && lcl_IsContent(*xEntry, *m_xTreeView) &&
2359 (State::HIDDEN != m_eState))
2360 {
2361 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry));
2362 assert(pCnt && "no UserData");
2363 if (pCnt && !pCnt->IsInvisible())
2364 {
2365 // fdo#36308 don't expand outlines on double-click
2366 bConsumed = pCnt->GetParent()->GetType() == ContentTypeId::OUTLINE;
2367 }
2368 }
2369
2370 return bConsumed; // false/true == allow/disallow more to be done, i.e. expand/collapse children
2371}
2372
2373IMPL_LINK_NOARG(SwContentTree, AsyncContentDoubleClickHdl, void*, void)
2374{
2375 m_nRowActivateEventId = nullptr;
2376
2377 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2378 bool bEntry = m_xTreeView->get_cursor(xEntry.get());
2379 // Is it a content type?
2380 OSL_ENSURE(bEntry, "no current entry!");
2381 if (bEntry)
2382 {
2383 if (lcl_IsContentType(*xEntry, *m_xTreeView) && !m_xTreeView->iter_has_child(*xEntry))
2384 {
2385 RequestingChildren(*xEntry);
2386 m_xTreeView->set_children_on_demand(*xEntry, false);
2387 }
2388 else if (!lcl_IsContentType(*xEntry, *m_xTreeView) && (State::HIDDEN != m_eState))
2389 {
2390 assert(dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
2391 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry));
2392 assert(pCnt && "no UserData");
2393 if (pCnt && !pCnt->IsInvisible())
2394 {
2395 if (State::CONSTANT == m_eState)
2396 {
2397 m_pActiveShell->GetView().GetViewFrame().GetWindow().ToTop();
2398 }
2399 //Jump to content type:
2400 GotoContent(pCnt);
2401 }
2402 }
2403 }
2404}
2405
2406namespace
2407{
2408 OUString GetImageIdForContentTypeId(ContentTypeId eType)
2409 {
2410 OUString sResId;
2411
2412 switch (eType)
2413 {
2415 sResId = RID_BMP_NAVI_OUTLINE;
2416 break;
2418 sResId = RID_BMP_NAVI_TABLE;
2419 break;
2421 sResId = RID_BMP_NAVI_FRAME;
2422 break;
2424 sResId = RID_BMP_NAVI_GRAPHIC;
2425 break;
2426 case ContentTypeId::OLE:
2427 sResId = RID_BMP_NAVI_OLE;
2428 break;
2430 sResId = RID_BMP_NAVI_BOOKMARK;
2431 break;
2433 sResId = RID_BMP_NAVI_REGION;
2434 break;
2436 sResId = RID_BMP_NAVI_URLFIELD;
2437 break;
2439 sResId = RID_BMP_NAVI_REFERENCE;
2440 break;
2442 sResId = RID_BMP_NAVI_INDEX;
2443 break;
2445 sResId = RID_BMP_NAVI_POSTIT;
2446 break;
2448 sResId = RID_BMP_NAVI_DRAWOBJECT;
2449 break;
2451 sResId = RID_BMP_NAVI_TEXTFIELD;
2452 break;
2454 sResId = RID_BMP_NAVI_FOOTNOTE;
2455 break;
2457 sResId = RID_BMP_NAVI_ENDNOTE;
2458 break;
2460 SAL_WARN("sw.ui", "ContentTypeId::UNKNOWN has no bitmap preview");
2461 break;
2462 }
2463
2464 return sResId;
2465 };
2466}
2467
2469{
2470 return weld::GetAbsPos(*m_xTreeView, rIter);
2471}
2472
2474{
2475 return m_nEntryCount;
2476}
2477
2479{
2480 if (!m_xTreeView->iter_has_child(rParent))
2481 return 0;
2482
2483 std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rParent));
2484
2485 size_t nCount = 0;
2486 auto nRefDepth = m_xTreeView->get_iter_depth(*xParent);
2487 auto nActDepth = nRefDepth;
2488 do
2489 {
2490 if (!m_xTreeView->iter_next(*xParent))
2491 xParent.reset();
2492 else
2493 nActDepth = m_xTreeView->get_iter_depth(*xParent);
2494 nCount++;
2495 } while(xParent && nRefDepth < nActDepth);
2496
2497 nCount--;
2498 return nCount;
2499}
2500
2501std::unique_ptr<weld::TreeIter> SwContentTree::GetEntryAtAbsPos(size_t nAbsPos) const
2502{
2503 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2504 if (!m_xTreeView->get_iter_first(*xEntry))
2505 xEntry.reset();
2506
2507 while (nAbsPos && xEntry)
2508 {
2509 if (!m_xTreeView->iter_next(*xEntry))
2510 xEntry.reset();
2511 nAbsPos--;
2512 }
2513 return xEntry;
2514}
2515
2516void SwContentTree::Display( bool bActive )
2517{
2518 // First read the selected entry to select it later again if necessary
2519 // -> the user data here are no longer valid!
2520 std::unique_ptr<weld::TreeIter> xOldSelEntry(m_xTreeView->make_iterator());
2521 if (!m_xTreeView->get_selected(xOldSelEntry.get()))
2522 xOldSelEntry.reset();
2523 OUString sOldSelEntryId;
2524 size_t nEntryRelPos = 0; // relative position to their parent
2525 size_t nOldEntryCount = GetEntryCount();
2526 sal_Int32 nOldScrollPos = 0;
2527 if (xOldSelEntry)
2528 {
2530 sOldSelEntryId = m_xTreeView->get_id(*xOldSelEntry);
2531 nOldScrollPos = m_xTreeView->vadjustment_get_value();
2532 std::unique_ptr<weld::TreeIter> xParentEntry = m_xTreeView->make_iterator(xOldSelEntry.get());
2533 while (m_xTreeView->get_iter_depth(*xParentEntry))
2534 m_xTreeView->iter_parent(*xParentEntry);
2535 if (m_xTreeView->get_iter_depth(*xOldSelEntry))
2536 nEntryRelPos = GetAbsPos(*xOldSelEntry) - GetAbsPos(*xParentEntry);
2537 }
2538
2539 clear();
2540
2541 if (!bActive)
2542 {
2544 if (m_xOverlayObject && m_xOverlayObject->getOverlayManager())
2545 {
2546 m_xOverlayObject->getOverlayManager()->remove(*m_xOverlayObject);
2547 m_xOverlayObject.reset();
2548 }
2550 }
2551 else if (State::HIDDEN == m_eState)
2553 SwWrtShell* pShell = GetWrtShell();
2554 const bool bReadOnly = !pShell || pShell->GetView().GetDocShell()->IsReadOnly();
2556 {
2558 bool bDisable = pShell == nullptr || bReadOnly;
2560 pNavi->m_xContent6ToolBox->set_item_sensitive("chapterup", !bDisable);
2561 pNavi->m_xContent6ToolBox->set_item_sensitive("chapterdown", !bDisable);
2562 pNavi->m_xContent6ToolBox->set_item_sensitive("promote", !bDisable);
2563 pNavi->m_xContent6ToolBox->set_item_sensitive("demote", !bDisable);
2564 pNavi->m_xContent5ToolBox->set_item_sensitive("reminder", !bDisable);
2565 }
2566
2567 if (pShell)
2568 {
2569 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
2570 std::unique_ptr<weld::TreeIter> xCntTypeEntry;
2571 std::vector<std::unique_ptr<weld::TreeIter>> aNodesToExpand;
2572 // all content navigation view
2574 {
2575 m_xTreeView->freeze();
2576
2578 {
2579 std::unique_ptr<SwContentType>& rpContentT = bActive ?
2580 m_aActiveContentArr[nCntType] :
2581 m_aHiddenContentArr[nCntType];
2582 if(!rpContentT)
2583 rpContentT.reset(new SwContentType(pShell, nCntType, m_nOutlineLevel ));
2584
2585 OUString aImage(GetImageIdForContentTypeId(nCntType));
2586 bool bChOnDemand = 0 != rpContentT->GetMemberCount();
2587 OUString sId(weld::toId(rpContentT.get()));
2588 insert(nullptr, rpContentT->GetName(), sId, bChOnDemand, xEntry.get());
2589 m_xTreeView->set_image(*xEntry, aImage);
2590
2591 m_xTreeView->set_sensitive(*xEntry, bChOnDemand);
2592
2593 if (nCntType == m_nLastSelType)
2594 xCntTypeEntry = m_xTreeView->make_iterator(xEntry.get());
2595
2596 sal_Int32 nExpandOptions = (State::HIDDEN == m_eState)
2599 if (nExpandOptions & (1 << static_cast<int>(nCntType)))
2600 {
2601 // fill contents of to-be expanded entries while frozen
2602 Expand(*xEntry, &aNodesToExpand);
2603 m_xTreeView->set_children_on_demand(*xEntry, false);
2604 }
2605 }
2606
2607 m_xTreeView->thaw();
2608
2609 // restore visual expanded tree state
2610 for (const auto& rNode : aNodesToExpand)
2611 m_xTreeView->expand_row(*rNode);
2612 }
2613 // root content navigation view
2614 else
2615 {
2616 m_xTreeView->freeze();
2617
2618 std::unique_ptr<SwContentType>& rpRootContentT = bActive ?
2621 if(!rpRootContentT)
2622 rpRootContentT.reset(new SwContentType(pShell, m_nRootType, m_nOutlineLevel ));
2623 OUString aImage(GetImageIdForContentTypeId(m_nRootType));
2624 bool bChOnDemand = m_nRootType == ContentTypeId::OUTLINE;
2625 OUString sId(weld::toId(rpRootContentT.get()));
2626 insert(nullptr, rpRootContentT->GetName(), sId, bChOnDemand, xEntry.get());
2627 m_xTreeView->set_image(*xEntry, aImage);
2628
2629 xCntTypeEntry = m_xTreeView->make_iterator(xEntry.get());
2630
2631 if (!bChOnDemand)
2632 InsertContent(*xEntry);
2633 else
2634 {
2635 // fill contents of to-be expanded entries while frozen
2636 Expand(*xEntry, &aNodesToExpand);
2637 m_xTreeView->set_children_on_demand(*xEntry, false);
2638 }
2639
2640 m_xTreeView->set_sensitive(*xEntry, m_xTreeView->iter_has_child(*xEntry));
2641
2642 m_xTreeView->thaw();
2643
2644 if (bChOnDemand)
2645 {
2646 // restore visual expanded tree state
2647 for (const auto& rNode : aNodesToExpand)
2648 m_xTreeView->expand_row(*rNode);
2649 }
2650 else
2651 m_xTreeView->expand_row(*xEntry);
2652 }
2653
2654 // Reselect the old selected entry. If it is not available, select the entry at the old
2655 // selected entry position unless that entry position is now a content type or is past the
2656 // end of the member list then select the entry at the previous entry position.
2657 if (xOldSelEntry)
2658 {
2659 std::unique_ptr<weld::TreeIter> xSelEntry = m_xTreeView->make_iterator(xCntTypeEntry.get());
2660 if (nEntryRelPos)
2661 {
2662 std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator(xCntTypeEntry.get()));
2663 std::unique_ptr<weld::TreeIter> xTemp(m_xTreeView->make_iterator(xIter.get()));
2664 sal_uLong nPos = 1;
2665 bool bNext;
2666 while ((bNext = m_xTreeView->iter_next(*xIter) && lcl_IsContent(*xIter, *m_xTreeView)))
2667 {
2668 if (m_xTreeView->get_id(*xIter) == sOldSelEntryId || nPos == nEntryRelPos)
2669 {
2670 m_xTreeView->copy_iterator(*xIter, *xSelEntry);
2671 break;
2672 }
2673 m_xTreeView->copy_iterator(*xIter, *xTemp); // note previous entry
2674 nPos++;
2675 }
2676 if (!bNext)
2677 xSelEntry = std::move(xTemp);
2678 }
2679 // set_cursor unselects all entries, makes passed entry visible, and selects it
2680 m_xTreeView->set_cursor(*xSelEntry);
2681 Select();
2682 }
2683 }
2684
2685 if (!m_bIgnoreDocChange && GetEntryCount() == nOldEntryCount)
2686 {
2687 m_xTreeView->vadjustment_set_value(nOldScrollPos);
2688 }
2689}
2690
2692{
2693 m_xTreeView->freeze();
2694 m_xTreeView->clear();
2695 m_nEntryCount = 0;
2696 m_xTreeView->thaw();
2697}
2698
2700 sal_Int8& rDragMode )
2701{
2702 bool bRet = false;
2703 SwWrtShell* pWrtShell = GetWrtShell();
2704 OSL_ENSURE(pWrtShell, "no Shell!");
2705
2706 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2707 bool bEntry = m_xTreeView->get_cursor(xEntry.get());
2708 if (!bEntry || lcl_IsContentType(*xEntry, *m_xTreeView) || !pWrtShell)
2709 return false;
2710 OUString sEntry;
2711 assert(dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
2712 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry));
2713
2714 const ContentTypeId nActType = pCnt->GetParent()->GetType();
2715 OUString sUrl;
2716 bool bOutline = false;
2717 OUString sOutlineText;
2718 switch( nActType )
2719 {
2721 {
2722 const SwOutlineNodes::size_type nPos = static_cast<SwOutlineContent*>(pCnt)->GetOutlinePos();
2723 OSL_ENSURE(nPos < pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount(),
2724 "outlinecnt changed");
2725
2726 // make sure outline may actually be copied
2727 if( pWrtShell->IsOutlineCopyable( nPos ) )
2728 {
2729 const SwNumRule* pOutlRule = pWrtShell->GetOutlineNumRule();
2730 const SwTextNode* pTextNd =
2732 if (pTextNd && pOutlRule && pTextNd->IsNumbered(pWrtShell->GetLayout()))
2733 {
2734 SwNumberTree::tNumberVector aNumVector =
2735 pTextNd->GetNumberVector(pWrtShell->GetLayout());
2736 for( int nLevel = 0;
2737 nLevel <= pTextNd->GetActualListLevel();
2738 nLevel++ )
2739 {
2740 const SwNumberTree::tSwNumTreeNumber nVal = aNumVector[nLevel] + 1;
2741 sEntry += OUString::number( nVal - pOutlRule->Get(nLevel).GetStart() ) + ".";
2742 }
2743 }
2744 sEntry += pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout(), false);
2745 sOutlineText = pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout());
2746 m_bIsOutlineMoveable = static_cast<SwOutlineContent*>(pCnt)->IsMoveable();
2747 bOutline = true;
2748 }
2749 }
2750 break;
2757 // cannot be inserted, neither as URL nor as section
2758 break;
2760 sUrl = static_cast<SwURLFieldContent*>(pCnt)->GetURL();
2761 [[fallthrough]];
2762 case ContentTypeId::OLE:
2764 if(GetParentWindow()->GetRegionDropMode() != RegionMode::NONE)
2765 break;
2766 else
2767 rDragMode &= ~( DND_ACTION_MOVE | DND_ACTION_LINK );
2768 [[fallthrough]];
2769 default:
2770 sEntry = m_xTreeView->get_text(*xEntry);
2771 }
2772
2773 if(!sEntry.isEmpty())
2774 {
2775 const SwDocShell* pDocShell = pWrtShell->GetView().GetDocShell();
2776 if(sUrl.isEmpty())
2777 {
2778 if(pDocShell->HasName())
2779 {
2780 SfxMedium* pMedium = pDocShell->GetMedium();
2781 sUrl = pMedium->GetURLObject().GetURLNoMark();
2782 // only if a primarily link shall be integrated.
2783 bRet = true;
2784 }
2785 else if ( nActType == ContentTypeId::REGION || nActType == ContentTypeId::BOOKMARK )
2786 {
2787 // For field and bookmarks a link is also allowed
2788 // without a filename into its own document.
2789 bRet = true;
2790 }
2791 else if (State::CONSTANT == m_eState &&
2792 ( !::GetActiveView() ||
2794 {
2795 // Urls of inactive views cannot dragged without
2796 // file names, also.
2797 bRet = false;
2798 }
2799 else
2800 {
2801 bRet = GetParentWindow()->GetRegionDropMode() == RegionMode::NONE;
2802 rDragMode = DND_ACTION_MOVE;
2803 }
2804
2805 const OUString& rToken = pCnt->GetParent()->GetTypeToken();
2806 sUrl += "#" + sEntry;
2807 if(!rToken.isEmpty())
2808 {
2809 sUrl += OUStringChar(cMarkSeparator) + rToken;
2810 }
2811 }
2812 else
2813 bRet = true;
2814
2815 if( bRet )
2816 {
2817 // In Outlines of heading text must match
2818 // the real number into the description.
2819 if(bOutline)
2820 sEntry = sOutlineText;
2821
2822 {
2823 NaviContentBookmark aBmk( sUrl, sEntry,
2824 GetParentWindow()->GetRegionDropMode(),
2825 pDocShell);
2826 aBmk.Copy( rTransfer );
2827 }
2828
2829 // An INetBookmark must a be delivered to foreign DocShells
2830 if( pDocShell->HasName() )
2831 {
2832 INetBookmark aBkmk( sUrl, sEntry );
2833 rTransfer.CopyINetBookmark( aBkmk );
2834 }
2835 }
2836 }
2837 return bRet;
2838}
2839
2841{
2842 if(!m_bIsRoot)
2843 {
2844 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2845 bool bEntry = m_xTreeView->get_cursor(xEntry.get());
2846 if (bEntry)
2847 {
2848 const SwContentType* pCntType;
2849 if (lcl_IsContentType(*xEntry, *m_xTreeView))
2850 {
2851 assert(dynamic_cast<SwContentType*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
2852 pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xEntry));
2853 }
2854 else
2855 {
2856 assert(dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
2857 pCntType = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->GetParent();
2858 }
2859 m_nRootType = pCntType->GetType();
2860 m_bIsRoot = true;
2862 {
2863 m_xTreeView->set_selection_mode(SelectionMode::Multiple);
2864 }
2866 }
2867 }
2868 else
2869 {
2870 m_xTreeView->set_selection_mode(SelectionMode::Single);
2873 m_bIsRoot = false;
2874 // Other content type member data could have changed while in root view. Fill the content
2875 // member lists excluding the toggled from root content which should already have the most
2876 // recent data.
2877 if (State::HIDDEN != m_eState)
2878 {
2880 {
2882 m_aActiveContentArr[i]->FillMemberList();
2883 }
2884 }
2886 }
2889 pBox->set_item_active("root", m_bIsRoot);
2890}
2891
2893{
2894 bool bContentChanged = false;
2895
2896// - Run through the local array and the Treelistbox in parallel.
2897// - Are the records not expanded, they are discarded only in the array
2898// and the content type will be set as the new UserData.
2899// - Is the root mode is active only this will be updated.
2900
2901// Valid for the displayed content types is:
2902// the Memberlist will be erased and the membercount will be updated
2903// If content will be checked, the memberlists will be replenished
2904// at the same time. Once a difference occurs it will be only replenished
2905// no longer checked. Finally, the box is filled again.
2906
2907 if (State::HIDDEN == m_eState)
2908 {
2910 {
2912 m_aActiveContentArr[i]->Invalidate();
2913 }
2914 return false;
2915 }
2916
2917 // root content navigation view
2918 if(m_bIsRoot)
2919 {
2920 std::unique_ptr<weld::TreeIter> xRootEntry(m_xTreeView->make_iterator());
2921 if (!m_xTreeView->get_iter_first(*xRootEntry))
2922 return true;
2923
2924 assert(dynamic_cast<SwContentType*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xRootEntry))));
2925 const ContentTypeId nType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xRootEntry))->GetType();
2926 SwContentType* pArrType = m_aActiveContentArr[nType].get();
2927 assert(weld::toId(pArrType) == m_xTreeView->get_id(*xRootEntry));
2928 if (!pArrType)
2929 return true;
2930
2931 pArrType->FillMemberList(&bContentChanged);
2932 if (bContentChanged)
2933 return true;
2934
2935 // FillMemberList tests if member count in old member array equals member count in new
2936 // member array. Test here for member count difference between array and tree.
2937 const size_t nChildCount = GetChildCount(*xRootEntry);
2938 if (nChildCount != pArrType->GetMemberCount())
2939 return true;
2940
2941 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(xRootEntry.get()));
2942 for (size_t j = 0; j < nChildCount; ++j)
2943 {
2944 if (!m_xTreeView->iter_next(*xEntry))
2945 {
2946 SAL_WARN("sw.ui", "unexpected missing entry");
2947 return true;
2948 }
2949
2950 // FillMemberList clears the content type member list and refills with new data.
2951 // Treeview entry user data is set here to the string representation of the pointer to
2952 // the member data in the array. The Display function will clear and recreate the
2953 // treeview from the content type member arrays if content change is detected.
2954 const SwContent* pCnt = pArrType->GetMember(j);
2955 OUString sSubId(weld::toId(pCnt));
2956 m_xTreeView->set_id(*xEntry, sSubId);
2957
2958 OUString sEntryText = m_xTreeView->get_text(*xEntry);
2959 if (sEntryText != pCnt->GetName() &&
2960 !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
2961 {
2962 return true;
2963 }
2964 }
2965 }
2966 // all content navigation view
2967 else
2968 {
2969 // Fill member list for each content type and check for content change. If content change
2970 // is detected only fill member lists for remaining content types. The Display function
2971 // will clear and recreate the treeview from the content type member arrays if content has
2972 // changed.
2973 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
2974
2975 // lambda function to find the next content type entry
2976 auto lcl_nextContentTypeEntry = [this, &xEntry](){
2977 while (m_xTreeView->get_iter_depth(*xEntry))
2978 m_xTreeView->iter_parent(*xEntry);
2979 return m_xTreeView->iter_next_sibling(*xEntry);
2980 };
2981
2982 for (bool bEntry = m_xTreeView->get_iter_first(*xEntry); bEntry;
2983 bEntry = lcl_nextContentTypeEntry())
2984 {
2985 assert(dynamic_cast<SwContentType*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
2986 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xEntry));
2987 const size_t nCntCount = pCntType->GetMemberCount();
2988 const ContentTypeId nType = pCntType->GetType();
2989 SwContentType* pArrType = m_aActiveContentArr[nType].get();
2990 assert(weld::toId(pArrType) == m_xTreeView->get_id(*xEntry));
2991
2992 if (!pArrType)
2993 {
2994 bContentChanged = true;
2995 continue;
2996 }
2997
2998 // all content type member lists must be filled!
2999 if (bContentChanged)
3000 {
3001 // If content change has already been detected there is no need to detect
3002 // other content change so no argument is supplied here to FillMemberList.
3003 pArrType->FillMemberList();
3004 continue;
3005 }
3006
3007 pArrType->FillMemberList(&bContentChanged);
3008 if (bContentChanged)
3009 continue;
3010
3011 // does entry have children?
3012 if (m_xTreeView->get_row_expanded(*xEntry))
3013 {
3014 const size_t nChildCount = GetChildCount(*xEntry);
3015 if(nChildCount != pArrType->GetMemberCount())
3016 {
3017 bContentChanged = true;
3018 continue;
3019 }
3020
3021 for(size_t j = 0; j < nChildCount; ++j)
3022 {
3023 if (!m_xTreeView->iter_next(*xEntry))
3024 {
3025 SAL_WARN("sw.ui", "unexpected missing entry");
3026 bContentChanged = true;
3027 continue;
3028 }
3029
3030 const SwContent* pCnt = pArrType->GetMember(j);
3031 OUString sSubId(weld::toId(pCnt));
3032 m_xTreeView->set_id(*xEntry, sSubId);
3033
3034 OUString sEntryText = m_xTreeView->get_text(*xEntry);
3035 if( sEntryText != pCnt->GetName() &&
3036 !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
3037 {
3038 bContentChanged = true;
3039 continue;
3040 }
3041 }
3042 }
3043 // not expanded and has children
3044 else if (m_xTreeView->iter_has_child(*xEntry))
3045 {
3046 bool bRemoveChildren = false;
3047 const size_t nOldChildCount = GetChildCount(*xEntry);
3048 const size_t nNewChildCount = pArrType->GetMemberCount();
3049 if (nOldChildCount != nNewChildCount)
3050 {
3051 bRemoveChildren = true;
3052 }
3053 else
3054 {
3055 std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
3056 (void)m_xTreeView->iter_children(*xChild);
3057 for (size_t j = 0; j < nOldChildCount; ++j)
3058 {
3059 const SwContent* pCnt = pArrType->GetMember(j);
3060 OUString sSubId(weld::toId(pCnt));
3061 m_xTreeView->set_id(*xChild, sSubId);
3062 OUString sEntryText = m_xTreeView->get_text(*xChild);
3063 if( sEntryText != pCnt->GetName() &&
3064 !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
3065 {
3066 bRemoveChildren = true;
3067 }
3068 (void)m_xTreeView->iter_next(*xChild);
3069 }
3070 }
3071 if (bRemoveChildren)
3072 {
3073 std::unique_ptr<weld::TreeIter> xRemove(m_xTreeView->make_iterator(xEntry.get()));
3074 while (m_xTreeView->iter_children(*xRemove))
3075 {
3076 remove(*xRemove);
3077 m_xTreeView->copy_iterator(*xEntry, *xRemove);
3078 }
3079 m_xTreeView->set_children_on_demand(*xEntry, nNewChildCount != 0);
3080 }
3081 }
3082 else if((nCntCount != 0)
3083 != (pArrType->GetMemberCount()!=0))
3084 {
3085 bContentChanged = true;
3086 continue;
3087 }
3088 }
3089 }
3090
3091 return bContentChanged;
3092}
3093
3095{
3096 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3097 if (m_xTreeView->get_selected(xEntry.get()))
3098 {
3099 while (m_xTreeView->get_iter_depth(*xEntry))
3100 m_xTreeView->iter_parent(*xEntry);
3101 void* pId = weld::fromId<void*>(m_xTreeView->get_id(*xEntry));
3102 if (pId && lcl_IsContentType(*xEntry, *m_xTreeView))
3103 {
3104 assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pId)));
3105 m_nLastSelType = static_cast<SwContentType*>(pId)->GetType();
3106 }
3107 }
3108}
3109
3111{
3113
3114 // If clear is called by TimerUpdate:
3115 // Only for root can the validity of the UserData be guaranteed.
3116 m_xTreeView->all_foreach([this](weld::TreeIter& rEntry){
3117 m_xTreeView->set_id(rEntry, "");
3118 return false;
3119 });
3120}
3121
3123{
3124 m_pHiddenShell = pSh;
3128 {
3129 m_aHiddenContentArr[i].reset();
3130 }
3131 Display(false);
3132
3134}
3135
3137{
3138 bool bClear = m_pActiveShell != pSh;
3139 if (State::ACTIVE == m_eState && bClear)
3140 {
3142 m_pActiveShell = pSh;
3144 clear();
3145 }
3146 else if (State::CONSTANT == m_eState)
3147 {
3149 m_pActiveShell = pSh;
3151 bClear = true;
3152 }
3153
3154 // tdf#148432 in LTR UI override the navigator treeview direction based on
3155 // the first page directionality
3157 {
3158 const SwPageDesc& rDesc = m_pActiveShell->GetPageDesc(0);
3159 const SvxFrameDirectionItem& rFrameDir = rDesc.GetMaster().GetFrameDir();
3160 m_xTreeView->set_direction(rFrameDir.GetValue() == SvxFrameDirection::Horizontal_RL_TB);
3161 }
3162
3163 // Only if it is the active view, the array will be deleted and
3164 // the screen filled new.
3165 if (State::ACTIVE == m_eState && bClear)
3166 {
3167 if (m_pActiveShell)
3171 {
3172 m_aActiveContentArr[i].reset();
3173 }
3174 Display(true);
3175 }
3176}
3177
3179{
3181 m_pActiveShell = pSh;
3186 {
3187 m_aActiveContentArr[i].reset();
3188 }
3189 Display(true);
3190}
3191
3193{
3194 SfxViewEventHint const*const pVEHint(dynamic_cast<SfxViewEventHint const*>(&rHint));
3195 SwXTextView* pDyingShell = nullptr;
3196 if (m_pActiveShell && pVEHint && pVEHint->GetEventName() == "OnViewClosed")
3197 pDyingShell = dynamic_cast<SwXTextView*>(pVEHint->GetController().get());
3198 if (pDyingShell && pDyingShell->GetView() == &m_pActiveShell->GetView())
3199 {
3200 SetActiveShell(nullptr); // our view is dying, clear our pointers to it
3201 }
3202 else
3203 {
3204 SfxListener::Notify(rBC, rHint);
3205 }
3206 switch (rHint.GetId())
3207 {
3208 case SfxHintId::SwNavigatorUpdateTracking:
3210 break;
3211 case SfxHintId::SwNavigatorSelectOutlinesWithSelections:
3212 {
3214 {
3216 // make first selected entry visible
3217 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3218 if (xEntry && m_xTreeView->get_selected(xEntry.get()))
3219 m_xTreeView->scroll_to_row(*xEntry);
3220 }
3222 m_xTreeView->unselect_all();
3223 break;
3224 }
3225 case SfxHintId::DocChanged:
3226 if (!m_bIgnoreDocChange)
3227 {
3228 m_bDocHasChanged = true;
3229 TimerUpdate(&m_aUpdTimer);
3230 }
3231 break;
3232 case SfxHintId::ModeChanged:
3233 if (SwWrtShell* pShell = GetWrtShell())
3234 {
3235 const bool bReadOnly = pShell->GetView().GetDocShell()->IsReadOnly();
3237 {
3239
3240 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
3241 if (m_xTreeView->get_cursor(xEntry.get()))
3242 {
3243 m_xTreeView->select(*xEntry);
3244 Select();
3245 }
3246 else
3247 m_xTreeView->unselect_all();
3248 }
3249 }
3250 break;
3251 default:
3252 break;
3253 }
3254}
3255
3256// Handler for outline entry up/down left/right movement
3257void SwContentTree::ExecCommand(std::u16string_view rCmd, bool bOutlineWithChildren)
3258{
3259 if (m_xTreeView->count_selected_rows() == 0)
3260 return;
3261
3262 const bool bUp = rCmd == u"chapterup";
3263 const bool bUpDown = bUp || rCmd == u"chapterdown";
3264 const bool bLeft = rCmd == u"promote";
3265 const bool bLeftRight = bLeft || rCmd == u"demote";
3266 if (!bUpDown && !bLeftRight)
3267 return;
3268 if (GetWrtShell()->GetView().GetDocShell()->IsReadOnly() ||
3269 (State::ACTIVE != m_eState &&
3270 (State::CONSTANT != m_eState || m_pActiveShell != GetParentWindow()->GetCreateView()->GetWrtShellPtr())))
3271 {
3272 return;
3273 }
3274
3275 SwWrtShell *const pShell = GetWrtShell();
3276
3277 const SwNodes& rNodes = pShell->GetNodes();
3278 const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
3279 const SwOutlineNodes::size_type nOutlineNdsSize = rOutlineNodes.size();
3280
3281 std::vector<SwTextNode*> selectedOutlineNodes;
3282 std::vector<std::unique_ptr<weld::TreeIter>> selected;
3283
3284 m_xTreeView->selected_foreach([&](weld::TreeIter& rEntry){
3285 // it's possible to select the root node too which is a really bad idea
3286 if (lcl_IsContentType(rEntry, *m_xTreeView))
3287 return false;
3288 // filter out children of selected parents so they don't get promoted
3289 // or moved twice (except if there is Ctrl modifier, since in that
3290 // case children are re-parented)
3291 if ((bLeftRight || bOutlineWithChildren) && !selected.empty())
3292 {
3293 std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
3294 for (bool bParent = m_xTreeView->iter_parent(*xParent); bParent; bParent = m_xTreeView->iter_parent(*xParent))
3295 {
3296 if (m_xTreeView->iter_compare(*selected.back(), *xParent) == 0)
3297 {
3298 return false;
3299 }
3300 }
3301 }
3302 selected.emplace_back(m_xTreeView->make_iterator(&rEntry));
3303
3304 // Use the outline node position in the SwOutlineNodes array. Bad things
3305 // happen if the tree entry position is used and it doesn't match the node position
3306 // in SwOutlineNodes, which is usually the case for outline nodes in frames.
3308 = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(rEntry))->GetOutlinePos();
3309 if (nPos < nOutlineNdsSize)
3310 {
3311 SwNode* pNode = rNodes.GetOutLineNds()[ nPos ];
3312 if (pNode)
3313 {
3314 selectedOutlineNodes.push_back(pNode->GetTextNode());
3315 }
3316 }
3317 return false;
3318 });
3319
3320 if (!selected.size())
3321 return;
3322
3323 if (bUpDown && !bUp)
3324 { // to move down, start at the end!
3325 std::reverse(selected.begin(), selected.end());
3326 }
3327
3328 m_bIgnoreDocChange = true;
3329
3331 bool bStartedAction = false;
3332
3333 MakeAllOutlineContentTemporarilyVisible a(GetWrtShell()->GetDoc());
3334
3335 // get first regular document content node outline node position in outline nodes array
3336 SwOutlineNodes::size_type nFirstRegularDocContentOutlineNodePos = SwOutlineNodes::npos;
3337 SwNodeOffset nEndOfExtrasIndex = rNodes.GetEndOfExtras().GetIndex();
3338 for (SwOutlineNodes::size_type nPos = 0; nPos < nOutlineNdsSize; nPos++)
3339 {
3340 if (rOutlineNodes[nPos]->GetIndex() > nEndOfExtrasIndex)
3341 {
3342 nFirstRegularDocContentOutlineNodePos = nPos;
3343 break;
3344 }
3345 }
3346
3347 for (auto const& pCurrentEntry : selected)
3348 {
3349 nActPos = weld::fromId<SwOutlineContent*>(
3350 m_xTreeView->get_id(*pCurrentEntry))->GetOutlinePos();
3351
3352 // outline nodes in frames and tables are not up/down moveable
3353 if (nActPos == SwOutlineNodes::npos ||
3354 (bUpDown && (!pShell->IsOutlineMovable(nActPos) ||
3355 nFirstRegularDocContentOutlineNodePos == SwOutlineNodes::npos)))
3356 {
3357 continue;
3358 }
3359
3360 if (!bStartedAction)
3361 {
3362 pShell->StartAllAction();
3363 pShell->StartUndo(bLeftRight ? SwUndoId::OUTLINE_LR : SwUndoId::OUTLINE_UD);
3364 bStartedAction = true;
3365 }
3366
3367 pShell->GotoOutline( nActPos); // If text selection != box selection
3368 pShell->Push();
3369
3370 if (bUpDown)
3371 {
3372 // move outline position up/down (outline position promote/demote)
3373 SwOutlineNodes::difference_type nDir = bUp ? -1 : 1;
3374 if ((nDir == -1 && nActPos > 0) || (nDir == 1 && nActPos < nOutlineNdsSize - 1))
3375 {
3376 // make outline selection for use by MoveOutlinePara
3377 pShell->MakeOutlineSel(nActPos, nActPos, bOutlineWithChildren);
3378
3379 int nActPosOutlineLevel =
3380 rOutlineNodes[nActPos]->GetTextNode()->GetAttrOutlineLevel();
3382 if (!bUp)
3383 {
3384 // move down
3385 int nPosOutlineLevel = -1;
3386 while (++nPos < nOutlineNdsSize)
3387 {
3388 nPosOutlineLevel =
3389 rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
3390 // discontinue if moving out of parent or equal level is found
3391 if (nPosOutlineLevel <= nActPosOutlineLevel)
3392 break;
3393 // count the children of the node when they are not included in the move
3394 if (!bOutlineWithChildren)
3395 nDir++;
3396 }
3397 if (nPosOutlineLevel >= nActPosOutlineLevel)
3398 {
3399 // move past children
3400 while (++nPos < nOutlineNdsSize)
3401 {
3402 nPosOutlineLevel =
3403 rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
3404 // discontinue if moving out of parent or equal level is found
3405 if (nPosOutlineLevel <= nActPosOutlineLevel)
3406 break;
3407 nDir++;
3408 }
3409 }
3410 }
3411 else
3412 {
3413 // move up
3414 while (nPos && --nPos >= nFirstRegularDocContentOutlineNodePos)
3415 {
3416 int nPosOutlineLevel =
3417 rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
3418 // discontinue if equal level is found
3419 if (nPosOutlineLevel == nActPosOutlineLevel)
3420 break;
3421 // discontinue if moving out of parent
3422 if (nPosOutlineLevel < nActPosOutlineLevel)
3423 {
3424 // Required for expected chapter placement when the chapter being moved
3425 // up has an outline level less than the outline level of chapters it
3426 // is being moved above and then encounters a chapter with an outline
3427 // level that is greater before reaching a chapter with the same
3428 // outline level as itself.
3429 if (nDir < -1)
3430 nDir++;
3431 break;
3432 }
3433 nDir--;
3434 }
3435 }
3436 pShell->MoveOutlinePara(nDir);
3437 }
3438 pShell->ClearMark();
3439 }
3440 else
3441 {
3442 // move outline left/right (outline level promote/demote)
3443 if (!pShell->IsProtectedOutlinePara())
3444 {
3445 bool bAllow = true;
3446 const SwOutlineNodes& rOutlNds = pShell->GetDoc()->GetNodes().GetOutLineNds();
3447 const int nActLevel = rOutlNds[nActPos]->GetTextNode()->GetAttrOutlineLevel();
3448 if (!bLeft)
3449 {
3450 // disallow if any outline node to demote will exceed MAXLEVEL
3452 do
3453 {
3454 int nLevel = rOutlNds[nPos]->GetTextNode()->GetAttrOutlineLevel();
3455 if (nLevel == MAXLEVEL)
3456 {
3457 bAllow = false;
3458 break;
3459 }
3460 } while (bOutlineWithChildren && ++nPos < rOutlNds.size() &&
3461 rOutlNds[nPos]->GetTextNode()->GetAttrOutlineLevel() > nActLevel);
3462 }
3463 else
3464 {
3465 // disallow if trying to promote outline of level 1
3466 if (nActLevel == 1)
3467 bAllow = false;
3468 }
3469 if (bAllow)
3470 {
3472 do
3473 {
3474 pShell->SwCursorShell::GotoOutline(nPos);
3475 pShell->OutlineUpDown(bLeft ? -1 : 1);
3476 } while (bOutlineWithChildren && ++nPos < rOutlNds.size() &&
3477 rOutlNds[nPos]->GetTextNode()->GetAttrOutlineLevel() > nActLevel);
3478 }
3479 }
3480 }
3481
3482 pShell->Pop(SwCursorShell::PopMode::DeleteCurrent); // Cursor is now back at the current heading.
3483 }
3484
3485 if (bStartedAction)
3486 {
3487 pShell->EndUndo();
3488 pShell->EndAllAction();
3489 if (m_aActiveContentArr[ContentTypeId::OUTLINE])
3490 m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate();
3491
3492 // tdf#143547 LO Writer: navigator should stand still on promoting and demoting
3493 // In addition to m_bIgnoreDocChange being true, selections are cleared before the Display
3494 // call. Either of these conditions disable restore of scroll position happening in the
3495 // Display function so it needs to be done here.
3496 auto nOldScrollPos = m_xTreeView->vadjustment_get_value();
3497
3498 // clear all selections to prevent the Display function from trying to reselect selected entries
3499 m_xTreeView->unselect_all();
3500 Display(true);
3501 m_xTreeView->vadjustment_set_value(nOldScrollPos);
3502
3503 if (m_bIsRoot)
3504 {
3505 // reselect entries, do this only when in outline content navigation mode
3506 const SwOutlineNodes& rOutlineNds = pShell->GetNodes().GetOutLineNds();
3507 for (SwTextNode* pNode : selectedOutlineNodes)
3508 {
3509 m_xTreeView->all_foreach([this, &rOutlineNds, pNode](weld::TreeIter& rEntry){
3510 if (lcl_IsContentType(rEntry, *m_xTreeView))
3511 return false;
3512 SwOutlineNodes::size_type nPos = weld::fromId<SwOutlineContent*>(
3513 m_xTreeView->get_id(rEntry))->GetOutlinePos();
3514 if (pNode == rOutlineNds[nPos]->GetTextNode())
3515 {
3516 std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
3517 if (m_xTreeView->iter_parent(*xParent)
3518 && !m_xTreeView->get_row_expanded(*xParent))
3519 {
3520 m_xTreeView->expand_row(*xParent);
3521 }
3522 m_xTreeView->select(rEntry);
3523 return true;
3524 }
3525 return false;
3526 });
3527 }
3528 }
3529 else
3530 {
3531 m_pActiveShell->GetView().GetEditWin().GrabFocus();
3532 m_bIgnoreDocChange = false;
3533 UpdateTracking();
3534 grab_focus();
3535 }
3536 }
3537 m_bIgnoreDocChange = false;
3538}
3539
3541{
3542 m_xTreeView->show();
3544}
3545
3547{
3548 // folded together will not be idled
3549 m_aUpdTimer.Stop();
3550 m_xTreeView->hide();
3551}
3552
3554 ContentTypeId nType, const void* ptr)
3555{
3556 if (!ptr)
3557 {
3558 rContentTree.set_cursor(-1);
3559 pThis->Select();
3560 return;
3561 }
3562
3563 // find content type entry
3564 std::unique_ptr<weld::TreeIter> xIter(rContentTree.make_iterator());
3565
3566 bool bFoundEntry = rContentTree.get_iter_first(*xIter);
3567 while (bFoundEntry)
3568 {
3569 void* pUserData = weld::fromId<void*>(rContentTree.get_id(*xIter));
3570 assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pUserData)));
3571 if (nType == static_cast<SwContentType*>(pUserData)->GetType())
3572 break;
3573 bFoundEntry = rContentTree.iter_next_sibling(*xIter);
3574 }
3575
3576 if (!bFoundEntry)
3577 {
3578 rContentTree.set_cursor(-1);
3579 pThis->Select();
3580 return;
3581 }
3582
3583 // assure content type entry is expanded
3584 rContentTree.expand_row(*xIter);
3585
3586 // find content type content entry and select it
3587 const void* p = nullptr;
3588 while (rContentTree.iter_next(*xIter) && lcl_IsContent(*xIter, rContentTree))
3589 {
3590 void* pUserData = weld::fromId<void*>(rContentTree.get_id(*xIter));
3591 switch( nType )
3592 {
3595 {
3596 assert(dynamic_cast<SwTextFootnoteContent*>(static_cast<SwTypeNumber*>(pUserData)));
3597 SwTextFootnoteContent* pCnt = static_cast<SwTextFootnoteContent*>(pUserData);
3598 p = pCnt->GetTextFootnote();
3599 break;
3600 }
3602 {
3603 assert(dynamic_cast<SwURLFieldContent*>(static_cast<SwTypeNumber*>(pUserData)));
3604 SwURLFieldContent* pCnt = static_cast<SwURLFieldContent*>(pUserData);
3605 p = static_cast<const SwTextAttr*>(pCnt->GetINetAttr());
3606 break;
3607 }
3609 {
3610 assert(dynamic_cast<SwTextFieldContent*>(static_cast<SwTypeNumber*>(pUserData)));
3611 SwTextFieldContent* pCnt = static_cast<SwTextFieldContent*>(pUserData);
3612 p = pCnt->GetFormatField()->GetField();
3613 break;
3614 }
3616 {
3617 assert(dynamic_cast<SwPostItContent*>(static_cast<SwTypeNumber*>(pUserData)));
3618 SwPostItContent* pCnt = static_cast<SwPostItContent*>(pUserData);
3619 p = pCnt->GetPostIt()->GetField();
3620 break;
3621 }
3622 default:
3623 break;
3624 }
3625 if (ptr == p)
3626 {
3627 // get first selected for comparison
3628 std::unique_ptr<weld::TreeIter> xFirstSelected(rContentTree.make_iterator());
3629 if (!rContentTree.get_selected(xFirstSelected.get()))
3630 xFirstSelected.reset();
3631 if (rContentTree.count_selected_rows() != 1 || !xFirstSelected ||
3632 rContentTree.iter_compare(*xIter, *xFirstSelected) != 0)
3633 {
3634 // unselect all entries and make passed entry visible and selected
3635 rContentTree.set_cursor(*xIter);
3636 pThis->Select();
3637 }
3638 return;
3639 }
3640 }
3641
3642 rContentTree.set_cursor(-1);
3643 pThis->Select();
3644 return;
3645}
3646
3648 std::u16string_view rContentTypeName, std::u16string_view rName)
3649{
3650 if (rName.empty())
3651 return;
3652
3653 // find content type entry
3654 std::unique_ptr<weld::TreeIter> xIter(rContentTree.make_iterator());
3655 bool bFoundEntry = rContentTree.get_iter_first(*xIter);
3656 while (bFoundEntry && rContentTypeName != rContentTree.get_text(*xIter))
3657 bFoundEntry = rContentTree.iter_next_sibling(*xIter);
3658 // find content type content entry and select it
3659 if (!bFoundEntry)
3660 return;
3661
3662 rContentTree.expand_row(*xIter); // assure content type entry is expanded
3663 while (rContentTree.iter_next(*xIter) && lcl_IsContent(*xIter, rContentTree))
3664 {
3665 if (rName == rContentTree.get_text(*xIter))
3666 {
3667 // get first selected for comparison
3668 std::unique_ptr<weld::TreeIter> xFirstSelected(rContentTree.make_iterator());
3669 if (!rContentTree.get_selected(xFirstSelected.get()))
3670 xFirstSelected.reset();
3671 if (rContentTree.count_selected_rows() != 1 || !xFirstSelected ||
3672 rContentTree.iter_compare(*xIter, *xFirstSelected) != 0)
3673 {
3674 // unselect all entries and make passed entry visible and selected
3675 rContentTree.set_cursor(*xIter);
3676 pThis->Select();
3677 }
3678 break;
3679 }
3680 }
3681}
3682
3683static void lcl_SelectDrawObjectByName(weld::TreeView& rContentTree, std::u16string_view rName)
3684{
3685 if (rName.empty())
3686 return;
3687
3688 // find content type entry
3689 std::unique_ptr<weld::TreeIter> xIter(rContentTree.make_iterator());
3690 bool bFoundEntry = rContentTree.get_iter_first(*xIter);
3691 while (bFoundEntry && SwResId(STR_CONTENT_TYPE_DRAWOBJECT) != rContentTree.get_text(*xIter))
3692 bFoundEntry = rContentTree.iter_next_sibling(*xIter);
3693 // find content type content entry and select it
3694 if (bFoundEntry)
3695 {
3696 rContentTree.expand_row(*xIter); // assure content type entry is expanded
3697 while (rContentTree.iter_next(*xIter) && lcl_IsContent(*xIter, rContentTree))
3698 {
3699 if (rName == rContentTree.get_text(*xIter))
3700 {
3701 if (!rContentTree.is_selected(*xIter))
3702 {
3703 rContentTree.select(*xIter);
3704 rContentTree.scroll_to_row(*xIter);
3705 }
3706 break;
3707 }
3708 }
3709 }
3710}
3711
3714{
3715 // No need to update if content tree is not visible
3716 if (!m_xTreeView->is_visible())
3717 return;
3718
3719 // No update while focus is not in document.
3720 // No update while drag and drop.
3721 // Query view because the Navigator is cleared too late.
3722 SwView* pView = GetParentWindow()->GetCreateView();
3723
3724 SwWrtShell* pActShell = pView ? pView->GetWrtShellPtr() : nullptr;
3725 if(pActShell && pActShell->GetWin() &&
3726 (pActShell->GetWin()->HasFocus() || m_bDocHasChanged || m_bViewHasChanged) &&
3727 !IsInDrag() && !pActShell->ActionPend())
3728 {
3729 if (m_bDocHasChanged || m_bViewHasChanged)
3730 {
3731 if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell))
3732 {
3733 SetActiveShell(pActShell);
3734 GetParentWindow()->UpdateListBox();
3735 }
3736 if (State::ACTIVE == m_eState && pActShell != GetWrtShell())
3737 {
3738 SetActiveShell(pActShell);
3739 }
3740 else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) &&
3741 HasContentChanged())
3742 {
3743 FindActiveTypeAndRemoveUserData();
3744 Display(true);
3745 }
3746 }
3747 UpdateTracking();
3748 m_bIsIdleClear = false;
3749 m_bDocHasChanged = false;
3750 m_bViewHasChanged = false;
3751 }
3752 else if (!pView && State::ACTIVE == m_eState && !m_bIsIdleClear) // this block seems never to be entered
3753 {
3754 if(m_pActiveShell)
3755 {
3756 SetActiveShell(nullptr);
3757 }
3758 clear();
3759 m_bIsIdleClear = true;
3760 }
3761}
3762
3764{
3766 return;
3767
3768 // only when treeview or treeview context menu does not have focus
3769 if (m_xTreeView->has_focus() || m_xTreeView->has_child_focus())
3770 return;
3771
3772 // m_bIgnoreDocChange is set on delete and outline visibility toggle
3774 {
3775 m_bIgnoreDocChange = false;
3776 return;
3777 }
3778
3779 // bTrack is used to disallow tracking after jumping to an outline until the outline position
3780 // that was jumped to is no longer the current outline position.
3781 bool bTrack = true;
3783 {
3785 bTrack = false;
3786 else
3788 }
3789
3790 if (bTrack)
3791 {
3792 // graphic, frame, and ole
3795 {
3796 OUString aContentTypeName;
3799 {
3801 aContentTypeName = SwResId(STR_CONTENT_TYPE_GRAPHIC);
3802 }
3805 {
3807 aContentTypeName = SwResId(STR_CONTENT_TYPE_FRAME);
3808 }
3811 {
3813 aContentTypeName = SwResId(STR_CONTENT_TYPE_OLE);
3814 }
3815 if (!aContentTypeName.isEmpty())
3816 {
3817 OUString aName(m_pActiveShell->GetFlyName());
3818 lcl_SelectByContentTypeAndName(this, *m_xTreeView, aContentTypeName, aName);
3819 return;
3820 }
3821 }
3822 // drawing
3827 {
3829 {
3830 // Multiple selection is possible when in root content navigation view so unselect all
3831 // selected entries before reselecting. This causes a bit of an annoyance when the treeview
3832 // scroll bar is used and focus is in the document by causing the last selected entry to
3833 // scroll back into view.
3834 if (m_bIsRoot)
3835 m_xTreeView->unselect_all();
3836 SdrView* pSdrView = m_pActiveShell->GetDrawView();
3837 if (pSdrView)
3838 {
3839 for (size_t nIdx(0); nIdx < pSdrView->GetMarkedObjectCount(); nIdx++)
3840 {
3841 SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(nIdx);
3842 OUString aName(pSelected->GetName());
3843 if (!aName.isEmpty())
3845 }
3846 }
3847 else
3848 {
3849 // clear treeview selections
3850 m_xTreeView->unselect_all();
3851 }
3852 Select();
3853 }
3854 return;
3855 }
3856 // footnotes and endnotes
3857 if (SwContentAtPos aContentAtPos(IsAttrAtPos::Ftn);
3859 && aContentAtPos.pFndTextAttr &&
3862 {
3863 if (!aContentAtPos.pFndTextAttr->GetFootnote().IsEndNote())
3864 {
3867 aContentAtPos.pFndTextAttr);
3868 }
3871 aContentAtPos.pFndTextAttr);
3872 return;
3873 }
3874 // bookmarks - track first bookmark at cursor
3877 {
3878 SwPaM* pCursor = m_pActiveShell->GetCursor();
3880 IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
3881 if (pCursor && ppBookmark != pMarkAccess->getBookmarksEnd() &&
3883 {
3884 OUString sBookmarkName;
3885 SwPosition* pCursorPoint = pCursor->GetPoint();
3886 while (ppBookmark != pMarkAccess->getBookmarksEnd())
3887 {
3888 if (lcl_IsUiVisibleBookmark(*ppBookmark) &&
3889 *pCursorPoint >= (*ppBookmark)->GetMarkStart() &&
3890 *pCursorPoint <= (*ppBookmark)->GetMarkEnd())
3891 {
3892 sBookmarkName = (*ppBookmark)->GetName();
3893 // keep previously selected bookmark instead
3894 // of selecting a different bookmark inside of it
3895 if (sBookmarkName == m_sSelectedItem)
3896 break;
3897 }
3898 else if (!sBookmarkName.isEmpty() &&
3899 *pCursorPoint < (*ppBookmark)->GetMarkStart())
3900 {
3901 // don't search a different bookmark inside the
3902 // previous one, if the starting position of the next bookmarks
3903 // is after the cursor position (assuming that the
3904 // bookmark iterator jumps inside the same text by positions)
3905 break;
3906 }
3907 ++ppBookmark;
3908 }
3909
3910 if (!sBookmarkName.isEmpty())
3911 {
3912 // select the bookmark
3914 SwResId(STR_CONTENT_TYPE_BOOKMARK),
3915 sBookmarkName);
3916 return;
3917 }
3918 }
3919 }
3920 // references
3921 if (SwContentAtPos aContentAtPos(IsAttrAtPos::RefMark);
3923 aContentAtPos.pFndTextAttr &&
3925 {
3927 {
3928 const SwFormatRefMark& rRefMark = aContentAtPos.pFndTextAttr->GetRefMark();
3929 lcl_SelectByContentTypeAndName(this, *m_xTreeView, SwResId(STR_CONTENT_TYPE_REFERENCE),
3930 rRefMark.GetRefName());
3931 }
3932 return;
3933 }
3934 // hyperlinks
3935 if (SwContentAtPos aContentAtPos(IsAttrAtPos::InetAttr);
3938 {
3939 // There is no need to search for hyperlinks in ToxContent tdf#148312
3940 if (const SwTextINetFormat* pTextINetFormat =
3941 static_txtattr_cast<const SwTextINetFormat*>(aContentAtPos.pFndTextAttr))
3942 {
3943 if (const SwTextNode* pTextNode = pTextINetFormat->GetpTextNode())
3944 {
3945 if (const SwSectionNode* pSectNd = pTextNode->FindSectionNode())
3946 {
3947 SectionType eType = pSectNd->GetSection().GetType();
3949 {
3950 m_xTreeView->set_cursor(-1);
3951 Select();
3952 return;
3953 }
3954 }
3955 }
3956 }
3957 // Because hyperlink item names do not need to be unique, finding the corresponding item
3958 // in the tree by name may result in incorrect selection. Find the item in the tree by
3959 // comparing the SwTextINetFormat pointer at the document cursor position to that stored
3960 // in the item SwURLFieldContent.
3963 aContentAtPos.pFndTextAttr);
3964 return;
3965 }
3966 // fields, comments
3967 if (SwField* pField = m_pActiveShell->GetCurField(); pField &&
3968 !(m_bIsRoot &&
3971 {
3972 ContentTypeId eCntTypeId =
3973 pField->GetTypeId() == SwFieldTypesEnum::Postit ? ContentTypeId::POSTIT :
3975 if (mTrackContentType[eCntTypeId])
3976 lcl_SelectByContentTypeAndAddress(this, *m_xTreeView, eCntTypeId, pField);
3977 return;
3978 }
3979 // table
3982 {
3984 {
3985 OUString aName = m_pActiveShell->GetTableFormat()->GetName();
3986 lcl_SelectByContentTypeAndName(this, *m_xTreeView, SwResId(STR_CONTENT_TYPE_TABLE),
3987 aName);
3988 }
3989 return;
3990 }
3991 // indexes
3992 if (const SwTOXBase* pTOX = m_pActiveShell->GetCurTOX(); pTOX &&
3994 {
3996 lcl_SelectByContentTypeAndName(this, *m_xTreeView, SwResId(STR_CONTENT_TYPE_INDEX),
3997 pTOX->GetTOXName());
3998 return;
3999 }
4000 // section
4001 if (const SwSection* pSection = m_pActiveShell->GetCurrSection(); pSection &&
4003 {
4005 {
4006 lcl_SelectByContentTypeAndName(this, *m_xTreeView, SwResId(STR_CONTENT_TYPE_REGION),
4007 pSection->GetSectionName());
4008 return;
4009 }
4010 else
4011 {
4012 // prevent fall through to outline tracking when section tracking is off and the last
4013 // GotoContent is the current section
4015 m_xTreeView->get_selected_text() == pSection->GetSectionName())
4016 return;
4017 }
4018 // fall through to outline tracking when section tracking is off and the last GotoContent
4019 // is not the current section
4020 }
4021 }
4022 // outline
4023 if (m_nOutlineTracking == 3)
4024 return;
4025 // find out where the cursor is
4028 {
4029 // assure outline content type is expanded
4030 // this assumes outline content type is first in treeview
4031 std::unique_ptr<weld::TreeIter> xFirstEntry(m_xTreeView->make_iterator());
4032 if (m_xTreeView->get_iter_first(*xFirstEntry))
4033 m_xTreeView->expand_row(*xFirstEntry);
4034
4035 m_xTreeView->all_foreach([this, nActPos](weld::TreeIter& rEntry){
4036 bool bRet = false;
4037 if (lcl_IsContent(rEntry, *m_xTreeView) && weld::fromId<SwContent*>(
4038 m_xTreeView->get_id(rEntry))->GetParent()->GetType() ==
4040 {
4041 if (weld::fromId<SwOutlineContent*>(
4042 m_xTreeView->get_id(rEntry))->GetOutlinePos() == nActPos)
4043 {
4044 std::unique_ptr<weld::TreeIter> xFirstSelected(
4045 m_xTreeView->make_iterator());
4046 if (!m_xTreeView->get_selected(xFirstSelected.get()))
4047 xFirstSelected.reset();
4048 // only select if not already selected or tree has multiple entries selected
4049 if (m_xTreeView->count_selected_rows() != 1 || !xFirstSelected ||
4050 m_xTreeView->iter_compare(rEntry, *xFirstSelected) != 0)
4051 {
4052 if (m_nOutlineTracking == 2) // focused outline tracking
4053 {
4054 // collapse to children of root node
4055 std::unique_ptr<weld::TreeIter> xChildEntry(
4056 m_xTreeView->make_iterator());
4057 if (m_xTreeView->get_iter_first(*xChildEntry) &&
4058 m_xTreeView->iter_children(*xChildEntry))
4059 {
4060 do
4061 {
4062 if (weld::fromId<SwContent*>(
4063 m_xTreeView->get_id(*xChildEntry))->
4064 GetParent()->GetType() == ContentTypeId::OUTLINE)
4065 m_xTreeView->collapse_row(*xChildEntry);
4066 else
4067 break;
4068 }
4069 while (m_xTreeView->iter_next(*xChildEntry));
4070 }
4071 }
4072 // unselect all entries, make pEntry visible, and select
4073 m_xTreeView->set_cursor(rEntry);
4074 Select();
4075
4076 // tdf#149279 show at least two outline entries before the set cursor entry
4077 std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator(&rEntry));
4078 for (int i = 0; i < 2; i++)
4079 {
4080 if (m_xTreeView->get_iter_depth(*xIter) == 0)
4081 break;
4082 if (!m_xTreeView->iter_previous(*xIter))
4083 break;
4084 while (!weld::IsEntryVisible(*m_xTreeView, *xIter))
4085 m_xTreeView->iter_parent(*xIter);
4086 }
4087 // Assure the scroll to row is collapsed after scrolling if it was collapsed
4088 // before. This is required here to make gtkinst scroll_to_row behave like
4089 // salinst.
4090 const bool bRowExpanded = m_xTreeView->get_row_expanded(*xIter);
4091 m_xTreeView->scroll_to_row(*xIter);
4092 if (!bRowExpanded)
4093 m_xTreeView->collapse_row(*xIter);
4094 }
4095 bRet = true;
4096 }
4097 }
4098 else
4099 {
4100 // use of this break assumes outline content type is first in tree
4101 if (lcl_IsContentType(rEntry, *m_xTreeView) &&
4102 weld::fromId<SwContentType*>(
4103 m_xTreeView->get_id(rEntry))->GetType() !=
4105 bRet = true;
4106 }
4107 return bRet;
4108 });
4109 }
4110 else
4111 {
4112 // clear treeview selections
4113 if (m_xTreeView->count_selected_rows() > 0)
4114 {
4115 m_xTreeView->unselect_all();
4116 m_xTreeView->set_cursor(-1);
4117 Select();
4118 }
4119 }
4120}
4121
4123{
4124 SwCursor* pFirstCursor = m_pActiveShell->GetCursor();
4125 SwCursor* pCursor = pFirstCursor;
4126 std::vector<SwOutlineNodes::size_type> aOutlinePositions;
4127 do
4128 {
4129 if (pCursor)
4130 {
4131 if (pCursor->HasMark())
4132 {
4133 aOutlinePositions.push_back(m_pActiveShell->GetOutlinePos(UCHAR_MAX, pCursor));
4134 }
4135 pCursor = pCursor->GetNext();
4136 }
4137 } while (pCursor && pCursor != pFirstCursor);
4138
4139 if (aOutlinePositions.empty())
4140 return;
4141
4142 // remove duplicates before selecting
4143 aOutlinePositions.erase(std::unique(aOutlinePositions.begin(), aOutlinePositions.end()),
4144 aOutlinePositions.end());
4145
4146 m_xTreeView->unselect_all();
4147
4148 for (auto nOutlinePosition : aOutlinePositions)
4149 {
4150 m_xTreeView->all_foreach([this, nOutlinePosition](const weld::TreeIter& rEntry){
4151 if (lcl_IsContent(rEntry, *m_xTreeView) &&
4152 weld::fromId<SwContent*>(
4153 m_xTreeView->get_id(rEntry))->GetParent()->GetType() ==
4155 {
4156 if (weld::fromId<SwOutlineContent*>(
4157 m_xTreeView->get_id(rEntry))->GetOutlinePos() ==
4158 nOutlinePosition)
4159 {
4160 std::unique_ptr<weld::TreeIter> xParent =
4161 m_xTreeView->make_iterator(&rEntry);
4162 if (m_xTreeView->iter_parent(*xParent) &&
4163 !m_xTreeView->get_row_expanded(*xParent))
4164 m_xTreeView->expand_row(*xParent);
4165 m_xTreeView->select(rEntry);
4166 return true;
4167 }
4168 }
4169 return false;
4170 });
4171 }
4172
4173 Select();
4174}
4175
4177{
4179
4180 SwWrtShell *const pShell = GetWrtShell();
4181 pShell->StartAllAction();
4183
4185 SwOutlineNodes::size_type nPrevTargetPosOrOffset = SwOutlineNodes::npos;
4186
4187 bool bFirstMove = true;
4188
4189 for (const auto& source : m_aDndOutlinesSelected)
4190 {
4191 SwOutlineNodes::size_type nSourcePos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*source))->GetOutlinePos();
4192
4193 // Done on the first selection move
4194 if (bFirstMove) // only do once
4195 {
4196 if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos)
4197 {
4198 // Up moves
4199 // The first up move sets the up move amount for the remaining selected outlines to be moved
4200 if (nTargetPos != SwOutlineNodes::npos)
4201 nPrevTargetPosOrOffset = nSourcePos - nTargetPos;
4202 else
4203 nPrevTargetPosOrOffset = nSourcePos + 1;
4204 }
4205 else if (nSourcePos < nTargetPos)
4206 {
4207 // Down moves
4208 // The first down move sets the source and target positions for the remaining selected outlines to be moved
4209 nPrevSourcePos = nSourcePos;
4210 nPrevTargetPosOrOffset = nTargetPos;
4211 }
4212 bFirstMove = false;
4213 }
4214 else
4215 {
4216 if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos)
4217 {
4218 // Move up
4219 nTargetPos = nSourcePos - nPrevTargetPosOrOffset;
4220 }
4221 else if (nSourcePos < nTargetPos)
4222 {
4223 // Move down
4224 nSourcePos = nPrevSourcePos;
4225 nTargetPos = nPrevTargetPosOrOffset;
4226 }
4227 }
4228 GetParentWindow()->MoveOutline(nSourcePos, nTargetPos);
4229 }
4230
4231 pShell->EndUndo();
4232 pShell->EndAllAction();
4234 Display(true);
4235 m_aDndOutlinesSelected.clear();
4236}
4237
4238// Update immediately
4240{
4241 SwView* pActView = GetParentWindow()->GetCreateView();
4242 if(pActView)
4243 {
4244 SwWrtShell* pActShell = pActView->GetWrtShellPtr();
4245 if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell))
4246 {
4247 SetActiveShell(pActShell);
4248 }
4249
4250 if (State::ACTIVE == m_eState && pActShell != GetWrtShell())
4251 SetActiveShell(pActShell);
4252 // Only call HasContentChanged() if the document has changed since last called
4253 else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) &&
4254 m_bDocHasChanged)
4255 {
4256 if (HasContentChanged())
4257 Display(true);
4258 m_bDocHasChanged = false;
4259 }
4260 }
4261 else if (State::ACTIVE == m_eState)
4262 clear();
4263}
4264
4265IMPL_LINK(SwContentTree, KeyInputHdl, const KeyEvent&, rEvent, bool)
4266{
4267 bool bConsumed = true;
4268
4269 const vcl::KeyCode aCode = rEvent.GetKeyCode();
4270 if (aCode.GetCode() == KEY_MULTIPLY && aCode.IsMod1())
4271 {
4272 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4273 if (m_xTreeView->get_selected(xEntry.get()))
4274 ExpandOrCollapseAll(*m_xTreeView, *xEntry);
4275 }
4276 else if (aCode.GetCode() == KEY_RETURN)
4277 {
4278 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4279 if (m_xTreeView->get_selected(xEntry.get()))
4280 {
4281 switch(aCode.GetModifier())
4282 {
4283 case KEY_MOD2:
4284 // Switch boxes
4285 GetParentWindow()->ToggleTree();
4286 break;
4287 case KEY_MOD1:
4288 // Switch RootMode
4289 ToggleToRoot();
4290 break;
4291 case 0:
4292 if (lcl_IsContentType(*xEntry, *m_xTreeView))
4293 {
4294 m_xTreeView->get_row_expanded(*xEntry) ? m_xTreeView->collapse_row(*xEntry)
4295 : m_xTreeView->expand_row(*xEntry);
4296 }
4297 else
4298 ContentDoubleClickHdl(*m_xTreeView);
4299 break;
4300 case KEY_SHIFT:
4301 m_bSelectTo = true;
4302 ContentDoubleClickHdl(*m_xTreeView);
4303 break;
4304 }
4305 }
4306 }
4307 else if(aCode.GetCode() == KEY_DELETE && 0 == aCode.GetModifier())
4308 {
4309 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4310 if (m_xTreeView->get_selected(xEntry.get()) && lcl_IsContent(*xEntry, *m_xTreeView))
4311 {
4312 assert(dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry))));
4313 if (weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry))->GetParent()->IsDeletable() &&
4314 !m_pActiveShell->GetView().GetDocShell()->IsReadOnly())
4315 {
4316 EditEntry(*xEntry, EditEntryMode::DELETE);
4317 }
4318 }
4319 }
4320 //Make KEY_SPACE has same function as DoubleClick, and realize
4321 //multi-selection.
4322 else if (aCode.GetCode() == KEY_SPACE && 0 == aCode.GetModifier())
4323 {
4324 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4325 if (m_xTreeView->get_cursor(xEntry.get()))
4326 {
4327 if (State::HIDDEN != m_eState)
4328 {
4329 if (State::CONSTANT == m_eState)
4330 {
4331 m_pActiveShell->GetView().GetViewFrame().GetWindow().ToTop();
4332 }
4333
4334 SwContent* pCnt = dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry)));
4335
4336 if (pCnt && pCnt->GetParent()->GetType() == ContentTypeId::DRAWOBJECT)
4337 {
4338 SdrView* pDrawView = m_pActiveShell->GetDrawView();
4339 if (pDrawView)
4340 {
4341 pDrawView->SdrEndTextEdit();
4342
4343 SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
4344 SdrPage* pPage = pDrawModel->GetPage(0);
4345 const size_t nCount = pPage->GetObjCount();
4346 bool hasObjectMarked = false;
4347
4348 if (SdrObject* pObject = GetDrawingObjectsByContent(pCnt))
4349 {
4350 SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/);
4351 if( pPV )
4352 {
4353 bool bUnMark = pDrawView->IsObjMarked(pObject);
4354 pDrawView->MarkObj( pObject, pPV, bUnMark);
4355
4356 }
4357 }
4358 for( size_t i=0; i<nCount; ++i )
4359 {
4360 SdrObject* pTemp = pPage->GetObj(i);
4361 bool bMark = pDrawView->IsObjMarked(pTemp);
4362 switch( pTemp->GetObjIdentifier() )
4363 {
4364 case SdrObjKind::Group:
4365 case SdrObjKind::Text:
4366 case SdrObjKind::Line:
4367 case SdrObjKind::Rectangle:
4368 case SdrObjKind::CircleOrEllipse:
4369 case SdrObjKind::CircleSection:
4370 case SdrObjKind::CircleArc:
4371 case SdrObjKind::CircleCut:
4372 case SdrObjKind::Polygon:
4373 case SdrObjKind::PolyLine:
4374 case SdrObjKind::PathLine:
4375 case SdrObjKind::PathFill:
4376 case SdrObjKind::FreehandLine:
4377 case SdrObjKind::FreehandFill:
4378 case SdrObjKind::PathPoly:
4379 case SdrObjKind::PathPolyLine:
4380 case SdrObjKind::Caption:
4381 case SdrObjKind::CustomShape:
4382 if( bMark )
4383 hasObjectMarked = true;
4384 break;
4385 default:
4386 if ( bMark )
4387 {
4388 SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/);
4389 if (pPV)
4390 {
4391 pDrawView->MarkObj(pTemp, pPV, true);
4392 }
4393 }
4394 }
4395 //mod end
4396 }
4397 if ( !hasObjectMarked )
4398 {
4399 SwEditWin& rEditWindow = m_pActiveShell->GetView().GetEditWin();
4400 vcl::KeyCode tempKeycode( KEY_ESCAPE );
4401 KeyEvent rKEvt( 0 , tempKeycode );
4402 static_cast<vcl::Window*>(&rEditWindow)->KeyInput( rKEvt );
4403 }
4404 }
4405 }
4406
4407 m_bViewHasChanged = true;
4408 }
4409 }
4410 }
4411 else
4412 {
4413 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4414 if (m_xTreeView->get_cursor(xEntry.get()))
4415 {
4416 SwContent* pCnt = dynamic_cast<SwContent*>(weld::fromId<SwTypeNumber*>(m_xTreeView->get_id(*xEntry)));
4417 if (pCnt && pCnt->GetParent()->GetType() == ContentTypeId::OUTLINE)
4418 {
4419 if (m_bIsRoot && aCode.GetCode() == KEY_LEFT && aCode.GetModifier() == 0)
4420 {
4421 m_xTreeView->unselect_all();
4422 bConsumed = false;
4423 }
4424 else if (aCode.IsMod1())
4425 {
4426 if (aCode.GetCode() == KEY_LEFT)
4427 ExecCommand(u"promote", !aCode.IsShift());
4428 else if (aCode.GetCode() == KEY_RIGHT)
4429 ExecCommand(u"demote", !aCode.IsShift());
4430 else if (aCode.GetCode() == KEY_UP)
4431 ExecCommand(u"chapterup", !aCode.IsShift());
4432 else if (aCode.GetCode() == KEY_DOWN)
4433 ExecCommand(u"chapterdown", !aCode.IsShift());
4434 else if (aCode.GetCode() == KEY_C)
4435 CopyOutlineSelections();
4436 else
4437 bConsumed = false;
4438 }
4439 else
4440 bConsumed = false;
4441 }
4442 else
4443 bConsumed = false;
4444 }
4445 else
4446 bConsumed = false;
4447 }
4448 return bConsumed;
4449}
4450
4451IMPL_LINK(SwContentTree, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
4452{
4454 bool bContent = false;
4455 void* pUserData = weld::fromId<void*>(m_xTreeView->get_id(rEntry));
4456 if (lcl_IsContentType(rEntry, *m_xTreeView))
4457 {
4458 assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pUserData)));
4459 nType = static_cast<SwContentType*>(pUserData)->GetType();
4460 }
4461 else
4462 {
4463 assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pUserData)));
4464 nType = static_cast<SwContent*>(pUserData)->GetParent()->GetType();
4465 bContent = true;
4466 }
4467 OUString sEntry;
4468 if(bContent)
4469 {
4470 switch( nType )
4471 {
4473 assert(dynamic_cast<SwURLFieldContent*>(static_cast<SwTypeNumber*>(pUserData)));
4474 sEntry = static_cast<SwURLFieldContent*>(pUserData)->GetURL();
4475 break;
4476
4478 assert(dynamic_cast<SwPostItContent*>(static_cast<SwTypeNumber*>(pUserData)));
4479 sEntry = static_cast<SwPostItContent*>(pUserData)->GetName();
4480 break;
4482 assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pUserData)));
4483 sEntry = static_cast<SwOutlineContent*>(pUserData)->GetName();
4484 break;
4486 assert(dynamic_cast<SwGraphicContent*>(static_cast<SwTypeNumber*>(pUserData)));
4487 sEntry = static_cast<SwGraphicContent*>(pUserData)->GetLink();
4488 break;
4490 {
4491 assert(dynamic_cast<SwRegionContent*>(static_cast<SwTypeNumber*>(pUserData)));
4492 sEntry = static_cast<SwRegionContent*>(pUserData)->GetName();
4493 const SwSectionFormats& rFormats = GetWrtShell()->GetDoc()->GetSections();
4494 for (SwSectionFormats::size_type n = rFormats.size(); n;)
4495 {
4496 const SwNodeIndex* pIdx = nullptr;
4497 const SwSectionFormat* pFormat = rFormats[--n];
4498 const SwSection* pSect;
4499 if (nullptr != (pSect = pFormat->GetSection()) &&
4500 pSect->GetSectionName() == sEntry &&
4501 nullptr != (pIdx = pFormat->GetContent().GetContentIdx()) &&
4502 pIdx->GetNode().GetNodes().IsDocNodes())
4503 {
4504 SwDocStat aDocStat;
4505 SwPaM aPaM(pIdx->GetNode(), *pIdx->GetNode().EndOfSectionNode());
4506 SwDoc::CountWords(aPaM, aDocStat);
4507 sEntry = SwResId(STR_REGION_DEFNAME) + ": " + sEntry + "\n" +
4508 SwResId(FLD_STAT_WORD) + ": " + OUString::number(aDocStat.nWord) + "\n" +
4509 SwResId(FLD_STAT_CHAR) + ": " + OUString::number(aDocStat.nChar);
4510 break;
4511 }
4512 }
4513 }
4514 break;
4517 {
4518 assert(dynamic_cast<SwTextFootnoteContent*>(static_cast<SwTypeNumber*>(pUserData)));
4519 const SwTextFootnote* pFootnote =
4520 static_cast<const SwTextFootnoteContent*>(pUserData)->GetTextFootnote();
4521
4522 sEntry = pFootnote->GetFootnote().IsEndNote() ? SwResId(STR_CONTENT_ENDNOTE) :
4523 SwResId(STR_CONTENT_FOOTNOTE);
4524 }
4525 break;
4526 default: break;
4527 }
4528 if(static_cast<SwContent*>(pUserData)->IsInvisible())
4529 {
4530 if(!sEntry.isEmpty())
4531 sEntry += ", ";
4532 sEntry += m_sInvisible;
4533 }
4534 }
4535 else
4536 {
4537 size_t nMemberCount = static_cast<SwContentType*>(pUserData)->GetMemberCount();
4538 sEntry = OUString::number(nMemberCount) + " " +
4539 (nMemberCount == 1
4540 ? static_cast<SwContentType*>(pUserData)->GetSingleName()
4541 : static_cast<SwContentType*>(pUserData)->GetName());
4542 }
4543
4544 return sEntry;
4545}
4546
4547void SwContentTree::ExecuteContextMenuAction(const OUString& rSelectedPopupEntry)
4548{
4549 if (rSelectedPopupEntry == "copy")
4550 {
4552 return;
4553 }
4554 if (rSelectedPopupEntry == "collapseallcategories")
4555 {
4556 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
4557 bool bEntry = m_xTreeView->get_iter_first(*xEntry);
4558 while (bEntry)
4559 {
4560 m_xTreeView->collapse_row(*xEntry);
4561 bEntry = m_xTreeView->iter_next_sibling(*xEntry);
4562 }
4563 return;
4564 }
4565
4566 {
4567 std::map<OUString, ContentTypeId> mPopupEntryToContentTypeId
4568 {
4569 {"tabletracking", ContentTypeId::TABLE},
4570 {"frametracking", ContentTypeId::FRAME},
4571 {"imagetracking", ContentTypeId::GRAPHIC},
4572 {"oleobjecttracking", ContentTypeId::OLE},
4573 {"bookmarktracking", ContentTypeId::BOOKMARK},
4574 {"sectiontracking", ContentTypeId::REGION},
4575 {"hyperlinktracking", ContentTypeId::URLFIELD},
4576 {"referencetracking", ContentTypeId::REFERENCE},
4577 {"indextracking", ContentTypeId::INDEX},
4578 {"commenttracking", ContentTypeId::POSTIT},
4579 {"drawingobjecttracking", ContentTypeId::DRAWOBJECT},
4580 {"fieldtracking", ContentTypeId::TEXTFIELD},
4581 {"footnotetracking", ContentTypeId::FOOTNOTE},
4582 {"endnotetracking", ContentTypeId::ENDNOTE}
4583 };
4584
4585 if (mPopupEntryToContentTypeId.count(rSelectedPopupEntry))
4586 {
4587 ContentTypeId eCntTypeId = mPopupEntryToContentTypeId[rSelectedPopupEntry];
4588 SetContentTypeTracking(eCntTypeId, !mTrackContentType[eCntTypeId]);
4589 return;
4590 }
4591 }
4592
4593 std::unique_ptr<weld::TreeIter> xFirst(m_xTreeView->make_iterator());
4594 if (!m_xTreeView->get_selected(xFirst.get()))
4595 return; // this shouldn't happen, but better to be safe than ...
4596
4597 if (rSelectedPopupEntry == "sort")
4598 {
4599 SwContentType* pCntType;
4600 const OUString& rId(m_xTreeView->get_id(*xFirst));
4601 if (lcl_IsContentType(*xFirst, *m_xTreeView))
4602 pCntType = weld::fromId<SwContentType*>(rId);
4603 else
4604 pCntType = const_cast<SwContentType*>(weld::fromId<SwContent*>(rId)->GetParent());
4605 pCntType->SetSortType(!pCntType->GetSortType());
4606 pCntType->FillMemberList();
4607 Display(true);
4608 return;
4609 }
4610 else if (rSelectedPopupEntry == "deletechapter" ||
4611 rSelectedPopupEntry == "deletetable" ||
4612 rSelectedPopupEntry == "deleteframe" ||
4613 rSelectedPopupEntry == "deleteimage" ||
4614 rSelectedPopupEntry == "deleteoleobject" ||
4615 rSelectedPopupEntry == "deletebookmark" ||
4616 rSelectedPopupEntry == "deletehyperlink" ||
4617 rSelectedPopupEntry == "deletereference" ||
4618 rSelectedPopupEntry == "deleteindex" ||
4619 rSelectedPopupEntry == "deletecomment" ||
4620 rSelectedPopupEntry == "deletedrawingobject" ||
4621 rSelectedPopupEntry == "deletefield")
4622 {
4624 return;
4625 }
4626
4627 auto nSelectedPopupEntry = rSelectedPopupEntry.toUInt32();
4628 switch (nSelectedPopupEntry)
4629 {
4630 case TOGGLE_OUTLINE_CONTENT_VISIBILITY:
4631 case HIDE_OUTLINE_CONTENT_VISIBILITY:
4632 case SHOW_OUTLINE_CONTENT_VISIBILITY:
4633 {
4635 m_bIgnoreDocChange = true;
4636 SwOutlineContent* pCntFirst = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(*xFirst));
4637
4638 // toggle the outline node outline content visible attribute
4639 if (nSelectedPopupEntry == TOGGLE_OUTLINE_CONTENT_VISIBILITY)
4640 {
4641 SwNode* pNode = m_pActiveShell->GetDoc()->GetNodes().GetOutLineNds()[pCntFirst->GetOutlinePos()];
4644 }
4645 else
4646 {
4647 // with subs
4649 if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry
4652 int nLevel = -1;
4653 if (nPos != SwOutlineNodes::npos) // not root
4655 else
4656 nPos = 0;
4657 bool bShow(nSelectedPopupEntry == SHOW_OUTLINE_CONTENT_VISIBILITY);
4658 do
4659 {
4661 m_pActiveShell->GetDoc()->GetNodes().GetOutLineNds()[nPos]->GetTextNode()->SetAttrOutlineContentVisible(bShow);
4662 } while (++nPos < nOutlineNodesCount
4663 && (nLevel == -1 || m_pActiveShell->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel));
4664 }
4666 // show in the document what was toggled
4667 if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry
4668 m_pActiveShell->GotoPage(1, true);
4669 else
4671 grab_focus();
4672 m_bIgnoreDocChange = false;
4674 m_pActiveShell->GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged));
4675 }
4676 break;
4677 case 11:
4678 case 12:
4679 case 13:
4680 nSelectedPopupEntry -= 10;
4681 if(m_nOutlineTracking != nSelectedPopupEntry)
4682 SetOutlineTracking(static_cast<sal_uInt8>(nSelectedPopupEntry));
4683 break;
4684 //Outlinelevel
4685 case 101:
4686 case 102:
4687 case 103:
4688 case 104:
4689 case 105:
4690 case 106:
4691 case 107:
4692 case 108:
4693 case 109:
4694 case 110:
4695 nSelectedPopupEntry -= 100;
4696 if(m_nOutlineLevel != nSelectedPopupEntry )
4697 SetOutlineLevel(static_cast<sal_Int8>(nSelectedPopupEntry));
4698 break;
4699 case 201:
4700 case 202:
4701 case 203:
4702 GetParentWindow()->SetRegionDropMode(static_cast<RegionMode>(nSelectedPopupEntry - 201));
4703 break;
4704 case 401:
4705 case 402:
4706 EditEntry(*xFirst, nSelectedPopupEntry == 401 ? EditEntryMode::RMV_IDX : EditEntryMode::UPD_IDX);
4707 break;
4708 // Edit entry
4709 case 403:
4711 break;
4712 case 404:
4714 break;
4715 case 405 :
4716 {
4717 const SwTOXBase* pBase = weld::fromId<SwTOXBaseContent*>(m_xTreeView->get_id(*xFirst))
4718 ->GetTOXBase();
4720 }
4721 break;
4722 case 502 :
4724 break;
4725 case 600:
4727 break;
4728 case 601:
4730 break;
4731 case 602:
4732 {
4735 break;
4736 }
4737 case 700:
4738 {
4740 break;
4741 }
4742 case 800:
4743 ExpandOrCollapseAll(*m_xTreeView, *xFirst);
4744 break;
4745 case 801:
4746 ExecCommand(u"chapterup", true);
4747 break;
4748 case 802:
4749 ExecCommand(u"chapterdown", true);
4750 break;
4751 case 803:
4752 ExecCommand(u"promote", true);
4753 break;
4754 case 804:
4755 ExecCommand(u"demote", true);
4756 break;
4757 case 805: // select document content
4758 {
4762 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xFirst));
4763 const ContentTypeId eTypeId = pCnt->GetParent()->GetType();
4764 if (eTypeId == ContentTypeId::OUTLINE)
4765 {
4766 SwOutlineNodes::size_type nActPos = weld::fromId<SwOutlineContent*>(
4767 m_xTreeView->get_id(*xFirst))->GetOutlinePos();
4768 m_pActiveShell->GotoOutline(nActPos);
4769 m_xTreeView->selected_foreach([this](weld::TreeIter& rEntry){
4770 SwOutlineNodes::size_type nPos = weld::fromId<SwOutlineContent*>(
4771 m_xTreeView->get_id(rEntry))->GetOutlinePos();
4773 // select children if not expanded and don't kill PaMs
4775 !m_xTreeView->get_row_expanded(rEntry), false);
4777 return false;
4778 });
4779 }
4780 else if (eTypeId == ContentTypeId::TABLE)
4781 {
4784 }
4785 else if (eTypeId == ContentTypeId::REGION)
4786 {
4794 }
4796 }
4797 break;
4798 case 900:
4799 {
4800 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xFirst));
4801 GotoContent(pCnt);
4802 }
4803 break;
4804 //Display
4805 default:
4806 if(nSelectedPopupEntry > 300 && nSelectedPopupEntry < 400)
4807 {
4808 nSelectedPopupEntry -= 300;
4809 SwView *pView = SwModule::GetFirstView();
4810 while (pView)
4811 {
4812 nSelectedPopupEntry --;
4813 if(nSelectedPopupEntry == 0)
4814 {
4815 SetConstantShell(&pView->GetWrtShell());
4816 break;
4817 }
4818 pView = SwModule::GetNextView(pView);
4819 }
4820 if(nSelectedPopupEntry)
4821 {
4822 m_bViewHasChanged = nSelectedPopupEntry == 1;
4823 m_eState = (nSelectedPopupEntry == 1) ? State::ACTIVE : State::HIDDEN;
4824 Display(nSelectedPopupEntry == 1);
4825 }
4827 }
4828 }
4829}
4830
4832{
4833 auto nChapters(0);
4834
4836
4838 m_xTreeView->selected_foreach([this, &nChapters](weld::TreeIter& rEntry){
4839 ++nChapters;
4840 if (m_xTreeView->iter_has_child(rEntry) &&
4841 !m_xTreeView->get_row_expanded(rEntry)) // only count children if not expanded
4842 {
4843 nChapters += m_xTreeView->iter_n_children(rEntry);
4844 }
4845 SwOutlineNodes::size_type nActPos = weld::fromId<SwOutlineContent*>(m_xTreeView->get_id(rEntry))->GetOutlinePos();
4847 m_pActiveShell->MakeOutlineSel(nActPos, nActPos, !m_xTreeView->get_row_expanded(rEntry), false); // select children if not expanded
4848 // The outline selection may already be to the start of the following outline paragraph
4849 // as happens when a table is the last content of the to be deleted outline. In this case
4850 // do not extend the to be deleted selection right or the first character of the following
4851 // outline paragraph will be removed. Also check if no selection was made which indicates
4852 // an empty paragraph and selection right is needed.
4856 return false;
4857 });
4859
4860 SwRewriter aRewriter;
4861 aRewriter.AddRule(UndoArg1, SwResId(STR_CHAPTERS, nChapters));
4863 m_pActiveShell->Delete(false);
4865
4867}
4868
4870{
4871 if (nSet == m_nOutlineLevel)
4872 return;
4873 m_nOutlineLevel = nSet;
4875 std::unique_ptr<SwContentType>& rpContentT = (State::ACTIVE == m_eState)
4878 if(rpContentT)
4879 {
4880 rpContentT->SetOutlineLevel(m_nOutlineLevel);
4881 rpContentT->FillMemberList();
4882 }
4884}
4885
4887{
4888 m_nOutlineTracking = nSet;
4890}
4891
4893{
4894 mTrackContentType[eCntTypeId] = bSet;
4895 m_pConfig->SetContentTypeTrack(eCntTypeId, bSet);
4896}
4897
4898// Mode Change: Show dropped Doc
4900{
4901 if(m_pHiddenShell)
4902 {
4904 Display(false);
4905 }
4906}
4907
4908// Mode Change: Show active view
4910{
4912 Display(true);
4914}
4915
4917{
4918 if (m_pConfig->IsNavigateOnSelect())
4919 {
4920 ContentDoubleClickHdl(*m_xTreeView);
4921 grab_focus();
4922 }
4923 Select();
4924 if (m_bIsRoot)
4925 return;
4926 // Select the content type in the Navigate By control
4927 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4928 if (!m_xTreeView->get_selected(xEntry.get()))
4929 return;
4930 while (m_xTreeView->get_iter_depth(*xEntry))
4931 m_xTreeView->iter_parent(*xEntry);
4932 m_pDialog->SelectNavigateByContentType(m_xTreeView->get_text(*xEntry));
4933}
4934
4935// Here the buttons for moving outlines are en-/disabled.
4937{
4938 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
4939 if (!m_xTreeView->get_selected(xEntry.get()))
4940 return;
4941
4942 bool bEnable = false;
4943 std::unique_ptr<weld::TreeIter> xParentEntry(m_xTreeView->make_iterator(xEntry.get()));
4944 bool bParentEntry = m_xTreeView->iter_parent(*xParentEntry);
4945 while (bParentEntry && (!lcl_IsContentType(*xParentEntry, *m_xTreeView)))
4946 bParentEntry = m_xTreeView->iter_parent(*xParentEntry);
4947 if (!m_bIsLastReadOnly)
4948 {
4949 if (!m_xTreeView->get_visible())
4950 bEnable = true;
4951 else if (bParentEntry)
4952 {
4954 (lcl_IsContent(*xEntry, *m_xTreeView) &&
4955 weld::fromId<SwContentType*>(m_xTreeView->get_id(*xParentEntry))->GetType() == ContentTypeId::OUTLINE))
4956 {
4957 bEnable = true;
4958 }
4959 }
4960 }
4961
4963 pNavi->m_xContent6ToolBox->set_item_sensitive("chapterup", bEnable);
4964 pNavi->m_xContent6ToolBox->set_item_sensitive("chapterdown", bEnable);
4965 pNavi->m_xContent6ToolBox->set_item_sensitive("promote", bEnable);
4966 pNavi->m_xContent6ToolBox->set_item_sensitive("demote", bEnable);
4967}
4968
4970{
4972 m_bIsRoot = true;
4974}
4975
4976OUString SwContentType::RemoveNewline(const OUString& rEntry)
4977{
4978 if (rEntry.isEmpty())
4979 return rEntry;
4980
4981 OUStringBuffer aEntry(rEntry);
4982 for (sal_Int32 i = 0; i < rEntry.getLength(); ++i)
4983 if(aEntry[i] == 10 || aEntry[i] == 13)
4984 aEntry[i] = 0x20;
4985
4986 return aEntry.makeStringAndClear();
4987}
4988
4990{
4991 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(rEntry));
4992 GotoContent(pCnt);
4993 const ContentTypeId nType = pCnt->GetParent()->GetType();
4994 sal_uInt16 nSlot = 0;
4995
4996 if(EditEntryMode::DELETE == nMode)
4997 m_bIgnoreDocChange = true;
4998
4999 uno::Reference< container::XNameAccess > xNameAccess, xSecond, xThird;
5000 switch(nType)
5001 {
5003 if(nMode == EditEntryMode::DELETE)
5004 {
5006 }
5007 break;
5008
5011 {
5013 GetDoc()->UnProtectCells( pCnt->GetName());
5014 }
5015 else if(nMode == EditEntryMode::DELETE)
5016 {
5018 OUString sTable = SwResId(STR_TABLE_NAME);
5019 SwRewriter aRewriterTableName;
5020 aRewriterTableName.AddRule(UndoArg1, SwResId(STR_START_QUOTE));
5021 aRewriterTableName.AddRule(UndoArg2, pCnt->GetName());
5022 aRewriterTableName.AddRule(UndoArg3, SwResId(STR_END_QUOTE));
5023 sTable = aRewriterTableName.Apply(sTable);
5024
5025 SwRewriter aRewriter;
5026 aRewriter.AddRule(UndoArg1, sTable);
5032 }
5033 else if(nMode == EditEntryMode::RENAME)
5034 {
5035 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5036 uno::Reference< text::XTextTablesSupplier > xTables(xModel, uno::UNO_QUERY);
5037 xNameAccess = xTables->getTextTables();
5038 }
5039 else
5040 nSlot = FN_FORMAT_TABLE_DLG;
5041 break;
5042
5044 if(nMode == EditEntryMode::DELETE)
5045 {
5047 }
5048 else if(nMode == EditEntryMode::RENAME)
5049 {
5050 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5051 uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
5052 xNameAccess = xGraphics->getGraphicObjects();
5053 uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
5054 xSecond = xFrames->getTextFrames();
5055 uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
5056 xThird = xObjs->getEmbeddedObjects();
5057 }
5058 else
5059 nSlot = FN_FORMAT_GRAFIC_DLG;
5060 break;
5061
5063 case ContentTypeId::OLE :
5064 if(nMode == EditEntryMode::DELETE)
5065 {
5067 }
5068 else if(nMode == EditEntryMode::RENAME)
5069 {
5070 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5071 uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
5072 uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
5074 {
5075 xNameAccess = xFrames->getTextFrames();
5076 xSecond = xObjs->getEmbeddedObjects();
5077 }
5078 else
5079 {
5080 xNameAccess = xObjs->getEmbeddedObjects();
5081 xSecond = xFrames->getTextFrames();
5082 }
5083 uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
5084 xThird = xGraphics->getGraphicObjects();
5085 }
5086 else
5087 nSlot = FN_FORMAT_FRAME_DLG;
5088 break;
5090 if(nMode == EditEntryMode::DELETE)
5091 {
5094 pMarkAccess->deleteMark(pMarkAccess->findMark(pCnt->GetName()), false);
5095 }
5096 else if(nMode == EditEntryMode::RENAME)
5097 {
5099 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5100 uno::Reference< text::XBookmarksSupplier > xBkms(xModel, uno::UNO_QUERY);
5101 xNameAccess = xBkms->getBookmarks();
5102 }
5103 else
5104 {
5105 // allowed despite PROTECT_BOOKMARKS: the dialog itself enforces it
5107 SfxPoolItem const* args[2] = { &name, nullptr };
5109 GetDispatcher()->Execute(FN_EDIT_BOOKMARK, SfxCallMode::SYNCHRON, args);
5110 }
5111 break;
5112
5114 if(nMode == EditEntryMode::RENAME)
5115 {
5116 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5117 uno::Reference< text::XTextSectionsSupplier > xSects(xModel, uno::UNO_QUERY);
5118 xNameAccess = xSects->getTextSections();
5119 }
5120 else
5121 nSlot = FN_EDIT_REGION;
5122 break;
5123
5125 if (nMode == EditEntryMode::DELETE)
5126 nSlot = SID_REMOVE_HYPERLINK;
5127 else
5128 nSlot = SID_EDIT_HYPERLINK;
5129 break;
5131 {
5132 if(nMode == EditEntryMode::DELETE)
5133 {
5134 const OUString& rName = pCnt->GetName();
5135 for (SfxPoolItem* pItem :
5137 {
5138 assert(dynamic_cast<const SwFormatRefMark*>(pItem));
5139 const auto pFormatRefMark = static_cast<const SwFormatRefMark*>(pItem);
5140 if (!pFormatRefMark)
5141 continue;
5142 const SwTextRefMark* pTextRef = pFormatRefMark->GetTextRefMark();
5143 if (pTextRef && &pTextRef->GetTextNode().GetNodes() ==
5144 &m_pActiveShell->GetNodes() && rName == pFormatRefMark->GetRefName())
5145 {
5146 m_pActiveShell->GetDoc()->DeleteFormatRefMark(pFormatRefMark);
5147 m_pActiveShell->SwViewShell::UpdateFields();
5148 break;
5149 }
5150 }
5151 }
5152 }
5153 break;
5155 {
5156 if (nMode == EditEntryMode::DELETE)
5157 {
5158 const SwTextFieldContent* pTextFieldCnt =
5159 static_cast<const SwTextFieldContent*>(pCnt);
5160 const SwTextField* pTextField = pTextFieldCnt->GetFormatField()->GetTextField();
5161 SwTextField::DeleteTextField(*pTextField);
5162 }
5163 else
5164 nSlot = FN_EDIT_FIELD;
5165 }
5166 break;
5168 {
5169 auto& rView = m_pActiveShell->GetView();
5170 auto pPostItMgr = rView.GetPostItMgr();
5171 pPostItMgr->AssureStdModeAtShell();
5172 pPostItMgr->SetActiveSidebarWin(nullptr);
5173 rView.GetEditWin().GrabFocus();
5174 if(nMode == EditEntryMode::DELETE)
5176 else
5177 nSlot = FN_POSTIT;
5178 }
5179 break;
5181 {
5182 const SwTOXBase* pBase = static_cast<SwTOXBaseContent*>(pCnt)->GetTOXBase();
5183 switch(nMode)
5184 {
5186 if(pBase)
5187 {
5188 SwPtrItem aPtrItem( FN_INSERT_MULTI_TOX, const_cast<SwTOXBase *>(pBase));
5191 SfxCallMode::ASYNCHRON, { &aPtrItem });
5192
5193 }
5194 break;
5197 {
5198 if( pBase )
5200 }
5201 break;
5204 {
5205 Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5206 Reference< XDocumentIndexesSupplier > xIndexes(xModel, UNO_QUERY);
5207 Reference< XIndexAccess> xIdxAcc(xIndexes->getDocumentIndexes());
5208 Reference< XNameAccess >xLocalNameAccess(xIdxAcc, UNO_QUERY);
5209 if(EditEntryMode::RENAME == nMode)
5210 xNameAccess = xLocalNameAccess;
5211 else if(xLocalNameAccess.is() && xLocalNameAccess->hasByName(pBase->GetTOXName()))
5212 {
5213 Any aIdx = xLocalNameAccess->getByName(pBase->GetTOXName());
5214 Reference< XDocumentIndex> xIdx;
5215 if(aIdx >>= xIdx)
5216 xIdx->update();
5217 }
5218 }
5219 break;
5220 default: break;
5221 }
5222 }
5223 break;
5225 if(EditEntryMode::DELETE == nMode)
5226 nSlot = SID_DELETE;
5227 else if(nMode == EditEntryMode::RENAME)
5228 nSlot = FN_NAME_SHAPE;
5229 else if (nMode == EditEntryMode::EDIT)
5230 {
5231 vcl::KeyCode aKeyCode(KEY_RETURN, false, false, false, false);
5232 KeyEvent aKeyEvent(0, aKeyCode);
5233 m_pActiveShell->GetWin()->KeyInput(aKeyEvent);
5234 }
5235 break;
5238 if (EditEntryMode::EDIT == nMode)
5239 nSlot = FN_FORMAT_FOOTNOTE_DLG;
5240 break;
5241 default: break;
5242 }
5243 if(nSlot)
5245 GetDispatcher()->Execute(nSlot, SfxCallMode::SYNCHRON);
5246 else if(xNameAccess.is())
5247 {
5248 uno::Any aObj = xNameAccess->getByName(pCnt->GetName());
5249 uno::Reference< uno::XInterface > xTmp;
5250 aObj >>= xTmp;
5251 uno::Reference< container::XNamed > xNamed(xTmp, uno::UNO_QUERY);
5253 ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(pFact->CreateSwRenameXNamedDlg(m_xTreeView.get(), xNamed, xNameAccess));
5254 if(xSecond.is())
5255 pDlg->SetAlternativeAccess( xSecond, xThird);
5256
5257 OUString sForbiddenChars;
5259 {
5260 sForbiddenChars = "/\\@:*?\";,.#";
5261 }
5262 else if(ContentTypeId::TABLE == nType)
5263 {
5264 sForbiddenChars = " .<>";
5265 }
5266 pDlg->SetForbiddenChars(sForbiddenChars);
5267 pDlg->Execute();
5268 }
5269 if(EditEntryMode::DELETE == nMode)
5270 {
5271 auto nPos = m_xTreeView->vadjustment_get_value();
5272 m_bViewHasChanged = true;
5273 TimerUpdate(&m_aUpdTimer);
5274 grab_focus();
5275 m_xTreeView->vadjustment_set_value(nPos);
5276 }
5277}
5278
5280{
5281 // deselect any drawing or frame and leave editing mode
5282 if (SdrView* pSdrView = pWrtShell->GetDrawView())
5283 {
5284 if (pSdrView->IsTextEdit())
5285 {
5286 bool bLockView = pWrtShell->IsViewLocked();
5287 pWrtShell->LockView(true);
5288 pWrtShell->EndTextEdit();
5289 pWrtShell->LockView(bLockView);
5290 }
5291 // go out of the frame
5292 Point aPt(LONG_MIN, LONG_MIN);
5293 pWrtShell->SelectObj(aPt, SW_LEAVE_FRAME);
5294 }
5295
5296 if (pWrtShell->IsSelFrameMode() || pWrtShell->IsObjSelected())
5297 {
5298 pWrtShell->UnSelectFrame();
5299 pWrtShell->LeaveSelFrameMode();
5300 pWrtShell->GetView().LeaveDrawCreate();
5301 pWrtShell->EnterStdMode();
5302 pWrtShell->DrawSelChanged();
5303 pWrtShell->GetView().StopShellTimer();
5304 }
5305 else
5306 pWrtShell->EnterStdMode();
5307}
5308
5310{
5311 m_pActiveShell->LockView(true);
5312 {
5316 size_t nCount = m_xTreeView->get_selected_rows().size();
5317 m_xTreeView->selected_foreach([this, &nCount](weld::TreeIter& rEntry){
5318 SwOutlineNodes::size_type nOutlinePos = reinterpret_cast<SwOutlineContent*>(
5319 m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos();
5321 m_pActiveShell->MakeOutlineSel(nOutlinePos, nOutlinePos,
5322 !m_xTreeView->get_row_expanded(rEntry), false);
5323 // don't move if this is the last selected outline or the cursor is at start of para
5324 if (--nCount && !m_pActiveShell->IsSttPara())
5327 return false;
5328 });
5331 }
5332 m_pActiveShell->LockView(false);
5333}
5334
5336{
5337 if (m_bSelectTo)
5338 {
5342 {
5343 m_bSelectTo = false;
5345 return;
5346 }
5347 }
5348
5350 m_sSelectedItem = "";
5352
5353 std::optional<std::unique_ptr<SwPosition>> oPosition;
5354 if (m_bSelectTo)
5355 oPosition.emplace(new SwPosition(m_pActiveShell->GetCursor()->GetPoint()->nNode,
5357
5358 switch(m_nLastSelType = pCnt->GetParent()->GetType())
5359 {
5361 {
5363 *static_cast<const SwTextFieldContent*>(pCnt)->GetFormatField());
5364 }
5365 break;
5367 {
5369 static_cast<const SwOutlineContent*>(pCnt)->GetOutlinePos();
5372 }
5373 break;
5375 {
5377 }
5378 break;
5381 case ContentTypeId::OLE :
5382 {
5383 m_pActiveShell->GotoFly(pCnt->GetName());
5384 }
5385 break;
5387 {
5391 m_sSelectedItem = pCnt->GetName();
5392
5393 // If the hidden title of SwNavigatorPanel was emptied via UNO XPanel interface,
5394 // store the name of the selected bookmark there. This allows to query the
5395 // selected bookmark using UNO e.g. in add-ons, i.e. to disambiguate when
5396 // multiple bookmarks are there on the selected text range.
5397 // Note: this is a workaround because getDialog() of XPanel is not implemented
5398 // for SwNavigatorPanel.
5399 uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel();
5400
5401 Reference<frame::XController2> xController( xModel->getCurrentController(), uno::UNO_QUERY);
5402 if ( !xController.is() )
5403 break;
5404
5405 Reference<ui::XSidebarProvider> xSidebarProvider = xController->getSidebar();
5406 if ( !xSidebarProvider.is() )
5407 break;
5408
5409 Reference<ui::XDecks> xDecks = xSidebarProvider->getDecks();
5410 if ( !xDecks.is() )
5411 break;
5412
5413 Reference<ui::XDeck> xDeck ( xDecks->getByName("NavigatorDeck"), uno::UNO_QUERY);
5414 if ( !xDeck.is() )
5415 break;
5416
5417 Reference<ui::XPanels> xPanels = xDeck->getPanels();
5418 if ( !xPanels.is() )
5419 break;
5420
5421 if (xPanels->hasByName("SwNavigatorPanel"))
5422 {
5423 Reference<ui::XPanel> xPanel ( xPanels->getByName("SwNavigatorPanel"), uno::UNO_QUERY);
5424 if ( !xPanel.is() || !xPanel->getTitle().isEmpty() )
5425 break;
5426
5427 xPanel->setTitle( pCnt->GetName() );
5428 }
5429 }
5430 break;
5432 {
5434 }
5435 break;
5437 {
5439 *static_cast<const SwURLFieldContent*>(pCnt)->GetINetAttr() ))
5440 {
5441 m_pActiveShell->Right( SwCursorSkipMode::Chars, true, 1, false);
5442 m_pActiveShell->SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true );
5443 }
5444 }
5445 break;
5447 {
5449 }
5450 break;
5452 {
5453 const OUString& sName(pCnt->GetName());
5456 }
5457 break;
5459 m_pActiveShell->GotoFormatField(*static_cast<const SwPostItContent*>(pCnt)->GetPostIt());
5460 break;
5462 {
5464 }
5465 break;
5468 {
5469 const SwTextFootnote* pFootnote =
5470 static_cast<const SwTextFootnoteContent*>(pCnt)->GetTextFootnote();
5471 if (!pFootnote)
5472 return;
5474 }
5475 break;
5476 default: break;
5477 }
5478
5479 if (m_bSelectTo)
5480 {
5483 {
5485 if (!m_pActiveShell->Left(SwCursorSkipMode::Chars, false, 1, false))
5486 break; // Table is at the beginning of the document. It can't be selected this way.
5487 }
5489
5491
5493 m_pActiveShell->GetCursor()->GetMark()->nNode = oPosition.value()->nNode;
5494 m_pActiveShell->GetCursor()->GetMark()->nContent = oPosition.value()->nContent;
5496
5498
5499 m_bSelectTo = false;
5500 }
5501 else
5502 {
5504 {
5507 }
5508
5509 SwView& rView = m_pActiveShell->GetView();
5510 rView.StopShellTimer();
5511 rView.GetPostItMgr()->SetActiveSidebarWin(nullptr);
5512 rView.GetEditWin().GrabFocus();
5513
5514 // Assure cursor is in visible view area.
5515 // (tdf#147041) Always show the navigated outline at the top of the visible view area.
5516 if (pCnt->GetParent()->GetType() == ContentTypeId::OUTLINE ||
5519 {
5520 Point aPoint(rView.GetVisArea().getX(), m_pActiveShell->GetCursorDocPos().getY());
5521 rView.SetVisArea(aPoint);
5522 }
5523 }
5524}
5525
5526// Now even the matching text::Bookmark
5528 :
5529 m_nDocSh(0),
5530 m_nDefaultDrag( RegionMode::NONE )
5531{
5532}
5533
5535 OUString aDesc,
5536 RegionMode nDragType,
5537 const SwDocShell* pDocSh ) :
5538 m_aUrl(std::move( aUrl )),
5539 m_aDescription(std::move(aDesc)),
5540 m_nDocSh(reinterpret_cast<sal_IntPtr>(pDocSh)),
5541 m_nDefaultDrag( nDragType )
5542{
5543}
5544
5546{
5547 rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding();
5548
5549 OString sStrBuf(OUStringToOString(m_aUrl, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) +
5550 OUStringToOString(m_aDescription, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) +
5551 OString::number(static_cast<int>(m_nDefaultDrag)) + OStringChar(NAVI_BOOKMARK_DELIM) +
5552 OString::number(m_nDocSh));
5553 rData.CopyByteString(SotClipboardFormatId::SONLK, sStrBuf);
5554}
5555
5556bool NaviContentBookmark::Paste( const TransferableDataHelper& rData, const OUString& rsDesc )
5557{
5558 OUString sStr;
5559 bool bRet = rData.GetString( SotClipboardFormatId::SONLK, sStr );
5560 if( bRet )
5561 {
5562 sal_Int32 nPos = 0;
5563 m_aUrl = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos );
5564 m_aDescription = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos );
5565 m_nDefaultDrag= static_cast<RegionMode>( o3tl::toInt32(o3tl::getToken(sStr, 0, NAVI_BOOKMARK_DELIM, nPos )) );
5566 m_nDocSh = o3tl::toInt32(o3tl::getToken(sStr, 0, NAVI_BOOKMARK_DELIM, nPos ));
5567 if (!rsDesc.isEmpty())
5568 m_aDescription = rsDesc;
5569 }
5570 return bRet;
5571}
5572
5574{
5575 return m_pDialog;
5576}
5577
5578void SwContentTree::SelectContentType(std::u16string_view rContentTypeName)
5579{
5580 std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
5581 if (!m_xTreeView->get_iter_first(*xIter))
5582 return;
5583 do
5584 {
5585 if (m_xTreeView->get_text(*xIter) == rContentTypeName)
5586 {
5587 m_xTreeView->set_cursor(*xIter);
5588 Select();
5589 break;
5590 }
5591 } while (m_xTreeView->iter_next_sibling(*xIter));
5592}
5593
5594IMPL_LINK_NOARG(SwContentTree, OverlayObjectDelayTimerHdl, Timer *, void)
5595{
5596 m_aOverlayObjectDelayTimer.Stop();
5597 if (m_xOverlayObject)
5598 {
5599 if (SdrView* pView = m_pActiveShell->GetDrawView())
5600 {
5601 if (SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(0))
5602 {
5603 const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager =
5604 pPaintWindow->GetOverlayManager();
5605 xOverlayManager->add(*m_xOverlayObject);
5606 }
5607 }
5608 }
5609}
5610
5611void SwContentTree::OverlayObject(std::vector<basegfx::B2DRange>&& aRanges)
5612{
5614 if (m_xOverlayObject && m_xOverlayObject->getOverlayManager())
5615 m_xOverlayObject->getOverlayManager()->remove(*m_xOverlayObject);
5616 if (aRanges.empty())
5617 m_xOverlayObject.reset();
5618 else
5619 {
5622 Color(), std::move(aRanges), true/*unused for Invert type*/));
5624 }
5625}
5626
5628{
5629 if (lcl_IsContent(rEntry, *m_xTreeView)) // content entry
5630 {
5631 SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(rEntry));
5632 if (pCnt->IsInvisible())
5633 OverlayObject();
5634 else
5635 {
5636 const ContentTypeId nType = pCnt->GetParent()->GetType();
5638 {
5640 GetOutLineNds()[static_cast<SwOutlineContent*>(pCnt)->GetOutlinePos()]});
5641 }
5642 else if (nType == ContentTypeId::TABLE)
5643 {
5644 if (const sw::TableFrameFormats* pFrameFormats = m_pActiveShell->GetDoc()->GetTableFrameFormats())
5645 if (const SwTableFormat* pFrameFormat = pFrameFormats->FindFrameFormatByName(pCnt->GetName()))
5646 {
5647 SwTable* pTable = SwTable::FindTable(pFrameFormat);
5648 if (pTable)
5650 }
5651 }
5654 {
5655 SwNodeType eNodeType = SwNodeType::Text;
5657 eNodeType = SwNodeType::Grf;
5658 else if(nType == ContentTypeId::OLE)
5659 eNodeType = SwNodeType::Ole;
5660 if (const SwFrameFormat* pFrameFormat =
5661 m_pActiveShell->GetDoc()->FindFlyByName(pCnt->GetName(), eNodeType))
5662 BringFramesToAttention(std::vector<const SwFrameFormat*> {pFrameFormat});
5663 }
5664 else if (nType == ContentTypeId::BOOKMARK)
5665 {
5666 BringBookmarksToAttention(std::vector<OUString> {pCnt->GetName()});
5667 }
5669 {
5670 const SwSectionFormats& rFormats = m_pActiveShell->GetDoc()->GetSections();
5671 const SwSectionFormat* pFormat = rFormats.FindFormatByName(pCnt->GetName());
5672 if (pFormat)
5674 }
5675 else if (nType == ContentTypeId::URLFIELD)
5676 {
5678 *static_cast<SwURLFieldContent*>(pCnt)->GetINetAttr())});
5679 }
5680 else if (nType == ContentTypeId::REFERENCE)
5681 {
5682 if (const SwTextAttr* pTextAttr =
5684 {
5685 std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr};
5686 BringReferencesToAttention(aTextAttrArr);
5687 }
5688 }
5689 else if (nType == ContentTypeId::POSTIT)
5690 {
5691 if (const SwTextAttr* pTextAttr =
5692 static_cast<SwPostItContent*>(pCnt)->GetPostIt()->GetTextField())
5693 {
5694 std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr};
5695 BringPostItFieldsToAttention(aTextAttrArr);
5696 }
5697 }
5698 else if (nType == ContentTypeId::DRAWOBJECT)
5699 {
5700 std::vector<const SdrObject*> aSdrObjectArr {GetDrawingObjectsByContent(pCnt)};
5701 BringDrawingObjectsToAttention(aSdrObjectArr);
5702 }
5703 else if (nType == ContentTypeId::TEXTFIELD)
5704 {
5705 if (const SwTextAttr* pTextAttr =
5706 static_cast<SwTextFieldContent*>(pCnt)->GetFormatField()->GetTextField())
5707 {
5708 std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr};
5709 BringTextFieldsToAttention(aTextAttrArr);
5710 }
5711 }
5713 {
5714 if (const SwTextAttr* pTextAttr =
5715 static_cast<SwTextFootnoteContent*> (pCnt)->GetTextFootnote())
5716 {
5717 std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr};
5718 BringFootnotesToAttention(aTextAttrArr);
5719 }
5720 }
5721 }
5722 }
5723 else // content type entry
5724 {
5725 SwContentType* pCntType = weld::fromId<SwContentType*>(m_xTreeView->get_id(rEntry));
5726 if (pCntType->GetMemberCount() == 0)
5727 OverlayObject();
5728 else
5729 {
5730 const ContentTypeId nType = pCntType->GetType();
5732 {
5733 std::vector<const SwNode*> aNodesArr(
5737 }
5738 else if (nType == ContentTypeId::TABLE)
5739 {
5740 std::vector<const SwNode*> aNodesArr;
5741 const size_t nCount = m_pActiveShell->GetTableFrameFormatCount(false);
5744 for(size_t i = 0; i < nCount; ++i)
5745 {
5746 if (const SwTableFormat* pTableFormat = rTableFormats[i])
5747 if (!pTableFormat->GetInfo(aGetHt)) // skip deleted tables
5748 {
5749 SwTable* pTable = SwTable::FindTable(pTableFormat);
5750 if (pTable)
5751 aNodesArr.push_back(pTable->GetTableNode());
5752 }
5753 }
5755 }
5758 {
5762 else if(nType == ContentTypeId::OLE)
5765 }
5766 else if (nType == ContentTypeId::BOOKMARK)
5767 {
5768 std::vector<OUString> aNames;
5769 const auto nCount = pCntType->GetMemberCount();
5770 for (size_t i = 0; i < nCount; i++)
5771 {
5772 const SwContent* pMember = pCntType->GetMember(i);
5773 if (pMember && !pMember->IsInvisible())
5774 aNames.push_back(pMember->GetName());
5775 }
5777 }
5779 {
5780 std::vector<const SwNode*> aNodesArr;
5781 const SwSectionFormats& rFormats = m_pActiveShell->GetDoc()->GetSections();
5782 const size_t nSize = rFormats.size();
5783 for (SwSectionFormats::size_type n = nSize; n;)
5784 {
5785 const SwSectionFormat* pSectionFormat = rFormats[--n];
5786 if (pSectionFormat && pSectionFormat->IsInNodesArr())
5787 {
5788 const SwSection* pSection = pSectionFormat->GetSection();
5789 if (pSection && !pSection->IsHiddenFlag())
5790 {
5791 const SectionType eSectionType = pSection->GetType();
5793 (eSectionType == SectionType::ToxContent ||
5794 eSectionType == SectionType::ToxHeader))
5795 continue;
5796 if (nType == ContentTypeId::INDEX &&
5797 eSectionType != SectionType::ToxContent)
5798 continue;
5799 if (const SwNode* pNode = pSectionFormat->GetSectionNode())
5800 aNodesArr.push_back(pNode);
5801 }
5802 }
5803 }
5805 }
5806 else if (nType == ContentTypeId::URLFIELD)
5807 {
5808 SwGetINetAttrs aINetAttrsArr;
5809 m_pActiveShell->GetINetAttrs(aINetAttrsArr, false);
5810 BringURLFieldsToAttention(aINetAttrsArr);
5811 }
5812 else if (nType == ContentTypeId::REFERENCE)
5813 {
5814 std::vector<const SwTextAttr*> aTextAttrArr;
5815 for (const SfxPoolItem* pItem :
5817 {
5818 if (const auto pRefMark = dynamic_cast<const SwFormatRefMark*>(pItem))
5819 {
5820 const SwTextRefMark* pTextRef = pRefMark->GetTextRefMark();
5821 if (pTextRef && &pTextRef->GetTextNode().GetNodes() ==
5823 aTextAttrArr.push_back(pTextRef);
5824 }
5825 }
5826 BringReferencesToAttention(aTextAttrArr);
5827 }
5828 else if (nType == ContentTypeId::POSTIT)
5829 {
5830 std::vector<const SwTextAttr*> aTextAttrArr;
5831 const auto nCount = pCntType->GetMemberCount();
5832 for (size_t i = 0; i < nCount; i++)
5833 {
5834 const SwPostItContent* pPostItContent = static_cast<const SwPostItContent*>(
5835 pCntType->GetMember(i));
5836 if (pPostItContent && !pPostItContent->IsInvisible())
5837 if (const SwFormatField* pFormatField = pPostItContent->GetPostIt())
5838 if (const SwTextAttr* pTextAttr = pFormatField->GetTextField())
5839 aTextAttrArr.push_back(pTextAttr);
5840 }
5841 BringPostItFieldsToAttention(aTextAttrArr);
5842 }
5843 else if (nType == ContentTypeId::DRAWOBJECT)
5844 {
5846 if (const SwDrawModel* pModel = rIDDMA.GetDrawModel())
5847 {
5848 if (const SdrPage* pPage = pModel->GetPage(0))
5849 {
5850 if (const size_t nCount = pPage->GetObjCount())
5851 {
5852 std::vector<const SdrObject*> aSdrObjectArr;
5853 for (size_t i = 0; i < nCount; ++i)
5854 {
5855 const SdrObject* pObject = pPage->GetObj(i);
5856 if (pObject && !pObject->GetName().isEmpty() &&
5857 rIDDMA.IsVisibleLayerId(pObject->GetLayer()))
5858 aSdrObjectArr.push_back(pObject);
5859 }
5860 BringDrawingObjectsToAttention(aSdrObjectArr);
5861 }
5862 }
5863 }
5864 }
5865 else if (nType == ContentTypeId::TEXTFIELD)
5866 {
5867 std::vector<const SwTextAttr*> aTextAttrArr;
5868 const auto nCount = pCntType->GetMemberCount();
5869 for (size_t i = 0; i < nCount; i++)
5870 {
5871 const SwTextFieldContent* pTextFieldCnt =
5872 static_cast<const SwTextFieldContent*>(pCntType->GetMember(i));
5873 if (pTextFieldCnt && !pTextFieldCnt->IsInvisible())
5874 if (const SwFormatField* pFormatField = pTextFieldCnt->GetFormatField())
5875 if (const SwTextAttr* pTextAttr = pFormatField->GetTextField())
5876 aTextAttrArr.push_back(pTextAttr);
5877 }
5878 BringTextFieldsToAttention(aTextAttrArr);
5879 }
5881 {
5882 std::vector<const SwTextAttr*> aTextAttrArr;
5883 const auto nCount = pCntType->GetMemberCount();
5884 for (size_t i = 0; i < nCount; i++)
5885 {
5886 const SwTextFootnoteContent* pTextFootnoteCnt =
5887 static_cast<const SwTextFootnoteContent*>(pCntType->GetMember(i));
5888 if (pTextFootnoteCnt && !pTextFootnoteCnt->IsInvisible())
5889 if (const SwTextAttr* pTextAttr = pTextFootnoteCnt->GetTextFootnote())
5890 aTextAttrArr.push_back(pTextAttr);
5891 }
5892 BringFootnotesToAttention(aTextAttrArr);
5893 }
5894 }
5895 }
5896}
5897
5898static void lcl_CalcOverlayRanges(const SwTextFrame* pStartFrame, const SwTextFrame* pEndFrame,
5899 const SwPosition& aStartPos, const SwPosition& aEndPos,
5900 std::vector<basegfx::B2DRange>& aRanges)
5901{
5902 if (pStartFrame && pEndFrame)
5903 {
5904 SwRect aStartCharRect;
5905 pStartFrame->GetCharRect(aStartCharRect, aStartPos);
5906 SwRect aEndCharRect;
5907 pEndFrame->GetCharRect(aEndCharRect, aEndPos);
5908 if (aStartCharRect.Top() == aEndCharRect.Top())
5909 {
5910 // single line range
5911 aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(),
5912 aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1);
5913 }
5914 else
5915 {
5916 // multi line range
5917 SwRect aFrameRect = pStartFrame->getFrameArea();
5918 aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(),
5919 aFrameRect.Right(), aStartCharRect.Bottom() + 1);
5920 if (aStartCharRect.Bottom() + 1 != aEndCharRect.Top())
5921 aRanges.emplace_back(aFrameRect.Left(), aStartCharRect.Bottom() + 1,
5922 aFrameRect.Right(), aEndCharRect.Top() + 1);
5923 aRanges.emplace_back(aFrameRect.Left(), aEndCharRect.Top() + 1,
5924 aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1);
5925 }
5926 }
5927}
5928
5929void SwContentTree::BringFramesToAttention(const std::vector<const SwFrameFormat*>& rFrameFormats)
5930{
5931 std::vector<basegfx::B2DRange> aRanges;
5932 for (const SwFrameFormat* pFrameFormat : rFrameFormats)
5933 {
5934 if (!pFrameFormat)
5935 continue;
5936 SwRect aFrameRect = pFrameFormat->FindLayoutRect();
5937 if (!aFrameRect.IsEmpty())
5938 aRanges.emplace_back(aFrameRect.Left(), aFrameRect.Top(), aFrameRect.Right(),
5939 aFrameRect.Bottom());
5940 }
5941 OverlayObject(std::move(aRanges));
5942}
5943
5944void SwContentTree::BringBookmarksToAttention(const std::vector<OUString>& rNames)
5945{
5946 std::vector<basegfx::B2DRange> aRanges;
5948 for (const auto& rName : rNames)
5949 {
5950 IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findBookmark(rName);
5951 if (ppBkmk == pMarkAccess->getBookmarksEnd())
5952 continue;
5953 SwPosition aMarkStart = (*ppBkmk)->GetMarkStart();
5954 const SwTextNode* pMarkStartTextNode = aMarkStart.GetNode().GetTextNode();
5955 if (!pMarkStartTextNode)
5956 continue;
5957 const SwTextFrame* pMarkStartFrame = static_cast<const SwTextFrame*>(
5958 pMarkStartTextNode->getLayoutFrame(m_pActiveShell->GetLayout()));
5959 if (!pMarkStartFrame)
5960 continue;
5961 SwPosition aMarkEnd = (*ppBkmk)->GetMarkEnd();
5962 const SwTextNode* pMarkEndTextNode = aMarkEnd.GetNode().GetTextNode();
5963 if (!pMarkEndTextNode)
5964 continue;
5965 const SwTextFrame* pMarkEndFrame = static_cast<const SwTextFrame*>(
5966 pMarkEndTextNode->getLayoutFrame(m_pActiveShell->GetLayout()));
5967 if (!pMarkEndFrame)
5968 continue;
5969 // adjust span when mark start equals mark end
5970 if (aMarkStart == aMarkEnd)
5971 {
5972 if (aMarkEnd.GetContentIndex() < pMarkEndTextNode->Len() - 1)
5973 aMarkEnd.AdjustContent(+1);
5974 else if (aMarkStart.GetContentIndex() > 0)
5975 aMarkStart.AdjustContent(-1);
5976 }
5977 lcl_CalcOverlayRanges(pMarkStartFrame, pMarkEndFrame, aMarkStart, aMarkEnd, aRanges);
5978 }
5979 OverlayObject(std::move(aRanges));
5980}
5981
5982void SwContentTree::BringTypesWithFlowFramesToAttention(const std::vector<const SwNode*>& rNodes)
5983{
5984 std::vector<basegfx::B2DRange> aRanges;
5985 for (const auto* pNode : rNodes)
5986 {
5987 if (!pNode)
5988 continue;
5989 SwNode2Layout aTmp(*pNode, pNode->GetIndex() - 1);
5990 SwFrame* pFrame = aTmp.NextFrame();
5991 while (pFrame)
5992 {
5993 const SwRect& rFrameRect = pFrame->getFrameArea();
5994 if (!rFrameRect.IsEmpty())
5995 aRanges.emplace_back(rFrameRect.Left(), rFrameRect.Top(), rFrameRect.Right(),
5996 rFrameRect.Bottom());
5997 if (!pFrame->IsFlowFrame())
5998 break;
5999 SwFlowFrame *pFollow = SwFlowFrame::CastFlowFrame(pFrame)->GetFollow();
6000 if (!pFollow)
6001 break;
6002 pFrame = &pFollow->GetFrame();
6003 }
6004 }
6005 OverlayObject(std::move(aRanges));
6006}
6007
6009{
6010 std::vector<basegfx::B2DRange> aRanges;
6011 for (const auto& r : rINetAttrsArr)
6012 {
6013 const SwTextNode& rTextNode = r.rINetAttr.GetTextNode();
6014 if (SwTextFrame* pFrame = static_cast<SwTextFrame*>(
6016 {
6017 auto nStart = r.rINetAttr.GetStart();
6018 auto nEnd = r.rINetAttr.GetAnyEnd();
6019 SwPosition aStartPos(rTextNode, nStart), aEndPos(rTextNode, nEnd);
6020 lcl_CalcOverlayRanges(pFrame, pFrame, aStartPos, aEndPos, aRanges);
6021 }
6022 }
6023 OverlayObject(std::move(aRanges));
6024}
6025
6026void SwContentTree::BringReferencesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
6027{
6028 std::vector<basegfx::B2DRange> aRanges;
6029 for (const SwTextAttr* p : rTextAttrsArr)
6030 {
6031 if (!p)
6032 continue;
6033 const SwTextRefMark* pTextRefMark = p->GetRefMark().GetTextRefMark();
6034 if (!pTextRefMark)
6035 continue;
6036 const SwTextNode& rTextNode = pTextRefMark->GetTextNode();
6037 if (SwTextFrame* pFrame = static_cast<SwTextFrame*>(
6039 {
6040 auto nStart = p->GetStart();
6041 auto nEnd = p->GetAnyEnd();
6042 SwPosition aStartPos(rTextNode, nStart), aEndPos(rTextNode, nEnd);
6043 lcl_CalcOverlayRanges(pFrame, pFrame, aStartPos, aEndPos, aRanges);
6044 }
6045 }
6046 OverlayObject(std::move(aRanges));
6047}
6048
6049void SwContentTree::BringPostItFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
6050{
6051 std::vector<basegfx::B2DRange> aRanges;
6052 for (const SwTextAttr* p : rTextAttrsArr)
6053 {
6054 if (!p)
6055 continue;
6056 const SwTextField* pTextField = p->GetFormatField().GetTextField();
6057 if (!pTextField)
6058 continue;
6059 // use as a fallback when there is no mark
6060 SwTextNode& rTextNode = pTextField->GetTextNode();
6061 if (!rTextNode.getLayoutFrame(m_pActiveShell->GetLayout()))
6062 continue;
6063 assert(dynamic_cast<const SwTextAnnotationField*>(pTextField));
6064 const SwTextAnnotationField* pTextAnnotationField =
6065 static_cast<const SwTextAnnotationField*>(pTextField);
6066 const ::sw::mark::IMark* pAnnotationMark = pTextAnnotationField->GetAnnotationMark();
6067 const SwPosition aMarkStart = pAnnotationMark ? pAnnotationMark->GetMarkStart()
6068 : SwPosition(rTextNode, p->GetStart());
6069 const SwPosition aMarkEnd = pAnnotationMark ? pAnnotationMark->GetMarkEnd()
6070 : SwPosition(rTextNode, p->GetAnyEnd());
6071 const SwTextFrame* pMarkStartFrame = static_cast<SwTextFrame*>(
6073 const SwTextFrame* pMarkEndFrame = static_cast<SwTextFrame*>(
6075 if (!pMarkStartFrame || !pMarkEndFrame)
6076 continue;
6077 lcl_CalcOverlayRanges(pMarkStartFrame, pMarkEndFrame, aMarkStart,
6078 aMarkEnd, aRanges);
6079 }
6080 OverlayObject(std::move(aRanges));
6081}
6082
6083void SwContentTree::BringFootnotesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
6084{
6085 std::vector<basegfx::B2DRange> aRanges;
6086 for (const SwTextAttr* p : rTextAttrsArr)
6087 {
6088 if (!p)
6089 continue;
6090 const SwTextFootnote* pTextFootnote = p->GetFootnote().GetTextFootnote();
6091 if (!pTextFootnote)
6092 continue;
6093 const SwTextNode& rTextNode = pTextFootnote->GetTextNode();
6094 if (SwTextFrame* pFrame = static_cast<SwTextFrame*>(
6096 {
6097 auto nStart = p->GetStart();
6098 auto nEnd = nStart + 1;
6099 SwPosition aStartPos(rTextNode, nStart), aEndPos(rTextNode, nEnd);
6100 lcl_CalcOverlayRanges(pFrame, pFrame, aStartPos, aEndPos, aRanges);
6101 }
6102 }
6103 OverlayObject(std::move(aRanges));
6104}
6105
6106void SwContentTree::BringDrawingObjectsToAttention(std::vector<const SdrObject*>& rDrawingObjectsArr)
6107{
6108 std::vector<basegfx::B2DRange> aRanges;
6109 for (const SdrObject* pObject : rDrawingObjectsArr)
6110 {
6111 if (pObject)
6112 {
6113 tools::Rectangle aRect(pObject->GetLogicRect());
6114 if (!aRect.IsEmpty())
6115 aRanges.emplace_back(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
6116 }
6117 }
6118 OverlayObject(std::move(aRanges));
6119}
6120
6121void SwContentTree::BringTextFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
6122{
6123 std::vector<basegfx::B2DRange> aRanges;
6124 std::shared_ptr<SwPaM> pPamForTextField;
6125 for (const SwTextAttr* p : rTextAttrsArr)
6126 {
6127 if (!p)
6128 continue;
6129 const SwTextField* pTextField = p->GetFormatField().GetTextField();
6130 if (!pTextField)
6131 continue;
6132 if (SwTextFrame* pFrame = static_cast<SwTextFrame*>(
6134 {
6135 SwTextField::GetPamForTextField(*pTextField, pPamForTextField);
6136 if (!pPamForTextField)
6137 continue;
6138 SwPosition aStartPos(*pPamForTextField->GetMark());
6139 SwPosition aEndPos(*pPamForTextField->GetPoint());
6140 lcl_CalcOverlayRanges(pFrame, pFrame, aStartPos, aEndPos, aRanges);
6141 }
6142 }
6143 OverlayObject(std::move(aRanges));
6144}
6145
6146/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ UndoArg1
Definition: SwRewriter.hxx:29
@ UndoArg3
Definition: SwRewriter.hxx:31
@ UndoArg2
Definition: SwRewriter.hxx:30
constexpr OUStringLiteral sFrameName
static bool GetLayoutRTL()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
virtual const SwFieldTypes * GetFieldTypes() const =0
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getBookmarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
virtual const_iterator_t findMark(const OUString &rMark) const =0
Finds a mark by name.
virtual std::unique_ptr< ILazyDeleter > deleteMark(const IDocumentMarkAccess::const_iterator_t &ppMark, bool isMoveNodes)=0
Deletes a mark.
virtual const_iterator_t findBookmark(const OUString &rMark) const =0
Finds a bookmark by name.
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:502
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
virtual SwTextNode * getOutlineNode(const tSortedOutlineNodeList::size_type nIdx) const =0
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
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
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
static OUString decode(std::u16string_view rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
tools::Long m_nDocSh
Definition: navicont.hxx:39
bool Paste(const TransferableDataHelper &rData, const OUString &rsDesc)
Definition: content.cxx:5556
void Copy(TransferDataContainer &rData) const
Definition: content.cxx:5545
OUString m_aDescription
Definition: navicont.hxx:38
RegionMode m_nDefaultDrag
Definition: navicont.hxx:40
constexpr tools::Long getY() const
bool IsObjMarked(SdrObject const *pObj) const
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
size_t GetMarkedObjectCount() const
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
const SdrPage * GetPage(sal_uInt16 nPgNum) const
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
virtual const OUString & GetName() const
virtual SdrObjKind GetObjIdentifier() const
virtual SdrLayerID GetLayer() const
virtual const tools::Rectangle & GetLogicRect() const
SdrPageView * GetSdrPageView() const
bool Execute(sal_uInt16 nSlot, const SfxPoolItem **pArgs=nullptr, SfxCallMode nCall=SfxCallMode::SLOT)
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
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 * >())
const OUString & GetEventName() const
SfxHintId GetId() const
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListeningAll()
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint)
const INetURLObject & GetURLObject() const
bool HasName() const
bool IsReadOnly() const
SfxMedium * GetMedium() const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
const css::uno::Reference< css::frame::XController2 > & GetController() const
SfxBindings & GetBindings()
SfxDispatcher * GetDispatcher()
SfxViewFrame & GetViewFrame() const
sal_uInt16 GetStart() const
virtual VclPtr< AbstractSwRenameXNamedDlg > CreateSwRenameXNamedDlg(weld::Widget *pParent, css::uno::Reference< css::container::XNamed > &xNamed, css::uno::Reference< css::container::XNameAccess > &xNameAccess)=0
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
SwContentTreeDropTarget(SwContentTree &rTreeView)
Definition: content.cxx:1239
SwContentTree & m_rTreeView
Definition: conttree.hxx:80
virtual sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt) override
Definition: content.cxx:1245
virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt) override
Definition: content.cxx:1292
TreeListBox for content indicator.
Definition: conttree.hxx:91
sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt)
Definition: content.cxx:1265
void Select()
Definition: content.cxx:4936
void BringTypesWithFlowFramesToAttention(const std::vector< const SwNode * > &rNodes)
Definition: content.cxx:5982
SwOutlineNodes::size_type m_nLastGotoContentWasOutlinePos
Definition: conttree.hxx:121
void SetOutlineTracking(sal_uInt8 nSet)
Definition: content.cxx:4886
void BringURLFieldsToAttention(const SwGetINetAttrs &rINetAttrsArr)
Definition: content.cxx:6008
void BringTextFieldsToAttention(std::vector< const SwTextAttr * > &rTextAttrsArr)
Definition: content.cxx:6121
std::map< void *, bool > mOutLineNodeMap
Definition: conttree.hxx:109
bool m_bIgnoreDocChange
Definition: conttree.hxx:135
void GotoContent(const SwContent *pCnt)
Definition: content.cxx:5335
void ShowActualView()
Definition: content.cxx:4909
weld::TreeView & get_widget()
Definition: conttree.hxx:300
void ShowHiddenShell()
Definition: content.cxx:4899
void SelectContentType(std::u16string_view rContentTypeName)
Definition: content.cxx:5578
size_t GetEntryCount() const
Definition: content.cxx:2473
SwNavigationPI * GetParentWindow()
Definition: content.cxx:5573
void ExecCommand(std::u16string_view rCmd, bool bModifier)
Execute commands of the Navigator.
Definition: content.cxx:3257
std::unique_ptr< weld::TreeIter > GetEntryAtAbsPos(size_t nAbsPos) const
Definition: content.cxx:2501
void UpdateLastSelType()
Definition: content.cxx:3094
void BringFootnotesToAttention(std::vector< const SwTextAttr * > &rTextAttrsArr)
Definition: content.cxx:6083
void insert(const weld::TreeIter *pParent, const OUString &rStr, const OUString &rId, bool bChildrenOnDemand, weld::TreeIter *pRet)
Definition: content.cxx:2104
void FindActiveTypeAndRemoveUserData()
Before any data will be deleted, the last active entry has to be found.
Definition: content.cxx:3110
bool IsInDrag() const
Definition: content.cxx:1259
void ToggleToRoot()
Switch the display to Root.
Definition: content.cxx:2840
void remove(const weld::TreeIter &rIter)
Definition: content.cxx:2111
void BringFramesToAttention(const std::vector< const SwFrameFormat * > &rFrameFormats)
Definition: content.cxx:5929
bool m_bSelectTo
Definition: conttree.hxx:138
OUString m_sSelectedItem
Definition: conttree.hxx:103
void SelectOutlinesWithSelection()
Definition: content.cxx:4122
o3tl::enumarray< ContentTypeId, std::unique_ptr< SwContentType > > m_aHiddenContentArr
Definition: conttree.hxx:100
std::unique_ptr< sdr::overlay::OverlayObject > m_xOverlayObject
Definition: conttree.hxx:141
sal_uInt8 GetOutlineLevel() const
Definition: conttree.hxx:247
AutoTimer m_aOverlayObjectDelayTimer
Definition: conttree.hxx:97
bool m_bIsLastReadOnly
Definition: conttree.hxx:127
std::vector< std::unique_ptr< weld::TreeIter > > m_aDndOutlinesSelected
Definition: conttree.hxx:132
bool m_bIsOutlineMoveable
Definition: conttree.hxx:128
sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt)
Definition: content.cxx:1297
void SetConstantShell(SwWrtShell *pSh)
Set an open view as active.
Definition: content.cxx:3178
bool RequestingChildren(const weld::TreeIter &rParent)
Definition: content.cxx:2124
size_t GetAbsPos(const weld::TreeIter &rIter)
Definition: content.cxx:2468
void MoveOutline(SwOutlineNodes::size_type nTargetPos)
Definition: content.cxx:4176
virtual void Notify(SfxBroadcaster &rBC, SfxHint const &rHint) override
Definition: content.cxx:3192
void Display(bool bActiveView)
Show the file.
Definition: content.cxx:2516
void SetContentTypeTracking(ContentTypeId eCntTypeId, bool bSet)
Definition: content.cxx:4892
bool FillTransferData(TransferDataContainer &rTransfer, sal_Int8 &rDragMode)
Definition: content.cxx:2699
ContentTypeId m_nLastSelType
Definition: conttree.hxx:115
void SetHiddenShell(SwWrtShell *pSh)
After a file is dropped on the Navigator, the new shell will be set.
Definition: content.cxx:3122
const SwWrtShell * GetActiveWrtShell() const
Definition: conttree.hxx:263
void Expand(const weld::TreeIter &rParent, std::vector< std::unique_ptr< weld::TreeIter > > *pNodesToExpand)
Definition: content.cxx:2219
void EditEntry(const weld::TreeIter &rEntry, EditEntryMode nMode)
Definition: content.cxx:4989
sal_Int32 m_nHiddenBlock
Definition: conttree.hxx:112
size_t m_nEntryCount
Definition: conttree.hxx:113
OUString m_aContextStrings[CONTEXT_COUNT+1]
Definition: conttree.hxx:101
sal_Int32 m_nActiveBlock
Definition: conttree.hxx:111
OUString m_sSpace
Definition: conttree.hxx:95
void OverlayObject(std::vector< basegfx::B2DRange > &&aRanges={})
Definition: content.cxx:5611
o3tl::enumarray< ContentTypeId, std::unique_ptr< SwContentType > > m_aActiveContentArr
Definition: conttree.hxx:99
void BringEntryToAttention(const weld::TreeIter &rEntry)
Definition: content.cxx:5627
enum SwContentTree::State m_eState
bool HasContentChanged()
Check if the displayed content is valid.
Definition: content.cxx:2892
SwWrtShell * m_pHiddenShell
Definition: conttree.hxx:105
void BringPostItFieldsToAttention(std::vector< const SwTextAttr * > &rTextAttrsArr)
Definition: content.cxx:6049
void grab_focus()
Definition: conttree.hxx:290
ContentTypeId m_nRootType
Definition: conttree.hxx:114
SwNavigationConfig * m_pConfig
Definition: conttree.hxx:107
sal_uInt8 m_nOutlineLevel
Definition: conttree.hxx:116
void clear()
In the clear the content types have to be deleted, also.
Definition: content.cxx:2691
SwWrtShell * GetWrtShell()
Definition: conttree.hxx:242
void DeleteOutlineSelections()
Definition: content.cxx:4831
void SetActiveShell(SwWrtShell *pSh)
Document change - set new Shell.
Definition: content.cxx:3136
void UpdateTracking()
Definition: content.cxx:3763
size_t GetChildCount(const weld::TreeIter &rParent) const
Definition: content.cxx:2478
o3tl::enumarray< ContentTypeId, bool > mTrackContentType
Definition: conttree.hxx:119
void BringReferencesToAttention(std::vector< const SwTextAttr * > &rTextAttrsArr)
Definition: content.cxx:6026
SwWrtShell * m_pActiveShell
Definition: conttree.hxx:106
AutoTimer m_aUpdTimer
Definition: conttree.hxx:96
SwContentTree(std::unique_ptr< weld::TreeView > xTreeView, SwNavigationPI *pDialog)
Definition: content.cxx:1072
void SetOutlineLevel(sal_uInt8 nSet)
Definition: content.cxx:4869
void BringDrawingObjectsToAttention(std::vector< const SdrObject * > &rDrawingObjectsArr)
Definition: content.cxx:6106
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: conttree.hxx:92
void CopyOutlineSelections()
Definition: content.cxx:5309
void SetRootType(ContentTypeId nType)
Definition: content.cxx:4969
SwNavigationPI * m_pDialog
Definition: conttree.hxx:94
SdrObject * GetDrawingObjectsByContent(const SwContent *pCnt)
Definition: content.cxx:2187
void InsertContent(const weld::TreeIter &rParent)
Definition: content.cxx:2076
bool m_bViewHasChanged
Definition: conttree.hxx:129
void ShowTree()
Definition: content.cxx:3540
void HideTree()
Definition: content.cxx:3546
void BringBookmarksToAttention(const std::vector< OUString > &rNames)
Definition: content.cxx:5944
void ExecuteContextMenuAction(const OUString &rSelectedPopupEntry)
Definition: content.cxx:4547
sal_uInt8 m_nOutlineTracking
Definition: conttree.hxx:118
bool m_bDocHasChanged
Definition: conttree.hxx:134
Content type, knows it's contents and the WrtShell.
Definition: content.hxx:173
void FillMemberList(bool *pbContentChanged=nullptr)
Fill the List of contents.
Definition: content.cxx:426
sal_uInt8 m_nOutlineLevel
Definition: content.hxx:182
void Invalidate()
Definition: content.cxx:421
bool GetSortType() const
Definition: content.hxx:212
void SetSortType(bool bAlphabetic)
Definition: content.hxx:213
size_t m_nMemberCount
Definition: content.hxx:180
SwWrtShell * m_pWrtShell
Definition: content.hxx:174
bool m_bDataValid
Definition: content.hxx:183
bool IsEditable() const
Definition: content.hxx:217
virtual ~SwContentType() override
Definition: content.cxx:405
ContentTypeId GetType() const
Definition: content.hxx:198
SwContentType(SwWrtShell *pParent, ContentTypeId nType, sal_uInt8 nLevel)
Definition: content.cxx:326
std::unique_ptr< SwContentArr > m_pMember
Definition: content.hxx:176
bool IsDeletable() const
Definition: content.hxx:218
bool m_bAlphabeticSort
Definition: content.hxx:187
size_t GetMemberCount() const
Definition: content.hxx:196
const OUString & GetTypeToken() const
Definition: content.hxx:204
bool m_bDelete
Definition: content.hxx:185
const SwContent * GetMember(size_t nIndex)
Deliver content, for that if necessary fill the list.
Definition: content.cxx:409
OUString m_sTypeToken
Definition: content.hxx:179
ContentTypeId m_nContentType
Definition: content.hxx:181
static OUString RemoveNewline(const OUString &)
Definition: content.cxx:4976
bool IsInvisible() const
Definition: swcont.hxx:102
const OUString & GetName() const
Definition: swcont.hxx:88
const SwContentType * GetParent() const
Definition: swcont.hxx:87
void SetInvisible()
Definition: swcont.hxx:103
SwContent(const SwContentType *pCnt, OUString aName, double nYPos)
Definition: content.cxx:204
virtual bool IsProtect() const
Definition: content.cxx:218
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1876
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2550
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:494
void StartAction()
Definition: crsrsh.cxx:226
const SwTableNode * IsCursorInTable() const
Check if Point of current cursor is placed within a table.
Definition: crsrsh.cxx:600
void SttCursorMove()
Definition: crsrsh.cxx:301
bool GotoPrevTOXBase(const OUString *=nullptr)
jump to previous index
Definition: crstrvl.cxx:313
Point & GetCursorDocPos() const
Definition: crsrsh.hxx:925
void HideCursor()
Definition: crsrsh.cxx:2731
bool IsCursorVisible() const
Definition: crsrsh.hxx:540
virtual SwCursor & GetCurrentShellCursor() override
Return the current shell cursor.
Definition: crsrsh.cxx:185
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:679
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool IsSttPara() const
Definition: crsrsh.cxx:1381
SwField * GetCurField(const bool bIncludeInputFieldAtStart=false) const
Definition: crstrvl.cxx:1073
void MakeOutlineSel(SwOutlineNodes::size_type nSttPos, SwOutlineNodes::size_type nEndPos, bool bWithChildren, bool bKillPams=true)
Definition: crstrvl.cxx:1348
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:243
void ClearMark()
Definition: crsrsh.cxx:1225
void SetMark()
Definition: crsrsh.hxx:906
void KillPams()
Definition: crsrsh.cxx:1308
SwOutlineNodes::size_type GetOutlinePos(sal_uInt8 nLevel=UCHAR_MAX, SwPaM *pPaM=nullptr)
search "outline position" before previous outline node at given level
Definition: crstrvl.cxx:1319
bool GetContentAtPos(const Point &rPt, SwContentAtPos &rContentAtPos, bool bSetCursor=false, SwRect *pFieldRect=nullptr)
Definition: crstrvl.cxx:1433
void EndCursorMove(const bool bIdleEnd=false)
Definition: crsrsh.cxx:310
SwCursor * GetNext()
Definition: swcrsr.hxx:219
SwSectionFormats & GetSections()
Definition: doc.hxx:1356
static void CountWords(const SwPaM &rPaM, SwDocStat &rStat)
Definition: docedt.cxx:826
const sw::TableFrameFormats * GetTableFrameFormats() const
Definition: doc.hxx:826
void DeleteFormatRefMark(const SwFormatRefMark *pFormatRefMark)
Definition: doc.cxx:1127
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:371
const SwFlyFrameFormat * FindFlyByName(const OUString &rName, SwNodeType nNdTyp=SwNodeType::NONE) const
Definition: doclay.cxx:1420
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:649
const SwFormatRefMark * GetRefMark(std::u16string_view rName) const
Definition: doc.cxx:1060
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1337
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:169
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
bool IsInHeaderFooter(const SwNode &) const
Definition: doclay.cxx:1582
const SwDoc & GetDoc() const
Definition: drawdoc.hxx:35
void GetINetAttrs(SwGetINetAttrs &rArr, bool bIncludeInToxContent=true)
Definition: editsh.cxx:687
const SwTOXBase * GetCurTOX() const
Get current listing before or at the Cursor.
Definition: edtox.cxx:191
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
size_t GetTableFrameFormatCount(bool bUsed=false) const
TABLE.
Definition: edfmt.cxx:99
size_t GetSectionFormatCount() const
Definition: edsect.cxx:114
sal_uInt16 GetTOXCount() const
Definition: edtox.cxx:215
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
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
bool Delete(bool isArtificialSelection=false)
Delete content of all ranges.
Definition: eddel.cxx:134
SwFrameFormat * GetTableFormat()
Definition: edws.cxx:183
bool IsOutlineCopyable(SwOutlineNodes::size_type nIdx) const
Definition: ednumber.cxx:627
const SwSection * GetCurrSection() const
Definition: edsect.cxx:71
const SwTOXBase * GetTOX(sal_uInt16 nPos) const
Definition: edtox.cxx:229
const SwNumRule * GetOutlineNumRule() const
Definition: ednumber.cxx:117
sal_uInt16 GetRefMarks(std::vector< OUString > *=nullptr) const
get the names of all references in a Doc
Definition: editsh.cxx:447
bool IsProtectedOutlinePara() const
Definition: ednumber.cxx:552
static bool IsTOXBaseReadonly(const SwTOXBase &rTOXBase)
Definition: edtox.cxx:92
void SetModified()
Definition: edws.cxx:70
const SwSectionFormat & GetSectionFormat(size_t nFormat) const
Definition: edsect.cxx:142
bool OutlineUpDown(short nOffset=1)
Definition: ednumber.cxx:520
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
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:622
bool MoveOutlinePara(SwOutlineNodes::difference_type nOffset)
Definition: ednumber.cxx:543
bool DeleteTOX(const SwTOXBase &rTOXBase, bool bDelNodes)
Definition: edtox.cxx:196
void SetTOXBaseReadonly(const SwTOXBase &rTOXBase, bool bReadonly)
Definition: edtox.cxx:99
void EndAllAction()
Definition: edws.cxx:97
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:61
const SwView & GetView() const
Definition: edtwin.hxx:246
std::vector< SwFrameFormat const * > GetFlyFrameFormats(FlyCntType eType, bool bIgnoreTextBoxes)
Definition: feshview.cxx:2561
OUString GetFlyName() const
Definition: fefly1.cxx:1481
bool IsFrameSelected() const
Definition: feshview.cxx:1133
size_t GetFlyCount(FlyCntType eType, bool bIgnoreTextBoxes=false) const
Iterate over flys - for Basic-collections.
Definition: feshview.cxx:2551
bool DeleteRow(bool bCompleteTable=false)
Definition: fetab.cxx:382
void EndTextEdit()
Deletes object if required.
Definition: feshview.cxx:1193
size_t IsObjSelected() const
Definition: feshview.cxx:1125
bool SelectObj(const Point &rSelPt, sal_uInt8 nFlag=0, SdrObject *pObj=nullptr)
If an object has been given, exactly this object is selected (instead of searching over position).
Definition: feshview.cxx:161
const SwPageDesc & GetPageDesc(size_t i) const
Definition: fedesc.cxx:126
void GetSubTypes(SwFieldTypesEnum nId, std::vector< OUString > &rToFill)
Definition: fldmgr.cxx:573
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:247
SwFieldIds Which() const
Definition: fldbas.hxx:276
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:205
Base class of all fields.
Definition: fldbas.hxx:296
SwFieldTypesEnum GetTypeId() const
Definition: fldbas.cxx:270
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:355
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:491
virtual OUString GetFieldName() const
get name or content
Definition: fldbas.cxx:318
virtual OUString GetDescription() const
Definition: fldbas.cxx:909
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const SwField * GetField() const
Definition: fmtfld.hxx:131
bool IsProtect() const
Definition: atrfld.cxx:467
const SwTextField * GetTextField() const
Definition: fmtfld.hxx:149
SfxPoolItem subclass for footnotes and endnotes, stored in the anchor text node.
Definition: fmtftn.hxx:47
OUString GetViewNumStr(const SwDoc &rDoc, SwRootFrame const *pLayout, bool bInclStrings=false) const
Returns string to be displayed of footnote / endnote.
Definition: atrftn.cxx:218
bool IsEndNote() const
Definition: fmtftn.hxx:75
const SwTextRefMark * GetTextRefMark() const
Definition: fmtrfmrk.hxx:61
OUString & GetRefName()
Definition: fmtrfmrk.hxx:63
const SvxFrameDirectionItem & GetFrameDir(bool=true) const
Definition: frmatr.hxx:118
const OUString & GetName() const
Definition: format.hxx:131
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
virtual Value FindFormatByName(const OUString &rName) const override
Definition: docary.hxx:166
const SwRect & getFrameArea() const
Definition: frame.hxx:179
Style of a layout element.
Definition: frmfmt.hxx:72
virtual bool IsVisible() const
Definition: atrfrm.cxx:3631
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2749
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsFlowFrame() const
Definition: frame.hxx:1248
bool IsRefToNumItemCrossRefBookmark() const
Definition: reffld.cxx:386
bool IsRefToHeadingCrossRefBookmark() const
Definition: reffld.cxx:380
OUString GetExpandedTextOfReferencedTextNode(SwRootFrame const &rLayout) const
Definition: reffld.cxx:413
virtual ~SwGraphicContent() override
Definition: content.cxx:238
static SwView * GetNextView(SwView const *)
Definition: swmodul1.cxx:128
static SwView * GetFirstView()
Definition: swmodul1.cxx:121
void SetContentTypeTrack(ContentTypeId eCntTypeId, const bool bSet)
Definition: navicfg.hxx:118
void SetActiveBlock(sal_Int32 nSet)
Definition: navicfg.hxx:79
void SetOutlineTracking(sal_Int32 nSet)
Definition: navicfg.hxx:106
void SetRootType(ContentTypeId nSet)
Definition: navicfg.hxx:52
sal_Int32 GetActiveBlock() const
Definition: navicfg.hxx:78
void SetOutlineLevel(sal_Int32 nSet)
Definition: navicfg.hxx:61
sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt)
Definition: navipi.cxx:1026
RegionMode GetRegionDropMode() const
Definition: navipi.hxx:154
void MoveOutline(SwOutlineNodes::size_type nSource, SwOutlineNodes::size_type nTarget)
Definition: navipi.cxx:73
sal_Int8 AcceptDrop()
Definition: navipi.cxx:1011
void UpdateListBox()
Definition: navipi.cxx:885
std::unique_ptr< weld::Toolbar > m_xContent5ToolBox
Definition: navipi.hxx:58
static OUString CleanEntry(const OUString &rEntry)
Definition: navipi.cxx:58
void SetRegionDropMode(RegionMode nNewMode)
Definition: navipi.cxx:1068
std::unique_ptr< weld::Toolbar > m_xContent6ToolBox
Definition: navipi.hxx:59
SwFrame * NextFrame()
Definition: node2lay.cxx:495
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset nIdx)
Definition: ndindex.hxx:114
Base class of the Writer document model elements.
Definition: node.hxx:98
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:738
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
bool IsTextNode() const
Definition: node.hxx:190
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:968
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:236
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc....
Definition: nodes.cxx:2555
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
SwOutlineNodes::size_type GetOutlinePos() const
Definition: content.hxx:54
static constexpr auto npos
Definition: ndarr.hxx:81
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
const SwPosition * GetPoint() const
Definition: pam.hxx:253
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:238
virtual bool IsProtect() const override
Definition: content.cxx:228
const SwFormatField * m_pField
Definition: content.hxx:126
const SwFormatField * GetPostIt() const
Definition: content.hxx:136
void Delete(const OUString &aAuthor)
Definition: PostItMgr.cxx:1510
const_iterator begin() const
Definition: PostItMgr.hxx:180
void Hide(std::u16string_view rAuthor)
Definition: PostItMgr.cxx:1740
std::vector< std::unique_ptr< SwSidebarItem > >::const_iterator const_iterator
Definition: PostItMgr.hxx:179
void SetActiveSidebarWin(sw::annotation::SwAnnotationWin *p)
Definition: PostItMgr.cxx:2200
const_iterator end() const
Definition: PostItMgr.hxx:181
void AssureStdModeAtShell()
Definition: PostItMgr.cxx:2348
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
bool IsEmpty() const
Definition: swrect.hxx:304
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
OUString Apply(const OUString &rStr) const
Definition: SwRewriter.cxx:39
SwSection * GetSection() const
Definition: section.cxx:646
SwSectionFormat * GetParent() const
Definition: section.hxx:360
virtual bool IsVisible() const override
Definition: section.cxx:813
SwSectionNode * GetSectionNode()
Definition: section.cxx:923
bool IsInNodesArr() const
Definition: section.cxx:885
Array of Undo-history.
Definition: docary.hxx:193
A section node represents the start of a section on the UI, i.e.
Definition: node.hxx:575
bool IsHiddenFlag() const
Definition: section.hxx:190
const OUString & GetSectionName() const
Definition: section.hxx:171
SectionType GetType() const
Definition: section.hxx:173
virtual ~SwTOXBaseContent() override
Definition: content.cxx:242
const OUString & GetTOXName() const
Definition: tox.hxx:481
virtual bool IsVisible() const
Definition: tox.hxx:565
bool IsTOXBaseInReadonly() const
Definition: doctxm.cxx:2095
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
SwTableNode * GetTableNode() const
Definition: swtable.cxx:2315
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:2308
::sw::mark::IMark * GetAnnotationMark() const
Definition: atrfld.cxx:784
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
const SwFormatField * GetFormatField() const
Definition: content.hxx:105
virtual bool IsProtect() const override
Definition: content.cxx:223
const SwFormatField * m_pFormatField
Definition: content.hxx:95
SwTextNode & GetTextNode() const
Definition: txtfld.hxx:53
static void DeleteTextField(const SwTextField &rTextField)
Definition: atrfld.cxx:654
static void GetPamForTextField(const SwTextField &rTextField, std::shared_ptr< SwPaM > &rPamForTextField)
Definition: atrfld.cxx:634
const SwTextFootnote * GetTextFootnote() const
Definition: content.hxx:121
SwTextAttr subclass for footnotes and endnotes.
Definition: txtftn.hxx:34
const SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:43
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:72
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the view rectangle for the rPos model position.
Definition: frmcrsr.cxx:178
SwTextAttr subclass that tracks the location of the wrapped SwFormatURL.
Definition: txtinet.hxx:30
bool IsProtect() const
Definition: txtatr2.cxx:174
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:291
SwNumberTree::tNumberVector GetNumberVector(SwRootFrame const *pLayout=nullptr, SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Definition: ndtxt.cxx:4125
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4248
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2989
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4168
void SetAttrOutlineContentVisible(bool bVisible)
Definition: ndtxt.cxx:4191
const SwTextNode & GetTextNode() const
Definition: txtrfmrk.hxx:50
virtual ~SwTypeNumber()
Definition: content.cxx:214
const SwTextINetFormat * GetINetAttr() const
Definition: content.hxx:90
const SwTextINetFormat * m_pINetAttr
Definition: content.hxx:77
virtual bool IsProtect() const override
Definition: content.cxx:233
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:67
size_t size() const
Definition: docary.hxx:88
bool IsViewLocked() const
Definition: viewsh.hxx:490
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2817
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2181
const IDocumentMarkAccess * getIDocumentMarkAccess() const
Provides access to the document bookmark interface.
Definition: viewsh.cxx:2821
bool ActionPend() const
Definition: viewsh.hxx:225
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
vcl::Window * GetWin() const
Definition: viewsh.hxx:364
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2823
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
void LockView(bool b)
Definition: viewsh.hxx:491
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2844
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:648
SdrView * GetDrawView()
Definition: vnew.cxx:386
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
virtual SdrView * GetDrawView() const override
Definition: viewdraw.cxx:621
const tools::Rectangle & GetVisArea() const
Definition: view.hxx:436
SwPostItMgr * GetPostItMgr()
Definition: view.hxx:650
void StopShellTimer()
Definition: view.cxx:1836
SwWrtShell * GetWrtShellPtr() const
Definition: view.hxx:424
SwEditWin & GetEditWin()
Definition: view.hxx:426
SwDocShell * GetDocShell()
Definition: view.cxx:1193
void SetVisArea(const tools::Rectangle &, bool bUpdateScrollbar=true)
Definition: viewport.cxx:198
void LeaveDrawCreate()
Definition: view.hxx:549
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
bool IsSelFrameMode() const
Definition: wrtsh.hxx:177
void EnterSelFrameMode(const Point *pStartDrag=nullptr)
Definition: select.cxx:711
void GotoFormatField(const SwFormatField &rField)
Definition: move.cxx:740
bool Right(SwCursorSkipMode nMode, bool bSelect, sal_uInt16 nCount, bool bBasicCall, bool bVisual=false)
Definition: move.cxx:127
bool GotoNextTOXBase(const OUString *pName=nullptr)
Definition: move.cxx:722
bool GotoDrawingObject(std::u16string_view rName)
Definition: move.cxx:670
void EndSelect()
Definition: select.cxx:434
void LeaveSelFrameMode()
Definition: select.cxx:729
bool IsOutlineContentVisible(const size_t nPos)
Definition: wrtsh1.cxx:2330
bool GetAttrOutlineContentVisible(const size_t nPos) const
Definition: wrtsh1.cxx:2637
bool GotoPage(sal_uInt16 nPage, bool bRecord)
Definition: move.cxx:611
void LeaveAddMode()
Definition: select.cxx:650
void GotoMark(const ::sw::mark::IMark *const pMark)
Definition: wrtsh3.cxx:272
bool Left(SwCursorSkipMode nMode, bool bSelect, sal_uInt16 nCount, bool bBasicCall, bool bVisual=false)
Definition: move.cxx:110
bool GotoFly(const OUString &rName, FlyCntType eType=FLYCNTTYPE_ALL, bool bSelFrame=true)
Definition: move.cxx:637
bool GotoINetAttr(const SwTextINetFormat &rAttr)
Definition: move.cxx:646
SelectionType GetSelectionType() const
Definition: wrtsh1.cxx:1723
void EnterStdMode()
Definition: select.cxx:560
bool GotoTable(const OUString &rName)
Definition: move.cxx:731
void GotoFootnoteAnchor(const SwTextFootnote &rTextFootnote)
Definition: move.cxx:747
bool GotoRegion(std::u16string_view rName)
Definition: move.cxx:703
void GotoOutline(SwOutlineNodes::size_type nIdx)
Definition: move.cxx:655
bool DelRight(bool isReplaceHeuristic=false)
Definition: delete.cxx:285
bool HasSelection() const
Definition: wrtsh.hxx:147
virtual void DrawSelChanged() override
Definition: wrtsh3.cxx:243
bool GotoRefMark(const OUString &rRefMark, sal_uInt16 nSubType=0, sal_uInt16 nSeqNo=0)
Definition: move.cxx:712
void SttSelect()
Definition: select.cxx:394
void UnSelectFrame()
Definition: select.cxx:332
void InvalidateOutlineContentVisibility()
Definition: wrtsh1.cxx:2543
void EnterAddMode()
Definition: select.cxx:635
bool Pop(SwCursorShell::PopMode, ::std::optional< SwCallLink > &roLink)
Definition: wrtsh1.cxx:2047
const SwView & GetView() const
Definition: wrtsh.hxx:443
SwView * GetView()
Definition: unotxvw.hxx:138
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
void CopyINetBookmark(const INetBookmark &rBkmk)
void CopyByteString(SotClipboardFormatId nFormatId, const OString &rStr)
bool GetString(SotClipboardFormatId nFormat, OUString &rStr) const
const Value & back() const
std::vector< Value >::difference_type difference_type
const_iterator begin() const
const_iterator end() const
size_type size() const
constexpr tools::Long Top() const
constexpr tools::Long Right() const
tools::Long getX() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
bool IsMod1() const
sal_uInt16 GetCode() const
sal_uInt16 GetModifier() const
bool IsShift() const
void GrabFocus()
bool HasFocus() const
virtual void KeyInput(const KeyEvent &rKEvt)
virtual void set_label(const OUString &rIdent, const OUString &rLabel)=0
virtual void set_sensitive(const OUString &rIdent, bool bSensitive)=0
virtual void set_item_active(const OUString &rIdent, bool bActive)=0
virtual void scroll_to_row(int row)=0
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const=0
virtual bool get_selected(TreeIter *pIter) const=0
virtual void expand_row(const TreeIter &rIter)=0
virtual bool get_row_expanded(const TreeIter &rIter) const=0
virtual OUString get_text(int row, int col=-1) const=0
virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter *pResult, bool bDnDMode, bool bAutoScroll=true)=0
virtual bool get_iter_first(TreeIter &rIter) const=0
virtual bool is_selected(int pos) const=0
virtual bool iter_next_sibling(TreeIter &rIter) const=0
virtual void select(int pos)=0
virtual bool iter_next(TreeIter &rIter) const=0
virtual int iter_compare(const TreeIter &a, const TreeIter &b) const=0
virtual void collapse_row(const TreeIter &rIter)=0
virtual bool iter_children(TreeIter &rIter) const=0
virtual bool get_children_on_demand(const TreeIter &rIter) const=0
virtual bool iter_has_child(const TreeIter &rIter) const=0
virtual void set_cursor(int pos)=0
virtual int get_iter_depth(const TreeIter &rIter) const=0
virtual int count_selected_rows() const=0
virtual OUString get_id(int pos) const=0
#define FN_OUTLINE_TO_CLIPBOARD
Definition: cmdid.h:72
#define FN_EDIT_BOOKMARK
Definition: cmdid.h:325
#define FN_EDIT_REGION
Definition: cmdid.h:117
#define FN_FORMAT_FRAME_DLG
Definition: cmdid.h:353
#define FN_POSTIT
Definition: cmdid.h:233
#define FN_FORMAT_FOOTNOTE_DLG
Definition: cmdid.h:358
#define FN_FORMAT_GRAFIC_DLG
Definition: cmdid.h:354
#define FN_FORMAT_TABLE_DLG
Definition: cmdid.h:355
#define FN_NAME_SHAPE
Definition: cmdid.h:473
#define FN_TABLE_SELECT_ALL
Definition: cmdid.h:394
#define FN_INSERT_MULTI_TOX
Definition: cmdid.h:303
#define FN_EDIT_FIELD
Definition: cmdid.h:77
IMPL_LINK(SwContentTree, MousePressHdl, const MouseEvent &, rMEvt, bool)
Definition: content.cxx:1152
IMPL_LINK_NOARG(SwContentTree, ContentDoubleClickHdl, weld::TreeView &, bool)
Definition: content.cxx:2346
static void * lcl_GetOutlineKey(SwContentTree &rTree, SwOutlineContent const *pContent)
Definition: content.cxx:1279
static void lcl_SetOutlineContentEntriesSensitivities(SwContentTree *pThis, const weld::TreeView &rContentTree, const weld::TreeIter &rEntry, weld::Menu &rPop)
Definition: content.cxx:1417
static void lcl_SelectByContentTypeAndName(SwContentTree *pThis, weld::TreeView &rContentTree, std::u16string_view rContentTypeName, std::u16string_view rName)
Definition: content.cxx:3647
#define CTYPE_CNT
Definition: content.cxx:119
const TranslateId STR_CONTEXT_ARY[]
Definition: content.cxx:1051
static void lcl_CalcOverlayRanges(const SwTextFrame *pStartFrame, const SwTextFrame *pEndFrame, const SwPosition &aStartPos, const SwPosition &aEndPos, std::vector< basegfx::B2DRange > &aRanges)
Definition: content.cxx:5898
static void lcl_AssureStdModeAtShell(SwWrtShell *pWrtShell)
Definition: content.cxx:5279
static void lcl_SelectDrawObjectByName(weld::TreeView &rContentTree, std::u16string_view rName)
Definition: content.cxx:3683
static bool lcl_InsertExpandCollapseAllItem(const weld::TreeView &rContentTree, const weld::TreeIter &rEntry, weld::Menu &rPop)
Definition: content.cxx:1407
static void lcl_SelectByContentTypeAndAddress(SwContentTree *pThis, weld::TreeView &rContentTree, ContentTypeId nType, const void *ptr)
Definition: content.cxx:3553
#define CTYPE_CTT
Definition: content.cxx:120
const TranslateId STR_CONTENT_TYPE_SINGLE_ARY[]
Definition: content.cxx:265
const TranslateId STR_CONTENT_TYPE_ARY[]
Definition: content.cxx:246
EditEntryMode
Definition: conttree.hxx:50
int nCount
virtual OUString GetName() const override
virtual OUString GetURL() const override
float u
std::vector< SwGetINetAttr > SwGetINetAttrs
Definition: editsh.hxx:128
EmbeddedObjectRef * pObject
#define SW_LEAVE_FRAME
Definition: fesh.hxx:168
UNKNOWN
constexpr OUStringLiteral IsReadOnly(u"IsReadOnly")
FlyCntType
Definition: flyenum.hxx:24
@ FLYCNTTYPE_GRF
Definition: flyenum.hxx:27
@ FLYCNTTYPE_OLE
Definition: flyenum.hxx:28
@ FLYCNTTYPE_FRM
Definition: flyenum.hxx:26
DocumentType eType
OUString sName
bool bReadOnly
constexpr OUStringLiteral HID_NAVIGATOR_TREELIST
Definition: helpids.h:32
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
const char * name
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
uno_Any a
constexpr sal_uInt16 KEY_RETURN
constexpr sal_uInt16 KEY_MOD2
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_MOD1
constexpr sal_uInt16 KEY_LEFT
constexpr sal_uInt16 KEY_UP
constexpr sal_uInt16 KEY_RIGHT
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_DOWN
constexpr sal_uInt16 KEY_SPACE
constexpr sal_uInt16 KEY_C
constexpr sal_uInt16 KEY_SHIFT
constexpr sal_uInt16 KEY_MULTIPLY
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
tools::Long tSwNumTreeNumber
std::vector< tSwNumTreeNumber > tNumberVector
SfxDispatcher * GetDispatcher()
size
OString stripStart(const OString &rIn, char c)
RegionMode
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
sal_Int64 toInt64(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
args
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Display
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
const SvxPageUsage aArr[]
long Long
size_t GetAbsPos(const weld::TreeView &rTreeView, const weld::TreeIter &rIter)
OUString toId(const void *pValue)
SwNodeType
Definition: ndtyp.hxx:28
sal_Int16 nId
SwMoveFnCollection const & fnRegionEnd
Definition: paminit.cxx:58
SwMoveFnCollection const & fnTableStart
Definition: paminit.cxx:54
SwMoveFnCollection const & fnRegionStart
Definition: paminit.cxx:57
QPRO_FUNC_TYPE nType
@ REF_FOOTNOTE
Definition: reffld.hxx:41
@ REF_ENDNOTE
Definition: reffld.hxx:42
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
SectionType
Definition: section.hxx:46
sal_uIntPtr sal_uLong
sal_Int8 mnAction
sal_uLong nWord
Definition: docstat.hxx:35
sal_uLong nChar
Definition: docstat.hxx:37
For querying the INet-attributes for Navigator.
Definition: editsh.hxx:120
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
SwNodeIndex nNode
Definition: pam.hxx:39
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
void AdjustContent(sal_Int32 nDelta)
Adjust content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:262
SwContentIndex nContent
Definition: pam.hxx:40
Reference< XController > xController
Reference< XModel > xModel
#define CONTEXT_COUNT
Definition: swcont.hxx:51
ContentTypeId
Definition: swcont.hxx:30
SwView * GetActiveView()
Definition: swmodul1.cxx:115
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
#define SW_MOD()
Definition: swmodule.hxx:254
const sal_Unicode cMarkSeparator
Definition: swtypes.hxx:124
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
bool bVisible
#define DND_ACTION_COPYMOVE
#define DND_ACTION_MOVE
#define DND_ACTION_LINK
#define DND_ACTION_NONE
bool GotoCurrRegionAndSkip(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosRegion, bool bInReadOnly)
Definition: trvlreg.cxx:181
bool GotoCurrTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:631
unsigned char sal_uInt8
signed char sal_Int8
OUString sId