Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/uibase/utlui/content.cxx
Warning:line 3036, column 14
Value stored to 'bListEntry' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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