LibreOffice Module sw (master) 1
callnk.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/i18n/XBreakIterator.hpp>
21#include <osl/diagnose.h>
22#include <fmtcntnt.hxx>
23#include <txatbase.hxx>
24#include "callnk.hxx"
25#include <crsrsh.hxx>
26#include <doc.hxx>
27#include <frmfmt.hxx>
28#include <txtfrm.hxx>
29#include <rowfrm.hxx>
30#include <fmtfsize.hxx>
31#include <ndtxt.hxx>
32#include <flyfrm.hxx>
33#include <breakit.hxx>
34#include <UndoTable.hxx>
35
37 : m_rShell( rSh )
38{
39 // remember SPoint-values of current cursor
41 SwNode& rNd = pCursor->GetPoint()->GetNode();
42 m_nNode = rNd.GetIndex();
43 m_nContent = pCursor->GetPoint()->GetContentIndex();
45 m_bHasSelection = ( *pCursor->GetPoint() != *pCursor->GetMark() );
46
47 if( rNd.IsTextNode() )
50 else
51 {
53
54 // A special treatment for SwFeShell:
55 // When deleting the header/footer, footnotes SwFeShell sets the
56 // Cursor to NULL (Node + Content).
57 // If the Cursor is not on a ContentNode (ContentNode) this fact gets
58 // saved in nNdType.
61 }
62}
63
64namespace sw {
65
73void NotifyTableCollapsedParagraph(const SwContentNode *const pNode, SwCursorShell *const pShell)
74{
75 if ( !pNode )
76 return;
77
78 SwFrame *const pMyFrame = pNode->getLayoutFrame(pShell ? pShell->GetLayout() : nullptr);
79 if ( !pMyFrame )
80 return;
81
82 // important: only invalidate layout if something is actually hidden or
83 // shown! Otherwise performance is going to suffer with "difficult" tables.
84 if (!pMyFrame->IsCollapse())
85 return;
86
87 SwRowFrame *const pRow = pMyFrame->FindRowFrame();
88 if ( !pRow )
89 return;
90
91 const SwTableLine* pLine = pRow->GetTabLine( );
92
93 if (pShell && (pShell->IsTableMode() || (pShell->StartsWith_() != SwCursorShell::StartsWith::None && pShell->ExtendedSelectedAll())))
94 {
95 // If we have a table selection, then avoid the notification: it's not necessary (the text
96 // cursor needs no updating) and the notification may kill the selection overlay, leading to
97 // flicker.
98 // Same for whole-document selection when it starts with a table.
99 return;
100 }
101
102 // notify a change in frame size to force reformatting of the row
103 const SwFormatFrameSize aSize = pLine->GetFrameFormat()->GetFrameSize();
104 pRow->OnFrameSize(aSize);
105}
106
107} // namespace sw
108
110{
111 if( m_nNodeType == SwNodeType::NONE || !m_rShell.m_bCallChgLnk ) // see ctor
112 return ;
113
114 // If travelling over Nodes check formats and register them anew at the
115 // new Node.
116 SwPaM* pCurrentCursor = m_rShell.IsTableMode() ? m_rShell.GetTableCrs() : m_rShell.GetCursor();
117 SwContentNode * pCNd = pCurrentCursor->GetPointContentNode();
118 if( !pCNd )
119 return;
120
121 if (pCNd->GetIndex() != m_nNode) // only if moved to different node
122 {
124
125 const SwDoc *pDoc=m_rShell.GetDoc();
126 if (sal_Int32(m_nNode) < sal_Int32(pDoc->GetNodes().Count()))
127 {
128 const SwContentNode *const pNode = pDoc->GetNodes()[m_nNode]->GetContentNode();
130 }
131 }
132
133 sal_Int32 nCmp, nCurrentContent = pCurrentCursor->GetPoint()->GetContentIndex();
134 SwNodeType nNdWhich = pCNd->GetNodeType();
135 SwNodeOffset nCurrentNode = pCurrentCursor->GetPoint()->GetNodeIndex();
136
137 // Register the Shell as dependent at the current Node. By doing this all
138 // attribute changes can be signaled over the link.
139 pCNd->Add( &m_rShell );
140
141 const bool bCurrentHasSelection = (*pCurrentCursor->GetPoint() != *pCurrentCursor->GetMark());
142
143 if( m_nNodeType != nNdWhich || m_nNode != nCurrentNode )
144 {
145 // Every time a switch between nodes occurs, there is a chance that
146 // new attributes do apply - meaning text-attributes.
147 // So the currently applying attributes would have to be determined.
148 // That can be done in one go by the handler.
150 }
151 else if (m_bHasSelection != bCurrentHasSelection)
152 {
153 // always call change link when selection changes
155 }
156 else if( m_rShell.m_aChgLnk.IsSet() && SwNodeType::Text == nNdWhich &&
157 m_nContent != nCurrentContent )
158 {
159 // If travelling with left/right only and the frame is
160 // unchanged (columns!) then check text hints.
161 if( m_nLeftFramePos == SwCallLink::getLayoutFrame( m_rShell.GetLayout(), *pCNd->GetTextNode(), nCurrentContent,
162 !m_rShell.ActionPend() ) &&
163 (( nCmp = m_nContent ) + 1 == nCurrentContent || // Right
164 m_nContent -1 == ( nCmp = nCurrentContent )) ) // Left
165 {
166 if( nCmp == nCurrentContent && pCurrentCursor->HasMark() ) // left & select
167 ++nCmp;
168
169 if ( pCNd->GetTextNode()->HasHints() )
170 {
171 const SwpHints &rHts = pCNd->GetTextNode()->GetSwpHints();
172
173 for( size_t n = 0; n < rHts.Count(); ++n )
174 {
175 const SwTextAttr* pHt = rHts.Get( n );
176 const sal_Int32 *pEnd = pHt->End();
177 const sal_Int32 nStart = pHt->GetStart();
178
179 // If "only start" or "start and end equal" then call on
180 // every overflow of start.
181 if( ( !pEnd || ( nStart == *pEnd ) ) &&
182 ( nStart == m_nContent || nStart == nCurrentContent) )
183 {
185 return;
186 }
187
188 // If the attribute has an area and that area is not empty ...
189 else if( pEnd && nStart < *pEnd &&
190 // ... then test if travelling occurred via start/end.
191 ( nStart == nCmp ||
192 ( pHt->DontExpand() ? nCmp == *pEnd-1
193 : nCmp == *pEnd ) ))
194 {
196 return;
197 }
198 }
199 }
200
201 assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
202 const OUString rText = pCNd->GetTextNode()->GetText();
203 if( !nCmp ||
204 g_pBreakIt->GetBreakIter()->getScriptType( rText, m_nContent )
205 != g_pBreakIt->GetBreakIter()->getScriptType(rText, nCurrentContent))
206 {
208 return;
209 }
210 }
211 else
212 // If travelling more than one character with home/end/.. then
213 // always call ChgLnk, because it can not be determined here what
214 // has changed. Something may have changed.
216 }
217
218 const SwFrame* pFrame;
219 const SwFlyFrame *pFlyFrame;
220 if (m_rShell.ActionPend())
221 return;
222 pFrame = pCNd->getLayoutFrame(m_rShell.GetLayout(), nullptr, nullptr);
223 if (!pFrame)
224 return;
225 pFlyFrame = pFrame->FindFlyFrame();
226 if ( !pFlyFrame || m_rShell.IsTableMode() )
227 return;
228
229 const SwNodeIndex* pIndex = pFlyFrame->GetFormat()->GetContent().GetContentIdx();
230 OSL_ENSURE( pIndex, "Fly without Content" );
231
232 if (!pIndex)
233 return;
234
235 const SwNode& rStNd = pIndex->GetNode();
236
238 m_nNode > rStNd.EndOfSectionIndex() )
239 m_rShell.GetFlyMacroLnk().Call( pFlyFrame->GetFormat() );
240}
241
243{
245}
246
248 SwTextNode const & rNd, sal_Int32 nCntPos, bool /*bCalcFrame*/)
249{
250 SwTextFrame* pFrame = static_cast<SwTextFrame*>(rNd.getLayoutFrame(pRoot, nullptr, nullptr));
251 SwTextFrame* pNext;
252 if ( pFrame && !pFrame->IsHiddenNow() )
253 {
254 if( pFrame->HasFollow() )
255 {
256 TextFrameIndex const nPos(pFrame->MapModelToView(&rNd, nCntPos));
257 for (;;)
258 {
259 pNext = pFrame->GetFollow();
260 if(!pNext || nPos < pNext->GetOffset())
261 break;
262 pFrame = pNext;
263 }
264 }
265
266 return pFrame->getFrameArea().Left();
267 }
268 return 0;
269}
270
271/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:63
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
const SwPaM * GetTableCrs() const
Definition: crsrsh.hxx:930
StartsWith StartsWith_()
If document body starts with a table or starts/ends with hidden paragraph.
Definition: crsrsh.cxx:895
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool m_bCallChgLnk
flag for derived classes
Definition: crsrsh.hxx:224
const Link< const SwFlyFrameFormat *, void > & GetFlyMacroLnk() const
Definition: crsrsh.hxx:500
void CallChgLnk()
Definition: crsrsh.cxx:2847
Link< LinkParamNone *, void > m_aChgLnk
link will be called by every attribute/ format changes at cursor position.
Definition: crsrsh.hxx:182
bool IsTableMode() const
Definition: crsrsh.hxx:668
::std::optional<::std::pair< SwNode const *, ::std::vector< SwTableNode * > > > ExtendedSelectedAll() const
If ExtendedSelectAll() was called and selection didn't change since then.
Definition: crsrsh.cxx:823
Definition: doc.hxx:197
SwNodes & GetNodes()
Definition: doc.hxx:422
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:3119
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
const SwRect & getFrameArea() const
Definition: frame.hxx:179
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsCollapse() const
Definition: calcmove.cxx:1052
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1117
SwRowFrame * FindRowFrame()
Definition: findfrm.cxx:624
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:687
bool IsTextNode() const
Definition: node.hxx:190
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
SwNodeType GetNodeType() const
Definition: node.hxx:166
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
SwNodeOffset Count() const
Definition: ndarr.hxx:142
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:279
const SwPosition * GetPoint() const
Definition: pam.hxx:253
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
The root element of a Writer document layout.
Definition: rootfrm.hxx:85
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:29
void OnFrameSize(const SfxPoolItem &)
Definition: tabfrm.cxx:4098
const SwTableLine * GetTabLine() const
Definition: rowfrm.hxx:70
SwTableLine is one table row in the document model.
Definition: swtable.hxx:376
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:398
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const sal_Int32 * End() const
Definition: txatbase.hxx:156
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
bool DontExpand() const
Definition: txatbase.hxx:98
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:889
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1339
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1447
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
bool HasHints() const
Definition: ndtxt.hxx:254
SwpHints & GetSwpHints()
getters for SwpHints
Definition: ndtxt.hxx:867
const OUString & GetText() const
Definition: ndtxt.hxx:244
bool ActionPend() const
Definition: viewsh.hxx:225
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:68
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
size_t Count() const
Definition: ndhints.hxx:142
#define suppress_fun_call_w_exception(expr)
sal_Int64 n
sal_uInt16 nPos
Dialog to specify the properties of date form field.
void NotifyTableCollapsedParagraph(const SwContentNode *const pNode, SwCursorShell *const pShell)
An empty paragraph inside a table with a nested table preceding it should be hidden,...
Definition: callnk.cxx:73
long Long
SwNodeType
Definition: ndtyp.hxx:28
SwNode & GetNode() const
Definition: pam.hxx:81
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85