File: | home/maarten/src/libreoffice/core/sw/inc/crsrsh.hxx |
Warning: | line 881, column 29 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <config_features.h> | |||
21 | ||||
22 | #include <vcl/weld.hxx> | |||
23 | #include <vcl/svapp.hxx> | |||
24 | #include <vcl/settings.hxx> | |||
25 | #include <viewopt.hxx> | |||
26 | #include <frmtool.hxx> | |||
27 | #include <viscrs.hxx> | |||
28 | #include <crsrsh.hxx> | |||
29 | #include <doc.hxx> | |||
30 | #include <swtable.hxx> | |||
31 | #include <viewimp.hxx> | |||
32 | #include <dview.hxx> | |||
33 | #include <rootfrm.hxx> | |||
34 | #include <txtfrm.hxx> | |||
35 | #include <ndtxt.hxx> | |||
36 | #include <txtfld.hxx> | |||
37 | #include <scriptinfo.hxx> | |||
38 | #include <view.hxx> | |||
39 | #include <IDocumentLayoutAccess.hxx> | |||
40 | ||||
41 | #include <svx/sdr/overlay/overlaymanager.hxx> | |||
42 | #include <svx/sdrpaintwindow.hxx> | |||
43 | #include <svx/srchdlg.hxx> | |||
44 | #include <svx/sdr/overlay/overlayselection.hxx> | |||
45 | #include "overlayrangesoutline.hxx" | |||
46 | ||||
47 | #include <memory> | |||
48 | ||||
49 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | |||
50 | #include <comphelper/lok.hxx> | |||
51 | #include <sfx2/lokhelper.hxx> | |||
52 | #include <boost/property_tree/json_parser.hpp> | |||
53 | #include <comphelper/string.hxx> | |||
54 | #include <paintfrm.hxx> | |||
55 | #include <PostItMgr.hxx> | |||
56 | #include <SwGrammarMarkUp.hxx> | |||
57 | #include <docsh.hxx> | |||
58 | ||||
59 | #include <cellfrm.hxx> | |||
60 | #include <wrtsh.hxx> | |||
61 | ||||
62 | // Here static members are defined. They will get changed on alteration of the | |||
63 | // MapMode. This is done so that on ShowCursor the same size does not have to be | |||
64 | // expensively determined again and again. | |||
65 | ||||
66 | long SwSelPaintRects::s_nPixPtX = 0; | |||
67 | long SwSelPaintRects::s_nPixPtY = 0; | |||
68 | MapMode* SwSelPaintRects::s_pMapMode = nullptr; | |||
69 | ||||
70 | // Starting from here: classes / methods for the non-text-cursor | |||
71 | SwVisibleCursor::SwVisibleCursor( const SwCursorShell * pCShell ) | |||
72 | : m_pCursorShell( pCShell ) | |||
73 | , m_nPageLastTime(0) | |||
74 | { | |||
75 | pCShell->GetWin()->SetCursor( &m_aTextCursor ); | |||
76 | m_bIsVisible = m_aTextCursor.IsVisible(); | |||
77 | m_bIsDragCursor = false; | |||
78 | m_aTextCursor.SetWidth( 0 ); | |||
79 | } | |||
80 | ||||
81 | SwVisibleCursor::~SwVisibleCursor() | |||
82 | { | |||
83 | if( m_bIsVisible && m_aTextCursor.IsVisible() ) | |||
84 | m_aTextCursor.Hide(); | |||
85 | ||||
86 | m_pCursorShell->GetWin()->SetCursor( nullptr ); | |||
87 | } | |||
88 | ||||
89 | void SwVisibleCursor::Show() | |||
90 | { | |||
91 | if( !m_bIsVisible ) | |||
| ||||
92 | { | |||
93 | m_bIsVisible = true; | |||
94 | ||||
95 | // display at all? | |||
96 | if( m_pCursorShell->VisArea().IsOver( m_pCursorShell->m_aCharRect ) || comphelper::LibreOfficeKit::isActive() ) | |||
97 | SetPosAndShow(nullptr); | |||
98 | } | |||
99 | } | |||
100 | ||||
101 | void SwVisibleCursor::Hide() | |||
102 | { | |||
103 | if( m_bIsVisible ) | |||
104 | { | |||
105 | m_bIsVisible = false; | |||
106 | ||||
107 | if( m_aTextCursor.IsVisible() ) // Shouldn't the flags be in effect? | |||
108 | m_aTextCursor.Hide(); | |||
109 | } | |||
110 | } | |||
111 | ||||
112 | namespace | |||
113 | { | |||
114 | ||||
115 | // Build JSON message to be sent to Online | |||
116 | OString buildHyperlinkJSON(const OUString& sText, const OUString& sLink) | |||
117 | { | |||
118 | boost::property_tree::ptree aTree; | |||
119 | aTree.put("text", sText); | |||
120 | aTree.put("link", sLink); | |||
121 | std::stringstream aStream; | |||
122 | boost::property_tree::write_json(aStream, aTree, false); | |||
123 | ||||
124 | return OString(aStream.str().c_str()).trim(); | |||
125 | } | |||
126 | ||||
127 | } | |||
128 | ||||
129 | void SwVisibleCursor::SetPosAndShow(SfxViewShell const * pViewShell) | |||
130 | { | |||
131 | SwRect aRect; | |||
132 | long nTmpY = m_pCursorShell->m_aCursorHeight.getY(); | |||
133 | if( 0 > nTmpY ) | |||
134 | { | |||
135 | nTmpY = -nTmpY; | |||
136 | m_aTextCursor.SetOrientation( 900 ); | |||
137 | aRect = SwRect( m_pCursorShell->m_aCharRect.Pos(), | |||
138 | Size( m_pCursorShell->m_aCharRect.Height(), nTmpY ) ); | |||
139 | aRect.Pos().setX(aRect.Pos().getX() + m_pCursorShell->m_aCursorHeight.getX()); | |||
140 | if( m_pCursorShell->IsOverwriteCursor() ) | |||
141 | aRect.Pos().setY(aRect.Pos().getY() + aRect.Width()); | |||
142 | } | |||
143 | else | |||
144 | { | |||
145 | m_aTextCursor.SetOrientation(); | |||
146 | aRect = SwRect( m_pCursorShell->m_aCharRect.Pos(), | |||
147 | Size( m_pCursorShell->m_aCharRect.Width(), nTmpY ) ); | |||
148 | aRect.Pos().setY(aRect.Pos().getY() + m_pCursorShell->m_aCursorHeight.getX()); | |||
149 | } | |||
150 | ||||
151 | // check if cursor should show the current cursor bidi level | |||
152 | m_aTextCursor.SetDirection(); | |||
153 | const SwCursor* pTmpCursor = m_pCursorShell->GetCursor_(); | |||
154 | ||||
155 | if ( pTmpCursor && !m_pCursorShell->IsOverwriteCursor() ) | |||
156 | { | |||
157 | SwNode& rNode = pTmpCursor->GetPoint()->nNode.GetNode(); | |||
158 | if( rNode.IsTextNode() ) | |||
159 | { | |||
160 | const SwTextNode& rTNd = *rNode.GetTextNode(); | |||
161 | const SwFrame* pFrame = rTNd.getLayoutFrame(m_pCursorShell->GetLayout(), nullptr, nullptr); | |||
162 | if ( pFrame ) | |||
163 | { | |||
164 | const SwScriptInfo* pSI = static_cast<const SwTextFrame*>(pFrame)->GetScriptInfo(); | |||
165 | // cursor level has to be shown | |||
166 | if ( pSI && pSI->CountDirChg() > 1 ) | |||
167 | { | |||
168 | m_aTextCursor.SetDirection( | |||
169 | ( pTmpCursor->GetCursorBidiLevel() % 2 ) ? | |||
170 | CursorDirection::RTL : | |||
171 | CursorDirection::LTR ); | |||
172 | } | |||
173 | if ( pFrame->IsRightToLeft() ) | |||
174 | { | |||
175 | const OutputDevice *pOut = m_pCursorShell->GetOut(); | |||
176 | if ( pOut ) | |||
177 | { | |||
178 | long nSize = pOut->GetSettings().GetStyleSettings().GetCursorSize(); | |||
179 | Size aSize( nSize, nSize ); | |||
180 | aSize = pOut->PixelToLogic( aSize ); | |||
181 | aRect.Left( aRect.Left() - aSize.Width() ); | |||
182 | } | |||
183 | } | |||
184 | } | |||
185 | } | |||
186 | } | |||
187 | ||||
188 | if( aRect.Height()) | |||
189 | { | |||
190 | ::SwCalcPixStatics( m_pCursorShell->GetOut() ); | |||
191 | ||||
192 | // Disable pixel alignment when tiled rendering, so that twip values of | |||
193 | // the cursor don't depend on statics. | |||
194 | if (!comphelper::LibreOfficeKit::isActive()) | |||
195 | ::SwAlignRect( aRect, static_cast<SwViewShell const *>(m_pCursorShell), m_pCursorShell->GetOut() ); | |||
196 | } | |||
197 | if( !m_pCursorShell->IsOverwriteCursor() || m_bIsDragCursor || | |||
198 | m_pCursorShell->IsSelection() ) | |||
199 | aRect.Width( 0 ); | |||
200 | ||||
201 | m_aTextCursor.SetSize( aRect.SSize() ); | |||
202 | ||||
203 | m_aTextCursor.SetPos( aRect.Pos() ); | |||
204 | ||||
205 | bool bPostItActive = false; | |||
206 | SwView* pView = dynamic_cast<SwView*>(m_pCursorShell->GetSfxViewShell()); | |||
207 | if (pView) | |||
208 | { | |||
209 | if (SwPostItMgr* pPostItMgr = pView->GetPostItMgr()) | |||
210 | bPostItActive = pPostItMgr->GetActiveSidebarWin() != nullptr; | |||
211 | } | |||
212 | ||||
213 | if (comphelper::LibreOfficeKit::isActive() && !bPostItActive) | |||
214 | { | |||
215 | // notify about page number change (if that happened) | |||
216 | sal_uInt16 nPage, nVirtPage; | |||
217 | // bCalcFrame=false is important to avoid calculating the layout when | |||
218 | // we're in the middle of doing that already. | |||
219 | const_cast<SwCursorShell*>(m_pCursorShell)->GetPageNum(nPage, nVirtPage, /*bAtCursorPos=*/true, /*bCalcFrame=*/false); | |||
220 | if (nPage != m_nPageLastTime) | |||
221 | { | |||
222 | m_nPageLastTime = nPage; | |||
223 | OString aPayload = OString::number(nPage - 1); | |||
224 | m_pCursorShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); | |||
225 | } | |||
226 | ||||
227 | // notify about the cursor position & size | |||
228 | tools::Rectangle aSVRect(aRect.Pos().getX(), aRect.Pos().getY(), aRect.Pos().getX() + aRect.SSize().Width(), aRect.Pos().getY() + aRect.SSize().Height()); | |||
229 | OString sRect = aSVRect.toString(); | |||
230 | ||||
231 | // is cursor at a misspelled word ? | |||
232 | bool bIsWrong = false; | |||
233 | if (pView && pView->GetWrtShellPtr()) | |||
234 | { | |||
235 | const SwViewOption* pVOpt = pView->GetWrtShell().GetViewOptions(); | |||
236 | if(pVOpt && pVOpt->IsOnlineSpell()) | |||
237 | { | |||
238 | SwPaM* pCursor = m_pCursorShell->GetCursor(); | |||
239 | SwPosition aPos(*pCursor->GetPoint()); | |||
240 | Point aPt = aRect.Pos(); | |||
241 | SwCursorMoveState eTmpState(CursorMoveState::SetOnlyText); | |||
242 | SwTextNode *pNode = nullptr; | |||
243 | if (m_pCursorShell->GetLayout()->GetModelPositionForViewPoint(&aPos, aPt, &eTmpState)) | |||
244 | pNode = aPos.nNode.GetNode().GetTextNode(); | |||
245 | if (pNode && !pNode->IsInProtectSect()) | |||
246 | { | |||
247 | sal_Int32 nBegin = aPos.nContent.GetIndex(); | |||
248 | sal_Int32 nLen = 1; | |||
249 | ||||
250 | SwWrongList *pWrong = nullptr; | |||
251 | pWrong = pNode->GetWrong(); | |||
252 | if (!pWrong) | |||
253 | pWrong = pNode->GetGrammarCheck(); | |||
254 | if (pWrong) | |||
255 | bIsWrong = pWrong->InWrongWord(nBegin,nLen) && !pNode->IsSymbolAt(nBegin); | |||
256 | } | |||
257 | } | |||
258 | } | |||
259 | ||||
260 | OString sHyperlink; | |||
261 | SwContentAtPos aContentAtPos(IsAttrAtPos::InetAttr); | |||
262 | bool bIsSelection = m_pCursorShell->IsSelection(); | |||
263 | ||||
264 | if (const_cast<SwCursorShell*>(m_pCursorShell)->GetContentAtPos(aRect.Pos(), aContentAtPos)) | |||
265 | { | |||
266 | const SwFormatINetFormat* pItem = static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr); | |||
267 | sHyperlink = buildHyperlinkJSON(aContentAtPos.sStr, pItem->GetValue()); | |||
268 | } | |||
269 | else if (bIsSelection) | |||
270 | { | |||
271 | SwWrtShell* pShell = m_pCursorShell->GetDoc()->GetDocShell()->GetWrtShell(); | |||
272 | ||||
273 | if (pShell) | |||
274 | { | |||
275 | SfxItemSet aSet(m_pCursorShell->GetSfxViewShell()->GetPool(), | |||
276 | svl::Items<RES_TXTATR_INETFMT, | |||
277 | RES_TXTATR_INETFMT>{}); | |||
278 | pShell->GetCurAttr(aSet); | |||
279 | if(SfxItemState::SET <= aSet.GetItemState( RES_TXTATR_INETFMT )) | |||
280 | { | |||
281 | sHyperlink = buildHyperlinkJSON(m_pCursorShell->GetSelText(), | |||
282 | aSet.GetItem(RES_TXTATR_INETFMT)->GetValue()); | |||
283 | } | |||
284 | } | |||
285 | } | |||
286 | ||||
287 | if (pViewShell) | |||
288 | { | |||
289 | if (pViewShell == m_pCursorShell->GetSfxViewShell()) | |||
290 | { | |||
291 | SfxLokHelper::notifyVisCursorInvalidation(pViewShell, sRect, bIsWrong, sHyperlink); | |||
292 | } | |||
293 | else | |||
294 | SfxLokHelper::notifyOtherView(m_pCursorShell->GetSfxViewShell(), pViewShell, LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect); | |||
295 | } | |||
296 | else | |||
297 | { | |||
298 | SfxLokHelper::notifyVisCursorInvalidation(m_pCursorShell->GetSfxViewShell(), sRect, bIsWrong, sHyperlink); | |||
299 | SfxLokHelper::notifyOtherViews(m_pCursorShell->GetSfxViewShell(), LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect); | |||
300 | } | |||
301 | } | |||
302 | ||||
303 | if ( m_pCursorShell->IsCursorReadonly() && !m_pCursorShell->GetViewOptions()->IsSelectionInReadonly() ) | |||
304 | return; | |||
305 | ||||
306 | if ( m_pCursorShell->GetDrawView() ) | |||
307 | const_cast<SwDrawView*>(static_cast<const SwDrawView*>(m_pCursorShell->GetDrawView()))->SetAnimationEnabled( | |||
308 | !m_pCursorShell->IsSelection() ); | |||
309 | ||||
310 | sal_uInt16 nStyle = m_bIsDragCursor ? CURSOR_SHADOW(sal_uInt16(0x0001)) : 0; | |||
311 | if( nStyle != m_aTextCursor.GetStyle() ) | |||
312 | { | |||
313 | m_aTextCursor.SetStyle( nStyle ); | |||
314 | m_aTextCursor.SetWindow( m_bIsDragCursor ? m_pCursorShell->GetWin() : nullptr ); | |||
315 | } | |||
316 | ||||
317 | m_aTextCursor.Show(); | |||
318 | } | |||
319 | ||||
320 | const vcl::Cursor& SwVisibleCursor::GetTextCursor() const | |||
321 | { | |||
322 | return m_aTextCursor; | |||
323 | } | |||
324 | ||||
325 | SwSelPaintRects::SwSelPaintRects( const SwCursorShell& rCSh ) | |||
326 | : SwRects() | |||
327 | , m_pCursorShell( &rCSh ) | |||
328 | #if HAVE_FEATURE_DESKTOP1 | |||
329 | , m_bShowTextInputFieldOverlay(true) | |||
330 | #endif | |||
331 | { | |||
332 | } | |||
333 | ||||
334 | SwSelPaintRects::~SwSelPaintRects() | |||
335 | { | |||
336 | Hide(); | |||
337 | } | |||
338 | ||||
339 | void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap) | |||
340 | { | |||
341 | SwRects::swap(rSwap); | |||
342 | ||||
343 | #if HAVE_FEATURE_DESKTOP1 | |||
344 | // #i75172# also swap m_pCursorOverlay | |||
345 | std::swap(m_pCursorOverlay, rSwap.m_pCursorOverlay); | |||
346 | std::swap(m_bShowTextInputFieldOverlay, rSwap.m_bShowTextInputFieldOverlay); | |||
347 | std::swap(m_pTextInputFieldOverlay, rSwap.m_pTextInputFieldOverlay); | |||
348 | #endif | |||
349 | } | |||
350 | ||||
351 | void SwSelPaintRects::Hide() | |||
352 | { | |||
353 | #if HAVE_FEATURE_DESKTOP1 | |||
354 | m_pCursorOverlay.reset(); | |||
355 | m_pTextInputFieldOverlay.reset(); | |||
356 | #endif | |||
357 | ||||
358 | SwRects::clear(); | |||
359 | } | |||
360 | ||||
361 | /** | |||
362 | * Return a layout rectangle (typically with minimal width) that represents a | |||
363 | * cursor at rPosition. | |||
364 | * | |||
365 | * @param rPoint layout position as a hint about what layout frame contains | |||
366 | * rPosition (there might be multiple frames for a single node) | |||
367 | * @param rPosition the doc model position (paragraph / character index) | |||
368 | */ | |||
369 | static SwRect lcl_getLayoutRect(const Point& rPoint, const SwPosition& rPosition) | |||
370 | { | |||
371 | const SwContentNode* pNode = rPosition.nNode.GetNode().GetContentNode(); | |||
372 | std::pair<Point, bool> const tmp(rPoint, true); | |||
373 | const SwContentFrame* pFrame = pNode->getLayoutFrame( | |||
374 | pNode->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), | |||
375 | &rPosition, &tmp); | |||
376 | SwRect aRect; | |||
377 | pFrame->GetCharRect(aRect, rPosition); | |||
378 | return aRect; | |||
379 | } | |||
380 | ||||
381 | void SwShellCursor::FillStartEnd(SwRect& rStart, SwRect& rEnd) const | |||
382 | { | |||
383 | const SwShellCursor* pCursor = GetShell()->getShellCursor(false); | |||
384 | rStart = lcl_getLayoutRect(pCursor->GetSttPos(), *pCursor->Start()); | |||
385 | rEnd = lcl_getLayoutRect(pCursor->GetEndPos(), *pCursor->End()); | |||
386 | } | |||
387 | ||||
388 | void SwSelPaintRects::Show(std::vector<OString>* pSelectionRectangles) | |||
389 | { | |||
390 | SdrView *const pView = const_cast<SdrView*>(m_pCursorShell->GetDrawView()); | |||
391 | ||||
392 | if(!(pView && pView->PaintWindowCount())) | |||
393 | return; | |||
394 | ||||
395 | // reset rects | |||
396 | SwRects::clear(); | |||
397 | FillRects(); | |||
398 | ||||
399 | #if HAVE_FEATURE_DESKTOP1 | |||
400 | // get new rects | |||
401 | std::vector< basegfx::B2DRange > aNewRanges; | |||
402 | aNewRanges.reserve(size()); | |||
403 | for(size_type a = 0; a < size(); ++a) | |||
404 | { | |||
405 | const SwRect aNextRect((*this)[a]); | |||
406 | const tools::Rectangle aPntRect(aNextRect.SVRect()); | |||
407 | ||||
408 | aNewRanges.emplace_back( | |||
409 | aPntRect.Left(), aPntRect.Top(), | |||
410 | aPntRect.Right() + 1, aPntRect.Bottom() + 1); | |||
411 | } | |||
412 | ||||
413 | if (m_pCursorOverlay) | |||
414 | { | |||
415 | if(!aNewRanges.empty()) | |||
416 | { | |||
417 | static_cast<sdr::overlay::OverlaySelection*>(m_pCursorOverlay.get())->setRanges(aNewRanges); | |||
418 | } | |||
419 | else | |||
420 | { | |||
421 | m_pCursorOverlay.reset(); | |||
422 | } | |||
423 | } | |||
424 | else if(!empty()) | |||
425 | { | |||
426 | SdrPaintWindow* pCandidate = pView->GetPaintWindow(0); | |||
427 | const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager(); | |||
428 | ||||
429 | if (xTargetOverlay.is()) | |||
430 | { | |||
431 | // get the system's highlight color | |||
432 | const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; | |||
433 | const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor()); | |||
434 | ||||
435 | // create correct selection | |||
436 | m_pCursorOverlay.reset( new sdr::overlay::OverlaySelection( | |||
437 | sdr::overlay::OverlayType::Transparent, | |||
438 | aHighlight, | |||
439 | aNewRanges, | |||
440 | true) ); | |||
441 | ||||
442 | xTargetOverlay->add(*m_pCursorOverlay); | |||
443 | } | |||
444 | } | |||
445 | ||||
446 | HighlightInputField(); | |||
447 | #endif | |||
448 | ||||
449 | // Tiled editing does not expose the draw and writer cursor, it just | |||
450 | // talks about "the" cursor at the moment. As long as that's true, | |||
451 | // don't say anything about the Writer cursor till a draw object is | |||
452 | // being edited. | |||
453 | if (!comphelper::LibreOfficeKit::isActive() || pView->GetTextEditObject()) | |||
454 | return; | |||
455 | ||||
456 | // If pSelectionRectangles is set, we're just collecting the text selections -> don't emit start/end. | |||
457 | if (!empty() && !pSelectionRectangles) | |||
458 | { | |||
459 | // The selection may be a complex polygon, emit the logical | |||
460 | // start/end cursor rectangle of the selection as separate | |||
461 | // events, if there is a real selection. | |||
462 | // This can be used to easily show selection handles on the | |||
463 | // client side. | |||
464 | SwRect aStartRect; | |||
465 | SwRect aEndRect; | |||
466 | FillStartEnd(aStartRect, aEndRect); | |||
467 | ||||
468 | if (aStartRect.HasArea()) | |||
469 | { | |||
470 | OString sRect = aStartRect.SVRect().toString(); | |||
471 | GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr()); | |||
472 | } | |||
473 | if (aEndRect.HasArea()) | |||
474 | { | |||
475 | OString sRect = aEndRect.SVRect().toString(); | |||
476 | GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr()); | |||
477 | } | |||
478 | } | |||
479 | ||||
480 | std::vector<OString> aRect; | |||
481 | aRect.reserve(size()); | |||
482 | for (size_type i = 0; i < size(); ++i) | |||
483 | { | |||
484 | const SwRect& rRect = (*this)[i]; | |||
485 | aRect.push_back(rRect.SVRect().toString()); | |||
486 | } | |||
487 | OString sRect = comphelper::string::join("; ", aRect); | |||
488 | if (!pSelectionRectangles) | |||
489 | { | |||
490 | GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); | |||
491 | SfxLokHelper::notifyOtherViews(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect); | |||
492 | } | |||
493 | else | |||
494 | pSelectionRectangles->push_back(sRect); | |||
495 | } | |||
496 | ||||
497 | void SwSelPaintRects::HighlightInputField() | |||
498 | { | |||
499 | std::vector< basegfx::B2DRange > aInputFieldRanges; | |||
500 | ||||
501 | if (m_bShowTextInputFieldOverlay) | |||
502 | { | |||
503 | SwTextInputField* pCurTextInputFieldAtCursor = | |||
504 | dynamic_cast<SwTextInputField*>(SwCursorShell::GetTextFieldAtPos( GetShell()->GetCursor()->Start(), false )); | |||
505 | if ( pCurTextInputFieldAtCursor != nullptr ) | |||
506 | { | |||
507 | SwTextNode* pTextNode = pCurTextInputFieldAtCursor->GetpTextNode(); | |||
508 | std::unique_ptr<SwShellCursor> pCursorForInputTextField( | |||
509 | new SwShellCursor( *GetShell(), SwPosition( *pTextNode, pCurTextInputFieldAtCursor->GetStart() ) ) ); | |||
510 | pCursorForInputTextField->SetMark(); | |||
511 | pCursorForInputTextField->GetMark()->nNode = *pTextNode; | |||
512 | pCursorForInputTextField->GetMark()->nContent.Assign( pTextNode, *(pCurTextInputFieldAtCursor->End()) ); | |||
513 | ||||
514 | pCursorForInputTextField->FillRects(); | |||
515 | SwRects* pRects = static_cast<SwRects*>(pCursorForInputTextField.get()); | |||
516 | for (const SwRect & rNextRect : *pRects) | |||
517 | { | |||
518 | const tools::Rectangle aPntRect(rNextRect.SVRect()); | |||
519 | ||||
520 | aInputFieldRanges.emplace_back( | |||
521 | aPntRect.Left(), aPntRect.Top(), | |||
522 | aPntRect.Right() + 1, aPntRect.Bottom() + 1); | |||
523 | } | |||
524 | } | |||
525 | } | |||
526 | ||||
527 | if ( !aInputFieldRanges.empty() ) | |||
528 | { | |||
529 | if (m_pTextInputFieldOverlay != nullptr) | |||
530 | { | |||
531 | m_pTextInputFieldOverlay->setRanges( aInputFieldRanges ); | |||
532 | } | |||
533 | else | |||
534 | { | |||
535 | SdrView* pView = const_cast<SdrView*>(GetShell()->GetDrawView()); | |||
536 | SdrPaintWindow* pCandidate = pView->GetPaintWindow(0); | |||
537 | const rtl::Reference<sdr::overlay::OverlayManager>& xTargetOverlay = pCandidate->GetOverlayManager(); | |||
538 | ||||
539 | if (xTargetOverlay.is()) | |||
540 | { | |||
541 | // use system's highlight color with decreased luminance as highlight color | |||
542 | const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; | |||
543 | Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor()); | |||
544 | aHighlight.DecreaseLuminance( 128 ); | |||
545 | ||||
546 | m_pTextInputFieldOverlay.reset( new sw::overlay::OverlayRangesOutline( | |||
547 | aHighlight, aInputFieldRanges ) ); | |||
548 | xTargetOverlay->add( *m_pTextInputFieldOverlay ); | |||
549 | } | |||
550 | } | |||
551 | } | |||
552 | else | |||
553 | { | |||
554 | m_pTextInputFieldOverlay.reset(); | |||
555 | } | |||
556 | } | |||
557 | ||||
558 | void SwSelPaintRects::Invalidate( const SwRect& rRect ) | |||
559 | { | |||
560 | size_type nSz = size(); | |||
561 | if( !nSz ) | |||
562 | return; | |||
563 | ||||
564 | SwRegionRects aReg( GetShell()->VisArea() ); | |||
565 | aReg.assign( begin(), end() ); | |||
566 | aReg -= rRect; | |||
567 | SwRects::erase( begin(), begin() + nSz ); | |||
568 | SwRects::insert( begin(), aReg.begin(), aReg.end() ); | |||
569 | ||||
570 | // If the selection is to the right or at the bottom, outside the | |||
571 | // visible area, it is never aligned on one pixel at the right/bottom. | |||
572 | // This has to be determined here and if that is the case the | |||
573 | // rectangle has to be expanded. | |||
574 | if( !(GetShell()->m_bVisPortChgd && 0 != ( nSz = size())) ) | |||
575 | return; | |||
576 | ||||
577 | SwSelPaintRects::Get1PixelInLogic( *GetShell() ); | |||
578 | iterator it = begin(); | |||
579 | for( ; nSz--; ++it ) | |||
580 | { | |||
581 | SwRect& rRectIt = *it; | |||
582 | if( rRectIt.Right() == GetShell()->m_aOldRBPos.X() ) | |||
583 | rRectIt.AddRight( s_nPixPtX ); | |||
584 | if( rRectIt.Bottom() == GetShell()->m_aOldRBPos.Y() ) | |||
585 | rRectIt.AddBottom( s_nPixPtY ); | |||
586 | } | |||
587 | } | |||
588 | ||||
589 | // check current MapMode of the shell and set possibly the static members. | |||
590 | // Optional set the parameters pX, pY | |||
591 | void SwSelPaintRects::Get1PixelInLogic( const SwViewShell& rSh, | |||
592 | long* pX, long* pY ) | |||
593 | { | |||
594 | const OutputDevice* pOut = rSh.GetWin(); | |||
595 | if ( ! pOut ) | |||
596 | pOut = rSh.GetOut(); | |||
597 | ||||
598 | const MapMode& rMM = pOut->GetMapMode(); | |||
599 | if (s_pMapMode->GetMapUnit() != rMM.GetMapUnit() || | |||
600 | s_pMapMode->GetScaleX() != rMM.GetScaleX() || | |||
601 | s_pMapMode->GetScaleY() != rMM.GetScaleY()) | |||
602 | { | |||
603 | *s_pMapMode = rMM; | |||
604 | Size aTmp( 1, 1 ); | |||
605 | aTmp = pOut->PixelToLogic( aTmp ); | |||
606 | s_nPixPtX = aTmp.Width(); | |||
607 | s_nPixPtY = aTmp.Height(); | |||
608 | } | |||
609 | if( pX ) | |||
610 | *pX = s_nPixPtX; | |||
611 | if( pY ) | |||
612 | *pY = s_nPixPtY; | |||
613 | } | |||
614 | ||||
615 | SwShellCursor::SwShellCursor( | |||
616 | const SwCursorShell& rCShell, | |||
617 | const SwPosition &rPos ) | |||
618 | : SwCursor(rPos,nullptr) | |||
619 | , SwSelPaintRects(rCShell) | |||
620 | , m_pInitialPoint(SwPaM::GetPoint()) | |||
621 | {} | |||
622 | ||||
623 | SwShellCursor::SwShellCursor( | |||
624 | const SwCursorShell& rCShell, | |||
625 | const SwPosition &rPos, | |||
626 | const Point& rPtPos, | |||
627 | SwPaM* pRing ) | |||
628 | : SwCursor(rPos, pRing) | |||
629 | , SwSelPaintRects(rCShell) | |||
630 | , m_MarkPt(rPtPos) | |||
631 | , m_PointPt(rPtPos) | |||
632 | , m_pInitialPoint(SwPaM::GetPoint()) | |||
633 | {} | |||
634 | ||||
635 | SwShellCursor::SwShellCursor( SwShellCursor& rICursor ) | |||
636 | : SwCursor(rICursor, &rICursor) | |||
637 | , SwSelPaintRects(*rICursor.GetShell()) | |||
638 | , m_MarkPt(rICursor.GetMkPos()) | |||
639 | , m_PointPt(rICursor.GetPtPos()) | |||
640 | , m_pInitialPoint(SwPaM::GetPoint()) | |||
641 | {} | |||
642 | ||||
643 | SwShellCursor::~SwShellCursor() | |||
644 | {} | |||
645 | ||||
646 | bool SwShellCursor::IsReadOnlyAvailable() const | |||
647 | { | |||
648 | return GetShell()->IsReadOnlyAvailable(); | |||
649 | } | |||
650 | ||||
651 | void SwShellCursor::SetMark() | |||
652 | { | |||
653 | if (SwPaM::GetPoint() == m_pInitialPoint) | |||
654 | m_MarkPt = m_PointPt; | |||
655 | else | |||
656 | m_PointPt = m_MarkPt; | |||
657 | SwPaM::SetMark(); | |||
658 | } | |||
659 | ||||
660 | void SwShellCursor::FillRects() | |||
661 | { | |||
662 | // calculate the new rectangles | |||
663 | if( HasMark() && | |||
664 | GetPoint()->nNode.GetNode().IsContentNode() && | |||
665 | GetPoint()->nNode.GetNode().GetContentNode()->getLayoutFrame( GetShell()->GetLayout() ) && | |||
666 | (GetMark()->nNode == GetPoint()->nNode || | |||
667 | (GetMark()->nNode.GetNode().IsContentNode() && | |||
668 | GetMark()->nNode.GetNode().GetContentNode()->getLayoutFrame( GetShell()->GetLayout() ) ) )) | |||
669 | GetShell()->GetLayout()->CalcFrameRects( *this ); | |||
670 | } | |||
671 | ||||
672 | void SwShellCursor::Show(SfxViewShell const * pViewShell) | |||
673 | { | |||
674 | std::vector<OString> aSelectionRectangles; | |||
675 | for(SwPaM& rPaM : GetRingContainer()) | |||
676 | { | |||
677 | SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM); | |||
678 | if(pShCursor) | |||
679 | pShCursor->SwSelPaintRects::Show(&aSelectionRectangles); | |||
680 | } | |||
681 | ||||
682 | if (!comphelper::LibreOfficeKit::isActive()) | |||
683 | return; | |||
684 | ||||
685 | std::vector<OString> aRect; | |||
686 | for (const OString & rSelectionRectangle : aSelectionRectangles) | |||
687 | { | |||
688 | if (rSelectionRectangle.isEmpty()) | |||
689 | continue; | |||
690 | aRect.push_back(rSelectionRectangle); | |||
691 | } | |||
692 | OString sRect = comphelper::string::join("; ", aRect); | |||
693 | if (pViewShell) | |||
694 | { | |||
695 | // Just notify pViewShell about our existing selection. | |||
696 | if (pViewShell != GetShell()->GetSfxViewShell()) | |||
697 | SfxLokHelper::notifyOtherView(GetShell()->GetSfxViewShell(), pViewShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect); | |||
698 | } | |||
699 | else | |||
700 | { | |||
701 | GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); | |||
702 | SfxLokHelper::notifyOtherViews(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect); | |||
703 | } | |||
704 | } | |||
705 | ||||
706 | // This rectangle gets painted anew, therefore the SSelection in this | |||
707 | // area is invalid. | |||
708 | void SwShellCursor::Invalidate( const SwRect& rRect ) | |||
709 | { | |||
710 | for(SwPaM& rPaM : GetRingContainer()) | |||
711 | { | |||
712 | SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM); | |||
713 | // skip any non SwShellCursor objects in the ring | |||
714 | // see also: SwAutoFormat::DeleteSel() | |||
715 | if(pShCursor) | |||
716 | pShCursor->SwSelPaintRects::Invalidate(rRect); | |||
717 | } | |||
718 | } | |||
719 | ||||
720 | void SwShellCursor::Hide() | |||
721 | { | |||
722 | for(SwPaM& rPaM : GetRingContainer()) | |||
723 | { | |||
724 | SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM); | |||
725 | if(pShCursor) | |||
726 | pShCursor->SwSelPaintRects::Hide(); | |||
727 | } | |||
728 | } | |||
729 | ||||
730 | SwCursor* SwShellCursor::Create( SwPaM* pRing ) const | |||
731 | { | |||
732 | return new SwShellCursor( *GetShell(), *GetPoint(), GetPtPos(), pRing ); | |||
733 | } | |||
734 | ||||
735 | short SwShellCursor::MaxReplaceArived() | |||
736 | { | |||
737 | short nRet = RET_YES; | |||
738 | SvxSearchDialog* pDlg = SwView::GetSearchDialog(); | |||
739 | if( pDlg ) | |||
740 | { | |||
741 | // Terminate old actions. The table-frames get constructed and | |||
742 | // a SSelection can be created. | |||
743 | std::vector<sal_uInt16> vActionCounts; | |||
744 | for(SwViewShell& rShell : const_cast< SwCursorShell* >( GetShell() )->GetRingContainer()) | |||
745 | { | |||
746 | sal_uInt16 nActCnt = 0; | |||
747 | while(rShell.ActionPend()) | |||
748 | { | |||
749 | rShell.EndAction(); | |||
750 | ++nActCnt; | |||
751 | } | |||
752 | vActionCounts.push_back(nActCnt); | |||
753 | } | |||
754 | std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDlg->getDialog(), "modules/swriter/ui/asksearchdialog.ui")); | |||
755 | std::unique_ptr<weld::MessageDialog> xDialog(xBuilder->weld_message_dialog("AskSearchDialog")); | |||
756 | nRet = xDialog->run(); | |||
757 | auto pActionCount = vActionCounts.begin(); | |||
758 | for(SwViewShell& rShell : const_cast< SwCursorShell* >( GetShell() )->GetRingContainer()) | |||
759 | { | |||
760 | while(*pActionCount) | |||
761 | { | |||
762 | rShell.StartAction(); | |||
763 | --(*pActionCount); | |||
764 | } | |||
765 | ++pActionCount; | |||
766 | } | |||
767 | } | |||
768 | else | |||
769 | // otherwise from the Basic, and then switch to RET_YES | |||
770 | nRet = RET_YES; | |||
771 | ||||
772 | return nRet; | |||
773 | } | |||
774 | ||||
775 | void SwShellCursor::SaveTableBoxContent( const SwPosition* pPos ) | |||
776 | { | |||
777 | const_cast<SwCursorShell*>(GetShell())->SaveTableBoxContent( pPos ); | |||
778 | } | |||
779 | ||||
780 | bool SwShellCursor::UpDown( bool bUp, sal_uInt16 nCnt ) | |||
781 | { | |||
782 | return SwCursor::UpDown( bUp, nCnt, | |||
783 | &GetPtPos(), GetShell()->GetUpDownX(), | |||
784 | *GetShell()->GetLayout()); | |||
785 | } | |||
786 | ||||
787 | // if <true> than the cursor can be set to the position. | |||
788 | bool SwShellCursor::IsAtValidPos( bool bPoint ) const | |||
789 | { | |||
790 | if( GetShell() && ( GetShell()->IsAllProtect() || | |||
791 | GetShell()->GetViewOptions()->IsReadonly() || | |||
792 | ( GetShell()->Imp()->GetDrawView() && | |||
793 | GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ))) | |||
794 | return true; | |||
795 | ||||
796 | return SwCursor::IsAtValidPos( bPoint ); | |||
797 | } | |||
798 | ||||
799 | SwShellTableCursor::SwShellTableCursor( const SwCursorShell& rCursorSh, | |||
800 | const SwPosition& rPos ) | |||
801 | : SwCursor(rPos,nullptr), SwShellCursor(rCursorSh, rPos), SwTableCursor(rPos) | |||
802 | { | |||
803 | } | |||
804 | ||||
805 | SwShellTableCursor::SwShellTableCursor( const SwCursorShell& rCursorSh, | |||
806 | const SwPosition& rMkPos, const Point& rMkPt, | |||
807 | const SwPosition& rPtPos, const Point& rPtPt ) | |||
808 | : SwCursor(rPtPos,nullptr), SwShellCursor(rCursorSh, rPtPos), SwTableCursor(rPtPos) | |||
809 | { | |||
810 | SetMark(); | |||
811 | *GetMark() = rMkPos; | |||
812 | GetMkPos() = rMkPt; | |||
813 | GetPtPos() = rPtPt; | |||
814 | } | |||
815 | ||||
816 | SwShellTableCursor::~SwShellTableCursor() {} | |||
817 | ||||
818 | void SwShellTableCursor::SetMark() { SwShellCursor::SetMark(); } | |||
819 | ||||
820 | SwCursor* SwShellTableCursor::Create( SwPaM* pRing ) const | |||
821 | { | |||
822 | return SwShellCursor::Create( pRing ); | |||
823 | } | |||
824 | ||||
825 | short SwShellTableCursor::MaxReplaceArived() | |||
826 | { | |||
827 | return SwShellCursor::MaxReplaceArived(); | |||
828 | } | |||
829 | ||||
830 | void SwShellTableCursor::SaveTableBoxContent( const SwPosition* pPos ) | |||
831 | { | |||
832 | SwShellCursor::SaveTableBoxContent( pPos ); | |||
833 | } | |||
834 | ||||
835 | void SwShellTableCursor::FillRects() | |||
836 | { | |||
837 | // Calculate the new rectangles. If the cursor is still "parked" do nothing | |||
838 | if (m_SelectedBoxes.empty() || m_bParked || !GetPoint()->nNode.GetIndex()) | |||
839 | return; | |||
840 | ||||
841 | bool bStart = true; | |||
842 | SwRegionRects aReg( GetShell()->VisArea() ); | |||
843 | if (comphelper::LibreOfficeKit::isActive()) | |||
844 | aReg = GetShell()->getIDocumentLayoutAccess().GetCurrentLayout()->getFrameArea(); | |||
845 | SwNodes& rNds = GetDoc().GetNodes(); | |||
846 | SwFrame* pEndFrame = nullptr; | |||
847 | for (size_t n = 0; n < m_SelectedBoxes.size(); ++n) | |||
848 | { | |||
849 | const SwStartNode* pSttNd = m_SelectedBoxes[n]->GetSttNd(); | |||
850 | const SwTableNode* pSelTableNd = pSttNd->FindTableNode(); | |||
851 | ||||
852 | SwNodeIndex aIdx( *pSttNd ); | |||
853 | SwContentNode* pCNd = rNds.GoNextSection( &aIdx, true, false ); | |||
854 | ||||
855 | // table in table | |||
856 | // (see also lcl_FindTopLevelTable in unoobj2.cxx for a different | |||
857 | // version to do this) | |||
858 | const SwTableNode* pCurTableNd = pCNd ? pCNd->FindTableNode() : nullptr; | |||
859 | while ( pSelTableNd != pCurTableNd && pCurTableNd ) | |||
860 | { | |||
861 | aIdx = pCurTableNd->EndOfSectionIndex(); | |||
862 | pCNd = rNds.GoNextSection( &aIdx, true, false ); | |||
863 | pCurTableNd = pCNd->FindTableNode(); | |||
864 | } | |||
865 | ||||
866 | if( !pCNd ) | |||
867 | continue; | |||
868 | ||||
869 | std::pair<Point, bool> const tmp(GetSttPos(), false); | |||
870 | SwFrame* pFrame = pCNd->getLayoutFrame(GetShell()->GetLayout(), nullptr, &tmp); | |||
871 | while( pFrame && !pFrame->IsCellFrame() ) | |||
872 | pFrame = pFrame->GetUpper(); | |||
873 | ||||
874 | OSL_ENSURE( pFrame, "Node not in a table" )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/crsr/viscrs.cxx" ":" "874" ": "), "%s", "Node not in a table"); } } while (false ); | |||
875 | ||||
876 | while ( pFrame ) | |||
877 | { | |||
878 | if( aReg.GetOrigin().IsOver( pFrame->getFrameArea() ) ) | |||
879 | { | |||
880 | aReg -= pFrame->getFrameArea(); | |||
881 | if (bStart) | |||
882 | { | |||
883 | bStart = false; | |||
884 | m_aStart = SwRect(pFrame->getFrameArea().Left(), pFrame->getFrameArea().Top(), 1, pFrame->getFrameArea().Height()); | |||
885 | } | |||
886 | } | |||
887 | ||||
888 | pEndFrame = pFrame; | |||
889 | pFrame = pFrame->GetNextCellLeaf(); | |||
890 | } | |||
891 | } | |||
892 | if (pEndFrame) | |||
893 | m_aEnd = SwRect(pEndFrame->getFrameArea().Right(), pEndFrame->getFrameArea().Top(), 1, pEndFrame->getFrameArea().Height()); | |||
894 | aReg.Invert(); | |||
895 | insert( begin(), aReg.begin(), aReg.end() ); | |||
896 | } | |||
897 | ||||
898 | void SwShellTableCursor::FillStartEnd(SwRect& rStart, SwRect& rEnd) const | |||
899 | { | |||
900 | rStart = m_aStart; | |||
901 | rEnd = m_aEnd; | |||
902 | } | |||
903 | ||||
904 | // Check if the SPoint is within the Table-SSelection. | |||
905 | bool SwShellTableCursor::IsInside( const Point& rPt ) const | |||
906 | { | |||
907 | // Calculate the new rectangles. If the cursor is still "parked" do nothing | |||
908 | if (m_SelectedBoxes.empty() || m_bParked || !GetPoint()->nNode.GetIndex()) | |||
909 | return false; | |||
910 | ||||
911 | SwNodes& rNds = GetDoc().GetNodes(); | |||
912 | for (size_t n = 0; n < m_SelectedBoxes.size(); ++n) | |||
913 | { | |||
914 | SwNodeIndex aIdx( *m_SelectedBoxes[n]->GetSttNd() ); | |||
915 | SwContentNode* pCNd = rNds.GoNextSection( &aIdx, true, false ); | |||
916 | if( !pCNd ) | |||
917 | continue; | |||
918 | ||||
919 | std::pair<Point, bool> const tmp(GetPtPos(), true); | |||
920 | SwFrame* pFrame = pCNd->getLayoutFrame(GetShell()->GetLayout(), nullptr, &tmp); | |||
921 | while( pFrame && !pFrame->IsCellFrame() ) | |||
922 | pFrame = pFrame->GetUpper(); | |||
923 | OSL_ENSURE( pFrame, "Node not in a table" )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/crsr/viscrs.cxx" ":" "923" ": "), "%s", "Node not in a table"); } } while (false ); | |||
924 | if( pFrame && pFrame->getFrameArea().IsInside( rPt ) ) | |||
925 | return true; | |||
926 | ||||
927 | for ( SwCellFrame* pCellFrame = static_cast<SwCellFrame*>(pFrame); pCellFrame; pCellFrame = pCellFrame->GetFollowCell() ) | |||
928 | { | |||
929 | if( pCellFrame->getFrameArea().IsInside( rPt ) ) | |||
930 | return true; | |||
931 | } | |||
932 | } | |||
933 | return false; | |||
934 | } | |||
935 | ||||
936 | bool SwShellTableCursor::IsAtValidPos( bool bPoint ) const | |||
937 | { | |||
938 | return SwShellCursor::IsAtValidPos( bPoint ); | |||
939 | } | |||
940 | ||||
941 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_SW_INC_CRSRSH_HXX | |||
20 | #define INCLUDED_SW_INC_CRSRSH_HXX | |||
21 | ||||
22 | #include <com/sun/star/i18n/WordType.hpp> | |||
23 | ||||
24 | #include <rtl/ustring.hxx> | |||
25 | #include <tools/link.hxx> | |||
26 | #include <vcl/keycod.hxx> | |||
27 | #include <o3tl/typed_flags_set.hxx> | |||
28 | ||||
29 | #include "IShellCursorSupplier.hxx" | |||
30 | #include "swdllapi.h" | |||
31 | #include "docary.hxx" | |||
32 | #include "viewsh.hxx" | |||
33 | #include "calbck.hxx" | |||
34 | #include "cshtyp.hxx" | |||
35 | #include "crstate.hxx" | |||
36 | #include "toxe.hxx" | |||
37 | #include "tblsel.hxx" | |||
38 | #include "viscrs.hxx" | |||
39 | #include "node.hxx" | |||
40 | #include "fldbas.hxx" | |||
41 | #include "IDocumentMarkAccess.hxx" | |||
42 | ||||
43 | class SfxItemSet; | |||
44 | class SfxPoolItem; | |||
45 | class SwContentFrame; | |||
46 | class SwUnoCursor; | |||
47 | class SwFormatField; | |||
48 | class SwTextFormatColl; | |||
49 | class SwTextINetFormat; | |||
50 | class SwFormatINetFormat; | |||
51 | class SwTextAttr; | |||
52 | class SwTableBox; | |||
53 | class SwTOXMark; | |||
54 | class SwRangeRedline; | |||
55 | class SwBlockCursor; | |||
56 | class SwPostItField; | |||
57 | class SwTextField; | |||
58 | ||||
59 | namespace i18nutil { | |||
60 | struct SearchOptions2; | |||
61 | } | |||
62 | namespace com::sun::star::text { class XTextRange; } | |||
63 | namespace com::sun::star::container { class XStringKeyMap; } | |||
64 | ||||
65 | // enum and struct to get information via the Doc-Position | |||
66 | ||||
67 | enum class IsAttrAtPos | |||
68 | { | |||
69 | NONE = 0x0000, | |||
70 | Field = 0x0001, | |||
71 | ClickField = 0x0002, | |||
72 | Ftn = 0x0004, | |||
73 | InetAttr = 0x0008, | |||
74 | TableBoxFml = 0x0010, | |||
75 | Redline = 0x0020, | |||
76 | Outline = 0x0040, | |||
77 | ToxMark = 0x0080, | |||
78 | RefMark = 0x0100, | |||
79 | NumLabel = 0x0200, | |||
80 | ContentCheck = 0x0400, | |||
81 | SmartTag = 0x0800, | |||
82 | FormControl = 0x1000 | |||
83 | #ifdef DBG_UTIL | |||
84 | ,CurrAttrs = 0x2000 ///< only for debugging | |||
85 | ,TableBoxValue = 0x4000 ///< only for debugging | |||
86 | #endif | |||
87 | }; | |||
88 | namespace o3tl { | |||
89 | template<> struct typed_flags<IsAttrAtPos> : is_typed_flags<IsAttrAtPos, 0x7fff> {}; | |||
90 | } | |||
91 | ||||
92 | struct SwContentAtPos | |||
93 | { | |||
94 | union { | |||
95 | const SwField* pField; | |||
96 | const SfxPoolItem* pAttr; | |||
97 | const SwRangeRedline* pRedl; | |||
98 | SwContentNode * pNode; | |||
99 | const sw::mark::IFieldmark* pFieldmark; | |||
100 | } aFnd; | |||
101 | IsAttrAtPos eContentAtPos; | |||
102 | int nDist; | |||
103 | OUString sStr; | |||
104 | const SwTextAttr* pFndTextAttr; | |||
105 | ||||
106 | SwContentAtPos( IsAttrAtPos eGetAtPos ) | |||
107 | : eContentAtPos( eGetAtPos ) | |||
108 | { | |||
109 | aFnd.pField = nullptr; | |||
110 | pFndTextAttr = nullptr; | |||
111 | nDist = 0; // #i23726# | |||
112 | } | |||
113 | ||||
114 | bool IsInProtectSect() const; | |||
115 | bool IsInRTLText() const; | |||
116 | }; | |||
117 | ||||
118 | // return values of SetCursor (can be combined via ||) | |||
119 | const int CRSR_POSOLD = 0x01, // cursor stays at old position | |||
120 | CRSR_POSCHG = 0x02; // position changed by the layout | |||
121 | ||||
122 | namespace sw { | |||
123 | ||||
124 | bool ReplaceImpl(SwPaM & rCursor, OUString const& rReplacement, | |||
125 | bool const bRegExp, SwDoc & rDoc, SwRootFrame const*const pLayout); | |||
126 | ||||
127 | /// Helperfunction to resolve backward references in regular expressions | |||
128 | std::optional<OUString> ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt, | |||
129 | SwPaM* pPam, SwRootFrame const* pLayout ); | |||
130 | ||||
131 | bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges, | |||
132 | SwDoc & rDoc, SwPaM const& rDelPam); | |||
133 | ||||
134 | } // namespace sw | |||
135 | ||||
136 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwCursorShell | |||
137 | : public SwViewShell | |||
138 | , public SwModify | |||
139 | , public ::sw::IShellCursorSupplier | |||
140 | { | |||
141 | friend class SwCallLink; | |||
142 | friend class SwVisibleCursor; | |||
143 | friend class SwSelPaintRects; | |||
144 | ||||
145 | // requires the Cursor as InternalCursor | |||
146 | friend bool GetAutoSumSel( const SwCursorShell&, SwCellFrames& ); | |||
147 | ||||
148 | public: | |||
149 | ||||
150 | /** for calling UpdateCursor */ | |||
151 | enum CursorFlag { | |||
152 | UPDOWN = (1 << 0), ///< keep Up/Down on columns | |||
153 | SCROLLWIN = (1 << 1), ///< scroll window | |||
154 | CHKRANGE = (1 << 2), ///< check overlapping PaMs | |||
155 | READONLY = (1 << 3) ///< make visible in spite of Readonly | |||
156 | }; | |||
157 | ||||
158 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void UpdateCursor( | |||
159 | sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, | |||
160 | bool bIdleEnd = false ); | |||
161 | ||||
162 | private: | |||
163 | ||||
164 | SwRect m_aCharRect; ///< Char-SRectangle on which the cursor is located | |||
165 | Point m_aCursorHeight; ///< height & offset from visible Cursor | |||
166 | Point m_aOldRBPos; ///< Right/Bottom of last VisArea | |||
167 | // (used in Invalidate by Cursor) | |||
168 | ||||
169 | Link<const SwFlyFrameFormat*,void> m_aFlyMacroLnk; /**< Link will be called, if the Cursor is set | |||
170 | into a fly. A macro can then be called */ | |||
171 | Link<LinkParamNone*,void> m_aChgLnk; /**< link will be called by every attribute/ | |||
172 | format changes at cursor position.*/ | |||
173 | Link<SwCursorShell&,void> m_aGrfArrivedLnk; ///< Link calls to UI if a graphic is arrived | |||
174 | ||||
175 | SwShellCursor* m_pCurrentCursor; ///< current cursor | |||
176 | SwShellCursor* m_pStackCursor; ///< stack for the cursor | |||
177 | SwVisibleCursor *m_pVisibleCursor; ///< the visible cursor | |||
178 | ||||
179 | SwBlockCursor *m_pBlockCursor; ///< interface of cursor for block (=rectangular) selection | |||
180 | ||||
181 | SwShellTableCursor* m_pTableCursor; /**< table Cursor; only in tables when the | |||
182 | selection lays over 2 columns */ | |||
183 | ||||
184 | SwNodeIndex* m_pBoxIdx; ///< for recognizing of the changed | |||
185 | SwTableBox* m_pBoxPtr; ///< table row | |||
186 | ||||
187 | long m_nUpDownX; /**< try to move the cursor on up/down always | |||
188 | in the same column */ | |||
189 | long m_nLeftFramePos; | |||
190 | sal_uLong m_nCurrentNode; // save CursorPos at Start-Action | |||
191 | sal_Int32 m_nCurrentContent; | |||
192 | SwNodeType m_nCurrentNdTyp; | |||
193 | ||||
194 | /* | |||
195 | * Via the Method SttCursorMove and EndCursorMove this counter gets | |||
196 | * incremented/decremented. As long as the counter is inequal to 0, the | |||
197 | * current Cursor gets no update. This way, "complicated" cursor movements | |||
198 | * (via Find()) can be realised. | |||
199 | */ | |||
200 | sal_uInt16 m_nCursorMove; | |||
201 | CursorMoveState m_eMvState; ///< Status for Cursor-Travelling - GetModelPositionForViewPoint | |||
202 | SwTable::SearchType m_eEnhancedTableSel; /// table rows or columns selected by not cell by cell | |||
203 | ||||
204 | OUString m_sMarkedListId; | |||
205 | int m_nMarkedListLevel; | |||
206 | ||||
207 | bool m_bHasFocus : 1; ///< Shell is "active" in a window | |||
208 | bool m_bSVCursorVis : 1; ///< SV-Cursor visible/invisible | |||
209 | bool m_bChgCallFlag : 1; ///< attribute change inside Start- and EndAction | |||
210 | bool m_bVisPortChgd : 1; ///< in VisPortChg-Call | |||
211 | // (used in Invalidate by the Cursor) | |||
212 | ||||
213 | bool m_bCallChgLnk : 1; ///< flag for derived classes | |||
214 | // true -> call ChgLnk | |||
215 | // access only via SwChgLinkFlag | |||
216 | bool m_bAllProtect : 1; ///< Flag for areas | |||
217 | // true -> everything protected / hidden | |||
218 | bool m_bInCMvVisportChgd : 1; ///< Flag for CursorMoves | |||
219 | // true -> view was moved | |||
220 | bool m_bGCAttr : 1; // true -> non expanded attributes exist. | |||
221 | bool m_bIgnoreReadonly : 1; // true -> make the cursor visible on next | |||
222 | // EndAction in spite of Readonly | |||
223 | bool m_bSelTableCells : 1; // true -> select cells over the InputWin | |||
224 | bool m_bAutoUpdateCells : 1; // true -> autoformat cells | |||
225 | bool m_bBasicHideCursor : 1; // true -> HideCursor from Basic | |||
226 | bool m_bSetCursorInReadOnly : 1;// true -> Cursor is allowed in ReadOnly-Areas | |||
227 | bool m_bOverwriteCursor : 1; // true -> show Overwrite Cursor | |||
228 | ||||
229 | bool m_bMacroExecAllowed : 1; | |||
230 | ||||
231 | SwFrame* m_oldColFrame; | |||
232 | ||||
233 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void MoveCursorToNum(); | |||
234 | ||||
235 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing ); | |||
236 | ||||
237 | /** Mark a certain list level of a certain list | |||
238 | ||||
239 | levels of a certain lists are marked now | |||
240 | ||||
241 | @param sListId list Id of the list whose level is marked | |||
242 | @param nLevel to be marked list level | |||
243 | ||||
244 | An empty sListId denotes that no level of a list is marked. | |||
245 | */ | |||
246 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void MarkListLevel( const OUString& sListId, | |||
247 | const int nLevel ); | |||
248 | ||||
249 | // private method(s) accessed from public inline method(s) must be exported. | |||
250 | bool LeftRight( bool, sal_uInt16, sal_uInt16, bool ); | |||
251 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool UpDown( bool, sal_uInt16 ); | |||
252 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool LRMargin( bool, bool bAPI = false ); | |||
253 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool IsAtLRMargin( bool, bool bAPI = false ) const; | |||
254 | ||||
255 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool isInHiddenTextFrame(SwShellCursor* pShellCursor); | |||
256 | ||||
257 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoStartWordImpl(); | |||
258 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoEndWordImpl(); | |||
259 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoNextWordImpl(); | |||
260 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoPrevWordImpl(); | |||
261 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoNextSentenceImpl(); | |||
262 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoEndSentenceImpl(); | |||
263 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool GoStartSentenceImpl(); | |||
264 | ||||
265 | typedef bool (SwCursor::*FNCursor)(); | |||
266 | typedef bool (SwCursorShell::*FNCursorShell)(); | |||
267 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool CallCursorFN( FNCursor ); | |||
268 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool CallCursorShellFN( FNCursorShell ); | |||
269 | ||||
270 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) const SwRangeRedline* GotoRedline_( SwRedlineTable::size_type nArrPos, bool bSelect ); | |||
271 | ||||
272 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void sendLOKCursorUpdates(); | |||
273 | protected: | |||
274 | ||||
275 | inline SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions, SwPaM* ) const; | |||
276 | ||||
277 | /* | |||
278 | * Compare-Method for the StackCursor and the current Cursor. | |||
279 | * The Methods return -1, 0, 1 for lower, equal, greater. | |||
280 | */ | |||
281 | int CompareCursorStackMkCurrPt() const; | |||
282 | ||||
283 | bool SelTableRowOrCol( bool bRow, bool bRowSimple = false ); | |||
284 | ||||
285 | bool SetInFrontOfLabel( bool bNew ); | |||
286 | ||||
287 | void RefreshBlockCursor(); | |||
288 | ||||
289 | /** Updates the marked list level according to the cursor. | |||
290 | */ | |||
291 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void UpdateMarkedListLevel(); | |||
292 | ||||
293 | protected: | |||
294 | virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) override; | |||
295 | ||||
296 | public: | |||
297 | SwCursorShell( SwDoc& rDoc, vcl::Window *pWin, const SwViewOption *pOpt ); | |||
298 | // disguised copy constructor | |||
299 | SwCursorShell( SwCursorShell& rShell, vcl::Window *pWin ); | |||
300 | virtual ~SwCursorShell() override; | |||
301 | ||||
302 | // create new cursor and append the old one | |||
303 | virtual SwPaM & CreateNewShellCursor() override; | |||
304 | virtual SwPaM & GetCurrentShellCursor() override; | |||
305 | ||||
306 | SwPaM * CreateCursor(); | |||
307 | ///< delete the current cursor and make the following into the current | |||
308 | void DestroyCursor(); | |||
309 | ///< transform TableCursor to normal cursor, nullify Tablemode | |||
310 | void TableCursorToCursor(); | |||
311 | ///< enter block mode, change normal cursor into block cursor | |||
312 | void CursorToBlockCursor(); | |||
313 | ///< leave block mode, change block cursor into normal cursor | |||
314 | void BlockCursorToCursor(); | |||
315 | ||||
316 | // SelAll() selects the document body content | |||
317 | // if ExtendedSelect() is called afterwards, the whole nodes array is selected | |||
318 | // only for usage in special cases allowed! | |||
319 | void ExtendedSelectAll(bool bFootnotes = true); | |||
320 | /// If ExtendedSelectAll() was called and selection didn't change since then. | |||
321 | bool ExtendedSelectedAll(); | |||
322 | /// If document body starts with a table. | |||
323 | bool StartsWithTable(); | |||
324 | ||||
325 | SwPaM* GetCursor( bool bMakeTableCursor = true ) const; | |||
326 | inline SwCursor* GetSwCursor() const; | |||
327 | // return only the current cursor | |||
328 | SwShellCursor* GetCursor_() { return m_pCurrentCursor; } | |||
329 | const SwShellCursor* GetCursor_() const { return m_pCurrentCursor; } | |||
330 | ||||
331 | // show passed cursor - for UNO | |||
332 | void SetSelection(const SwPaM& rCursor); | |||
333 | ||||
334 | // remove all cursors from ContentNodes and set to 0 | |||
335 | void ParkCursor( const SwNodeIndex &rIdx ); | |||
336 | ||||
337 | // return the current cursor stack | |||
338 | // (required in EditShell when deleting contents) | |||
339 | inline SwPaM* GetStackCursor() const; | |||
340 | ||||
341 | // start parenthesing, hide SV-Cursor and selected areas | |||
342 | void StartAction(); | |||
343 | // end parenthesing, show SV-Cursor and selected areas | |||
344 | void EndAction( const bool bIdleEnd = false, const bool DoSetPosX = false ); | |||
345 | ||||
346 | // basic cursor travelling | |||
347 | long GetUpDownX() const { return m_nUpDownX; } | |||
348 | ||||
349 | bool Left( sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual = false ) | |||
350 | { return LeftRight( true, nCnt, nMode, bAllowVisual ); } | |||
351 | bool Right( sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual = false ) | |||
352 | { return LeftRight( false, nCnt, nMode, bAllowVisual ); } | |||
353 | bool Up( sal_uInt16 nCnt = 1 ) { return UpDown( true, nCnt ); } | |||
354 | bool Down( sal_uInt16 nCnt = 1 ) { return UpDown( false, nCnt ); } | |||
355 | bool LeftMargin() { return LRMargin( true ); } | |||
356 | bool RightMargin(bool bAPI = false) { return LRMargin( false, bAPI ); } | |||
357 | bool SttEndDoc( bool bStt ); | |||
358 | ||||
359 | bool MovePage( SwWhichPage, SwPosPage ); | |||
360 | bool MovePara( SwWhichPara, SwMoveFnCollection const & ); | |||
361 | bool MoveSection( SwWhichSection, SwMoveFnCollection const & ); | |||
362 | bool MoveTable( SwWhichTable, SwMoveFnCollection const & ); | |||
363 | void MoveColumn( SwWhichColumn, SwPosColumn ); | |||
364 | bool MoveRegion( SwWhichRegion, SwMoveFnCollection const & ); | |||
365 | ||||
366 | // note: DO NOT call it FindText because windows.h | |||
367 | sal_uLong Find_Text( const i18nutil::SearchOptions2& rSearchOpt, | |||
368 | bool bSearchInNotes, | |||
369 | SwDocPositions eStart, SwDocPositions eEnd, | |||
370 | bool& bCancel, | |||
371 | FindRanges eRng, bool bReplace = false ); | |||
372 | ||||
373 | sal_uLong FindFormat( const SwTextFormatColl& rFormatColl, | |||
374 | SwDocPositions eStart, SwDocPositions eEnd, | |||
375 | bool& bCancel, | |||
376 | FindRanges eRng, const SwTextFormatColl* pReplFormat ); | |||
377 | ||||
378 | sal_uLong FindAttrs( const SfxItemSet& rSet, bool bNoCollections, | |||
379 | SwDocPositions eStart, SwDocPositions eEnd, | |||
380 | bool& bCancel, | |||
381 | FindRanges eRng, | |||
382 | const i18nutil::SearchOptions2* pSearchOpt, | |||
383 | const SfxItemSet* rReplSet ); | |||
384 | ||||
385 | // Position the Cursor | |||
386 | // return values: | |||
387 | // CRSR_POSCHG: when cursor was corrected from SPoint by the layout | |||
388 | // CRSR_POSOLD: when the cursor was not changed | |||
389 | int SetCursor( const Point &rPt, bool bOnlyText = false, bool bBlock = true ); | |||
390 | ||||
391 | /* | |||
392 | * Notification that the visible area was changed. m_aVisArea is reset, then | |||
393 | * scrolling is done. The passed Rectangle lays on pixel borders to avoid | |||
394 | * pixel errors. | |||
395 | */ | |||
396 | virtual void VisPortChgd( const SwRect & ) override; | |||
397 | ||||
398 | /* | |||
399 | * virtual paint method to make selection visible again after Paint | |||
400 | */ | |||
401 | void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle & rRect) override; | |||
402 | ||||
403 | // Areas | |||
404 | inline void SetMark(); | |||
405 | inline bool HasMark() const; | |||
406 | ||||
407 | void ClearMark(); | |||
408 | ||||
409 | /** | |||
410 | Ensure point and mark of the current PaM are in a specific order. | |||
411 | ||||
412 | @param bPointFirst true: If the point is behind the mark then | |||
413 | swap the PaM. false: If the mark is behind the point then swap | |||
414 | the PaM. | |||
415 | */ | |||
416 | void NormalizePam(bool bPointFirst = true); | |||
417 | ||||
418 | void SwapPam(); | |||
419 | bool TestCurrPam( const Point & rPt, | |||
420 | bool bTstHit = false); // only exact matches | |||
421 | void KillPams(); | |||
422 | ||||
423 | /// store a copy of the current cursor on the cursor stack | |||
424 | void Push(); | |||
425 | enum class PopMode { DeleteCurrent, DeleteStack }; | |||
426 | /* | |||
427 | * Delete a cursor | |||
428 | * - either from the top of the stack | |||
429 | * - or delete the current one and replace it with the cursor from the | |||
430 | * stack | |||
431 | * @return <true> if there was one on the stack, <false> otherwise | |||
432 | */ | |||
433 | bool Pop(PopMode); | |||
434 | /* | |||
435 | * Combine 2 Cursors. | |||
436 | * Delete the topmost from the stack and move its Mark into the current. | |||
437 | */ | |||
438 | void Combine(); | |||
439 | ||||
440 | void SttCursorMove(); | |||
441 | void EndCursorMove( const bool bIdleEnd = false ); | |||
442 | ||||
443 | /* | |||
444 | * When the focus is lost the selected ranges are not displayed anymore. | |||
445 | * On the other hand, on receiving the focus all selected ranges are displayed again | |||
446 | * (ranges must be recalculated!). | |||
447 | */ | |||
448 | bool HasShellFocus() const { return m_bHasFocus; } | |||
449 | void ShellLoseFocus(); | |||
450 | void ShellGetFocus(); | |||
451 | ||||
452 | // Methods for displaying or hiding the visible text cursor. | |||
453 | void ShowCursor(); | |||
454 | void HideCursor(); | |||
455 | // Methods for displaying or hiding the selected ranges with visible cursor. | |||
456 | void ShowCursors( bool bCursorVis ); | |||
457 | void HideCursors(); | |||
458 | ||||
459 | bool IsOverwriteCursor() const { return m_bOverwriteCursor; } | |||
460 | void SetOverwriteCursor( bool bFlag ) { m_bOverwriteCursor = bFlag; } | |||
461 | ||||
462 | // Return current frame in which the cursor is placed. | |||
463 | SwContentFrame *GetCurrFrame( const bool bCalcFrame = true ) const; | |||
464 | ||||
465 | //true if cursor is hidden because of readonly. | |||
466 | //false if it is working despite readonly. | |||
467 | bool IsCursorReadonly() const; | |||
468 | ||||
469 | // Cursor is placed in something that is protected or selection contains | |||
470 | // something that is protected. | |||
471 | bool HasReadonlySel() const; | |||
472 | ||||
473 | // Can the cursor be set to read only ranges? | |||
474 | bool IsReadOnlyAvailable() const { return m_bSetCursorInReadOnly; } | |||
475 | void SetReadOnlyAvailable( bool bFlag ); | |||
476 | bool IsOverReadOnlyPos( const Point& rPt ) const; | |||
477 | ||||
478 | // Methods for aFlyMacroLnk. | |||
479 | void SetFlyMacroLnk( const Link<const SwFlyFrameFormat*,void>& rLnk ) { m_aFlyMacroLnk = rLnk; } | |||
480 | const Link<const SwFlyFrameFormat*,void>& GetFlyMacroLnk() const { return m_aFlyMacroLnk; } | |||
481 | ||||
482 | // Methods returning/altering link for changes of attributes/formats. | |||
483 | void SetChgLnk( const Link<LinkParamNone*,void> &rLnk ) { m_aChgLnk = rLnk; } | |||
484 | const Link<LinkParamNone*,void>& GetChgLnk() const { return m_aChgLnk; } | |||
485 | ||||
486 | // Methods returning/altering link for "graphic completely loaded". | |||
487 | void SetGrfArrivedLnk( const Link<SwCursorShell&,void> &rLnk ) { m_aGrfArrivedLnk = rLnk; } | |||
488 | const Link<SwCursorShell&,void>& GetGrfArrivedLnk() const { return m_aGrfArrivedLnk; } | |||
489 | ||||
490 | //Call ChgLink. When within an action calling will be delayed. | |||
491 | void CallChgLnk(); | |||
492 | ||||
493 | // Check if the current cursor contains a selection, i.e. | |||
494 | // if Mark is set and SPoint and Mark are different. | |||
495 | bool HasSelection() const; | |||
496 | ||||
497 | // Check if a selection exists, i.e. if the current cursor comprises a selection. | |||
498 | inline bool IsSelection() const; | |||
499 | // returns if multiple cursors are available | |||
500 | inline bool IsMultiSelection() const; | |||
501 | ||||
502 | // Check if a complete paragraph was selected. | |||
503 | bool IsSelFullPara() const; | |||
504 | ||||
505 | // Check if selection is within one paragraph. | |||
506 | ||||
507 | //Should WaitPtr be activated for Clipboard. | |||
508 | bool ShouldWait() const; | |||
509 | ||||
510 | // Check if selection is within one paragraph. | |||
511 | bool IsSelOnePara() const; | |||
512 | ||||
513 | /* | |||
514 | * Returns SRectangle, at which the cursor is located. | |||
515 | */ | |||
516 | const SwRect &GetCharRect() const { return m_aCharRect; } | |||
517 | /* | |||
518 | * Returns if cursor is wholly or partly within visible range. | |||
519 | */ | |||
520 | bool IsCursorVisible() const { return VisArea().IsOver( GetCharRect() ); } | |||
521 | /* | |||
522 | * Returns SwRect, at which the character is located. | |||
523 | */ | |||
524 | void GetCharRectAt(SwRect& rRect, const SwPosition* pPos); | |||
525 | ||||
526 | // Return current page number: | |||
527 | // true: in which cursor is located. | |||
528 | // false: which is visible at the upper margin. | |||
529 | void GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, | |||
530 | bool bAtCursorPos = true, const bool bCalcFrame = true ); | |||
531 | // Returns current page's sequential number (1-based),in which cursor is located, ignoring autoinserted empty pages. | |||
532 | // Returns 0 on error | |||
533 | sal_uInt16 GetPageNumSeqNonEmpty(); | |||
534 | // Determine how "empty pages" are handled | |||
535 | // (used in PhyPage). | |||
536 | sal_uInt16 GetNextPrevPageNum( bool bNext = true ); | |||
537 | ||||
538 | // Move cursor at the beginning of page "nPage". | |||
539 | bool GotoPage( sal_uInt16 nPage ); | |||
540 | ||||
541 | sal_uInt16 GetPageCnt(); | |||
542 | ||||
543 | bool GoNextCursor(); | |||
544 | ||||
545 | bool GoPrevCursor(); | |||
546 | ||||
547 | bool GoNextPrevCursorSetSearchLabel(const bool bNext); | |||
548 | ||||
549 | // at CurrentCursor.SPoint | |||
550 | ::sw::mark::IMark* SetBookmark( | |||
551 | const vcl::KeyCode&, | |||
552 | const OUString& rName, | |||
553 | IDocumentMarkAccess::MarkType eMark = IDocumentMarkAccess::MarkType::BOOKMARK); | |||
554 | ::sw::mark::IMark* SetBookmark2( | |||
555 | const vcl::KeyCode&, | |||
556 | const OUString& rName, | |||
557 | bool bHide, | |||
558 | const OUString& rCondition); | |||
559 | bool GotoMark( const ::sw::mark::IMark* const pMark ); // sets CurrentCursor.SPoint | |||
560 | bool GotoMark( const ::sw::mark::IMark* const pMark, bool bAtStart ); | |||
561 | bool GoNextBookmark(); // true, if there was one | |||
562 | bool GoPrevBookmark(); | |||
563 | ||||
564 | bool IsFormProtected(); | |||
565 | ::sw::mark::IFieldmark* GetCurrentFieldmark(); | |||
566 | ::sw::mark::IFieldmark* GetFieldmarkAfter(); | |||
567 | ::sw::mark::IFieldmark* GetFieldmarkBefore(); | |||
568 | bool GotoFieldmark( const ::sw::mark::IFieldmark* const pMark ); | |||
569 | ||||
570 | // update Cursr, i.e. reset it into content should only be called when the | |||
571 | // cursor was set to a random position e.g. when deleting frames | |||
572 | void UpdateCursorPos(); | |||
573 | ||||
574 | // get the selected text at the current cursor. It will be filled with | |||
575 | // fields etc. | |||
576 | OUString GetSelText() const; | |||
577 | ||||
578 | // Check of SPoint or Mark of current cursor are placed within a table. | |||
579 | inline const SwTableNode* IsCursorInTable() const; | |||
580 | ||||
581 | bool IsCursorInFootnote() const; | |||
582 | ||||
583 | inline Point& GetCursorDocPos() const; | |||
584 | inline bool IsCursorPtAtEnd() const; | |||
585 | ||||
586 | inline const SwPaM* GetTableCrs() const; | |||
587 | inline SwPaM* GetTableCrs(); | |||
588 | ||||
589 | bool IsTableComplexForChart(); | |||
590 | // get current table selection as text | |||
591 | OUString GetBoxNms() const; | |||
592 | ||||
593 | // set Cursor to the next/previous cell | |||
594 | bool GoNextCell( bool bAppendLine = true ); | |||
595 | bool GoPrevCell(); | |||
596 | // go to this box (if available and inside of table) | |||
597 | bool GotoTable( const OUString& rName ); | |||
598 | ||||
599 | // select a table row, column or box (based on the current cursor) | |||
600 | bool SelTableRow() { return SelTableRowOrCol( true ); } | |||
601 | bool SelTableCol() { return SelTableRowOrCol( false ); } | |||
602 | bool SelTableBox(); | |||
603 | ||||
604 | bool SelTable(); | |||
605 | ||||
606 | void GotoNextNum(); | |||
607 | void GotoPrevNum(); | |||
608 | ||||
609 | bool GotoOutline( const OUString& rName ); | |||
610 | // to the next/previous or the given OutlineNode | |||
611 | void GotoOutline( SwOutlineNodes::size_type nIdx ); | |||
612 | // find the "outline position" in the nodes array of the current chapter | |||
613 | SwOutlineNodes::size_type GetOutlinePos(sal_uInt8 nLevel = UCHAR_MAX(127*2 +1), SwPaM* pPaM = nullptr); | |||
614 | // select the given range of OutlineNodes. Optionally including the children | |||
615 | // the sal_uInt16s are the positions in OutlineNodes-Array (EditShell) | |||
616 | bool MakeOutlineSel(SwOutlineNodes::size_type nSttPos, SwOutlineNodes::size_type nEndPos, | |||
617 | bool bWithChildren, bool bKillPams = true ); | |||
618 | ||||
619 | bool GotoNextOutline(); | |||
620 | bool GotoPrevOutline(); | |||
621 | ||||
622 | /** Delivers the current shell cursor | |||
623 | ||||
624 | Some operations have to run on the current cursor ring, | |||
625 | some on the m_pTableCursor (if exist) or the current cursor ring and | |||
626 | some on the m_pTableCursor or m_pBlockCursor or the current cursor ring. | |||
627 | This small function checks the existence and delivers the wished cursor. | |||
628 | ||||
629 | @param bBlock [bool] | |||
630 | if the block cursor is of interest or not | |||
631 | ||||
632 | @return m_pTableCursor if exist, | |||
633 | m_pBlockCursor if exist and of interest (param bBlock) | |||
634 | otherwise m_pCurrentCursor | |||
635 | */ | |||
636 | SwShellCursor* getShellCursor( bool bBlock ); | |||
637 | const SwShellCursor* getShellCursor( bool bBlock ) const | |||
638 | { return const_cast<SwCursorShell*>(this)->getShellCursor( bBlock ); } | |||
639 | ||||
640 | bool IsBlockMode() const { return nullptr != m_pBlockCursor; } | |||
641 | ||||
642 | // is the Cursor in a table and is the selection over 2 columns | |||
643 | bool IsTableMode() const { return nullptr != m_pTableCursor; } | |||
644 | ||||
645 | const SwShellTableCursor* GetTableCursor() const { return m_pTableCursor; } | |||
646 | SwShellTableCursor* GetTableCursor() { return m_pTableCursor; } | |||
647 | size_t UpdateTableSelBoxes(); | |||
648 | ||||
649 | bool GotoFootnoteText(); ///< jump from content to footnote | |||
650 | bool GotoFootnoteAnchor(); ///< jump from footnote to anchor | |||
651 | bool GotoPrevFootnoteAnchor(); | |||
652 | bool GotoNextFootnoteAnchor(); | |||
653 | ||||
654 | void GotoFlyAnchor(); ///< jump from the frame to the anchor | |||
655 | bool GotoHeaderText(); ///< jump from the content to the header | |||
656 | bool GotoFooterText(); ///< jump from the content to the footer | |||
657 | // jump to the header/footer of the given or current PageDesc | |||
658 | bool SetCursorInHdFt( size_t nDescNo, bool bInHeader ); | |||
659 | // is point of cursor in header/footer. pbInHeader return true if it is | |||
660 | // in a headerframe otherwise in a footerframe | |||
661 | bool IsInHeaderFooter( bool* pbInHeader = nullptr ) const; | |||
662 | ||||
663 | bool GotoNextTOXBase( const OUString* = nullptr ); | |||
664 | bool GotoPrevTOXBase( const OUString* = nullptr ); | |||
665 | void GotoTOXMarkBase(); | |||
666 | // jump to the next or previous index entry | |||
667 | bool GotoNxtPrvTOXMark( bool bNext = true ); | |||
668 | // jump to the next/previous index mark of this type | |||
669 | const SwTOXMark& GotoTOXMark( const SwTOXMark& rStart, SwTOXSearch eDir ); | |||
670 | ||||
671 | // jump to the next or previous table formula | |||
672 | // optionally only to broken formulas | |||
673 | bool GotoNxtPrvTableFormula( bool bNext = true, | |||
674 | bool bOnlyErrors = false ); | |||
675 | // jump to the next / previous hyperlink - inside text and also | |||
676 | // on graphics | |||
677 | bool SelectNxtPrvHyperlink( bool bNext ); | |||
678 | ||||
679 | bool GotoRefMark( const OUString& rRefMark, sal_uInt16 nSubType, | |||
680 | sal_uInt16 nSeqNo ); | |||
681 | ||||
682 | // get the nth character from the start or end of the current selection | |||
683 | sal_Unicode GetChar( bool bEnd = true, long nOffset = 0 ); | |||
684 | bool ExtendSelection( bool bEnd = true, sal_Int32 nCount = 1 ); | |||
685 | ||||
686 | // Place only the visible cursor at the given position in the document. | |||
687 | // Return false if SPoint was corrected by layout. | |||
688 | // (This is needed for displaying the Drag&Drop/Copy-Cursor.) | |||
689 | bool SetVisibleCursor( const Point &rPt ); | |||
690 | inline void UnSetVisibleCursor(); | |||
691 | SwVisibleCursor* GetVisibleCursor() const; | |||
692 | ||||
693 | // jump to the next or previous field of the corresponding type | |||
694 | bool MoveFieldType( | |||
695 | const SwFieldType* pFieldType, | |||
696 | const bool bNext, | |||
697 | const SwFieldIds nResType = SwFieldIds::Unknown, | |||
698 | const bool bAddSetExpressionFieldsToInputFields = true ); | |||
699 | ||||
700 | bool GotoFormatField( const SwFormatField& rField ); | |||
701 | ||||
702 | static SwTextField* GetTextFieldAtPos( | |||
703 | const SwPosition* pPos, | |||
704 | const bool bIncludeInputFieldAtStart ); | |||
705 | static SwTextField* GetTextFieldAtCursor( | |||
706 | const SwPaM* pCursor, | |||
707 | const bool bIncludeInputFieldAtStart ); | |||
708 | static SwField* GetFieldAtCursor( | |||
709 | const SwPaM* pCursor, | |||
710 | const bool bIncludeInputFieldAtStart ); | |||
711 | SwField* GetCurField( const bool bIncludeInputFieldAtStart = false ) const; | |||
712 | bool CursorInsideInputField() const; | |||
713 | static bool PosInsideInputField( const SwPosition& rPos ); | |||
714 | bool DocPtInsideInputField( const Point& rDocPt ) const; | |||
715 | static sal_Int32 StartOfInputFieldAtPos( const SwPosition& rPos ); | |||
716 | static sal_Int32 EndOfInputFieldAtPos( const SwPosition& rPos ); | |||
717 | ||||
718 | // Return number of cursors in ring (The flag indicates whether | |||
719 | // only cursors containing selections are requested). | |||
720 | sal_uInt16 GetCursorCnt( bool bAll = true ) const; | |||
721 | ||||
722 | // Char Travelling - methods (in crstrvl1.cxx) | |||
723 | bool GoStartWord(); | |||
724 | bool GoEndWord(); | |||
725 | bool GoNextWord(); | |||
726 | bool GoPrevWord(); | |||
727 | bool GoNextSentence(); | |||
728 | bool GoStartSentence(); | |||
729 | bool GoEndSentence(); | |||
730 | bool SelectWord( const Point* pPt ); | |||
731 | void ExpandToSentenceBorders(); | |||
732 | ||||
733 | // get position from current cursor | |||
734 | bool IsStartWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES )const; | |||
735 | bool IsEndWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ) const; | |||
736 | bool IsInWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ) const; | |||
737 | bool IsStartSentence() const; | |||
738 | bool IsEndSentence() const; | |||
739 | bool IsSttPara() const; | |||
740 | bool IsEndPara() const; | |||
741 | bool IsEndOfTable() const; ///< at the very last SwPosition inside a table | |||
742 | bool IsStartOfDoc() const; | |||
743 | bool IsEndOfDoc() const; | |||
744 | bool IsInFrontOfLabel() const; | |||
745 | bool IsAtLeftMargin() const { return IsAtLRMargin( true ); } | |||
746 | bool IsAtRightMargin() const { return IsAtLRMargin( false, true/*bAPI*/ ); } | |||
747 | ||||
748 | // delete all created cursors, set the table cursor and the last cursor to | |||
749 | // its TextNode (or StartNode?) | |||
750 | // They all get created on the next ::GetCursor again | |||
751 | // Used for Drag&Drop/Clipboard-Paste in tables | |||
752 | bool ParkTableCursor(); | |||
753 | ||||
754 | // Non expanded attributes? | |||
755 | bool IsGCAttr() const { return m_bGCAttr; } | |||
756 | void ClearGCAttr() { m_bGCAttr = false; } | |||
757 | void UpdateAttr() { m_bGCAttr = true; } | |||
758 | ||||
759 | // is the whole document protected/hidden (for UI...) | |||
760 | bool IsAllProtect() const { return m_bAllProtect; } | |||
761 | ||||
762 | bool GotoRegion( const OUString& rName ); | |||
763 | ||||
764 | // show the current selection | |||
765 | virtual void MakeSelVisible(); | |||
766 | ||||
767 | // set the cursor to a NOT protected/hidden node | |||
768 | bool FindValidContentNode( bool bOnlyText ); | |||
769 | ||||
770 | bool GetContentAtPos( const Point& rPt, | |||
771 | SwContentAtPos& rContentAtPos, | |||
772 | bool bSetCursor = false, | |||
773 | SwRect* pFieldRect = nullptr ); | |||
774 | ||||
775 | const SwPostItField* GetPostItFieldAtCursor() const; | |||
776 | ||||
777 | // get smart tags rectangle for the given point | |||
778 | void GetSmartTagRect( const Point& rPt, SwRect& rSelectRect ); | |||
779 | ||||
780 | // get smart tags at current cursor position | |||
781 | void GetSmartTagTerm( std::vector< OUString >& rSmartTagTypes, | |||
782 | css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > >& rStringKeyMaps, | |||
783 | css::uno::Reference<css::text::XTextRange>& rRange ) const; | |||
784 | ||||
785 | bool IsPageAtPos( const Point &rPt ) const; | |||
786 | ||||
787 | bool SelectTextAttr( sal_uInt16 nWhich, bool bExpand, const SwTextAttr* pAttr = nullptr ); | |||
788 | bool GotoINetAttr( const SwTextINetFormat& rAttr ); | |||
789 | const SwFormatINetFormat* FindINetAttr( const OUString& rName ) const; | |||
790 | ||||
791 | bool SelectText( const sal_Int32 nStart, | |||
792 | const sal_Int32 nEnd ); | |||
793 | ||||
794 | bool CheckTableBoxContent( const SwPosition* pPos = nullptr ); | |||
795 | void SaveTableBoxContent( const SwPosition* pPos = nullptr ); | |||
796 | void ClearTableBoxContent(); | |||
797 | bool EndAllTableBoxEdit(); | |||
798 | ||||
799 | void SetSelTableCells( bool bFlag ) { m_bSelTableCells = bFlag; } | |||
800 | bool IsSelTableCells() const { return m_bSelTableCells; } | |||
801 | ||||
802 | void UnsetEnhancedTableSelection() { m_eEnhancedTableSel = SwTable::SEARCH_NONE; } | |||
803 | SwTable::SearchType GetEnhancedTableSelection() const { return m_eEnhancedTableSel; } | |||
804 | ||||
805 | bool IsAutoUpdateCells() const { return m_bAutoUpdateCells; } | |||
806 | void SetAutoUpdateCells( bool bFlag ) { m_bAutoUpdateCells = bFlag; } | |||
807 | ||||
808 | bool GetShadowCursorPos( const Point& rPt, SwFillMode eFillMode, | |||
809 | SwRect& rRect, sal_Int16& rOrient ); | |||
810 | bool SetShadowCursorPos( const Point& rPt, SwFillMode eFillMode ); | |||
811 | ||||
812 | const SwRangeRedline* SelNextRedline(); | |||
813 | const SwRangeRedline* SelPrevRedline(); | |||
814 | const SwRangeRedline* GotoRedline( SwRedlineTable::size_type nArrPos, bool bSelect ); | |||
815 | ||||
816 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) SvxFrameDirection GetTextDirection( const Point* pPt = nullptr ) const; | |||
817 | // is cursor or the point in/over a vertical formatted text? | |||
818 | bool IsInVerticalText( const Point* pPt = nullptr ) const; | |||
819 | // is cursor or the point in/over a right to left formatted text? | |||
820 | bool IsInRightToLeftText() const; | |||
821 | ||||
822 | static void FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage); | |||
823 | bool bColumnChange(); | |||
824 | static void FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection); | |||
825 | static void FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn); | |||
826 | // If the current cursor position is inside a hidden range, the hidden range | |||
827 | // is selected and true is returned: | |||
828 | bool SelectHiddenRange(); | |||
829 | ||||
830 | // remove all invalid cursors | |||
831 | void ClearUpCursors(); | |||
832 | ||||
833 | void SetMacroExecAllowed( const bool _bMacroExecAllowed ) | |||
834 | { | |||
835 | m_bMacroExecAllowed = _bMacroExecAllowed; | |||
836 | } | |||
837 | bool IsMacroExecAllowed() const | |||
838 | { | |||
839 | return m_bMacroExecAllowed; | |||
840 | } | |||
841 | ||||
842 | /** | |||
843 | Returns textual description of the current selection. | |||
844 | ||||
845 | - If the current selection is a multi-selection the result is | |||
846 | STR_MULTISEL. | |||
847 | - Else the result is the text of the selection. | |||
848 | ||||
849 | @return the textual description of the current selection | |||
850 | */ | |||
851 | OUString GetCursorDescr() const; | |||
852 | ||||
853 | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override; | |||
854 | /// Implementation of lok::Document::getPartPageRectangles() for Writer. | |||
855 | OUString getPageRectangles(); | |||
856 | ||||
857 | /// See SwView::NotifyCursor(). | |||
858 | void NotifyCursor(SfxViewShell* pViewShell) const; | |||
859 | }; | |||
860 | ||||
861 | // Cursor Inlines: | |||
862 | inline SwMoveFnCollection const & SwCursorShell::MakeFindRange( | |||
863 | SwDocPositions nStt, SwDocPositions nEnd, SwPaM* pPam ) const | |||
864 | { | |||
865 | return m_pCurrentCursor->MakeFindRange( nStt, nEnd, pPam ); | |||
866 | } | |||
867 | ||||
868 | inline SwCursor* SwCursorShell::GetSwCursor() const | |||
869 | { | |||
870 | return static_cast<SwCursor*>(GetCursor()); | |||
871 | } | |||
872 | ||||
873 | inline SwPaM* SwCursorShell::GetStackCursor() const { return m_pStackCursor; } | |||
874 | ||||
875 | inline void SwCursorShell::SetMark() { m_pCurrentCursor->SetMark(); } | |||
876 | ||||
877 | inline bool SwCursorShell::HasMark() const { return m_pCurrentCursor->HasMark(); } | |||
878 | ||||
879 | inline bool SwCursorShell::IsSelection() const | |||
880 | { | |||
881 | return IsTableMode() || m_pCurrentCursor->HasMark() || | |||
| ||||
882 | m_pCurrentCursor->GetNext() != m_pCurrentCursor; | |||
883 | } | |||
884 | inline bool SwCursorShell::IsMultiSelection() const | |||
885 | { | |||
886 | return m_pCurrentCursor->GetNext() != m_pCurrentCursor; | |||
887 | } | |||
888 | ||||
889 | inline const SwTableNode* SwCursorShell::IsCursorInTable() const | |||
890 | { | |||
891 | return m_pCurrentCursor->GetNode().FindTableNode(); | |||
892 | } | |||
893 | ||||
894 | inline bool SwCursorShell::IsCursorPtAtEnd() const | |||
895 | { | |||
896 | return m_pCurrentCursor->End() == m_pCurrentCursor->GetPoint(); | |||
897 | } | |||
898 | ||||
899 | inline Point& SwCursorShell::GetCursorDocPos() const | |||
900 | { | |||
901 | return m_pCurrentCursor->GetPtPos(); | |||
902 | } | |||
903 | ||||
904 | inline const SwPaM* SwCursorShell::GetTableCrs() const | |||
905 | { | |||
906 | return m_pTableCursor; | |||
907 | } | |||
908 | ||||
909 | inline SwPaM* SwCursorShell::GetTableCrs() | |||
910 | { | |||
911 | return m_pTableCursor; | |||
912 | } | |||
913 | ||||
914 | inline void SwCursorShell::UnSetVisibleCursor() | |||
915 | { | |||
916 | m_pVisibleCursor->Hide(); | |||
917 | m_pVisibleCursor->SetDragCursor( false ); | |||
918 | } | |||
919 | ||||
920 | #endif // _CRSRSH_HXX | |||
921 | ||||
922 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |