android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / fields / postithelper.cxx
bloba3f27be6f5330a7f3eddb3163a6a3d8051779243
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <fmtfld.hxx>
25 #include <txtfld.hxx>
26 #include <ndtxt.hxx>
27 #include <pagefrm.hxx>
28 #include <rootfrm.hxx>
29 #include <txtfrm.hxx>
30 #include <IDocumentRedlineAccess.hxx>
31 #include <IDocumentFieldsAccess.hxx>
32 #include <IDocumentMarkAccess.hxx>
33 #include <redline.hxx>
34 #include <scriptinfo.hxx>
35 #include <calbck.hxx>
36 #include <IMark.hxx>
37 #include <sortedobjs.hxx>
38 #include <anchoredobject.hxx>
39 #include <fmtanchr.hxx>
41 class Point;
43 namespace
45 /// Checks if pAnnotationMark covers exactly rAnchorPos (the comment anchor).
46 bool AnnotationMarkCoversCommentAnchor(const sw::mark::IMark* pAnnotationMark,
47 const SwPosition& rAnchorPos)
49 if (!pAnnotationMark)
51 return false;
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)
65 return false;
68 aPosition.AdjustContent(+1);
69 if (aPosition != rMarkEnd)
71 return false;
74 return true;
77 if (rMarkStart.GetNode() != rMarkEnd.GetNode())
79 return false;
82 return rMarkEnd.GetContentIndex() == rMarkStart.GetContentIndex() + 1;
85 /**
86 * Finds the first draw object of rTextFrame which has the same anchor position as the start of
87 * rAnnotationMark.
89 SwAnchoredObject* GetAnchoredObjectOfAnnotationMark(const sw::mark::IMark& rAnnotationMark,
90 const SwTextFrame& rTextFrame)
92 const SwSortedObjs* pAnchored = rTextFrame.GetDrawObjs();
93 if (!pAnchored)
95 return nullptr;
98 for (SwAnchoredObject* pObject : *pAnchored)
100 SwFrameFormat& rFrameFormat = pObject->GetFrameFormat();
101 const SwPosition* pFrameAnchor = rFrameFormat.GetAnchor().GetContentAnchor();
102 if (!pFrameAnchor)
104 continue;
107 if (rAnnotationMark.GetMarkStart() == *pFrameAnchor)
109 return pObject;
113 return nullptr;
117 SwSidebarItem::SwSidebarItem(const bool aFocus)
118 : mpPostIt(nullptr)
119 , mbShow(true)
120 , mbFocus(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 )
136 return aRet;
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() )
147 aRet = VISIBLE;
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);
157 if (pFrame)
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();
175 else
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 );
191 if( pRedline )
193 if( RedlineType::Insert == pRedline->GetType() )
194 aRet = INSERTED;
195 else if( RedlineType::Delete == pRedline->GetType() )
197 bool bDeleted = pAnnotationMark == nullptr;
198 if( !bDeleted )
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() )
206 bDeleted = true;
208 if ( bDeleted )
209 aRet = DELETED;
211 o_rInfo.mRedlineAuthor = pRedline->GetAuthor();
218 return ( (aRet==VISIBLE) && SwScriptInfo::IsInHiddenRange( *pTextNode , rAnchorPos.GetContentIndex()) )
219 ? HIDDEN
220 : aRet;
223 tools::Long SwPostItHelper::getLayoutHeight( const SwRootFrame* pRoot )
225 tools::Long nRet = pRoot ? pRoot->getFrameArea().Height() : 0;
226 return nRet;
229 void SwPostItHelper::setSidebarChanged( SwRootFrame* pRoot, bool bBrowseMode )
231 if( pRoot )
233 pRoot->SetSidebarChanged();
234 if( bBrowseMode )
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 );
243 if( pPage )
245 nRet = pPage->GetPhyPageNum();
246 rPageFrame = pPage->getFrameArea();
248 return nRet;
251 SwPosition SwAnnotationItem::GetAnchorPosition() const
253 SwTextField* pTextField = mrFormatField.GetTextField();
254 SwTextNode* pTextNode = pTextField->GetpTextNode();
256 SwPosition aPos( *pTextNode, pTextField->GetStart() );
257 return aPos;
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(
269 SwEditWin& rEditWin,
270 SwPostItMgr& aMgr)
272 return VclPtr<sw::annotation::SwAnnotationWin>::Create( rEditWin,
273 aMgr,
274 *this,
275 &mrFormatField );
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */