1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <postithelper.hxx>
21 #include <PostItMgr.hxx>
22 #include <AnnotationWin.hxx>
27 #include <pagefrm.hxx>
28 #include <rootfrm.hxx>
30 #include <IDocumentRedlineAccess.hxx>
31 #include <IDocumentFieldsAccess.hxx>
32 #include <IDocumentMarkAccess.hxx>
33 #include <redline.hxx>
34 #include <scriptinfo.hxx>
37 #include <sortedobjs.hxx>
38 #include <anchoredobject.hxx>
39 #include <fmtanchr.hxx>
45 /// Checks if pAnnotationMark covers exactly rAnchorPos (the comment anchor).
46 bool AnnotationMarkCoversCommentAnchor(const sw::mark::IMark
* pAnnotationMark
,
47 const SwPosition
& rAnchorPos
)
54 const SwPosition
& rMarkStart
= pAnnotationMark
->GetMarkStart();
55 const SwPosition
& rMarkEnd
= pAnnotationMark
->GetMarkEnd();
57 if (rMarkStart
!= rAnchorPos
)
59 // This can be the as-char case: the comment placeholder character is exactly between the
60 // annotation mark start and end.
61 SwPosition
aPosition(rMarkStart
);
62 aPosition
.AdjustContent(+1);
63 if (aPosition
!= rAnchorPos
)
68 aPosition
.AdjustContent(+1);
69 if (aPosition
!= rMarkEnd
)
77 if (rMarkStart
.GetNode() != rMarkEnd
.GetNode())
82 return rMarkEnd
.GetContentIndex() == rMarkStart
.GetContentIndex() + 1;
86 * Finds the first draw object of rTextFrame which has the same anchor position as the start of
89 SwAnchoredObject
* GetAnchoredObjectOfAnnotationMark(const sw::mark::IMark
& rAnnotationMark
,
90 const SwTextFrame
& rTextFrame
)
92 const SwSortedObjs
* pAnchored
= rTextFrame
.GetDrawObjs();
98 for (SwAnchoredObject
* pObject
: *pAnchored
)
100 SwFrameFormat
& rFrameFormat
= pObject
->GetFrameFormat();
101 const SwPosition
* pFrameAnchor
= rFrameFormat
.GetAnchor().GetContentAnchor();
107 if (rAnnotationMark
.GetMarkStart() == *pFrameAnchor
)
117 SwSidebarItem::SwSidebarItem(const bool aFocus
)
121 , mbPendingLayout(false)
122 , mLayoutStatus(SwPostItHelper::INVISIBLE
)
126 SwSidebarItem::~SwSidebarItem() {}
128 SwPostItHelper::SwLayoutStatus
SwPostItHelper::getLayoutInfos(
129 SwLayoutInfo
& o_rInfo
,
130 const SwPosition
& rAnchorPos
,
131 const sw::mark::IMark
* pAnnotationMark
)
133 SwLayoutStatus aRet
= INVISIBLE
;
134 SwTextNode
* pTextNode
= rAnchorPos
.GetNode().GetTextNode();
135 if ( pTextNode
== nullptr )
138 SwIterator
<SwTextFrame
, SwContentNode
, sw::IteratorMode::UnwrapMulti
> aIter(*pTextNode
);
139 for( SwTextFrame
* pTextFrame
= aIter
.First(); pTextFrame
!= nullptr; pTextFrame
= aIter
.Next() )
141 if( !pTextFrame
->IsFollow() )
143 pTextFrame
= pTextFrame
->GetFrameAtPos( rAnchorPos
);
144 SwPageFrame
*pPage
= pTextFrame
? pTextFrame
->FindPageFrame() : nullptr;
145 if ( pPage
!= nullptr && !pPage
->IsInvalid() && !pPage
->IsInvalidFly() )
149 o_rInfo
.mpAnchorFrame
= pTextFrame
;
151 DisableCallbackAction
a(*pTextFrame
->getRootFrame());
152 bool bPositionFromCommentAnchor
= true;
153 if (AnnotationMarkCoversCommentAnchor(pAnnotationMark
, rAnchorPos
))
155 SwAnchoredObject
* pFrame
156 = GetAnchoredObjectOfAnnotationMark(*pAnnotationMark
, *pTextFrame
);
159 o_rInfo
.mPosition
= pFrame
->GetObjRect();
160 bPositionFromCommentAnchor
= false;
163 if (bPositionFromCommentAnchor
)
165 pTextFrame
->GetCharRect(o_rInfo
.mPosition
, rAnchorPos
, nullptr, false);
167 o_rInfo
.mPositionFromCommentAnchor
= bPositionFromCommentAnchor
;
169 if (pAnnotationMark
!= nullptr)
171 const SwPosition
& rAnnotationStartPos
= pAnnotationMark
->GetMarkStart();
172 o_rInfo
.mnStartNodeIdx
= rAnnotationStartPos
.GetNodeIndex();
173 o_rInfo
.mnStartContent
= rAnnotationStartPos
.GetContentIndex();
177 o_rInfo
.mnStartNodeIdx
= SwNodeOffset(0);
178 o_rInfo
.mnStartContent
= -1;
180 o_rInfo
.mPageFrame
= pPage
->getFrameArea();
181 o_rInfo
.mPagePrtArea
= pPage
->getFramePrintArea();
182 o_rInfo
.mPagePrtArea
.Pos() += o_rInfo
.mPageFrame
.Pos();
183 o_rInfo
.mnPageNumber
= pPage
->GetPhyPageNum();
184 o_rInfo
.meSidebarPosition
= pPage
->SidebarPosition();
185 o_rInfo
.mRedlineAuthor
= 0;
187 const IDocumentRedlineAccess
& rIDRA
= pTextNode
->getIDocumentRedlineAccess();
188 if( IDocumentRedlineAccess::IsShowChanges( rIDRA
.GetRedlineFlags() ) )
190 const SwRangeRedline
* pRedline
= rIDRA
.GetRedline( rAnchorPos
, nullptr );
193 if( RedlineType::Insert
== pRedline
->GetType() )
195 else if( RedlineType::Delete
== pRedline
->GetType() )
197 bool bDeleted
= pAnnotationMark
== nullptr;
200 IDocumentMarkAccess
& rDMA(*pTextNode
->GetDoc().getIDocumentMarkAccess());
201 IDocumentMarkAccess::const_iterator_t pAnnotationBookmark
=
202 rDMA
.findAnnotationBookmark(pAnnotationMark
->GetName());
203 // tdf#140980 only really deleted, if there is no helper bookmark
204 // in ChangesInMargin mode
205 if ( pAnnotationBookmark
== rDMA
.getBookmarksEnd() )
211 o_rInfo
.mRedlineAuthor
= pRedline
->GetAuthor();
218 return ( (aRet
==VISIBLE
) && SwScriptInfo::IsInHiddenRange( *pTextNode
, rAnchorPos
.GetContentIndex()) )
223 tools::Long
SwPostItHelper::getLayoutHeight( const SwRootFrame
* pRoot
)
225 tools::Long nRet
= pRoot
? pRoot
->getFrameArea().Height() : 0;
229 void SwPostItHelper::setSidebarChanged( SwRootFrame
* pRoot
, bool bBrowseMode
)
233 pRoot
->SetSidebarChanged();
235 pRoot
->InvalidateBrowseWidth();
239 tools::ULong
SwPostItHelper::getPageInfo( SwRect
& rPageFrame
, const SwRootFrame
* pRoot
, const Point
& rPoint
)
241 tools::ULong nRet
= 0;
242 const SwFrame
* pPage
= pRoot
->GetPageAtPos( rPoint
, nullptr, true );
245 nRet
= pPage
->GetPhyPageNum();
246 rPageFrame
= pPage
->getFrameArea();
251 SwPosition
SwAnnotationItem::GetAnchorPosition() const
253 SwTextField
* pTextField
= mrFormatField
.GetTextField();
254 SwTextNode
* pTextNode
= pTextField
->GetpTextNode();
256 SwPosition
aPos( *pTextNode
, pTextField
->GetStart() );
260 bool SwAnnotationItem::UseElement(SwRootFrame
const& rLayout
,
261 IDocumentRedlineAccess
const& rIDRA
)
263 return mrFormatField
.IsFieldInDoc()
264 && (!rLayout
.IsHideRedlines()
265 || !sw::IsFieldDeletedInModel(rIDRA
, *mrFormatField
.GetTextField()));
268 VclPtr
<sw::annotation::SwAnnotationWin
> SwAnnotationItem::GetSidebarWindow(
272 return VclPtr
<sw::annotation::SwAnnotationWin
>::Create( rEditWin
,
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */