| /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| /* |
| * This file is part of the LibreOffice project. |
| * |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| * |
| * This file incorporates work covered by the following license notice: |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
| */ |
| |
| #include <comphelper/string.hxx> |
| #include <svl/urlbmk.hxx> |
| #include <osl/thread.h> |
| #include <sal/log.hxx> |
| #include <tools/urlobj.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <sfx2/event.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <o3tl/enumrange.hxx> |
| #include <o3tl/sorted_vector.hxx> |
| #include <vcl/help.hxx> |
| #include <vcl/settings.hxx> |
| #include <sot/formats.hxx> |
| #include <uiitems.hxx> |
| #include <fmtinfmt.hxx> |
| #include <txtinet.hxx> |
| #include <fmtfld.hxx> |
| #include <swmodule.hxx> |
| #include <wrtsh.hxx> |
| #include <view.hxx> |
| #include <docsh.hxx> |
| #include <drawdoc.hxx> |
| #include <content.hxx> |
| #include <frmfmt.hxx> |
| #include <fldbas.hxx> |
| #include <IMark.hxx> |
| #include <section.hxx> |
| #include <tox.hxx> |
| #include <navipi.hxx> |
| #include <navicont.hxx> |
| #include <navicfg.hxx> |
| #include <edtwin.hxx> |
| #include <doc.hxx> |
| #include <IDocumentDrawModelAccess.hxx> |
| #include <IDocumentOutlineNodes.hxx> |
| #include <unotxvw.hxx> |
| #include <cmdid.h> |
| #include <helpids.h> |
| #include <strings.hrc> |
| #include <com/sun/star/text/XTextSectionsSupplier.hpp> |
| #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp> |
| #include <com/sun/star/text/XTextTablesSupplier.hpp> |
| #include <com/sun/star/text/XDocumentIndexesSupplier.hpp> |
| #include <com/sun/star/text/XDocumentIndex.hpp> |
| #include <com/sun/star/text/XBookmarksSupplier.hpp> |
| #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp> |
| #include <com/sun/star/text/XTextFramesSupplier.hpp> |
| #include <dcontact.hxx> |
| #include <svx/svdpage.hxx> |
| #include <svx/svdview.hxx> |
| #include <vcl/scrbar.hxx> |
| #include <SwRewriter.hxx> |
| #include <hints.hxx> |
| #include <numrule.hxx> |
| #include <swundo.hxx> |
| #include <ndtxt.hxx> |
| #include <PostItMgr.hxx> |
| #include <postithelper.hxx> |
| #include <vcl/treelistentry.hxx> |
| |
| #include <swabstdlg.hxx> |
| #include <bitmaps.hlst> |
| |
| #include <navmgr.hxx> |
| #include <AnnotationWin.hxx> |
| #include <memory> |
| |
| #define CTYPE_CNT 0 |
| #define CTYPE_CTT 1 |
| |
| using namespace ::std; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::text; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::container; |
| |
| namespace { |
| |
| constexpr char NAVI_BOOKMARK_DELIM = '\x01'; |
| |
| } |
| |
| class SwContentArr |
| : public o3tl::sorted_vector<std::unique_ptr<SwContent>, o3tl::less_uniqueptr_to<SwContent>, |
| o3tl::find_partialorder_ptrequals> |
| { |
| }; |
| |
| bool SwContentTree::bIsInDrag = false; |
| |
| namespace |
| { |
| bool lcl_IsContent(const SvTreeListEntry* pEntry) |
| { |
| return static_cast<const SwTypeNumber*>(pEntry->GetUserData())->GetTypeId() == CTYPE_CNT; |
| } |
| |
| bool lcl_IsContentType(const SvTreeListEntry* pEntry) |
| { |
| return static_cast<const SwTypeNumber*>(pEntry->GetUserData())->GetTypeId() == CTYPE_CTT; |
| } |
| |
| bool lcl_FindShell(SwWrtShell const * pShell) |
| { |
| bool bFound = false; |
| SwView *pView = SwModule::GetFirstView(); |
| while (pView) |
| { |
| if(pShell == &pView->GetWrtShell()) |
| { |
| bFound = true; |
| break; |
| } |
| pView = SwModule::GetNextView(pView); |
| } |
| return bFound; |
| } |
| |
| bool lcl_IsUiVisibleBookmark(const ::sw::mark::IMark* pMark) |
| { |
| return IDocumentMarkAccess::GetType(*pMark) == IDocumentMarkAccess::MarkType::BOOKMARK; |
| } |
| |
| size_t lcl_InsertURLFieldContent( |
| SwContentArr *pMember, |
| SwWrtShell* pWrtShell, |
| const SwContentType *pCntType) |
| { |
| SwGetINetAttrs aArr; |
| pWrtShell->GetINetAttrs( aArr ); |
| const SwGetINetAttrs::size_type nCount {aArr.size()}; |
| for( SwGetINetAttrs::size_type n = 0; n < nCount; ++n ) |
| { |
| SwGetINetAttr* p = &aArr[ n ]; |
| std::unique_ptr<SwURLFieldContent> pCnt(new SwURLFieldContent( |
| pCntType, |
| p->sText, |
| INetURLObject::decode( |
| p->rINetAttr.GetINetFormat().GetValue(), |
| INetURLObject::DecodeMechanism::Unambiguous ), |
| &p->rINetAttr, |
| n )); |
| pMember->insert( std::move(pCnt) ); |
| } |
| return nCount; |
| } |
| } |
| |
| // Content, contains names and reference at the content type. |
| |
| SwContent::SwContent(const SwContentType* pCnt, const OUString& rName, long nYPos) : |
| SwTypeNumber(CTYPE_CNT), |
| pParent(pCnt), |
| sContentName(rName), |
| nYPosition(nYPos), |
| bInvisible(false) |
| { |
| } |
| |
| |
| SwTypeNumber::~SwTypeNumber() |
| { |
| } |
| |
| bool SwContent::IsProtect() const |
| { |
| return false; |
| } |
| |
| bool SwPostItContent::IsProtect() const |
| { |
| return pField->IsProtect(); |
| } |
| |
| bool SwURLFieldContent::IsProtect() const |
| { |
| return pINetAttr->IsProtect(); |
| } |
| |
| SwGraphicContent::~SwGraphicContent() |
| { |
| } |
| |
| SwTOXBaseContent::~SwTOXBaseContent() |
| { |
| } |
| |
| static const char* STR_CONTENT_TYPE_ARY[] = |
| { |
| STR_CONTENT_TYPE_OUTLINE, |
| STR_CONTENT_TYPE_TABLE, |
| STR_CONTENT_TYPE_FRAME, |
| STR_CONTENT_TYPE_GRAPHIC, |
| STR_CONTENT_TYPE_OLE, |
| STR_CONTENT_TYPE_BOOKMARK, |
| STR_CONTENT_TYPE_REGION, |
| STR_CONTENT_TYPE_URLFIELD, |
| STR_CONTENT_TYPE_REFERENCE, |
| STR_CONTENT_TYPE_INDEX, |
| STR_CONTENT_TYPE_POSTIT, |
| STR_CONTENT_TYPE_DRAWOBJECT |
| }; |
| |
| static const char* STR_CONTENT_TYPE_SINGLE_ARY[] = |
| { |
| STR_CONTENT_TYPE_SINGLE_OUTLINE, |
| STR_CONTENT_TYPE_SINGLE_TABLE, |
| STR_CONTENT_TYPE_SINGLE_FRAME, |
| STR_CONTENT_TYPE_SINGLE_GRAPHIC, |
| STR_CONTENT_TYPE_SINGLE_OLE, |
| STR_CONTENT_TYPE_SINGLE_BOOKMARK, |
| STR_CONTENT_TYPE_SINGLE_REGION, |
| STR_CONTENT_TYPE_SINGLE_URLFIELD, |
| STR_CONTENT_TYPE_SINGLE_REFERENCE, |
| STR_CONTENT_TYPE_SINGLE_INDEX, |
| STR_CONTENT_TYPE_SINGLE_POSTIT, |
| STR_CONTENT_TYPE_SINGLE_DRAWOBJECT |
| }; |
| |
| namespace |
| { |
| bool checkVisibilityChanged( |
| const SwContentArr& rSwContentArrA, |
| const SwContentArr& rSwContentArrB) |
| { |
| if(rSwContentArrA.size() != rSwContentArrB.size()) |
| { |
| return true; |
| } |
| |
| for(size_t a(0); a < rSwContentArrA.size(); a++) |
| { |
| if(rSwContentArrA[a]->IsInvisible() != rSwContentArrB[a]->IsInvisible()) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| } // end of anonymous namespace |
| |
| SwContentType::SwContentType(SwWrtShell* pShell, ContentTypeId nType, sal_uInt8 nLevel) : |
| SwTypeNumber(CTYPE_CTT), |
| m_pWrtShell(pShell), |
| m_sContentTypeName(SwResId(STR_CONTENT_TYPE_ARY[static_cast<int>(nType)])), |
| m_sSingleContentTypeName(SwResId(STR_CONTENT_TYPE_SINGLE_ARY[static_cast<int>(nType)])), |
| m_nMemberCount(0), |
| m_nContentType(nType), |
| m_nOutlineLevel(nLevel), |
| m_bDataValid(false), |
| m_bEdit(false), |
| m_bDelete(true) |
| { |
| Init(); |
| } |
| |
| void SwContentType::Init(bool* pbInvalidateWindow) |
| { |
| // if the MemberCount is changing ... |
| size_t nOldMemberCount = m_nMemberCount; |
| m_nMemberCount = 0; |
| switch(m_nContentType) |
| { |
| case ContentTypeId::OUTLINE : |
| { |
| m_sTypeToken = "outline"; |
| m_nMemberCount = m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); |
| if (m_nMemberCount < MAXLEVEL) |
| { |
| const size_t nOutlineCount = m_nMemberCount; |
| for(size_t j = 0; j < nOutlineCount; ++j) |
| { |
| if (m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineLevel(j) > m_nOutlineLevel |
| || !m_pWrtShell->getIDocumentOutlineNodesAccess()->isOutlineInLayout(j, *m_pWrtShell->GetLayout())) |
| { |
| m_nMemberCount --; |
| } |
| } |
| } |
| } |
| break; |
| |
| case ContentTypeId::TABLE : |
| m_sTypeToken = "table"; |
| m_nMemberCount = m_pWrtShell->GetTableFrameFormatCount(true); |
| m_bEdit = true; |
| break; |
| |
| case ContentTypeId::FRAME : |
| case ContentTypeId::GRAPHIC : |
| case ContentTypeId::OLE : |
| { |
| FlyCntType eType = FLYCNTTYPE_FRM; |
| m_sTypeToken = "frame"; |
| if(m_nContentType == ContentTypeId::OLE) |
| { |
| eType = FLYCNTTYPE_OLE; |
| m_sTypeToken = "ole"; |
| } |
| else if(m_nContentType == ContentTypeId::GRAPHIC) |
| { |
| eType = FLYCNTTYPE_GRF; |
| m_sTypeToken = "graphic"; |
| } |
| m_nMemberCount = m_pWrtShell->GetFlyCount(eType, /*bIgnoreTextBoxes=*/true); |
| m_bEdit = true; |
| } |
| break; |
| case ContentTypeId::BOOKMARK: |
| { |
| IDocumentMarkAccess* const pMarkAccess = m_pWrtShell->getIDocumentMarkAccess(); |
| m_nMemberCount = count_if( |
| pMarkAccess->getBookmarksBegin(), |
| pMarkAccess->getBookmarksEnd(), |
| &lcl_IsUiVisibleBookmark); |
| m_sTypeToken.clear(); |
| m_bEdit = true; |
| } |
| break; |
| case ContentTypeId::REGION : |
| { |
| std::unique_ptr<SwContentArr> pOldMember; |
| if(!m_pMember) |
| m_pMember.reset( new SwContentArr ); |
| else if(!m_pMember->empty()) |
| { |
| pOldMember = std::move(m_pMember); |
| m_pMember.reset( new SwContentArr ); |
| } |
| const Point aNullPt; |
| m_nMemberCount = m_pWrtShell->GetSectionFormatCount(); |
| for(size_t i = 0; i < m_nMemberCount; ++i) |
| { |
| const SwSectionFormat* pFormat; |
| SectionType eTmpType; |
| if( (pFormat = &m_pWrtShell->GetSectionFormat(i))->IsInNodesArr() && |
| (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent |
| && SectionType::ToxHeader != eTmpType ) |
| { |
| const OUString& rSectionName = |
| pFormat->GetSection()->GetSectionName(); |
| sal_uInt8 nLevel = 0; |
| SwSectionFormat* pParentFormat = pFormat->GetParent(); |
| while(pParentFormat) |
| { |
| nLevel++; |
| pParentFormat = pParentFormat->GetParent(); |
| } |
| |
| std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, rSectionName, |
| nLevel, |
| pFormat->FindLayoutRect( false, &aNullPt ).Top())); |
| |
| SwPtrMsgPoolItem aAskItem( RES_CONTENT_VISIBLE, nullptr ); |
| if( !pFormat->GetInfo( aAskItem ) && |
| !aAskItem.pObject ) // not visible |
| pCnt->SetInvisible(); |
| m_pMember->insert(std::move(pCnt)); |
| } |
| } |
| m_nMemberCount = m_pMember->size(); |
| m_sTypeToken = "region"; |
| m_bEdit = true; |
| m_bDelete = false; |
| if(pOldMember) |
| { |
| if(nullptr != pbInvalidateWindow) |
| { |
| // need to check visibility (and equal entry number) after |
| // creation due to a sorted list being used here (before, |
| // entries with same index were compared already at creation |
| // time what worked before a sorted list was used) |
| *pbInvalidateWindow = checkVisibilityChanged( |
| *pOldMember, |
| *m_pMember); |
| } |
| } |
| } |
| break; |
| case ContentTypeId::INDEX: |
| { |
| m_nMemberCount = m_pWrtShell->GetTOXCount(); |
| m_bEdit = true; |
| m_bDelete = false; |
| } |
| break; |
| case ContentTypeId::REFERENCE: |
| { |
| m_nMemberCount = m_pWrtShell->GetRefMarks(); |
| m_bDelete = false; |
| } |
| break; |
| case ContentTypeId::URLFIELD: |
| { |
| m_nMemberCount = 0; |
| if(!m_pMember) |
| m_pMember.reset( new SwContentArr ); |
| else |
| m_pMember->clear(); |
| |
| m_nMemberCount = lcl_InsertURLFieldContent(m_pMember.get(), m_pWrtShell, this); |
| |
| m_bEdit = true; |
| nOldMemberCount = m_nMemberCount; |
| m_bDelete = false; |
| } |
| break; |
| case ContentTypeId::POSTIT: |
| { |
| m_nMemberCount = 0; |
| if(!m_pMember) |
| m_pMember.reset( new SwContentArr ); |
| else |
| m_pMember->clear(); |
| |
| SwPostItMgr* aMgr = m_pWrtShell->GetView().GetPostItMgr(); |
| if (aMgr) |
| { |
| for(SwPostItMgr::const_iterator i = aMgr->begin(); i != aMgr->end(); ++i) |
| { |
| if (const SwFormatField* pFormatField = dynamic_cast<const SwFormatField *>((*i)->GetBroadcaster())) // SwPostit |
| { |
| if (pFormatField->GetTextField() && pFormatField->IsFieldInDoc() && |
| (*i)->mLayoutStatus!=SwPostItHelper::INVISIBLE ) |
| { |
| OUString sEntry = pFormatField->GetField()->GetPar2(); |
| sEntry = RemoveNewline(sEntry); |
| std::unique_ptr<SwPostItContent> pCnt(new SwPostItContent( |
| this, |
| sEntry, |
| pFormatField, |
| m_nMemberCount)); |
| m_pMember->insert(std::move(pCnt)); |
| m_nMemberCount++; |
| } |
| } |
| } |
| } |
| m_sTypeToken.clear(); |
| m_bEdit = true; |
| nOldMemberCount = m_nMemberCount; |
| } |
| break; |
| case ContentTypeId::DRAWOBJECT: |
| { |
| m_sTypeToken.clear(); |
| m_bEdit = true; |
| m_nMemberCount = 0; |
| SwDrawModel* pModel = m_pWrtShell->getIDocumentDrawModelAccess().GetDrawModel(); |
| if(pModel) |
| { |
| SdrPage* pPage = pModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| SdrObject* pTemp = pPage->GetObj(i); |
| // #i51726# - all drawing objects can be named now |
| if (!pTemp->GetName().isEmpty()) |
| m_nMemberCount++; |
| } |
| } |
| } |
| break; |
| default: break; |
| } |
| // ... then, the data can also no longer be valid, |
| // apart from those which have already been corrected, |
| // then nOldMemberCount is nevertheless not so old. |
| if( nOldMemberCount != m_nMemberCount ) |
| m_bDataValid = false; |
| } |
| |
| SwContentType::~SwContentType() |
| { |
| } |
| |
| const SwContent* SwContentType::GetMember(size_t nIndex) |
| { |
| if(!m_bDataValid || !m_pMember) |
| { |
| FillMemberList(); |
| } |
| if(nIndex < m_pMember->size()) |
| return (*m_pMember)[nIndex].get(); |
| |
| return nullptr; |
| } |
| |
| void SwContentType::Invalidate() |
| { |
| m_bDataValid = false; |
| } |
| |
| void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged) |
| { |
| std::unique_ptr<SwContentArr> pOldMember; |
| size_t nOldMemberCount = 0; |
| SwPtrMsgPoolItem aAskItem( RES_CONTENT_VISIBLE, nullptr ); |
| if(m_pMember && pbLevelOrVisibilityChanged) |
| { |
| pOldMember = std::move(m_pMember); |
| nOldMemberCount = pOldMember->size(); |
| m_pMember.reset( new SwContentArr ); |
| *pbLevelOrVisibilityChanged = false; |
| } |
| else if(!m_pMember) |
| m_pMember.reset( new SwContentArr ); |
| else |
| m_pMember->clear(); |
| switch(m_nContentType) |
| { |
| case ContentTypeId::OUTLINE : |
| { |
| const size_t nOutlineCount = m_nMemberCount = |
| m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); |
| |
| size_t nPos = 0; |
| for (size_t i = 0; i < nOutlineCount; ++i) |
| { |
| const sal_Int8 nLevel = static_cast<sal_Int8>(m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineLevel(i)); |
| if(nLevel >= m_nOutlineLevel ) |
| m_nMemberCount--; |
| else |
| { |
| if (!m_pWrtShell->getIDocumentOutlineNodesAccess()->isOutlineInLayout(i, *m_pWrtShell->GetLayout())) |
| { |
| --m_nMemberCount; |
| continue; // don't hide it, just skip it |
| } |
| OUString aEntry(comphelper::string::stripStart( |
| m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(i, m_pWrtShell->GetLayout()), ' ')); |
| aEntry = SwNavigationPI::CleanEntry(aEntry); |
| std::unique_ptr<SwOutlineContent> pCnt(new SwOutlineContent(this, aEntry, i, nLevel, |
| m_pWrtShell->IsOutlineMovable( i ), nPos )); |
| m_pMember->insert(std::move(pCnt)); |
| // with the same number and existing "pOldMember" the |
| // old one is compared with the new OutlinePos. |
| if (nOldMemberCount > nPos && static_cast<SwOutlineContent*>((*pOldMember)[nPos].get())->GetOutlineLevel() != nLevel) |
| *pbLevelOrVisibilityChanged = true; |
| |
| nPos++; |
| } |
| } |
| |
| } |
| break; |
| |
| case ContentTypeId::TABLE : |
| { |
| const size_t nCount = m_pWrtShell->GetTableFrameFormatCount(true); |
| OSL_ENSURE(m_nMemberCount == nCount, "MemberCount differs"); |
| Point aNullPt; |
| m_nMemberCount = nCount; |
| for(size_t i = 0; i < m_nMemberCount; ++i) |
| { |
| const SwFrameFormat& rTableFormat = m_pWrtShell->GetTableFrameFormat(i, true); |
| const OUString& sTableName( rTableFormat.GetName() ); |
| |
| SwContent* pCnt = new SwContent(this, sTableName, |
| rTableFormat.FindLayoutRect(false, &aNullPt).Top() ); |
| if( !rTableFormat.GetInfo( aAskItem ) && |
| !aAskItem.pObject ) // not visible |
| pCnt->SetInvisible(); |
| |
| m_pMember->insert(std::unique_ptr<SwContent>(pCnt)); |
| |
| if(nOldMemberCount > i && |
| (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible()) |
| *pbLevelOrVisibilityChanged = true; |
| } |
| } |
| break; |
| case ContentTypeId::OLE : |
| case ContentTypeId::FRAME : |
| case ContentTypeId::GRAPHIC : |
| { |
| FlyCntType eType = FLYCNTTYPE_FRM; |
| if(m_nContentType == ContentTypeId::OLE) |
| eType = FLYCNTTYPE_OLE; |
| else if(m_nContentType == ContentTypeId::GRAPHIC) |
| eType = FLYCNTTYPE_GRF; |
| Point aNullPt; |
| m_nMemberCount = m_pWrtShell->GetFlyCount(eType, /*bIgnoreTextBoxes=*/true); |
| std::vector<SwFrameFormat const*> formats(m_pWrtShell->GetFlyFrameFormats(eType, /*bIgnoreTextBoxes=*/true)); |
| SAL_WARN_IF(m_nMemberCount != formats.size(), "sw.ui", "MemberCount differs"); |
| m_nMemberCount = formats.size(); |
| for (size_t i = 0; i < m_nMemberCount; ++i) |
| { |
| SwFrameFormat const*const pFrameFormat = formats[i]; |
| const OUString sFrameName = pFrameFormat->GetName(); |
| |
| SwContent* pCnt; |
| if(ContentTypeId::GRAPHIC == m_nContentType) |
| { |
| OUString sLink; |
| m_pWrtShell->GetGrfNms( &sLink, nullptr, static_cast<const SwFlyFrameFormat*>( pFrameFormat)); |
| pCnt = new SwGraphicContent(this, sFrameName, |
| INetURLObject::decode( sLink, |
| INetURLObject::DecodeMechanism::Unambiguous ), |
| pFrameFormat->FindLayoutRect(false, &aNullPt).Top()); |
| } |
| else |
| { |
| pCnt = new SwContent(this, sFrameName, |
| pFrameFormat->FindLayoutRect(false, &aNullPt).Top() ); |
| } |
| if( !pFrameFormat->GetInfo( aAskItem ) && |
| !aAskItem.pObject ) // not visible |
| pCnt->SetInvisible(); |
| m_pMember->insert(std::unique_ptr<SwContent>(pCnt)); |
| if (nOldMemberCount > i && |
| (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible()) |
| *pbLevelOrVisibilityChanged = true; |
| } |
| } |
| break; |
| case ContentTypeId::BOOKMARK: |
| { |
| IDocumentMarkAccess* const pMarkAccess = m_pWrtShell->getIDocumentMarkAccess(); |
| for(IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin(); |
| ppBookmark != pMarkAccess->getBookmarksEnd(); |
| ++ppBookmark) |
| { |
| if(lcl_IsUiVisibleBookmark(*ppBookmark)) |
| { |
| const OUString& rBkmName = (*ppBookmark)->GetName(); |
| //nYPos from 0 -> text::Bookmarks will be sorted alphabetically |
| std::unique_ptr<SwContent> pCnt(new SwContent(this, rBkmName, 0)); |
| m_pMember->insert(std::move(pCnt)); |
| } |
| } |
| } |
| break; |
| case ContentTypeId::REGION : |
| { |
| const Point aNullPt; |
| m_nMemberCount = m_pWrtShell->GetSectionFormatCount(); |
| for(size_t i = 0; i < m_nMemberCount; ++i) |
| { |
| const SwSectionFormat* pFormat; |
| SectionType eTmpType; |
| if( (pFormat = &m_pWrtShell->GetSectionFormat(i))->IsInNodesArr() && |
| (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent |
| && SectionType::ToxHeader != eTmpType ) |
| { |
| OUString sSectionName = pFormat->GetSection()->GetSectionName(); |
| |
| sal_uInt8 nLevel = 0; |
| SwSectionFormat* pParentFormat = pFormat->GetParent(); |
| while(pParentFormat) |
| { |
| nLevel++; |
| pParentFormat = pParentFormat->GetParent(); |
| } |
| |
| std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, sSectionName, |
| nLevel, |
| pFormat->FindLayoutRect( false, &aNullPt ).Top())); |
| if( !pFormat->GetInfo( aAskItem ) && |
| !aAskItem.pObject ) // not visible |
| pCnt->SetInvisible(); |
| m_pMember->insert(std::move(pCnt)); |
| } |
| |
| if(nullptr != pbLevelOrVisibilityChanged) |
| { |
| assert(pOldMember); |
| // need to check visibility (and equal entry number) after |
| // creation due to a sorted list being used here (before, |
| // entries with same index were compared already at creation |
| // time what worked before a sorted list was used) |
| *pbLevelOrVisibilityChanged = checkVisibilityChanged( |
| *pOldMember, |
| *m_pMember); |
| } |
| } |
| m_nMemberCount = m_pMember->size(); |
| } |
| break; |
| case ContentTypeId::REFERENCE: |
| { |
| std::vector<OUString> aRefMarks; |
| m_nMemberCount = m_pWrtShell->GetRefMarks( &aRefMarks ); |
| |
| for (const auto& rRefMark : aRefMarks) |
| { |
| // References sorted alphabetically |
| m_pMember->insert(std::make_unique<SwContent>(this, rRefMark, 0)); |
| } |
| } |
| break; |
| case ContentTypeId::URLFIELD: |
| m_nMemberCount = lcl_InsertURLFieldContent(m_pMember.get(), m_pWrtShell, this); |
| break; |
| case ContentTypeId::INDEX: |
| { |
| |
| const sal_uInt16 nCount = m_pWrtShell->GetTOXCount(); |
| m_nMemberCount = nCount; |
| for ( sal_uInt16 nTox = 0; nTox < nCount; nTox++ ) |
| { |
| const SwTOXBase* pBase = m_pWrtShell->GetTOX( nTox ); |
| OUString sTOXNm( pBase->GetTOXName() ); |
| |
| SwContent* pCnt = new SwTOXBaseContent( |
| this, sTOXNm, nTox, *pBase); |
| |
| if( !pBase->GetInfo( aAskItem ) && |
| !aAskItem.pObject ) // not visible |
| pCnt->SetInvisible(); |
| |
| m_pMember->insert( std::unique_ptr<SwContent>(pCnt) ); |
| const size_t nPos = m_pMember->size() - 1; |
| if(nOldMemberCount > nPos && |
| (*pOldMember)[nPos]->IsInvisible() |
| != pCnt->IsInvisible()) |
| *pbLevelOrVisibilityChanged = true; |
| } |
| } |
| break; |
| case ContentTypeId::POSTIT: |
| { |
| m_nMemberCount = 0; |
| m_pMember->clear(); |
| SwPostItMgr* aMgr = m_pWrtShell->GetView().GetPostItMgr(); |
| if (aMgr) |
| { |
| for(SwPostItMgr::const_iterator i = aMgr->begin(); i != aMgr->end(); ++i) |
| { |
| if (const SwFormatField* pFormatField = dynamic_cast<const SwFormatField *>((*i)->GetBroadcaster())) // SwPostit |
| { |
| if (pFormatField->GetTextField() && pFormatField->IsFieldInDoc() && |
| (*i)->mLayoutStatus!=SwPostItHelper::INVISIBLE ) |
| { |
| OUString sEntry = pFormatField->GetField()->GetPar2(); |
| sEntry = RemoveNewline(sEntry); |
| std::unique_ptr<SwPostItContent> pCnt(new SwPostItContent( |
| this, |
| sEntry, |
| pFormatField, |
| m_nMemberCount)); |
| m_pMember->insert(std::move(pCnt)); |
| m_nMemberCount++; |
| } |
| } |
| } |
| } |
| } |
| break; |
| case ContentTypeId::DRAWOBJECT: |
| { |
| m_nMemberCount = 0; |
| m_pMember->clear(); |
| |
| IDocumentDrawModelAccess& rIDDMA = m_pWrtShell->getIDocumentDrawModelAccess(); |
| SwDrawModel* pModel = rIDDMA.GetDrawModel(); |
| if(pModel) |
| { |
| SdrPage* pPage = pModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| SdrObject* pTemp = pPage->GetObj(i); |
| // #i51726# - all drawing objects can be named now |
| if (!pTemp->GetName().isEmpty()) |
| { |
| SwContact* pContact = static_cast<SwContact*>(pTemp->GetUserCall()); |
| long nYPos = 0; |
| const Point aNullPt; |
| if(pContact && pContact->GetFormat()) |
| nYPos = pContact->GetFormat()->FindLayoutRect(false, &aNullPt).Top(); |
| SwContent* pCnt = new SwContent( |
| this, |
| pTemp->GetName(), |
| nYPos); |
| if(!rIDDMA.IsVisibleLayerId(pTemp->GetLayer())) |
| pCnt->SetInvisible(); |
| m_pMember->insert(std::unique_ptr<SwContent>(pCnt)); |
| m_nMemberCount++; |
| if (nOldMemberCount > i && |
| (*pOldMember)[i]->IsInvisible() != pCnt->IsInvisible() ) |
| *pbLevelOrVisibilityChanged = true; |
| } |
| } |
| } |
| } |
| break; |
| default: break; |
| } |
| m_bDataValid = true; |
| } |
| |
| namespace { |
| |
| enum STR_CONTEXT_IDX |
| { |
| IDX_STR_OUTLINE_LEVEL = 0, |
| IDX_STR_DRAGMODE = 1, |
| IDX_STR_HYPERLINK = 2, |
| IDX_STR_LINK_REGION = 3, |
| IDX_STR_COPY_REGION = 4, |
| IDX_STR_DISPLAY = 5, |
| IDX_STR_ACTIVE_VIEW = 6, |
| IDX_STR_HIDDEN = 7, |
| IDX_STR_ACTIVE = 8, |
| IDX_STR_INACTIVE = 9, |
| IDX_STR_EDIT_ENTRY = 10, |
| IDX_STR_DELETE_ENTRY = 11, |
| IDX_STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY = 12 |
| }; |
| |
| } |
| |
| static const char* STR_CONTEXT_ARY[] = |
| { |
| STR_OUTLINE_LEVEL, |
| STR_DRAGMODE, |
| STR_HYPERLINK, |
| STR_LINK_REGION, |
| STR_COPY_REGION, |
| STR_DISPLAY, |
| STR_ACTIVE_VIEW, |
| STR_HIDDEN, |
| STR_ACTIVE, |
| STR_INACTIVE, |
| STR_EDIT_ENTRY, |
| STR_DELETE_ENTRY, |
| STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY |
| }; |
| |
| SwContentTree::SwContentTree(vcl::Window* pParent, SwNavigationPI* pDialog) |
| : SvTreeListBox(pParent) |
| , m_xDialog(pDialog) |
| , m_sSpace(OUString(" ")) |
| , m_sRemoveIdx(SwResId(STR_REMOVE_INDEX)) |
| , m_sUpdateIdx(SwResId(STR_UPDATE)) |
| , m_sUnprotTable(SwResId(STR_REMOVE_TBL_PROTECTION)) |
| , m_sRename(SwResId(STR_RENAME)) |
| , m_sReadonlyIdx(SwResId(STR_READONLY_IDX)) |
| , m_sInvisible(SwResId(STR_INVISIBLE)) |
| , m_sPostItShow(SwResId(STR_POSTIT_SHOW)) |
| , m_sPostItHide(SwResId(STR_POSTIT_HIDE)) |
| , m_sPostItDelete(SwResId(STR_POSTIT_DELETE)) |
| , m_pHiddenShell(nullptr) |
| , m_pActiveShell(nullptr) |
| , m_pConfig(SW_MOD()->GetNavigationConfig()) |
| , m_nActiveBlock(0) |
| , m_nHiddenBlock(0) |
| , m_nRootType(ContentTypeId::UNKNOWN) |
| , m_nLastSelType(ContentTypeId::UNKNOWN) |
| , m_nOutlineLevel(MAXLEVEL) |
| , m_eState(State::ACTIVE) |
| , m_bDocChgdInDragging(false) |
| , m_bIsInternalDrag(false) |
| , m_bIsRoot(false) |
| , m_bIsIdleClear(false) |
| , m_bIsLastReadOnly(false) |
| , m_bIsOutlineMoveable(true) |
| , m_bViewHasChanged(false) |
| , m_bIsKeySpace(false) |
| { |
| SetHelpId(HID_NAVIGATOR_TREELIST); |
| |
| SetNodeDefaultImages(); |
| SetDoubleClickHdl(LINK(this, SwContentTree, ContentDoubleClickHdl)); |
| SetDragDropMode(DragDropMode::APP_COPY); |
| for (ContentTypeId i : o3tl::enumrange<ContentTypeId>()) |
| { |
| m_aActiveContentArr[i] = nullptr; |
| m_aHiddenContentArr[i] = nullptr; |
| } |
| for (int i = 0; i < CONTEXT_COUNT; ++i) |
| { |
| m_aContextStrings[i] = SwResId(STR_CONTEXT_ARY[i]); |
| } |
| m_nActiveBlock = m_pConfig->GetActiveBlock(); |
| m_aUpdTimer.SetInvokeHandler(LINK(this, SwContentTree, TimerUpdate)); |
| m_aUpdTimer.SetTimeout(1000); |
| Clear(); |
| EnableContextMenuHandling(); |
| SetQuickSearch(true); |
| } |
| |
| SwContentTree::~SwContentTree() |
| { |
| disposeOnce(); |
| } |
| |
| void SwContentTree::dispose() |
| { |
| Clear(); // If applicable erase content types previously. |
| bIsInDrag = false; |
| m_aUpdTimer.Stop(); |
| SetActiveShell(nullptr); |
| m_xDialog.clear(); |
| SvTreeListBox::dispose(); |
| } |
| |
| Size SwContentTree::GetOptimalSize() const |
| { |
| return LogicToPixel(Size(110, 112), MapMode(MapUnit::MapAppFont)); |
| } |
| |
| OUString SwContentTree::GetEntryAltText( SvTreeListEntry* pEntry ) const |
| { |
| if (pEntry == nullptr || !lcl_IsContent(pEntry)) |
| return OUString(); |
| |
| assert(pEntry->GetUserData() == nullptr || dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| if( pCnt == nullptr || pCnt->GetParent() == nullptr) |
| return OUString(); |
| |
| ContentTypeId nJumpType = pCnt->GetParent()->GetType(); |
| SdrObject* pTemp; |
| |
| switch(nJumpType) |
| { |
| case ContentTypeId::DRAWOBJECT: |
| { |
| SdrView* pDrawView = m_pActiveShell->GetDrawView(); |
| if (pDrawView) |
| { |
| SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); |
| SdrPage* pPage = pDrawModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| pTemp = pPage->GetObj(i); |
| sal_uInt16 nCmpId; |
| switch( pTemp->GetObjIdentifier() ) |
| { |
| case OBJ_GRUP: |
| case OBJ_TEXT: |
| case OBJ_LINE: |
| case OBJ_RECT: |
| case OBJ_CUSTOMSHAPE: |
| case OBJ_CIRC: |
| case OBJ_SECT: |
| case OBJ_CARC: |
| case OBJ_CCUT: |
| case OBJ_POLY: |
| case OBJ_PLIN: |
| case OBJ_PATHLINE: |
| case OBJ_PATHFILL: |
| case OBJ_FREELINE: |
| case OBJ_FREEFILL: |
| case OBJ_PATHPOLY: |
| case OBJ_PATHPLIN: |
| case OBJ_CAPTION: |
| nCmpId = OBJ_GRUP; |
| break; |
| default: |
| nCmpId = pTemp->GetObjIdentifier(); |
| } |
| if(nCmpId == OBJ_GRUP && pTemp->GetName() == pCnt->GetName()) |
| { |
| return pTemp->GetTitle(); |
| } |
| } |
| } |
| } |
| break; |
| case ContentTypeId::GRAPHIC : |
| { |
| if( m_pActiveShell && m_pActiveShell->GetDoc() ) |
| { |
| const SwFlyFrameFormat* pFrameFormat = m_pActiveShell->GetDoc()->FindFlyByName( pCnt->GetName()); |
| if( pFrameFormat ) |
| return pFrameFormat->GetObjTitle(); |
| } |
| } |
| break; |
| case ContentTypeId::OLE : |
| case ContentTypeId::FRAME : |
| { |
| //Can't find the GetAlternateText function. Need to verify again. |
| const SwFlyFrameFormat* pFlyFormat = m_pActiveShell->GetDoc()->FindFlyByName( pCnt->GetName()); |
| if( pFlyFormat ) |
| return pFlyFormat->/*GetAlternateText*/GetName(); |
| } |
| break; |
| default: break; |
| } |
| return OUString(); |
| } |
| |
| OUString SwContentTree::GetEntryLongDescription( SvTreeListEntry* pEntry ) const |
| { |
| if( pEntry == nullptr) |
| return OUString(); |
| |
| assert(pEntry->GetUserData() == nullptr || dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| if( pCnt == nullptr || pCnt->GetParent() == nullptr) |
| return OUString(); |
| |
| SdrObject* pTemp; |
| |
| switch(pCnt->GetParent()->GetType()) |
| { |
| case ContentTypeId::DRAWOBJECT: |
| { |
| SdrView* pDrawView = m_pActiveShell->GetDrawView(); |
| if (pDrawView) |
| { |
| SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); |
| SdrPage* pPage = pDrawModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| pTemp = pPage->GetObj(i); |
| sal_uInt16 nCmpId; |
| switch( pTemp->GetObjIdentifier() ) |
| { |
| case OBJ_GRUP: |
| case OBJ_TEXT: |
| case OBJ_LINE: |
| case OBJ_RECT: |
| case OBJ_CUSTOMSHAPE: |
| case OBJ_CIRC: |
| case OBJ_SECT: |
| case OBJ_CARC: |
| case OBJ_CCUT: |
| case OBJ_POLY: |
| case OBJ_PLIN: |
| case OBJ_PATHLINE: |
| case OBJ_PATHFILL: |
| case OBJ_FREELINE: |
| case OBJ_FREEFILL: |
| case OBJ_PATHPOLY: |
| case OBJ_PATHPLIN: |
| case OBJ_CAPTION: |
| nCmpId = OBJ_GRUP; |
| break; |
| default: |
| nCmpId = pTemp->GetObjIdentifier(); |
| } |
| if(nCmpId == OBJ_GRUP /*dynamic_cast< const SdrObjGroup *>( pTemp ) != nullptr*/ && pTemp->GetName() == pCnt->GetName()) |
| { |
| return pTemp->GetDescription(); |
| } |
| } |
| } |
| } |
| break; |
| case ContentTypeId::GRAPHIC : |
| case ContentTypeId::OLE : |
| case ContentTypeId::FRAME : |
| { |
| //Can't find the function "GetLongDescription". Need to verify again. |
| const SwFlyFrameFormat* pFlyFormat = m_pActiveShell->GetDoc()->FindFlyByName( pCnt->GetName()); |
| if( pFlyFormat ) |
| return pFlyFormat->GetDescription(); |
| } |
| break; |
| default: break; |
| } |
| return OUString(); |
| } |
| |
| // Drag&Drop methods |
| |
| void SwContentTree::StartDrag( sal_Int8 nAction, const Point& rPosPixel ) |
| { |
| if( !m_bIsRoot || m_nRootType != ContentTypeId::OUTLINE ) |
| { |
| ReleaseMouse(); |
| |
| rtl::Reference<TransferDataContainer> pContainer = new TransferDataContainer; |
| |
| sal_Int8 nDragMode = DND_ACTION_COPYMOVE | DND_ACTION_LINK; |
| if( FillTransferData( *pContainer, nDragMode )) |
| { |
| SwContentTree::SetInDrag(true); |
| pContainer->StartDrag( this, nDragMode, GetDragFinishedHdl() ); |
| } |
| } |
| else |
| { |
| SwWrtShell *const pShell = GetWrtShell(); |
| pShell->StartAllAction(); |
| pShell->StartUndo(SwUndoId::OUTLINE_UD); |
| // Only move drag entry and continuous selected siblings: |
| m_aDndOutlinesSelected.clear(); |
| SvTreeListEntry* pEntry = GetEntry(rPosPixel); |
| // Find first selected of continuous siblings |
| while (pEntry && IsSelected(pEntry->PrevSibling())) |
| { |
| pEntry = pEntry->PrevSibling(); |
| } |
| // Record continuous selected siblings |
| if (pEntry) |
| { |
| m_aDndOutlinesSelected.push_back(pEntry); |
| while (pEntry && IsSelected(pEntry->NextSibling())) |
| { |
| pEntry = pEntry->NextSibling(); |
| m_aDndOutlinesSelected.push_back(pEntry); |
| } |
| } |
| SvTreeListBox::StartDrag( nAction, rPosPixel ); |
| } |
| } |
| |
| void SwContentTree::DragFinished( sal_Int8 nAction ) |
| { |
| if (m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE) |
| { |
| SwWrtShell *const pShell = GetWrtShell(); |
| pShell->EndUndo(); |
| pShell->EndAllAction(); |
| m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); |
| Display(true); |
| m_aDndOutlinesSelected.clear(); |
| } |
| |
| // To prevent the removing of the selected entry in external drag and drop |
| // the drag action mustn't be MOVE. |
| SvTreeListBox::DragFinished( m_bIsInternalDrag ? nAction : DND_ACTION_COPY ); |
| SwContentTree::SetInDrag(false); |
| m_bIsInternalDrag = false; |
| } |
| |
| // QueryDrop will be executed in the navigator |
| |
| sal_Int8 SwContentTree::AcceptDrop( const AcceptDropEvent& rEvt ) |
| { |
| sal_Int8 nRet = DND_ACTION_NONE; |
| if( m_bIsRoot ) |
| { |
| if( m_bIsOutlineMoveable ) |
| nRet = SvTreeListBox::AcceptDrop( rEvt ); |
| } |
| else if( !bIsInDrag ) |
| nRet = GetParentWindow()->AcceptDrop(); |
| return nRet; |
| } |
| |
| // Drop will be executed in the navigator |
| |
| static void* lcl_GetOutlineKey( SwContentTree* pTree, SwOutlineContent const * pContent) |
| { |
| void* key = nullptr; |
| if( pTree && pContent ) |
| { |
| SwWrtShell* pShell = pTree->GetWrtShell(); |
| auto const nPos = pContent->GetOutlinePos(); |
| |
| key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos )); |
| } |
| return key; |
| } |
| |
| sal_Int8 SwContentTree::ExecuteDrop( const ExecuteDropEvent& rEvt ) |
| { |
| SvTreeListEntry* pEntry = pTargetEntry; |
| if( pEntry && ( m_nRootType == ContentTypeId::OUTLINE ) && lcl_IsContent( pEntry ) ) |
| { |
| assert(pEntry->GetUserData() == nullptr || dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwOutlineContent* pOutlineContent = static_cast<SwOutlineContent*>(pEntry->GetUserData()); |
| if( pOutlineContent ) |
| { |
| void* key = lcl_GetOutlineKey(this, pOutlineContent); |
| if( !mOutLineNodeMap[key] ) |
| { |
| while( pEntry->HasChildren() ) |
| { |
| SvTreeListEntry* pChildEntry = FirstChild( pEntry ); |
| while( pChildEntry ) |
| { |
| pEntry = pChildEntry; |
| pChildEntry = pChildEntry->NextSibling(); |
| } |
| } |
| pTargetEntry = pEntry; |
| } |
| } |
| } |
| if( m_bIsRoot ) |
| return SvTreeListBox::ExecuteDrop( rEvt ); |
| return bIsInDrag ? DND_ACTION_NONE : GetParentWindow()->ExecuteDrop(rEvt); |
| } |
| |
| // Handler for Dragging and ContextMenu |
| |
| static void lcl_InsertExpandCollapseAllItem(SwContentTree* pContentTree, SvTreeListEntry* pEntry, PopupMenu* pPop) |
| { |
| if(pEntry->HasChildren() || pEntry->HasChildrenOnDemand()) |
| { |
| pPop->InsertSeparator(); |
| pPop->InsertItem(800, pContentTree->IsAllExpanded(pEntry) ? SwResId(STR_COLLAPSEALL) : SwResId(STR_EXPANDALL)); |
| pPop->SetAccelKey(800, vcl::KeyCode(KEY_MULTIPLY, false, true, false, false)); |
| } |
| } |
| |
| VclPtr<PopupMenu> SwContentTree::CreateContextMenu() |
| { |
| bool bOutline(false); |
| |
| auto pPop = VclPtr<PopupMenu>::Create(); |
| VclPtrInstance<PopupMenu> pSubPop1; |
| VclPtrInstance<PopupMenu> pSubPop2; |
| VclPtrInstance<PopupMenu> pSubPop3; |
| |
| for(int i = 1; i <= MAXLEVEL; ++i) |
| { |
| pSubPop1->InsertItem(i + 100, OUString::number(i), MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK); |
| } |
| pSubPop1->CheckItem(100 + m_nOutlineLevel); |
| for(int i=0; i < 3; ++i) |
| { |
| pSubPop2->InsertItem(i + 201, m_aContextStrings[ |
| IDX_STR_HYPERLINK + i], MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK); |
| } |
| pSubPop2->CheckItem(201 + static_cast<int>(GetParentWindow()->GetRegionDropMode())); |
| // Insert the list of the open files |
| sal_uInt16 nId = 301; |
| const SwView* pActiveView = ::GetActiveView(); |
| SwView *pView = SwModule::GetFirstView(); |
| while (pView) |
| { |
| OUString sInsert = pView->GetDocShell()->GetTitle(); |
| if(pView == pActiveView) |
| { |
| sInsert += "(" + |
| m_aContextStrings[IDX_STR_ACTIVE] + |
| ")"; |
| } |
| pSubPop3->InsertItem(nId, sInsert, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK); |
| if (State::CONSTANT == m_eState && m_pActiveShell == &pView->GetWrtShell()) |
| pSubPop3->CheckItem(nId); |
| pView = SwModule::GetNextView(pView); |
| nId++; |
| } |
| pSubPop3->InsertItem(nId++, m_aContextStrings[IDX_STR_ACTIVE_VIEW], MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK); |
| if(m_pHiddenShell) |
| { |
| OUString sHiddenEntry = m_pHiddenShell->GetView().GetDocShell()->GetTitle() + |
| " ( " + |
| m_aContextStrings[IDX_STR_HIDDEN] + |
| " )"; |
| pSubPop3->InsertItem(nId, sHiddenEntry, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK); |
| } |
| |
| if (State::ACTIVE == m_eState) |
| pSubPop3->CheckItem( --nId ); |
| else if (State::HIDDEN == m_eState) |
| pSubPop3->CheckItem( nId ); |
| |
| SvTreeListEntry* pEntry = nullptr; |
| // Edit only if the shown content is coming from the current view. |
| if ((State::ACTIVE == m_eState || m_pActiveShell == pActiveView->GetWrtShellPtr()) |
| && nullptr != (pEntry = FirstSelected()) && lcl_IsContent(pEntry)) |
| { |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| const SwContentType* pContType = static_cast<SwContent*>(pEntry->GetUserData())->GetParent(); |
| const ContentTypeId nContentType = pContType->GetType(); |
| bool bReadonly = m_pActiveShell->GetView().GetDocShell()->IsReadOnly(); |
| bool bVisible = !static_cast<SwContent*>(pEntry->GetUserData())->IsInvisible(); |
| bool bProtected = static_cast<SwContent*>(pEntry->GetUserData())->IsProtect(); |
| bool bEditable = pContType->IsEditable() && |
| ((bVisible && !bProtected) ||ContentTypeId::REGION == nContentType); |
| bool bDeletable = pContType->IsDeletable() && |
| ((bVisible && !bProtected) ||ContentTypeId::REGION == nContentType); |
| bool bRenamable = bEditable && !bReadonly && |
| (ContentTypeId::TABLE == nContentType || |
| ContentTypeId::FRAME == nContentType || |
| ContentTypeId::GRAPHIC == nContentType || |
| ContentTypeId::OLE == nContentType || |
| ContentTypeId::BOOKMARK == nContentType || |
| ContentTypeId::REGION == nContentType || |
| ContentTypeId::INDEX == nContentType || |
| ContentTypeId::DRAWOBJECT == nContentType); |
| |
| if(!bReadonly && (bEditable || bDeletable)) |
| { |
| if(ContentTypeId::INDEX == nContentType) |
| { |
| pPop->InsertItem(401, m_sRemoveIdx); |
| pPop->InsertItem(402, m_sUpdateIdx); |
| |
| const SwTOXBase* pBase = static_cast<SwTOXBaseContent*>(pEntry->GetUserData())->GetTOXBase(); |
| if(!pBase->IsTOXBaseInReadonly()) |
| pPop->InsertItem(403, m_aContextStrings[IDX_STR_EDIT_ENTRY]); |
| pPop->InsertItem(405, m_sReadonlyIdx); |
| |
| pPop->CheckItem( 405, SwEditShell::IsTOXBaseReadonly(*pBase)); |
| pPop->InsertItem(501, m_aContextStrings[IDX_STR_DELETE_ENTRY]); |
| } |
| else if(ContentTypeId::TABLE == nContentType) |
| { |
| pPop->InsertItem(403, m_aContextStrings[IDX_STR_EDIT_ENTRY]); |
| pPop->InsertItem(404, m_sUnprotTable); |
| bool bFull = false; |
| OUString sTableName = static_cast<SwContent*>(pEntry->GetUserData())->GetName(); |
| bool bProt = m_pActiveShell->HasTableAnyProtection( &sTableName, &bFull ); |
| pPop->EnableItem(403, !bFull ); |
| pPop->EnableItem(404, bProt ); |
| pPop->InsertItem(501, m_aContextStrings[IDX_STR_DELETE_ENTRY]); |
| } |
| else if(ContentTypeId::OUTLINE == nContentType) |
| { |
| bOutline = true; |
| lcl_InsertExpandCollapseAllItem(this, pEntry, pPop); |
| pPop->InsertSeparator(); |
| pPop->InsertItem(501, SwResId(STR_DELETE_CHAPTER)); |
| pPop->InsertItem(801, SwResId(STR_PROMOTE_CHAPTER)); |
| pPop->InsertItem(802, SwResId(STR_DEMOTE_CHAPTER)); |
| pPop->InsertItem(803, SwResId(STR_PROMOTE_LEVEL)); |
| pPop->InsertItem(804, SwResId(STR_DEMOTE_LEVEL)); |
| } |
| else if(ContentTypeId::DRAWOBJECT == nContentType) |
| { |
| pPop->InsertItem(501, SwResId(STR_DELETE_ENTRY)); |
| } |
| else |
| { |
| if(bEditable && bDeletable) |
| { |
| pPop->InsertItem(403, m_aContextStrings[IDX_STR_EDIT_ENTRY]); |
| pPop->InsertItem(501, m_aContextStrings[IDX_STR_DELETE_ENTRY]); |
| } |
| else if(bEditable) |
| pPop->InsertItem(403, m_aContextStrings[IDX_STR_EDIT_ENTRY]); |
| else if(bDeletable) |
| { |
| pPop->InsertItem(501, m_aContextStrings[IDX_STR_DELETE_ENTRY]); |
| } |
| } |
| //Rename object |
| if(bRenamable) |
| pPop->InsertItem(502, m_sRename); |
| } |
| } |
| else if( pEntry ) |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContentType* pType = static_cast<SwContentType*>(pEntry->GetUserData()); |
| if(ContentTypeId::OUTLINE == pType->GetType()) |
| { |
| bOutline = true; |
| lcl_InsertExpandCollapseAllItem(this, pEntry, pPop); |
| pPop->InsertSeparator(); |
| pPop->InsertItem(700, m_aContextStrings[IDX_STR_SEND_OUTLINE_TO_CLIPBOARD_ENTRY]); |
| } |
| if ( (pType->GetType() == ContentTypeId::POSTIT) && (!m_pActiveShell->GetView().GetDocShell()->IsReadOnly()) && ( pType->GetMemberCount() > 0) ) |
| { |
| pPop->InsertItem(600, m_sPostItShow ); |
| pPop->InsertItem(601, m_sPostItHide ); |
| pPop->InsertItem(602, m_sPostItDelete ); |
| } |
| } |
| |
| pPop->InsertSeparator(); |
| if (bOutline) |
| { |
| pPop->InsertItem(1, m_aContextStrings[IDX_STR_OUTLINE_LEVEL]); |
| pPop->SetPopupMenu(1, pSubPop1); |
| } |
| else |
| pSubPop1.disposeAndClear(); |
| pPop->InsertItem(2, m_aContextStrings[IDX_STR_DRAGMODE]); |
| pPop->SetPopupMenu(2, pSubPop2); |
| pPop->InsertItem(3, m_aContextStrings[IDX_STR_DISPLAY]); |
| pPop->SetPopupMenu(3, pSubPop3); |
| |
| return pPop; |
| } |
| |
| // Indentation for outlines (and sections) |
| |
| sal_IntPtr SwContentTree::GetTabPos( SvTreeListEntry* pEntry, SvLBoxTab* pTab) |
| { |
| sal_IntPtr nLevel = 0; |
| if(lcl_IsContent(pEntry)) |
| { |
| nLevel++; |
| assert(pEntry->GetUserData() == nullptr || dynamic_cast<SwContent *>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContent* pCnt = static_cast<SwContent *>(pEntry->GetUserData()); |
| const SwContentType* pParent; |
| if(pCnt && nullptr != (pParent = pCnt->GetParent())) |
| { |
| if(pParent->GetType() == ContentTypeId::OUTLINE) |
| nLevel = nLevel + static_cast<SwOutlineContent*>(pCnt)->GetOutlineLevel(); |
| else if(pParent->GetType() == ContentTypeId::REGION) |
| nLevel = nLevel + static_cast<SwRegionContent*>(pCnt)->GetRegionLevel(); |
| } |
| } |
| return nLevel * 10 + (m_bIsRoot ? 0 : 5) + pTab->GetPos(); //determined empirically |
| } |
| |
| // Content will be integrated into the Box only on demand. |
| |
| void SwContentTree::RequestingChildren( SvTreeListEntry* pParent ) |
| { |
| // Is this a content type? |
| if(lcl_IsContentType(pParent)) |
| { |
| if(!pParent->HasChildren()) |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pParent->GetUserData()))); |
| SwContentType* pCntType = static_cast<SwContentType*>(pParent->GetUserData()); |
| |
| const size_t nCount = pCntType->GetMemberCount(); |
| // Add for outline plus/minus |
| if(pCntType->GetType() == ContentTypeId::OUTLINE) |
| { |
| SvTreeListEntry* pChild = nullptr; |
| for(size_t i = 0; i < nCount; ++i) |
| { |
| const SwContent* pCnt = pCntType->GetMember(i); |
| if(pCnt) |
| { |
| const auto nLevel = static_cast<const SwOutlineContent*>(pCnt)->GetOutlineLevel(); |
| OUString sEntry = pCnt->GetName(); |
| if(sEntry.isEmpty()) |
| sEntry = m_sSpace; |
| if(!pChild || (nLevel == 0)) |
| pChild = InsertEntry(sEntry, pParent, false, TREELIST_APPEND,const_cast<SwContent *>(pCnt)); |
| else |
| { |
| //back search parent. |
| if(static_cast<const SwOutlineContent*>(pCntType->GetMember(i-1))->GetOutlineLevel() < nLevel) |
| pChild = InsertEntry(sEntry, pChild, false, TREELIST_APPEND, const_cast<SwContent *>(pCnt)); |
| else |
| { |
| pChild = Prev(pChild); |
| assert(!pChild || lcl_IsContentType(pChild) || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pChild->GetUserData()))); |
| while(pChild && |
| lcl_IsContent(pChild) && |
| (static_cast<SwOutlineContent*>(pChild->GetUserData())->GetOutlineLevel() >= nLevel) |
| ) |
| { |
| pChild = Prev(pChild); |
| } |
| if(pChild) |
| pChild = InsertEntry(sEntry, pChild, |
| false, TREELIST_APPEND, const_cast<SwContent *>(pCnt)); |
| } |
| } |
| } |
| } |
| } |
| else |
| { |
| for(size_t i = 0; i < nCount; ++i) |
| { |
| const SwContent* pCnt = pCntType->GetMember(i); |
| if (pCnt) |
| { |
| OUString sEntry = pCnt->GetName(); |
| if (sEntry.isEmpty()) |
| sEntry = m_sSpace; |
| InsertEntry(sEntry, pParent, false, TREELIST_APPEND, const_cast<SwContent *>(pCnt)); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| SdrObject* SwContentTree::GetDrawingObjectsByContent(const SwContent *pCnt) |
| { |
| SdrObject *pRetObj = nullptr; |
| switch(pCnt->GetParent()->GetType()) |
| { |
| case ContentTypeId::DRAWOBJECT: |
| { |
| SdrView* pDrawView = m_pActiveShell->GetDrawView(); |
| if (pDrawView) |
| { |
| SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); |
| SdrPage* pPage = pDrawModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| SdrObject* pTemp = pPage->GetObj(i); |
| if( pTemp->GetName() == pCnt->GetName()) |
| { |
| pRetObj = pTemp; |
| break; |
| } |
| } |
| } |
| break; |
| } |
| default: |
| pRetObj = nullptr; |
| } |
| return pRetObj; |
| } |
| |
| bool SwContentTree::Expand( SvTreeListEntry* pParent ) |
| { |
| if (!(pParent->HasChildren() || pParent->HasChildrenOnDemand())) |
| return SvTreeListBox::Expand(pParent); |
| |
| if (!m_bIsRoot |
| || (lcl_IsContentType(pParent) && static_cast<SwContentType*>(pParent->GetUserData())->GetType() == ContentTypeId::OUTLINE) |
| || (m_nRootType == ContentTypeId::OUTLINE)) |
| { |
| if(lcl_IsContentType(pParent)) |
| { |
| SwContentType* pCntType = static_cast<SwContentType*>(pParent->GetUserData()); |
| const sal_Int32 nOr = 1 << static_cast<int>(pCntType->GetType()); //linear -> Bitposition |
| if (State::HIDDEN != m_eState) |
| { |
| m_nActiveBlock |= nOr; |
| m_pConfig->SetActiveBlock(m_nActiveBlock); |
| } |
| else |
| m_nHiddenBlock |= nOr; |
| if(pCntType->GetType() == ContentTypeId::OUTLINE) |
| { |
| std::map< void*, bool > aCurrOutLineNodeMap; |
| |
| SwWrtShell* pShell = GetWrtShell(); |
| bool bBool = SvTreeListBox::Expand(pParent); |
| SvTreeListEntry* pChild = Next(pParent); |
| while(pChild && lcl_IsContent(pChild) && pParent->HasChildren()) |
| { |
| if(pChild->HasChildren()) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pChild->GetUserData()))); |
| auto const nPos = static_cast<SwOutlineContent*>(pChild->GetUserData())->GetOutlinePos(); |
| void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos )); |
| aCurrOutLineNodeMap.emplace( key, false ); |
| std::map<void*, bool>::iterator iter = mOutLineNodeMap.find( key ); |
| if( iter != mOutLineNodeMap.end() && mOutLineNodeMap[key]) |
| { |
| aCurrOutLineNodeMap[key] = true; |
| SvTreeListBox::Expand(pChild); |
| } |
| } |
| pChild = Next(pChild); |
| } |
| mOutLineNodeMap = aCurrOutLineNodeMap; |
| return bBool; |
| } |
| |
| } |
| else if( lcl_IsContent(pParent) && static_cast<SwContentType*>(pParent->GetUserData())->GetType() == ContentTypeId::OUTLINE) |
| { |
| SwWrtShell* pShell = GetWrtShell(); |
| // paranoid assert now that outline type is checked |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pParent->GetUserData()))); |
| auto const nPos = static_cast<SwOutlineContent*>(pParent->GetUserData())->GetOutlinePos(); |
| void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos )); |
| mOutLineNodeMap[key] = true; |
| } |
| } |
| return SvTreeListBox::Expand(pParent); |
| } |
| |
| bool SwContentTree::Collapse( SvTreeListEntry* pParent ) |
| { |
| if (!pParent->HasChildren() || pParent->HasChildrenOnDemand()) |
| return SvTreeListBox::Collapse(pParent); |
| |
| if(lcl_IsContentType(pParent)) |
| { |
| if(m_bIsRoot) |
| { |
| // collapse to children of root node |
| for (SvTreeListEntry* pEntry = FirstChild(pParent); pEntry; pEntry = Next(pEntry)) |
| { |
| Collapse(pEntry); |
| } |
| return true; |
| } |
| SwContentType* pCntType = static_cast<SwContentType*>(pParent->GetUserData()); |
| const sal_Int32 nAnd = ~(1 << static_cast<int>(pCntType->GetType())); |
| if (State::HIDDEN != m_eState) |
| { |
| m_nActiveBlock &= nAnd; |
| m_pConfig->SetActiveBlock(m_nActiveBlock); |
| } |
| else |
| m_nHiddenBlock &= nAnd; |
| } |
| else if( lcl_IsContent(pParent) ) |
| { |
| SwWrtShell* pShell = GetWrtShell(); |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pParent->GetUserData()))); |
| auto const nPos = static_cast<SwOutlineContent*>(pParent->GetUserData())->GetOutlinePos(); |
| void* key = static_cast<void*>(pShell->getIDocumentOutlineNodesAccess()->getOutlineNode( nPos )); |
| mOutLineNodeMap[key] = false; |
| } |
| |
| return SvTreeListBox::Collapse(pParent); |
| } |
| |
| // Also on double click will be initially opened only. |
| |
| IMPL_LINK_NOARG(SwContentTree, ContentDoubleClickHdl, SvTreeListBox*, bool) |
| { |
| SvTreeListEntry* pEntry = GetCurEntry(); |
| // Is it a content type? |
| OSL_ENSURE(pEntry, "no current entry!"); |
| if(pEntry) |
| { |
| if(lcl_IsContentType(pEntry) && !pEntry->HasChildren()) |
| { |
| RequestingChildren(pEntry); |
| } |
| else if (!lcl_IsContentType(pEntry) && (State::HIDDEN != m_eState)) |
| { |
| if (State::CONSTANT == m_eState) |
| { |
| m_pActiveShell->GetView().GetViewFrame()->GetWindow().ToTop(); |
| } |
| //Jump to content type: |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| OSL_ENSURE( pCnt, "no UserData"); |
| GotoContent(pCnt); |
| if(pCnt->GetParent()->GetType() == ContentTypeId::FRAME) |
| m_pActiveShell->EnterStdMode(); |
| return false; // treelist processing finished |
| } |
| return true; // signal more to be done, i.e. expand/collapse children |
| } |
| return false; |
| } |
| |
| namespace |
| { |
| BitmapEx GetBitmapForContentTypeId(ContentTypeId eType) |
| { |
| OUString sResId; |
| |
| switch (eType) |
| { |
| case ContentTypeId::OUTLINE: |
| sResId = RID_BMP_NAVI_OUTLINE; |
| break; |
| case ContentTypeId::TABLE: |
| sResId = RID_BMP_NAVI_TABLE; |
| break; |
| case ContentTypeId::FRAME: |
| sResId = RID_BMP_NAVI_FRAME; |
| break; |
| case ContentTypeId::GRAPHIC: |
| sResId = RID_BMP_NAVI_GRAPHIC; |
| break; |
| case ContentTypeId::OLE: |
| sResId = RID_BMP_NAVI_OLE; |
| break; |
| case ContentTypeId::BOOKMARK: |
| sResId = RID_BMP_NAVI_BOOKMARK; |
| break; |
| case ContentTypeId::REGION: |
| sResId = RID_BMP_NAVI_REGION; |
| break; |
| case ContentTypeId::URLFIELD: |
| sResId = RID_BMP_NAVI_URLFIELD; |
| break; |
| case ContentTypeId::REFERENCE: |
| sResId = RID_BMP_NAVI_REFERENCE; |
| break; |
| case ContentTypeId::INDEX: |
| sResId = RID_BMP_NAVI_INDEX; |
| break; |
| case ContentTypeId::POSTIT: |
| sResId = RID_BMP_NAVI_POSTIT; |
| break; |
| case ContentTypeId::DRAWOBJECT: |
| sResId = RID_BMP_NAVI_DRAWOBJECT; |
| break; |
| case ContentTypeId::UNKNOWN: |
| SAL_WARN("sw.ui", "ContentTypeId::UNKNOWN has no bitmap preview"); |
| break; |
| } |
| |
| return BitmapEx(sResId); |
| }; |
| } |
| |
| void SwContentTree::Display( bool bActive ) |
| { |
| // First read the selected entry to select it later again if necessary |
| // -> the user data here are no longer valid! |
| SvTreeListEntry* pOldSelEntry = FirstSelected(); |
| OUString sEntryName; // Name of the entry |
| sal_uLong nEntryRelPos = 0; // relative position to their parent |
| sal_uInt32 nOldEntryCount = GetEntryCount(); |
| sal_Int32 nOldScrollPos = 0; |
| if(pOldSelEntry) |
| { |
| ScrollBar* pVScroll = GetVScroll(); |
| if(pVScroll && pVScroll->IsVisible()) |
| nOldScrollPos = pVScroll->GetThumbPos(); |
| |
| sEntryName = GetEntryText(pOldSelEntry); |
| SvTreeListEntry* pParantEntry = pOldSelEntry; |
| while( GetParent(pParantEntry)) |
| { |
| pParantEntry = GetParent(pParantEntry); |
| } |
| if(GetParent(pOldSelEntry)) |
| { |
| nEntryRelPos = GetModel()->GetAbsPos(pOldSelEntry) - GetModel()->GetAbsPos(pParantEntry); |
| } |
| } |
| Clear(); |
| SetUpdateMode( false ); |
| if (!bActive) |
| m_eState = State::HIDDEN; |
| else if (State::HIDDEN == m_eState) |
| m_eState = State::ACTIVE; |
| SwWrtShell* pShell = GetWrtShell(); |
| const bool bReadOnly = !pShell || pShell->GetView().GetDocShell()->IsReadOnly(); |
| if(bReadOnly != m_bIsLastReadOnly) |
| { |
| m_bIsLastReadOnly = bReadOnly; |
| bool bDisable = pShell == nullptr || bReadOnly; |
| SwNavigationPI* pNavi = GetParentWindow(); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("up"), !bDisable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("down"), !bDisable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("promote"), !bDisable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("demote"), !bDisable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("reminder"), !bDisable); |
| } |
| if(pShell) |
| { |
| SvTreeListEntry* pSelEntry = nullptr; |
| if(m_nRootType == ContentTypeId::UNKNOWN) |
| { |
| for( ContentTypeId nCntType : o3tl::enumrange<ContentTypeId>() ) |
| { |
| std::unique_ptr<SwContentType>& rpContentT = bActive ? |
| m_aActiveContentArr[nCntType] : |
| m_aHiddenContentArr[nCntType]; |
| if(!rpContentT) |
| rpContentT.reset(new SwContentType(pShell, nCntType, m_nOutlineLevel )); |
| |
| OUString sEntry = rpContentT->GetName(); |
| SvTreeListEntry* pEntry; |
| Image aImage(GetBitmapForContentTypeId(nCntType)); |
| bool bChOnDemand = 0 != rpContentT->GetMemberCount(); |
| pEntry = InsertEntry(sEntry, aImage, aImage, |
| nullptr, bChOnDemand, TREELIST_APPEND, rpContentT.get()); |
| if(nCntType == m_nLastSelType) |
| pSelEntry = pEntry; |
| sal_Int32 nExpandOptions = (State::HIDDEN == m_eState) |
| ? m_nHiddenBlock |
| : m_nActiveBlock; |
| if(nExpandOptions & (1 << static_cast<int>(nCntType))) |
| { |
| Expand(pEntry); |
| if(nEntryRelPos && nCntType == m_nLastSelType) |
| { |
| // Now maybe select an additional child |
| SvTreeListEntry* pChild = pEntry; |
| SvTreeListEntry* pTemp = nullptr; |
| sal_uLong nPos = 1; |
| while(nullptr != (pChild = Next(pChild))) |
| { |
| // The old text will be slightly favored |
| if(sEntryName == GetEntryText(pChild) || |
| nPos == nEntryRelPos ) |
| { |
| pSelEntry = pChild; |
| break; |
| } |
| pTemp = pChild; |
| nPos++; |
| } |
| if(!pSelEntry || lcl_IsContentType(pSelEntry)) |
| pSelEntry = pTemp; |
| } |
| |
| } |
| } |
| if(pSelEntry) |
| { |
| MakeVisible(pSelEntry); |
| Select(pSelEntry); |
| } |
| else |
| nOldScrollPos = 0; |
| } |
| else |
| { |
| std::unique_ptr<SwContentType>& rpRootContentT = bActive ? |
| m_aActiveContentArr[m_nRootType] : |
| m_aHiddenContentArr[m_nRootType]; |
| if(!rpRootContentT) |
| rpRootContentT.reset(new SwContentType(pShell, m_nRootType, m_nOutlineLevel )); |
| Image aImage(GetBitmapForContentTypeId(m_nRootType)); |
| SvTreeListEntry* pParent = InsertEntry( |
| rpRootContentT->GetName(), aImage, aImage, |
| nullptr, false, TREELIST_APPEND, rpRootContentT.get()); |
| |
| if(m_nRootType != ContentTypeId::OUTLINE) |
| { |
| for(size_t i = 0; i < rpRootContentT->GetMemberCount(); ++i) |
| { |
| const SwContent* pCnt = rpRootContentT->GetMember(i); |
| if(pCnt) |
| { |
| OUString sEntry = pCnt->GetName(); |
| if(sEntry.isEmpty()) |
| sEntry = m_sSpace; |
| InsertEntry( sEntry, pParent, |
| false, TREELIST_APPEND, const_cast<SwContent *>(pCnt)); |
| } |
| } |
| } |
| else |
| RequestingChildren(pParent); |
| Expand(pParent); |
| if (m_nRootType == ContentTypeId::OUTLINE && State::ACTIVE == m_eState) |
| { |
| // find out where the cursor is |
| const SwOutlineNodes::size_type nActPos = pShell->GetOutlinePos(MAXLEVEL); |
| SvTreeListEntry* pEntry = First(); |
| |
| while( nullptr != (pEntry = Next(pEntry)) ) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| if (static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos() == nActPos) |
| { |
| MakeVisible(pEntry); |
| Select(pEntry); |
| SetCurEntry(pEntry); |
| } |
| } |
| |
| } |
| else |
| { |
| // Now maybe select an additional child |
| SvTreeListEntry* pChild = pParent; |
| SvTreeListEntry* pTemp = nullptr; |
| sal_uLong nPos = 1; |
| while(nullptr != (pChild = Next(pChild))) |
| { |
| // The old text will be slightly favored |
| if(sEntryName == GetEntryText(pChild) || |
| nPos == nEntryRelPos ) |
| { |
| pSelEntry = pChild; |
| break; |
| } |
| pTemp = pChild; |
| nPos++; |
| } |
| if(!pSelEntry) |
| pSelEntry = pTemp; |
| if(pSelEntry) |
| { |
| MakeVisible(pSelEntry); |
| Select(pSelEntry); |
| } |
| } |
| } |
| } |
| SetUpdateMode( true ); |
| ScrollBar* pVScroll = GetVScroll(); |
| if(GetEntryCount() == nOldEntryCount && |
| nOldScrollPos && pVScroll && pVScroll->IsVisible() |
| && pVScroll->GetThumbPos() != nOldScrollPos) |
| { |
| sal_Int32 nDelta = pVScroll->GetThumbPos() - nOldScrollPos; |
| ScrollOutputArea( static_cast<short>(nDelta) ); |
| } |
| } |
| |
| void SwContentTree::Clear() |
| { |
| SetUpdateMode(false); |
| SvTreeListBox::Clear(); |
| SetUpdateMode(true); |
| } |
| |
| bool SwContentTree::FillTransferData( TransferDataContainer& rTransfer, |
| sal_Int8& rDragMode ) |
| { |
| SwWrtShell* pWrtShell = GetWrtShell(); |
| OSL_ENSURE(pWrtShell, "no Shell!"); |
| SvTreeListEntry* pEntry = GetCurEntry(); |
| if(!pEntry || lcl_IsContentType(pEntry) || !pWrtShell) |
| return false; |
| OUString sEntry; |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| |
| const ContentTypeId nActType = pCnt->GetParent()->GetType(); |
| OUString sUrl; |
| bool bOutline = false; |
| OUString sOutlineText; |
| switch( nActType ) |
| { |
| case ContentTypeId::OUTLINE: |
| { |
| const SwOutlineNodes::size_type nPos = static_cast<SwOutlineContent*>(pCnt)->GetOutlinePos(); |
| OSL_ENSURE(nPos < pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNodesCount(), |
| "outlinecnt changed"); |
| |
| // make sure outline may actually be copied |
| if( pWrtShell->IsOutlineCopyable( nPos ) ) |
| { |
| const SwNumRule* pOutlRule = pWrtShell->GetOutlineNumRule(); |
| const SwTextNode* pTextNd = |
| pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNode(nPos); |
| if (pTextNd && pOutlRule && pTextNd->IsNumbered(pWrtShell->GetLayout())) |
| { |
| SwNumberTree::tNumberVector aNumVector = |
| pTextNd->GetNumberVector(pWrtShell->GetLayout()); |
| for( int nLevel = 0; |
| nLevel <= pTextNd->GetActualListLevel(); |
| nLevel++ ) |
| { |
| const SwNumberTree::tSwNumTreeNumber nVal = aNumVector[nLevel] + 1; |
| sEntry += OUString::number( nVal - pOutlRule->Get(nLevel).GetStart() ) + "."; |
| } |
| } |
| sEntry += pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout(), false); |
| sOutlineText = pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(nPos, pWrtShell->GetLayout()); |
| m_bIsOutlineMoveable = static_cast<SwOutlineContent*>(pCnt)->IsMoveable(); |
| bOutline = true; |
| } |
| } |
| break; |
| case ContentTypeId::POSTIT: |
| case ContentTypeId::INDEX: |
| case ContentTypeId::REFERENCE : |
| // cannot be inserted, neither as URL nor as section |
| break; |
| case ContentTypeId::URLFIELD: |
| sUrl = static_cast<SwURLFieldContent*>(pCnt)->GetURL(); |
| [[fallthrough]]; |
| case ContentTypeId::OLE: |
| case ContentTypeId::GRAPHIC: |
| if(GetParentWindow()->GetRegionDropMode() != RegionMode::NONE) |
| break; |
| else |
| rDragMode &= ~( DND_ACTION_MOVE | DND_ACTION_LINK ); |
| [[fallthrough]]; |
| default: |
| sEntry = GetEntryText(pEntry); |
| } |
| |
| bool bRet = false; |
| if(!sEntry.isEmpty()) |
| { |
| const SwDocShell* pDocShell = pWrtShell->GetView().GetDocShell(); |
| if(sUrl.isEmpty()) |
| { |
| if(pDocShell->HasName()) |
| { |
| SfxMedium* pMedium = pDocShell->GetMedium(); |
| sUrl = pMedium->GetURLObject().GetURLNoMark(); |
| // only if a primarily link shall be integrated. |
| bRet = true; |
| } |
| else if ( nActType == ContentTypeId::REGION || nActType == ContentTypeId::BOOKMARK ) |
| { |
| // For field and bookmarks a link is also allowed |
| // without a filename into its own document. |
| bRet = true; |
| } |
| else if (State::CONSTANT == m_eState && |
| ( !::GetActiveView() || |
| m_pActiveShell != ::GetActiveView()->GetWrtShellPtr())) |
| { |
| // Urls of inactive views cannot dragged without |
| // file names, also. |
| bRet = false; |
| } |
| else |
| { |
| bRet = GetParentWindow()->GetRegionDropMode() == RegionMode::NONE; |
| rDragMode = DND_ACTION_MOVE; |
| } |
| |
| const OUString& rToken = pCnt->GetParent()->GetTypeToken(); |
| sUrl += "#" + sEntry; |
| if(!rToken.isEmpty()) |
| { |
| sUrl += OUStringChar(cMarkSeparator) + rToken; |
| } |
| } |
| else |
| bRet = true; |
| |
| if( bRet ) |
| { |
| // In Outlines of heading text must match |
| // the real number into the description. |
| if(bOutline) |
| sEntry = sOutlineText; |
| |
| { |
| NaviContentBookmark aBmk( sUrl, sEntry, |
| GetParentWindow()->GetRegionDropMode(), |
| pDocShell); |
| aBmk.Copy( rTransfer ); |
| } |
| |
| // An INetBookmark must a be delivered to foreign DocShells |
| if( pDocShell->HasName() ) |
| { |
| INetBookmark aBkmk( sUrl, sEntry ); |
| rTransfer.CopyINetBookmark( aBkmk ); |
| } |
| } |
| } |
| return bRet; |
| } |
| |
| void SwContentTree::ToggleToRoot() |
| { |
| if(!m_bIsRoot) |
| { |
| SvTreeListEntry* pEntry = GetCurEntry(); |
| const SwContentType* pCntType; |
| if(pEntry) |
| { |
| if(lcl_IsContentType(pEntry)) |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| pCntType = static_cast<SwContentType*>(pEntry->GetUserData()); |
| } |
| else |
| { |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| pCntType = static_cast<SwContent*>(pEntry->GetUserData())->GetParent(); |
| } |
| m_nRootType = pCntType->GetType(); |
| m_bIsRoot = true; |
| Display(State::HIDDEN != m_eState); |
| if (m_nRootType == ContentTypeId::OUTLINE) |
| { |
| SetSelectionMode(SelectionMode::Multiple); |
| SetDragDropMode(DragDropMode::CTRL_MOVE | |
| DragDropMode::CTRL_COPY | |
| DragDropMode::ENABLE_TOP); |
| } |
| } |
| } |
| else |
| { |
| SetSelectionMode(SelectionMode::Single); |
| m_nRootType = ContentTypeId::UNKNOWN; |
| m_bIsRoot = false; |
| FindActiveTypeAndRemoveUserData(); |
| Display(State::HIDDEN != m_eState); |
| if( m_bIsKeySpace ) |
| { |
| HideFocus(); |
| ShowFocus( m_aOldRectangle); |
| m_bIsKeySpace = false; |
| } |
| } |
| m_pConfig->SetRootType( m_nRootType ); |
| VclPtr<ToolBox> xBox = GetParentWindow()->m_aContentToolBox; |
| xBox->CheckItem(xBox->GetItemId("root"), m_bIsRoot); |
| } |
| |
| bool SwContentTree::HasContentChanged() |
| { |
| |
| // - Run through the local array and the Treelistbox in parallel. |
| // - Are the records not expanded, they are discarded only in the array |
| // and the content type will be set as the new UserData. |
| // - Is the root mode is active only this will be updated. |
| |
| // Valid for the displayed content types is: |
| // the Memberlist will be erased and the membercount will be updated |
| // If content will be checked, the memberlists will be replenished |
| // at the same time. Once a difference occurs it will be only replenished |
| // no longer checked. Finally, the box is filled again. |
| |
| bool bRepaint = false; |
| bool bInvalidate = false; |
| |
| if (State::HIDDEN == m_eState) |
| { |
| for(ContentTypeId i : o3tl::enumrange<ContentTypeId>()) |
| { |
| if(m_aActiveContentArr[i]) |
| m_aActiveContentArr[i]->Invalidate(); |
| } |
| } |
| else if(m_bIsRoot) |
| { |
| bool bOutline = false; |
| SvTreeListEntry* pEntry = First(); |
| if(!pEntry) |
| bRepaint = true; |
| else |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| const ContentTypeId nType = static_cast<SwContentType*>(pEntry->GetUserData())->GetType(); |
| bOutline = m_nRootType == ContentTypeId::OUTLINE; |
| SwContentType* pArrType = m_aActiveContentArr[nType].get(); |
| if(!pArrType) |
| bRepaint = true; |
| else |
| { |
| SvTreeListEntry* pFirstSel; |
| if(bOutline && !HasFocus() && |
| nullptr != ( pFirstSel = FirstSelected()) && |
| lcl_IsContent(pFirstSel)) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pFirstSel->GetUserData()))); |
| const auto nSelLevel = |
| static_cast<SwOutlineContent*>(pFirstSel->GetUserData())->GetOutlineLevel(); |
| SwWrtShell* pSh = GetWrtShell(); |
| const SwOutlineNodes::size_type nOutlinePos = pSh->GetOutlinePos(MAXLEVEL); |
| if (nOutlinePos != SwOutlineNodes::npos && |
| pSh->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos) != nSelLevel) |
| bRepaint = true; |
| } |
| |
| pArrType->Init(&bInvalidate); |
| pArrType->FillMemberList(); |
| pEntry->SetUserData(static_cast<void*>(pArrType)); |
| if(!bRepaint) |
| { |
| if(GetChildCount(pEntry) != pArrType->GetMemberCount()) |
| bRepaint = true; |
| else |
| { |
| const size_t nChildCount = GetChildCount(pEntry); |
| for(size_t j = 0; j < nChildCount; ++j) |
| { |
| pEntry = Next(pEntry); |
| assert(pEntry); |
| const SwContent* pCnt = pArrType->GetMember(j); |
| pEntry->SetUserData(const_cast<SwContent *>(pCnt)); |
| OUString sEntryText = GetEntryText(pEntry); |
| if( sEntryText != pCnt->GetName() && |
| !(sEntryText == m_sSpace && pCnt->GetName().isEmpty())) |
| bRepaint = true; |
| } |
| } |
| } |
| } |
| } |
| if( !bRepaint && bOutline && !HasFocus() ) |
| { |
| // find out where the cursor is |
| const SwOutlineNodes::size_type nActPos = GetWrtShell()->GetOutlinePos(MAXLEVEL); |
| SvTreeListEntry* pFirstEntry = First(); |
| |
| while( nullptr != (pFirstEntry = Next(pFirstEntry)) ) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pFirstEntry->GetUserData()))); |
| if (static_cast<SwOutlineContent*>(pFirstEntry->GetUserData())->GetOutlinePos() == nActPos) |
| { |
| if(FirstSelected() != pFirstEntry) |
| { |
| Select(pFirstEntry); |
| MakeVisible(pFirstEntry); |
| } |
| } |
| else if (IsSelected(pFirstEntry)) |
| { |
| SvTreeListBox::SelectListEntry(pFirstEntry, false); |
| bInvalidate = true; |
| } |
| } |
| |
| } |
| |
| } |
| else |
| { |
| SvTreeListEntry* pEntry = First(); |
| while ( pEntry ) |
| { |
| bool bNext = true; // at least a next must be |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwContentType* pTreeType = static_cast<SwContentType*>(pEntry->GetUserData()); |
| const size_t nTreeCount = pTreeType->GetMemberCount(); |
| const ContentTypeId nType = pTreeType->GetType(); |
| SwContentType* pArrType = m_aActiveContentArr[nType].get(); |
| if(!pArrType) |
| bRepaint = true; |
| else |
| { |
| pArrType->Init(&bInvalidate); |
| pEntry->SetUserData(static_cast<void*>(pArrType)); |
| if(IsExpanded(pEntry)) |
| { |
| bool bLevelOrVisibiblityChanged = false; |
| // bLevelOrVisibiblityChanged is set if outlines have changed their level |
| // or if the visibility of objects (frames, sections, tables) has changed |
| // i.e. in header/footer |
| pArrType->FillMemberList(&bLevelOrVisibiblityChanged); |
| const size_t nChildCount = GetChildCount(pEntry); |
| if((nType == ContentTypeId::OUTLINE) && bLevelOrVisibiblityChanged) |
| bRepaint = true; |
| if(bLevelOrVisibiblityChanged) |
| bInvalidate = true; |
| |
| if(nChildCount != pArrType->GetMemberCount()) |
| bRepaint = true; |
| else |
| { |
| for(size_t j = 0; j < nChildCount; ++j) |
| { |
| pEntry = Next(pEntry); |
| assert(pEntry); |
| bNext = false; |
| const SwContent* pCnt = pArrType->GetMember(j); |
| pEntry->SetUserData(const_cast<SwContent *>(pCnt)); |
| OUString sEntryText = GetEntryText(pEntry); |
| if( sEntryText != pCnt->GetName() && |
| !(sEntryText == m_sSpace && pCnt->GetName().isEmpty())) |
| bRepaint = true; |
| } |
| } |
| |
| } |
| else if(pEntry->HasChildren()) |
| { |
| // was the entry once opened, then must also the |
| // invisible records be examined. |
| // At least the user data must be updated. |
| bool bLevelOrVisibiblityChanged = false; |
| // bLevelOrVisibiblityChanged is set if outlines have changed their level |
| // or if the visibility of objects (frames, sections, tables) has changed |
| // i.e. in header/footer |
| pArrType->FillMemberList(&bLevelOrVisibiblityChanged); |
| bool bRemoveChildren = false; |
| const size_t nChildCount = GetChildCount(pEntry); |
| if( nChildCount != pArrType->GetMemberCount() ) |
| { |
| bRemoveChildren = true; |
| } |
| else |
| { |
| SvTreeListEntry* pChild = FirstChild(pEntry); |
| for(size_t j = 0; j < nChildCount; ++j) |
| { |
| const SwContent* pCnt = pArrType->GetMember(j); |
| assert(pChild); |
| pChild->SetUserData(const_cast<SwContent *>(pCnt)); |
| OUString sEntryText = GetEntryText(pChild); |
| if( sEntryText != pCnt->GetName() && |
| !(sEntryText == m_sSpace && pCnt->GetName().isEmpty())) |
| bRemoveChildren = true; |
| pChild = Next(pChild); |
| } |
| } |
| if(bRemoveChildren) |
| { |
| while (SvTreeListEntry *const pRemove = FirstChild(pEntry)) |
| RemoveEntry(pRemove); |
| } |
| if(!nChildCount) |
| { |
| pEntry->EnableChildrenOnDemand(false); |
| InvalidateEntry(pEntry); |
| } |
| |
| } |
| else if((nTreeCount != 0) |
| != (pArrType->GetMemberCount()!=0)) |
| { |
| bRepaint = true; |
| } |
| } |
| // The Root-Entry has to be found now |
| while( pEntry && (bNext || GetParent(pEntry ) )) |
| { |
| pEntry = Next(pEntry); |
| bNext = false; |
| } |
| } |
| } |
| if(!bRepaint && bInvalidate) |
| Invalidate(); |
| return bRepaint; |
| } |
| |
| void SwContentTree::FindActiveTypeAndRemoveUserData() |
| { |
| SvTreeListEntry* pEntry = FirstSelected(); |
| if(pEntry) |
| { |
| // If clear is called by TimerUpdate: |
| // Only for root can the validity of the UserData be guaranteed. |
| SvTreeListEntry* pParent; |
| while(nullptr != (pParent = GetParent(pEntry))) |
| pEntry = pParent; |
| if(pEntry->GetUserData() && lcl_IsContentType(pEntry)) |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| m_nLastSelType = static_cast<SwContentType*>(pEntry->GetUserData())->GetType(); |
| } |
| } |
| pEntry = First(); |
| while(pEntry) |
| { |
| pEntry->SetUserData(nullptr); |
| pEntry = Next(pEntry); |
| } |
| } |
| |
| void SwContentTree::SetHiddenShell(SwWrtShell* pSh) |
| { |
| m_pHiddenShell = pSh; |
| m_eState = State::HIDDEN; |
| FindActiveTypeAndRemoveUserData(); |
| for(ContentTypeId i : o3tl::enumrange<ContentTypeId>()) |
| { |
| m_aHiddenContentArr[i].reset(); |
| } |
| Display(false); |
| |
| GetParentWindow()->UpdateListBox(); |
| } |
| |
| void SwContentTree::SetActiveShell(SwWrtShell* pSh) |
| { |
| if(m_bIsInternalDrag) |
| m_bDocChgdInDragging = true; |
| bool bClear = m_pActiveShell != pSh; |
| if (State::ACTIVE == m_eState && bClear) |
| { |
| if (m_pActiveShell) |
| EndListening(*m_pActiveShell->GetView().GetDocShell()); |
| m_pActiveShell = pSh; |
| FindActiveTypeAndRemoveUserData(); |
| Clear(); |
| } |
| else if (State::CONSTANT == m_eState) |
| { |
| if (m_pActiveShell) |
| EndListening(*m_pActiveShell->GetView().GetDocShell()); |
| m_pActiveShell = pSh; |
| m_eState = State::ACTIVE; |
| bClear = true; |
| } |
| // Only if it is the active view, the array will be deleted and |
| // the screen filled new. |
| if (State::ACTIVE == m_eState && bClear) |
| { |
| if (m_pActiveShell) |
| StartListening(*m_pActiveShell->GetView().GetDocShell()); |
| FindActiveTypeAndRemoveUserData(); |
| for(ContentTypeId i : o3tl::enumrange<ContentTypeId>()) |
| { |
| m_aActiveContentArr[i].reset(); |
| } |
| Display(true); |
| } |
| } |
| |
| void SwContentTree::SetConstantShell(SwWrtShell* pSh) |
| { |
| if (m_pActiveShell) |
| EndListening(*m_pActiveShell->GetView().GetDocShell()); |
| m_pActiveShell = pSh; |
| m_eState = State::CONSTANT; |
| StartListening(*m_pActiveShell->GetView().GetDocShell()); |
| FindActiveTypeAndRemoveUserData(); |
| for(ContentTypeId i : o3tl::enumrange<ContentTypeId>()) |
| { |
| m_aActiveContentArr[i].reset(); |
| } |
| Display(true); |
| } |
| |
| |
| void SwContentTree::Notify(SfxBroadcaster & rBC, SfxHint const& rHint) |
| { |
| SfxViewEventHint const*const pVEHint(dynamic_cast<SfxViewEventHint const*>(&rHint)); |
| SwXTextView* pDyingShell = nullptr; |
| if (m_pActiveShell && pVEHint && pVEHint->GetEventName() == "OnViewClosed") |
| pDyingShell = dynamic_cast<SwXTextView*>(pVEHint->GetController().get()); |
| if (pDyingShell && pDyingShell->GetView() == &m_pActiveShell->GetView()) |
| { |
| SetActiveShell(nullptr); // our view is dying, clear our pointers to it |
| } |
| else |
| { |
| SfxListener::Notify(rBC, rHint); |
| } |
| switch (rHint.GetId()) |
| { |
| case SfxHintId::DocChanged: |
| if (!(m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE && HasFocus())) |
| { |
| m_bViewHasChanged = true; |
| } |
| break; |
| case SfxHintId::ModeChanged: |
| if (SwWrtShell* pShell = GetWrtShell()) |
| { |
| const bool bReadOnly = pShell->GetView().GetDocShell()->IsReadOnly(); |
| if (bReadOnly != m_bIsLastReadOnly) |
| { |
| m_bIsLastReadOnly = bReadOnly; |
| Select(GetCurEntry()); |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| |
| |
| void SwContentTree::ExecCommand(const OUString& rCmd, bool bOutlineWithChildren) |
| { |
| const bool bUp = rCmd == "up"; |
| const bool bUpDown = bUp || rCmd == "down"; |
| const bool bLeft = rCmd == "promote"; |
| const bool bLeftRight = bLeft || rCmd == "demote"; |
| if (!bUpDown && !bLeftRight) |
| return; |
| if (GetWrtShell()->GetView().GetDocShell()->IsReadOnly() || |
| (State::ACTIVE != m_eState && |
| (State::CONSTANT != m_eState || m_pActiveShell != GetParentWindow()->GetCreateView()->GetWrtShellPtr()))) |
| { |
| return; |
| } |
| |
| SwWrtShell *const pShell = GetWrtShell(); |
| sal_Int8 nActOutlineLevel = m_nOutlineLevel; |
| SwOutlineNodes::size_type nActPos = pShell->GetOutlinePos(nActOutlineLevel); |
| |
| std::vector<SwTextNode*> selectedOutlineNodes; |
| std::vector<SvTreeListEntry*> selected; |
| for (SvTreeListEntry * pEntry = FirstSelected(); pEntry; pEntry = NextSelected(pEntry)) |
| { |
| // it's possible to select the root node too which is a really bad idea |
| bool bSkip = lcl_IsContentType(pEntry); |
| // filter out children of selected parents so they don't get promoted |
| // or moved twice (except if there is Ctrl modifier, since in that |
| // case children are re-parented) |
| if ((bLeftRight || bOutlineWithChildren) && !selected.empty()) |
| { |
| for (auto pParent = GetParent(pEntry); pParent; pParent = GetParent(pParent)) |
| { |
| if (selected.back() == pParent) |
| { |
| bSkip = true; |
| break; |
| } |
| } |
| } |
| if (!bSkip) |
| { |
| selected.push_back(pEntry); |
| const SwNodes& rNodes = pShell->GetNodes(); |
| const sal_uLong nPos = GetAbsPos(pEntry) - 1; |
| if (nPos < rNodes.GetOutLineNds().size()) |
| { |
| SwNode* pNode = rNodes.GetOutLineNds()[ nPos ]; |
| if (pNode) |
| { |
| selectedOutlineNodes.push_back(pNode->GetTextNode()); |
| } |
| } |
| } |
| } |
| if (bUpDown && !bUp) |
| { // to move down, start at the end! |
| std::reverse(selected.begin(), selected.end()); |
| } |
| |
| SwOutlineNodes::difference_type nDirLast = bUp ? -1 : 1; |
| bool bStartedAction = false; |
| for (auto const pCurrentEntry : selected) |
| { |
| assert(pCurrentEntry && lcl_IsContent(pCurrentEntry)); |
| if (lcl_IsContent(pCurrentEntry)) |
| { |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pCurrentEntry->GetUserData()))); |
| if ((m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE) || |
| static_cast<SwContent*>(pCurrentEntry->GetUserData())->GetParent()->GetType() |
| == ContentTypeId::OUTLINE) |
| { |
| nActPos = static_cast<SwOutlineContent*>(pCurrentEntry->GetUserData())->GetOutlinePos(); |
| } |
| } |
| if (nActPos == SwOutlineNodes::npos || (bUpDown && !pShell->IsOutlineMovable(nActPos))) |
| { |
| continue; |
| } |
| |
| if (!bStartedAction) |
| { |
| pShell->StartAllAction(); |
| pShell->StartUndo(bLeftRight ? SwUndoId::OUTLINE_LR : SwUndoId::OUTLINE_UD); |
| bStartedAction = true; |
| } |
| pShell->GotoOutline( nActPos); // If text selection != box selection |
| pShell->Push(); |
| pShell->MakeOutlineSel(nActPos, nActPos, bOutlineWithChildren); |
| if (bUpDown) |
| { |
| sal_uLong const nEntryAbsPos(GetModel()->GetAbsPos(pCurrentEntry)); |
| SwOutlineNodes::difference_type nDir = bUp ? -1 : 1; |
| if (!bOutlineWithChildren && ((nDir == -1 && nActPos > 0) || |
| (nDir == 1 && nEntryAbsPos < GetEntryCount() - 2))) |
| { |
| pShell->MoveOutlinePara( nDir ); |
| // Set cursor back to the current position |
| pShell->GotoOutline( nActPos + nDir); |
| } |
| else if (bOutlineWithChildren) |
| { |
| SwOutlineNodes::size_type nActEndPos = nActPos; |
| SvTreeListEntry* pEntry = pCurrentEntry; |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pCurrentEntry->GetUserData()))); |
| const auto nActLevel = static_cast<SwOutlineContent*>( |
| pCurrentEntry->GetUserData())->GetOutlineLevel(); |
| pEntry = Next(pEntry); |
| while (pEntry && lcl_IsContent(pEntry)) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| if (nActLevel >= static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlineLevel()) |
| break; |
| nActEndPos = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| pEntry = Next(pEntry); |
| } |
| if (nDir == 1) // move down |
| { |
| if (IsSelected(pCurrentEntry->NextSibling())) |
| nDir = nDirLast; |
| else |
| { |
| // If the last entry is to be moved we're done |
| if (pEntry && lcl_IsContent(pEntry)) |
| { |
| // pEntry now points to the entry following the last |
| // selected entry. |
| SwOutlineNodes::size_type nDest = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| // here needs to found the next entry after next. |
| // The selection must be inserted in front of that. |
| while (pEntry) |
| { |
| pEntry = Next(pEntry); |
| assert(pEntry == nullptr || !lcl_IsContent(pEntry) || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| // nDest++ may only executed if pEntry != 0 |
| if (pEntry) |
| { |
| if (!lcl_IsContent(pEntry)) |
| break; |
| else if (nActLevel >= static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlineLevel()) |
| { |
| // nDest needs adjusted if there are selected entries (including ancestral lineage) |
| // immediately before the current moved entry. |
| SvTreeListEntry* pTmp = Prev(pEntry); |
| while (pTmp && lcl_IsContent(pTmp) && |
| nActLevel < static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlineLevel()) |
| { |
| while (pTmp && lcl_IsContent(pTmp) && !IsSelected(pTmp) && |
| nActLevel < static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlineLevel()) |
| { |
| pTmp = GetParent(pTmp); |
| } |
| if (!IsSelected(pTmp)) |
| break; |
| pTmp = Prev(pTmp); |
| nDest = static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlinePos(); |
| } |
| if (!IsSelected(pEntry->PrevSibling())) |
| break; |
| } |
| else |
| { |
| nDest = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| } |
| } |
| } |
| nDirLast = nDir = nDest - nActEndPos; |
| // If no entry was found that allows insertion before |
| // it, we just move it to the end. |
| } |
| else |
| nDirLast = nDir = 0; |
| } |
| } |
| else // move up |
| { |
| if (IsSelected(pCurrentEntry->PrevSibling())) |
| nDir = nDirLast; |
| else |
| { |
| SwOutlineNodes::size_type nDest = nActPos; |
| pEntry = pCurrentEntry; |
| while (pEntry && nDest) |
| { |
| pEntry = Prev(pEntry); |
| assert(pEntry == nullptr || !lcl_IsContent(pEntry) || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| if (pEntry && lcl_IsContent(pEntry)) |
| { |
| nDest = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| } |
| else |
| { |
| nDest = 0; // presumably? |
| } |
| if (pEntry) |
| { |
| if (!lcl_IsContent(pEntry)) |
| break; |
| else if (nActLevel >= static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlineLevel()) |
| { |
| // nDest needs adjusted if there are selected entries immediately |
| // after the level change. |
| SvTreeListEntry* pTmp = Next(pEntry); |
| while (pTmp && lcl_IsContent(pTmp) && |
| nActLevel < static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlineLevel() && |
| IsSelected(pTmp)) |
| { |
| nDest = static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlinePos(); |
| const auto nLevel = static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlineLevel(); |
| // account for selected entries' descendent lineage |
| pTmp = Next(pTmp); |
| while (pTmp && lcl_IsContent(pTmp) && |
| nLevel < static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlineLevel()) |
| { |
| nDest = static_cast<SwOutlineContent*>(pTmp->GetUserData())->GetOutlinePos(); |
| pTmp = Next(pTmp); |
| } |
| } |
| break; |
| } |
| } |
| } |
| nDirLast = nDir = nDest - nActPos; |
| } |
| } |
| if (nDir) |
| { |
| pShell->MoveOutlinePara( nDir ); |
| // Set cursor back to the current position |
| pShell->GotoOutline(nActPos + nDir); |
| } |
| } |
| } |
| else |
| { |
| if (!pShell->IsProtectedOutlinePara()) |
| pShell->OutlineUpDown(bLeft ? -1 : 1); |
| } |
| |
| pShell->ClearMark(); |
| pShell->Pop(SwCursorShell::PopMode::DeleteCurrent); // Cursor is now back at the current heading. |
| } |
| |
| if (bStartedAction) |
| { |
| pShell->EndUndo(); |
| pShell->EndAllAction(); |
| if (m_aActiveContentArr[ContentTypeId::OUTLINE]) |
| m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); |
| Display(true); |
| if (!m_bIsRoot) |
| { |
| const SwOutlineNodes::size_type nCurrPos = pShell->GetOutlinePos(MAXLEVEL); |
| SvTreeListEntry* pFirst = First(); |
| |
| while (nullptr != (pFirst = Next(pFirst)) && lcl_IsContent(pFirst)) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pFirst->GetUserData()))); |
| if (static_cast<SwOutlineContent*>(pFirst->GetUserData())->GetOutlinePos() == nCurrPos) |
| { |
| Select(pFirst); |
| MakeVisible(pFirst); |
| } |
| } |
| } |
| else |
| { |
| // Reselect entries |
| const SwOutlineNodes& rOutLineNds = pShell->GetNodes().GetOutLineNds(); |
| for (SwTextNode* pNode : selectedOutlineNodes) |
| { |
| SwOutlineNodes::const_iterator aFndIt = rOutLineNds.find(pNode); |
| if(aFndIt == rOutLineNds.end()) |
| continue; |
| const size_t nFndPos = aFndIt - rOutLineNds.begin(); |
| SvTreeListEntry* pEntry = GetEntryAtAbsPos(nFndPos + 1); |
| if (pEntry) |
| { |
| SvTreeListBox::SelectListEntry(pEntry, true); |
| if (!IsExpanded(pEntry->GetParent())) |
| Expand(pEntry->GetParent()); |
| } |
| } |
| SvTreeListBox::Invalidate(); |
| } |
| } |
| } |
| |
| void SwContentTree::ShowTree() |
| { |
| SvTreeListBox::Show(); |
| } |
| |
| void SwContentTree::Paint( vcl::RenderContext& rRenderContext, |
| const tools::Rectangle& rRect ) |
| { |
| // Start the update timer on the first paint; avoids |
| // flicker on the first reveal. |
| m_aUpdTimer.Start(); |
| SvTreeListBox::Paint( rRenderContext, rRect ); |
| } |
| |
| void SwContentTree::HideTree() |
| { |
| // folded together will not be idled |
| m_aUpdTimer.Stop(); |
| SvTreeListBox::Hide(); |
| } |
| |
| /** No idle with focus or while dragging */ |
| IMPL_LINK_NOARG(SwContentTree, TimerUpdate, Timer *, void) |
| { |
| if (IsDisposed()) |
| return; |
| |
| // No update while focus is not in document. |
| // No update while drag and drop. |
| // Query view because the Navigator is cleared too late. |
| SwView* pView = GetParentWindow()->GetCreateView(); |
| |
| if(pView && pView->GetWrtShellPtr() && |
| ((pView->GetWrtShellPtr()->GetWin() == GetFocusedWindow()) || m_bViewHasChanged) && |
| !bIsInDrag && !m_bIsInternalDrag && !pView->GetWrtShellPtr()->ActionPend()) |
| { |
| m_bViewHasChanged = false; |
| m_bIsIdleClear = false; |
| SwWrtShell* pActShell = pView->GetWrtShellPtr(); |
| if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell)) |
| { |
| SetActiveShell(pActShell); |
| GetParentWindow()->UpdateListBox(); |
| } |
| |
| if (State::ACTIVE == m_eState && pActShell != GetWrtShell()) |
| { |
| SetActiveShell(pActShell); |
| } |
| else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) && |
| HasContentChanged()) |
| { |
| FindActiveTypeAndRemoveUserData(); |
| Display(true); |
| } |
| } |
| else if (!pView && State::ACTIVE == m_eState && !m_bIsIdleClear) |
| { |
| if(m_pActiveShell) |
| { |
| SetActiveShell(nullptr); |
| } |
| Clear(); |
| m_bIsIdleClear = true; |
| } |
| } |
| |
| DragDropMode SwContentTree::NotifyStartDrag( |
| TransferDataContainer& rContainer, |
| SvTreeListEntry* pEntry ) |
| { |
| DragDropMode eMode = DragDropMode(0); |
| if (State::ACTIVE == m_eState && m_nRootType == ContentTypeId::OUTLINE && |
| GetModel()->GetAbsPos( pEntry ) > 0 |
| && !GetWrtShell()->GetView().GetDocShell()->IsReadOnly()) |
| { |
| eMode = GetDragDropMode(); |
| if (m_bIsRoot) |
| { |
| // Restore selection for multiple selected outlines. |
| for (const auto pSelected : m_aDndOutlinesSelected) |
| SelectListEntry(pSelected, true); |
| } |
| } |
| else if (State::ACTIVE != m_eState && GetWrtShell()->GetView().GetDocShell()->HasName()) |
| eMode = DragDropMode::APP_COPY; |
| |
| sal_Int8 nDragMode; |
| FillTransferData( rContainer, nDragMode ); |
| m_bDocChgdInDragging = false; |
| m_bIsInternalDrag = true; |
| return eMode; |
| } |
| // After the drag the current paragraph will be moved w i t h the children. |
| |
| TriState SwContentTree::NotifyMoving( SvTreeListEntry* pTarget, |
| SvTreeListEntry* pEntry, SvTreeListEntry*& , sal_uLong& ) |
| { |
| static SwOutlineNodes::size_type nStaticSourcePos = SwOutlineNodes::npos; |
| static SwOutlineNodes::size_type nStaticTargetPosOrOffset = SwOutlineNodes::npos; |
| if(!m_bDocChgdInDragging) |
| { |
| SwOutlineNodes::size_type nTargetPos = 0; |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwOutlineNodes::size_type nSourcePos = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| if(!lcl_IsContent(pTarget)) |
| nTargetPos = SwOutlineNodes::npos; |
| else |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pTarget->GetUserData()))); |
| nTargetPos = static_cast<SwOutlineContent*>(pTarget->GetUserData())->GetOutlinePos(); |
| } |
| if( MAXLEVEL > m_nOutlineLevel && // Not all layers are displayed. |
| nTargetPos != SwOutlineNodes::npos) |
| { |
| SvTreeListEntry* pNext = Next(pTarget); |
| if(pNext) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pNext->GetUserData()))); |
| nTargetPos = static_cast<SwOutlineContent*>(pNext->GetUserData())->GetOutlinePos() - 1; |
| } |
| else |
| nTargetPos = GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineNodesCount() - 1; |
| } |
| |
| OSL_ENSURE( pEntry && |
| lcl_IsContent(pEntry),"Source == 0 or Source has no Content" ); |
| |
| if (nStaticTargetPosOrOffset != SwOutlineNodes::npos) |
| { |
| if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos) |
| { |
| // Move up |
| nTargetPos = nSourcePos - nStaticTargetPosOrOffset; |
| } |
| else if (nSourcePos < nTargetPos) |
| { |
| // Move down |
| nSourcePos = nStaticSourcePos; |
| nTargetPos = nStaticTargetPosOrOffset; |
| } |
| } |
| // Done on the first selection move |
| if (nTargetPos == SwOutlineNodes::npos || (nStaticTargetPosOrOffset == SwOutlineNodes::npos && nSourcePos > nTargetPos)) // only do once |
| { |
| // Up moves |
| // The first up move sets the up move amount for the remaining selected outlines to be moved |
| if (nTargetPos != SwOutlineNodes::npos) |
| nStaticTargetPosOrOffset = nSourcePos - nTargetPos; |
| else |
| nStaticTargetPosOrOffset = nSourcePos + 1; |
| } |
| else if (nStaticTargetPosOrOffset == SwOutlineNodes::npos && nSourcePos < nTargetPos) |
| { |
| // Down moves |
| // The first down move sets the source and target positions for the remaining selected outlines to be moved |
| nStaticSourcePos = nSourcePos; |
| nStaticTargetPosOrOffset = nTargetPos; |
| } |
| // Done on the last selection move |
| if (!IsSelected(pEntry->NextSibling())) |
| nStaticTargetPosOrOffset = SwOutlineNodes::npos; |
| |
| GetParentWindow()->MoveOutline( nSourcePos, |
| nTargetPos, |
| true); |
| } |
| //TreeListBox will be reloaded from the document |
| return TRISTATE_FALSE; |
| } |
| |
| // After the drag the current paragraph will be moved w i t h o u t the children. |
| |
| TriState SwContentTree::NotifyCopying( SvTreeListEntry* pTarget, |
| SvTreeListEntry* pEntry, SvTreeListEntry*& , sal_uLong& ) |
| { |
| if(!m_bDocChgdInDragging) |
| { |
| SwOutlineNodes::size_type nTargetPos = 0; |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| SwOutlineNodes::size_type nSourcePos = static_cast<SwOutlineContent*>(pEntry->GetUserData())->GetOutlinePos(); |
| if(!lcl_IsContent(pTarget)) |
| nTargetPos = SwOutlineNodes::npos; |
| else |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pTarget->GetUserData()))); |
| nTargetPos = static_cast<SwOutlineContent*>(pTarget->GetUserData())->GetOutlinePos(); |
| } |
| |
| if( MAXLEVEL > m_nOutlineLevel && // Not all layers are displayed. |
| nTargetPos != SwOutlineNodes::npos) |
| { |
| SvTreeListEntry* pNext = Next(pTarget); |
| if(pNext) |
| { |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pNext->GetUserData()))); |
| nTargetPos = static_cast<SwOutlineContent*>(pNext->GetUserData())->GetOutlinePos() - 1; |
| } |
| else |
| nTargetPos = GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineNodesCount() - 1; |
| } |
| |
| OSL_ENSURE( pEntry && |
| lcl_IsContent(pEntry),"Source == 0 or Source has no Content" ); |
| GetParentWindow()->MoveOutline( nSourcePos, nTargetPos, false); |
| |
| //TreeListBox will be reloaded from the document |
| m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); |
| Display(true); |
| } |
| return TRISTATE_FALSE; |
| } |
| |
| // No drop before the first entry - it's a SwContentType |
| |
| bool SwContentTree::NotifyAcceptDrop( SvTreeListEntry* pEntry) |
| { |
| return pEntry != nullptr; |
| } |
| |
| // If a Ctrl + DoubleClick are executed in an open area, |
| // then the base function of the control is to be called. |
| |
| void SwContentTree::MouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| Point aPos( rMEvt.GetPosPixel()); |
| SvTreeListEntry* pEntry = GetEntry( aPos, true ); |
| if( !pEntry && rMEvt.IsLeft() && rMEvt.IsMod1() && (rMEvt.GetClicks() % 2) == 0) |
| Control::MouseButtonDown( rMEvt ); |
| else |
| { |
| if( pEntry && (rMEvt.GetClicks() % 2) == 0) |
| { |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| const ContentTypeId nActType = pCnt->GetParent()->GetType(); |
| SetSublistDontOpenWithDoubleClick( nActType == ContentTypeId::OUTLINE ); |
| } |
| SvTreeListBox::MouseButtonDown( rMEvt ); |
| } |
| } |
| |
| // Update immediately |
| |
| void SwContentTree::GetFocus() |
| { |
| SwView* pActView = GetParentWindow()->GetCreateView(); |
| if(pActView) |
| { |
| SwWrtShell* pActShell = pActView->GetWrtShellPtr(); |
| if (State::CONSTANT == m_eState && !lcl_FindShell(m_pActiveShell)) |
| { |
| SetActiveShell(pActShell); |
| } |
| |
| if (State::ACTIVE == m_eState && pActShell != GetWrtShell()) |
| SetActiveShell(pActShell); |
| else if ((State::ACTIVE == m_eState || (State::CONSTANT == m_eState && pActShell == GetWrtShell())) && |
| HasContentChanged()) |
| { |
| Display(true); |
| } |
| } |
| else if (State::ACTIVE == m_eState) |
| Clear(); |
| SvTreeListBox::GetFocus(); |
| } |
| |
| void SwContentTree::KeyInput(const KeyEvent& rEvent) |
| { |
| const vcl::KeyCode aCode = rEvent.GetKeyCode(); |
| if(aCode.GetCode() == KEY_RETURN) |
| { |
| SvTreeListEntry* pEntry = FirstSelected(); |
| if ( pEntry ) |
| { |
| switch(aCode.GetModifier()) |
| { |
| case KEY_MOD2: |
| // Switch boxes |
| GetParentWindow()->ToggleTree(); |
| break; |
| case KEY_MOD1: |
| // Switch RootMode |
| ToggleToRoot(); |
| break; |
| case 0: |
| if(lcl_IsContentType(pEntry)) |
| { |
| IsExpanded(pEntry) ? Collapse(pEntry) : Expand(pEntry); |
| } |
| else |
| ContentDoubleClickHdl(nullptr); |
| break; |
| } |
| } |
| } |
| else if(aCode.GetCode() == KEY_DELETE && 0 == aCode.GetModifier()) |
| { |
| SvTreeListEntry* pEntry = FirstSelected(); |
| assert(!pEntry || dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData()))); |
| if(pEntry && |
| lcl_IsContent(pEntry) && |
| static_cast<SwContent*>(pEntry->GetUserData())->GetParent()->IsDeletable() && |
| !m_pActiveShell->GetView().GetDocShell()->IsReadOnly()) |
| { |
| EditEntry(pEntry, EditEntryMode::DELETE); |
| m_bViewHasChanged = true; |
| GetParentWindow()->UpdateListBox(); |
| TimerUpdate(&m_aUpdTimer); |
| GrabFocus(); |
| } |
| } |
| //Make KEY_SPACE has same function as DoubleClick , |
| //and realize multi-selection . |
| else if(aCode.GetCode() == KEY_SPACE && 0 == aCode.GetModifier()) |
| { |
| SvTreeListEntry* pEntry = GetCurEntry(); |
| if(pEntry) |
| { |
| if( GetChildCount( pEntry ) == 0 ) |
| m_bIsKeySpace = true; |
| Point tempPoint = GetEntryPosition( pEntry );//Change from "GetEntryPos" to "GetEntryPosition" for acc migration |
| m_aOldRectangle = GetFocusRect(pEntry, tempPoint.Y()); |
| |
| if (State::HIDDEN != m_eState) |
| { |
| if (State::CONSTANT == m_eState) |
| { |
| m_pActiveShell->GetView().GetViewFrame()->GetWindow().ToTop(); |
| } |
| |
| SwContent* pCnt = dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pEntry->GetUserData())); |
| |
| if (pCnt && pCnt->GetParent()->GetType() == ContentTypeId::DRAWOBJECT) |
| { |
| SdrView* pDrawView = m_pActiveShell->GetDrawView(); |
| if (pDrawView) |
| { |
| pDrawView->SdrEndTextEdit(); |
| |
| SwDrawModel* pDrawModel = m_pActiveShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); |
| SdrPage* pPage = pDrawModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| bool hasObjectMarked = false; |
| |
| if (SdrObject* pObject = GetDrawingObjectsByContent(pCnt)) |
| { |
| SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/); |
| if( pPV ) |
| { |
| bool bUnMark = pDrawView->IsObjMarked(pObject); |
| pDrawView->MarkObj( pObject, pPV, bUnMark); |
| |
| } |
| } |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| SdrObject* pTemp = pPage->GetObj(i); |
| bool bMark = pDrawView->IsObjMarked(pTemp); |
| switch( pTemp->GetObjIdentifier() ) |
| { |
| case OBJ_GRUP: |
| case OBJ_TEXT: |
| case OBJ_LINE: |
| case OBJ_RECT: |
| case OBJ_CIRC: |
| case OBJ_SECT: |
| case OBJ_CARC: |
| case OBJ_CCUT: |
| case OBJ_POLY: |
| case OBJ_PLIN: |
| case OBJ_PATHLINE: |
| case OBJ_PATHFILL: |
| case OBJ_FREELINE: |
| case OBJ_FREEFILL: |
| case OBJ_PATHPOLY: |
| case OBJ_PATHPLIN: |
| case OBJ_CAPTION: |
| case OBJ_CUSTOMSHAPE: |
| if( bMark ) |
| hasObjectMarked = true; |
| break; |
| default: |
| if ( bMark ) |
| { |
| SdrPageView* pPV = pDrawView->GetSdrPageView/*GetPageViewPvNum*/(/*0*/); |
| if (pPV) |
| { |
| pDrawView->MarkObj(pTemp, pPV, true); |
| } |
| } |
| } |
| //mod end |
| } |
| if ( !hasObjectMarked ) |
| { |
| SwEditWin& rEditWindow = m_pActiveShell->GetView().GetEditWin(); |
| vcl::KeyCode tempKeycode( KEY_ESCAPE ); |
| KeyEvent rKEvt( 0 , tempKeycode ); |
| static_cast<vcl::Window*>(&rEditWindow)->KeyInput( rKEvt ); |
| } |
| } |
| } |
| |
| m_bViewHasChanged = true; |
| } |
| } |
| |
| } |
| else if (m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE && aCode.GetCode() == KEY_LEFT) |
| { |
| SelectAll(false); |
| SvTreeListBox::KeyInput(rEvent); |
| } |
| else |
| SvTreeListBox::KeyInput(rEvent); |
| |
| } |
| |
| void SwContentTree::RequestHelp( const HelpEvent& rHEvt ) |
| { |
| bool bCallBase = true; |
| if( rHEvt.GetMode() & HelpEventMode::QUICK ) |
| { |
| Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() )); |
| SvTreeListEntry* pEntry = GetEntry( aPos ); |
| if( pEntry ) |
| { |
| ContentTypeId nType; |
| bool bBalloon = false; |
| bool bContent = false; |
| void* pUserData = pEntry->GetUserData(); |
| if(lcl_IsContentType(pEntry)) |
| { |
| assert(dynamic_cast<SwContentType*>(static_cast<SwTypeNumber*>(pUserData))); |
| nType = static_cast<SwContentType*>(pUserData)->GetType(); |
| } |
| else |
| { |
| assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pUserData))); |
| nType = static_cast<SwContent*>(pUserData)->GetParent()->GetType(); |
| bContent = true; |
| } |
| OUString sEntry; |
| bool bRet = false; |
| if(bContent) |
| { |
| switch( nType ) |
| { |
| case ContentTypeId::URLFIELD: |
| assert(dynamic_cast<SwURLFieldContent*>(static_cast<SwTypeNumber*>(pUserData))); |
| sEntry = static_cast<SwURLFieldContent*>(pUserData)->GetURL(); |
| bRet = true; |
| break; |
| |
| case ContentTypeId::POSTIT: |
| assert(dynamic_cast<SwPostItContent*>(static_cast<SwTypeNumber*>(pUserData))); |
| sEntry = static_cast<SwPostItContent*>(pUserData)->GetName(); |
| bRet = true; |
| if(Help::IsBalloonHelpEnabled()) |
| bBalloon = true; |
| break; |
| case ContentTypeId::OUTLINE: |
| assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pUserData))); |
| sEntry = static_cast<SwOutlineContent*>(pUserData)->GetName(); |
| bRet = true; |
| break; |
| case ContentTypeId::GRAPHIC: |
| assert(dynamic_cast<SwGraphicContent*>(static_cast<SwTypeNumber*>(pUserData))); |
| sEntry = static_cast<SwGraphicContent*>(pUserData)->GetLink(); |
| bRet = true; |
| break; |
| default: break; |
| } |
| if(static_cast<SwContent*>(pUserData)->IsInvisible()) |
| { |
| if(!sEntry.isEmpty()) |
| sEntry += ", "; |
| sEntry += m_sInvisible; |
| bRet = true; |
| } |
| } |
| else |
| { |
| const size_t nMemberCount = static_cast<SwContentType*>(pUserData)->GetMemberCount(); |
| sEntry = OUString::number(nMemberCount) + " " + |
| (nMemberCount == 1 |
| ? static_cast<SwContentType*>(pUserData)->GetSingleName() |
| : static_cast<SwContentType*>(pUserData)->GetName()); |
| bRet = true; |
| } |
| if(bRet) |
| { |
| SvLBoxTab* pTab; |
| SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab ); |
| if (pItem && SvLBoxItemType::String == pItem->GetType()) |
| { |
| aPos = GetEntryPosition( pEntry ); |
| |
| aPos.setX( GetTabPos( pEntry, pTab ) ); |
| Size aSize(pItem->GetWidth(this, pEntry), pItem->GetHeight(this, pEntry)); |
| |
| if((aPos.X() + aSize.Width()) > GetSizePixel().Width()) |
| aSize.setWidth( GetSizePixel().Width() - aPos.X() ); |
| |
| aPos = OutputToScreenPixel(aPos); |
| tools::Rectangle aItemRect( aPos, aSize ); |
| if(bBalloon) |
| { |
| aPos.AdjustX(aSize.Width() ); |
| Help::ShowBalloon( this, aPos, aItemRect, sEntry ); |
| } |
| else |
| Help::ShowQuickHelp( this, aItemRect, sEntry, |
| QuickHelpFlags::Left|QuickHelpFlags::VCenter ); |
| bCallBase = false; |
| } |
| } |
| else |
| { |
| Help::ShowQuickHelp( this, tools::Rectangle(), OUString() ); |
| bCallBase = false; |
| } |
| } |
| } |
| if( bCallBase ) |
| Window::RequestHelp( rHEvt ); |
| } |
| |
| void SwContentTree::ExecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry ) |
| { |
| SvTreeListEntry* pFirst = FirstSelected(); |
| switch( nSelectedPopupEntry ) |
| { |
| //Outlinelevel |
| case 101: |
| case 102: |
| case 103: |
| case 104: |
| case 105: |
| case 106: |
| case 107: |
| case 108: |
| case 109: |
| case 110: |
| nSelectedPopupEntry -= 100; |
| if(m_nOutlineLevel != nSelectedPopupEntry ) |
| SetOutlineLevel(static_cast<sal_Int8>(nSelectedPopupEntry)); |
| break; |
| case 201: |
| case 202: |
| case 203: |
| GetParentWindow()->SetRegionDropMode(static_cast<RegionMode>(nSelectedPopupEntry - 201)); |
| break; |
| case 401: |
| case 402: |
| EditEntry(pFirst, nSelectedPopupEntry == 401 ? EditEntryMode::RMV_IDX : EditEntryMode::UPD_IDX); |
| break; |
| // Edit entry |
| case 403: |
| EditEntry(pFirst, EditEntryMode::EDIT); |
| break; |
| case 404: |
| EditEntry(pFirst, EditEntryMode::UNPROTECT_TABLE); |
| break; |
| case 405 : |
| { |
| const SwTOXBase* pBase = static_cast<SwTOXBaseContent*>(pFirst->GetUserData()) |
| ->GetTOXBase(); |
| m_pActiveShell->SetTOXBaseReadonly(*pBase, !SwEditShell::IsTOXBaseReadonly(*pBase)); |
| } |
| break; |
| case 4: |
| break; |
| case 501: |
| EditEntry(pFirst, EditEntryMode::DELETE); |
| break; |
| case 502 : |
| EditEntry(pFirst, EditEntryMode::RENAME); |
| break; |
| case 600: |
| m_pActiveShell->GetView().GetPostItMgr()->Show(); |
| break; |
| case 601: |
| m_pActiveShell->GetView().GetPostItMgr()->Hide(); |
| break; |
| case 602: |
| { |
| m_pActiveShell->GetView().GetPostItMgr()->SetActiveSidebarWin(nullptr); |
| m_pActiveShell->GetView().GetPostItMgr()->Delete(); |
| break; |
| } |
| case 700: |
| { |
| m_pActiveShell->GetView().GetViewFrame()->GetDispatcher()->Execute(FN_OUTLINE_TO_CLIPBOARD); |
| break; |
| } |
| case 800: |
| KeyInput(KeyEvent(0, KEY_MOD1|KEY_MULTIPLY)); |
| break; |
| case 801: |
| ExecCommand("up", true); |
| break; |
| case 802: |
| ExecCommand("down", true); |
| break; |
| case 803: |
| ExecCommand("promote", true); |
| break; |
| case 804: |
| ExecCommand("demote", true); |
| break; |
| //Display |
| default: |
| if(nSelectedPopupEntry > 300 && nSelectedPopupEntry < 400) |
| { |
| nSelectedPopupEntry -= 300; |
| SwView *pView = SwModule::GetFirstView(); |
| while (pView) |
| { |
| nSelectedPopupEntry --; |
| if(nSelectedPopupEntry == 0) |
| { |
| SetConstantShell(&pView->GetWrtShell()); |
| break; |
| } |
| pView = SwModule::GetNextView(pView); |
| } |
| if(nSelectedPopupEntry) |
| { |
| m_bViewHasChanged = nSelectedPopupEntry == 1; |
| m_eState = (nSelectedPopupEntry == 1) ? State::ACTIVE : State::HIDDEN; |
| Display(nSelectedPopupEntry == 1); |
| } |
| } |
| } |
| GetParentWindow()->UpdateListBox(); |
| } |
| |
| void SwContentTree::SetOutlineLevel(sal_uInt8 nSet) |
| { |
| m_nOutlineLevel = nSet; |
| m_pConfig->SetOutlineLevel( m_nOutlineLevel ); |
| std::unique_ptr<SwContentType>& rpContentT = (State::ACTIVE == m_eState) |
| ? m_aActiveContentArr[ContentTypeId::OUTLINE] |
| : m_aHiddenContentArr[ContentTypeId::OUTLINE]; |
| if(rpContentT) |
| { |
| rpContentT->SetOutlineLevel(m_nOutlineLevel); |
| rpContentT->Init(); |
| } |
| Display(State::ACTIVE == m_eState); |
| } |
| |
| // Mode Change: Show dropped Doc |
| |
| void SwContentTree::ShowHiddenShell() |
| { |
| if(m_pHiddenShell) |
| { |
| m_eState = State::HIDDEN; |
| Display(false); |
| } |
| } |
| |
| // Mode Change: Show active view |
| |
| void SwContentTree::ShowActualView() |
| { |
| m_eState = State::ACTIVE; |
| Display(true); |
| GetParentWindow()->UpdateListBox(); |
| } |
| |
| // Here the buttons for moving outlines are en-/disabled. |
| bool SwContentTree::Select( SvTreeListEntry* pEntry, bool bSelect ) |
| { |
| if(!pEntry) |
| return false; |
| bool bEnable = false; |
| SvTreeListEntry* pParentEntry = GetParent(pEntry); |
| while(pParentEntry && (!lcl_IsContentType(pParentEntry))) |
| { |
| pParentEntry = GetParent(pParentEntry); |
| } |
| if (!m_bIsLastReadOnly) |
| { |
| if (!IsVisible()) |
| bEnable = true; |
| else if (pParentEntry) |
| { |
| if ((m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE) || |
| (lcl_IsContent(pEntry) && |
| static_cast<SwContentType*>(pParentEntry->GetUserData())->GetType() == ContentTypeId::OUTLINE)) |
| { |
| bEnable = true; |
| } |
| } |
| } |
| SwNavigationPI* pNavi = GetParentWindow(); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("up"), bEnable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("down"), bEnable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("promote"), bEnable); |
| pNavi->m_aContentToolBox->EnableItem(pNavi->m_aContentToolBox->GetItemId("demote"), bEnable); |
| |
| return SvTreeListBox::Select(pEntry, bSelect); |
| } |
| |
| void SwContentTree::SetRootType(ContentTypeId nType) |
| { |
| m_nRootType = nType; |
| m_bIsRoot = true; |
| m_pConfig->SetRootType( m_nRootType ); |
| } |
| |
| OUString SwContentType::RemoveNewline(const OUString& rEntry) |
| { |
| if (rEntry.isEmpty()) |
| return rEntry; |
| |
| OUStringBuffer aEntry(rEntry); |
| for (sal_Int32 i = 0; i < rEntry.getLength(); ++i) |
| if(aEntry[i] == 10 || aEntry[i] == 13) |
| aEntry[i] = 0x20; |
| |
| return aEntry.makeStringAndClear(); |
| } |
| |
| void SwContentTree::EditEntry(SvTreeListEntry const * pEntry, EditEntryMode nMode) |
| { |
| SwContent* pCnt = static_cast<SwContent*>(pEntry->GetUserData()); |
| GotoContent(pCnt); |
| const ContentTypeId nType = pCnt->GetParent()->GetType(); |
| sal_uInt16 nSlot = 0; |
| |
| uno::Reference< container::XNameAccess > xNameAccess, xSecond, xThird; |
| switch(nType) |
| { |
| case ContentTypeId::TABLE : |
| if(nMode == EditEntryMode::UNPROTECT_TABLE) |
| { |
| m_pActiveShell->GetView().GetDocShell()-> |
| GetDoc()->UnProtectCells( pCnt->GetName()); |
| } |
| else if(nMode == EditEntryMode::DELETE) |
| { |
| m_pActiveShell->StartAction(); |
| OUString sTable = SwResId(STR_TABLE_NAME); |
| SwRewriter aRewriterTableName; |
| aRewriterTableName.AddRule(UndoArg1, SwResId(STR_START_QUOTE)); |
| aRewriterTableName.AddRule(UndoArg2, pCnt->GetName()); |
| aRewriterTableName.AddRule(UndoArg3, SwResId(STR_END_QUOTE)); |
| sTable = aRewriterTableName.Apply(sTable); |
| |
| SwRewriter aRewriter; |
| aRewriter.AddRule(UndoArg1, sTable); |
| m_pActiveShell->StartUndo(SwUndoId::DELETE, &aRewriter); |
| m_pActiveShell->GetView().GetViewFrame()->GetDispatcher()->Execute(FN_TABLE_SELECT_ALL); |
| m_pActiveShell->DeleteRow(); |
| m_pActiveShell->EndUndo(); |
| m_pActiveShell->EndAction(); |
| } |
| else if(nMode == EditEntryMode::RENAME) |
| { |
| uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| uno::Reference< text::XTextTablesSupplier > xTables(xModel, uno::UNO_QUERY); |
| xNameAccess = xTables->getTextTables(); |
| } |
| else |
| nSlot = FN_FORMAT_TABLE_DLG; |
| break; |
| |
| case ContentTypeId::GRAPHIC : |
| if(nMode == EditEntryMode::DELETE) |
| { |
| m_pActiveShell->DelRight(); |
| } |
| else if(nMode == EditEntryMode::RENAME) |
| { |
| uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY); |
| xNameAccess = xGraphics->getGraphicObjects(); |
| uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY); |
| xSecond = xFrames->getTextFrames(); |
| uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY); |
| xThird = xObjs->getEmbeddedObjects(); |
| } |
| else |
| nSlot = FN_FORMAT_GRAFIC_DLG; |
| break; |
| |
| case ContentTypeId::FRAME : |
| case ContentTypeId::OLE : |
| if(nMode == EditEntryMode::DELETE) |
| { |
| m_pActiveShell->DelRight(); |
| } |
| else if(nMode == EditEntryMode::RENAME) |
| { |
| uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY); |
| uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY); |
| if(ContentTypeId::FRAME == nType) |
| { |
| xNameAccess = xFrames->getTextFrames(); |
| xSecond = xObjs->getEmbeddedObjects(); |
| } |
| else |
| { |
| xNameAccess = xObjs->getEmbeddedObjects(); |
| xSecond = xFrames->getTextFrames(); |
| } |
| uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY); |
| xThird = xGraphics->getGraphicObjects(); |
| } |
| else |
| nSlot = FN_FORMAT_FRAME_DLG; |
| break; |
| case ContentTypeId::BOOKMARK : |
| if(nMode == EditEntryMode::DELETE) |
| { |
| IDocumentMarkAccess* const pMarkAccess = m_pActiveShell->getIDocumentMarkAccess(); |
| pMarkAccess->deleteMark( pMarkAccess->findMark(pCnt->GetName()) ); |
| } |
| else if(nMode == EditEntryMode::RENAME) |
| { |
| uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| uno::Reference< text::XBookmarksSupplier > xBkms(xModel, uno::UNO_QUERY); |
| xNameAccess = xBkms->getBookmarks(); |
| } |
| else |
| nSlot = FN_INSERT_BOOKMARK; |
| break; |
| |
| case ContentTypeId::REGION : |
| if(nMode == EditEntryMode::RENAME) |
| { |
| uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| uno::Reference< text::XTextSectionsSupplier > xSects(xModel, uno::UNO_QUERY); |
| xNameAccess = xSects->getTextSections(); |
| } |
| else |
| nSlot = FN_EDIT_REGION; |
| break; |
| |
| case ContentTypeId::URLFIELD: |
| nSlot = SID_EDIT_HYPERLINK; |
| break; |
| case ContentTypeId::REFERENCE: |
| nSlot = FN_EDIT_FIELD; |
| break; |
| |
| case ContentTypeId::POSTIT: |
| m_pActiveShell->GetView().GetPostItMgr()->AssureStdModeAtShell(); |
| if(nMode == EditEntryMode::DELETE) |
| { |
| m_pActiveShell->GetView().GetPostItMgr()->SetActiveSidebarWin(nullptr); |
| m_pActiveShell->DelRight(); |
| } |
| else |
| { |
| nSlot = FN_POSTIT; |
| } |
| break; |
| case ContentTypeId::INDEX: |
| { |
| const SwTOXBase* pBase = static_cast<SwTOXBaseContent*>(pCnt)->GetTOXBase(); |
| switch(nMode) |
| { |
| case EditEntryMode::EDIT: |
| if(pBase) |
| { |
| SwPtrItem aPtrItem( FN_INSERT_MULTI_TOX, const_cast<SwTOXBase *>(pBase)); |
| m_pActiveShell->GetView().GetViewFrame()-> |
| GetDispatcher()->ExecuteList(FN_INSERT_MULTI_TOX, |
| SfxCallMode::ASYNCHRON, { &aPtrItem }); |
| |
| } |
| break; |
| case EditEntryMode::RMV_IDX: |
| case EditEntryMode::DELETE: |
| { |
| if( pBase ) |
| m_pActiveShell->DeleteTOX(*pBase, EditEntryMode::DELETE == nMode); |
| } |
| break; |
| case EditEntryMode::UPD_IDX: |
| case EditEntryMode::RENAME: |
| { |
| Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); |
| Reference< XDocumentIndexesSupplier > xIndexes(xModel, UNO_QUERY); |
| Reference< XIndexAccess> xIdxAcc(xIndexes->getDocumentIndexes()); |
| Reference< XNameAccess >xLocalNameAccess(xIdxAcc, UNO_QUERY); |
| if(EditEntryMode::RENAME == nMode) |
| xNameAccess = xLocalNameAccess; |
| else if(xLocalNameAccess.is() && xLocalNameAccess->hasByName(pBase->GetTOXName())) |
| { |
| Any aIdx = xLocalNameAccess->getByName(pBase->GetTOXName()); |
| Reference< XDocumentIndex> xIdx; |
| if(aIdx >>= xIdx) |
| xIdx->update(); |
| } |
| } |
| break; |
| default: break; |
| } |
| } |
| break; |
| case ContentTypeId::OUTLINE : |
| if(EditEntryMode::DELETE == nMode) |
| { |
| SwOutlineNodes::size_type nActPos = static_cast<SwOutlineContent*>(pCnt)->GetOutlinePos(); |
| SwWrtShell* pShell = m_pActiveShell; |
| pShell->StartAllAction(); |
| pShell->StartUndo(); |
| pShell->Push(); |
| pShell->MakeOutlineSel(nActPos, nActPos, true); |
| pShell->SetTextFormatColl(nullptr); |
| pShell->Delete(); |
| pShell->ClearMark(); |
| pShell->Pop(SwCursorShell::PopMode::DeleteCurrent); |
| pShell->EndUndo(); |
| pShell->EndAllAction(); |
| } |
| break; |
| case ContentTypeId::DRAWOBJECT : |
| if(EditEntryMode::DELETE == nMode) |
| nSlot = SID_DELETE; |
| else if(nMode == EditEntryMode::RENAME) |
| nSlot = FN_NAME_SHAPE; |
| break; |
| default: break; |
| } |
| if(nSlot) |
| m_pActiveShell->GetView().GetViewFrame()-> |
| GetDispatcher()->Execute(nSlot, SfxCallMode::ASYNCHRON); |
| else if(xNameAccess.is()) |
| { |
| uno::Any aObj = xNameAccess->getByName(pCnt->GetName()); |
| uno::Reference< uno::XInterface > xTmp; |
| aObj >>= xTmp; |
| uno::Reference< container::XNamed > xNamed(xTmp, uno::UNO_QUERY); |
| SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); |
| ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(pFact->CreateSwRenameXNamedDlg(GetFrameWeld(), xNamed, xNameAccess)); |
| if(xSecond.is()) |
| pDlg->SetAlternativeAccess( xSecond, xThird); |
| |
| OUString sForbiddenChars; |
| if(ContentTypeId::BOOKMARK == nType) |
| { |
| sForbiddenChars = "/\\@:*?\";,.#"; |
| } |
| else if(ContentTypeId::TABLE == nType) |
| { |
| sForbiddenChars = " .<>"; |
| } |
| pDlg->SetForbiddenChars(sForbiddenChars); |
| pDlg->Execute(); |
| } |
| } |
| |
| void SwContentTree::GotoContent(const SwContent* pCnt) |
| { |
| m_pActiveShell->EnterStdMode(); |
| |
| bool bSel = false; |
| switch(pCnt->GetParent()->GetType()) |
| { |
| case ContentTypeId::OUTLINE : |
| { |
| m_pActiveShell->GotoOutline(static_cast<const SwOutlineContent*>(pCnt)->GetOutlinePos()); |
| } |
| break; |
| case ContentTypeId::TABLE : |
| { |
| m_pActiveShell->GotoTable(pCnt->GetName()); |
| } |
| break; |
| case ContentTypeId::FRAME : |
| case ContentTypeId::GRAPHIC : |
| case ContentTypeId::OLE : |
| { |
| if(m_pActiveShell->GotoFly(pCnt->GetName())) |
| bSel = true; |
| } |
| break; |
| case ContentTypeId::BOOKMARK: |
| { |
| m_pActiveShell->GotoMark(pCnt->GetName()); |
| } |
| break; |
| case ContentTypeId::REGION : |
| { |
| m_pActiveShell->GotoRegion(pCnt->GetName()); |
| } |
| break; |
| case ContentTypeId::URLFIELD: |
| { |
| if(m_pActiveShell->GotoINetAttr( |
| *static_cast<const SwURLFieldContent*>(pCnt)->GetINetAttr() )) |
| { |
| m_pActiveShell->Right( CRSR_SKIP_CHARS, true, 1, false); |
| m_pActiveShell->SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true ); |
| } |
| |
| } |
| break; |
| case ContentTypeId::REFERENCE: |
| { |
| m_pActiveShell->GotoRefMark(pCnt->GetName()); |
| } |
| break; |
| case ContentTypeId::INDEX: |
| { |
| const OUString& sName(pCnt->GetName()); |
| if (!m_pActiveShell->GotoNextTOXBase(&sName)) |
| m_pActiveShell->GotoPrevTOXBase(&sName); |
| } |
| break; |
| case ContentTypeId::POSTIT: |
| m_pActiveShell->GetView().GetPostItMgr()->AssureStdModeAtShell(); |
| m_pActiveShell->GotoFormatField(*static_cast<const SwPostItContent*>(pCnt)->GetPostIt()); |
| break; |
| case ContentTypeId::DRAWOBJECT: |
| { |
| SwPosition aPos = *m_pActiveShell->GetCursor()->GetPoint(); |
| SdrView* pDrawView = m_pActiveShell->GetDrawView(); |
| if (pDrawView) |
| { |
| pDrawView->SdrEndTextEdit(); |
| pDrawView->UnmarkAll(); |
| SwDrawModel* _pModel = m_pActiveShell->getIDocumentDrawModelAccess().GetDrawModel(); |
| SdrPage* pPage = _pModel->GetPage(0); |
| const size_t nCount = pPage->GetObjCount(); |
| for( size_t i=0; i<nCount; ++i ) |
| { |
| SdrObject* pTemp = pPage->GetObj(i); |
| if (pTemp->GetName() == pCnt->GetName()) |
| { |
| SdrPageView* pPV = pDrawView->GetSdrPageView(); |
| if( pPV ) |
| { |
| pDrawView->MarkObj( pTemp, pPV ); |
| } |
| } |
| } |
| m_pActiveShell->GetNavigationMgr().addEntry(aPos); |
| m_pActiveShell->EnterStdMode(); |
| bSel = true; |
| } |
| } |
| break; |
| default: break; |
| } |
| if(bSel) |
| { |
| m_pActiveShell->HideCursor(); |
| m_pActiveShell->EnterSelFrameMode(); |
| } |
| SwView& rView = m_pActiveShell->GetView(); |
| rView.StopShellTimer(); |
| rView.GetPostItMgr()->SetActiveSidebarWin(nullptr); |
| rView.GetEditWin().GrabFocus(); |
| |
| // force scroll to cursor position when navigating to inactive document |
| if(!bSel) |
| { |
| Point rPoint = m_pActiveShell->GetCursorDocPos(); |
| rPoint.setX(0); |
| rView.SetVisArea(rPoint); |
| } |
| } |
| |
| // Now even the matching text::Bookmark |
| NaviContentBookmark::NaviContentBookmark() |
| : |
| nDocSh(0), |
| nDefDrag( RegionMode::NONE ) |
| { |
| } |
| |
| NaviContentBookmark::NaviContentBookmark( const OUString &rUrl, |
| const OUString& rDesc, |
| RegionMode nDragType, |
| const SwDocShell* pDocSh ) : |
| aUrl( rUrl ), |
| aDescr(rDesc), |
| nDocSh(reinterpret_cast<sal_IntPtr>(pDocSh)), |
| nDefDrag( nDragType ) |
| { |
| } |
| |
| void NaviContentBookmark::Copy( TransferDataContainer& rData ) const |
| { |
| rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding(); |
| |
| OString sStrBuf(OUStringToOString(aUrl, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) + |
| OUStringToOString(aDescr, eSysCSet) + OStringChar(NAVI_BOOKMARK_DELIM) + |
| OString::number(static_cast<int>(nDefDrag)) + OStringChar(NAVI_BOOKMARK_DELIM) + |
| OString::number(nDocSh)); |
| rData.CopyByteString(SotClipboardFormatId::SONLK, sStrBuf); |
| } |
| |
| bool NaviContentBookmark::Paste( TransferableDataHelper& rData ) |
| { |
| OUString sStr; |
| bool bRet = rData.GetString( SotClipboardFormatId::SONLK, sStr ); |
| if( bRet ) |
| { |
| sal_Int32 nPos = 0; |
| aUrl = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ); |
| aDescr = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ); |
| nDefDrag= static_cast<RegionMode>( sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ).toInt32() ); |
| nDocSh = sStr.getToken(0, NAVI_BOOKMARK_DELIM, nPos ).toInt32(); |
| } |
| return bRet; |
| } |
| |
| namespace { |
| |
| class SwContentLBoxString : public SvLBoxString |
| { |
| public: |
| explicit SwContentLBoxString(const OUString& rStr) : SvLBoxString(rStr) {} |
| |
| virtual void Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, |
| const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override; |
| }; |
| |
| } |
| |
| void SwContentTree::InitEntry(SvTreeListEntry* pEntry, |
| const OUString& rStr ,const Image& rImg1,const Image& rImg2) |
| { |
| const size_t nColToHilite = 1; //0==Bitmap;1=="Column1";2=="Column2" |
| SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2 ); |
| SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite )); |
| pEntry->ReplaceItem(std::make_unique<SwContentLBoxString>(rCol.GetText()), nColToHilite); |
| } |
| |
| void SwContentLBoxString::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, |
| const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) |
| { |
| if (lcl_IsContent(&rEntry) && static_cast<SwContent *>(rEntry.GetUserData())->IsInvisible()) |
| { |
| vcl::Font aOldFont(rRenderContext.GetFont()); |
| vcl::Font aFont(aOldFont); |
| aFont.SetColor(COL_LIGHTGRAY); |
| rRenderContext.SetFont(aFont ); |
| rRenderContext.DrawText(rPos, GetText()); |
| rRenderContext.SetFont(aOldFont); |
| } |
| else |
| { |
| SvLBoxString::Paint(rPos, rDev, rRenderContext, pView, rEntry); |
| } |
| } |
| |
| void SwContentTree::DataChanged(const DataChangedEvent& rDCEvt) |
| { |
| if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && |
| (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) |
| { |
| FindActiveTypeAndRemoveUserData(); |
| |
| Display(true); |
| } |
| |
| SvTreeListBox::DataChanged( rDCEvt ); |
| } |
| |
| SwNavigationPI* SwContentTree::GetParentWindow() |
| { |
| return m_xDialog; |
| } |
| |
| /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |