LibreOffice Module sw (master)  1
viscrs.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 <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>
40 
42 #include <svx/sdrpaintwindow.hxx>
43 #include <svx/srchdlg.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 <comphelper/string.hxx>
53 #include <paintfrm.hxx>
54 #include <PostItMgr.hxx>
55 #include <SwGrammarMarkUp.hxx>
56 
57 #include <cellfrm.hxx>
58 #include <wrtsh.hxx>
59 
60 // Here static members are defined. They will get changed on alteration of the
61 // MapMode. This is done so that on ShowCursor the same size does not have to be
62 // expensively determined again and again.
63 
67 
68 // Starting from here: classes / methods for the non-text-cursor
70  : m_pCursorShell( pCShell )
71  , m_nPageLastTime(0)
72 {
73  pCShell->GetWin()->SetCursor( &m_aTextCursor );
75  m_bIsDragCursor = false;
77 }
78 
80 {
83 
84  m_pCursorShell->GetWin()->SetCursor( nullptr );
85 }
86 
88 {
89  if( !m_bIsVisible )
90  {
91  m_bIsVisible = true;
92 
93  // display at all?
95  SetPosAndShow(nullptr);
96  }
97 }
98 
100 {
101  if( m_bIsVisible )
102  {
103  m_bIsVisible = false;
104 
105  if( m_aTextCursor.IsVisible() ) // Shouldn't the flags be in effect?
107  }
108 }
109 
111 {
112  SwRect aRect;
113  long nTmpY = m_pCursorShell->m_aCursorHeight.getY();
114  if( 0 > nTmpY )
115  {
116  nTmpY = -nTmpY;
118  aRect = SwRect( m_pCursorShell->m_aCharRect.Pos(),
119  Size( m_pCursorShell->m_aCharRect.Height(), nTmpY ) );
120  aRect.Pos().setX(aRect.Pos().getX() + m_pCursorShell->m_aCursorHeight.getX());
122  aRect.Pos().setY(aRect.Pos().getY() + aRect.Width());
123  }
124  else
125  {
127  aRect = SwRect( m_pCursorShell->m_aCharRect.Pos(),
128  Size( m_pCursorShell->m_aCharRect.Width(), nTmpY ) );
129  aRect.Pos().setY(aRect.Pos().getY() + m_pCursorShell->m_aCursorHeight.getX());
130  }
131 
132  // check if cursor should show the current cursor bidi level
134  const SwCursor* pTmpCursor = m_pCursorShell->GetCursor_();
135 
136  if ( pTmpCursor && !m_pCursorShell->IsOverwriteCursor() )
137  {
138  SwNode& rNode = pTmpCursor->GetPoint()->nNode.GetNode();
139  if( rNode.IsTextNode() )
140  {
141  const SwTextNode& rTNd = *rNode.GetTextNode();
142  const SwFrame* pFrame = rTNd.getLayoutFrame(m_pCursorShell->GetLayout(), nullptr, nullptr);
143  if ( pFrame )
144  {
145  const SwScriptInfo* pSI = static_cast<const SwTextFrame*>(pFrame)->GetScriptInfo();
146  // cursor level has to be shown
147  if ( pSI && pSI->CountDirChg() > 1 )
148  {
150  ( pTmpCursor->GetCursorBidiLevel() % 2 ) ?
151  CursorDirection::RTL :
152  CursorDirection::LTR );
153  }
154  if ( pFrame->IsRightToLeft() )
155  {
157  if ( pOut )
158  {
159  long nSize = pOut->GetSettings().GetStyleSettings().GetCursorSize();
160  Size aSize( nSize, nSize );
161  aSize = pOut->PixelToLogic( aSize );
162  aRect.Left( aRect.Left() - aSize.Width() );
163  }
164  }
165  }
166  }
167  }
168 
169  if( aRect.Height())
170  {
172 
173  // Disable pixel alignment when tiled rendering, so that twip values of
174  // the cursor don't depend on statics.
176  ::SwAlignRect( aRect, static_cast<SwViewShell const *>(m_pCursorShell), m_pCursorShell->GetOut() );
177  }
180  aRect.Width( 0 );
181 
182  m_aTextCursor.SetSize( aRect.SSize() );
183 
184  m_aTextCursor.SetPos( aRect.Pos() );
185 
186  bool bPostItActive = false;
187  SwView* pView = dynamic_cast<SwView*>(m_pCursorShell->GetSfxViewShell());
188  if (pView)
189  {
190  if (SwPostItMgr* pPostItMgr = pView->GetPostItMgr())
191  bPostItActive = pPostItMgr->GetActiveSidebarWin() != nullptr;
192  }
193 
194  if (comphelper::LibreOfficeKit::isActive() && !bPostItActive)
195  {
196  // notify about page number change (if that happened)
197  sal_uInt16 nPage, nVirtPage;
198  // bCalcFrame=false is important to avoid calculating the layout when
199  // we're in the middle of doing that already.
200  const_cast<SwCursorShell*>(m_pCursorShell)->GetPageNum(nPage, nVirtPage, /*bAtCursorPos=*/true, /*bCalcFrame=*/false);
201  if (nPage != m_nPageLastTime)
202  {
203  m_nPageLastTime = nPage;
204  OString aPayload = OString::number(nPage - 1);
205  m_pCursorShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload.getStr());
206  }
207 
208  // notify about the cursor position & size
209  tools::Rectangle aSVRect(aRect.Pos().getX(), aRect.Pos().getY(), aRect.Pos().getX() + aRect.SSize().Width(), aRect.Pos().getY() + aRect.SSize().Height());
210  OString sRect = aSVRect.toString();
211 
212  // is cursor at a misspelled word ?
213  bool bIsWrong = false;
214  if (pView)
215  {
216  const SwViewOption* pVOpt = pView->GetWrtShell().GetViewOptions();
217  if(pVOpt && pVOpt->IsOnlineSpell())
218  {
219  SwPaM* pCursor = m_pCursorShell->GetCursor();
220  SwPosition aPos(*pCursor->GetPoint());
221  Point aPt = aRect.Pos();
223  SwTextNode *pNode = nullptr;
224  if (m_pCursorShell->GetLayout()->GetCursorOfst(&aPos, aPt, &eTmpState))
225  pNode = aPos.nNode.GetNode().GetTextNode();
226  if (pNode && !pNode->IsInProtectSect())
227  {
228  sal_Int32 nBegin = aPos.nContent.GetIndex();
229  sal_Int32 nLen = 1;
230 
231  SwWrongList *pWrong = nullptr;
232  pWrong = pNode->GetWrong();
233  if (!pWrong)
234  pWrong = pNode->GetGrammarCheck();
235  if (pWrong)
236  bIsWrong = pWrong->InWrongWord(nBegin,nLen) && !pNode->IsSymbolAt(nBegin);
237  }
238  }
239  }
240 
241  if (pViewShell)
242  {
243  if (pViewShell == m_pCursorShell->GetSfxViewShell())
244  {
245  SfxLokHelper::notifyVisCursorInvalidation(pViewShell, sRect, bIsWrong);
246  }
247  else
248  SfxLokHelper::notifyOtherView(m_pCursorShell->GetSfxViewShell(), pViewShell, LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect);
249  }
250  else
251  {
253  SfxLokHelper::notifyOtherViews(m_pCursorShell->GetSfxViewShell(), LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect);
254  }
255  }
256 
258  {
259  if ( m_pCursorShell->GetDrawView() )
260  const_cast<SwDrawView*>(static_cast<const SwDrawView*>(m_pCursorShell->GetDrawView()))->SetAnimationEnabled(
262 
263  sal_uInt16 nStyle = m_bIsDragCursor ? CURSOR_SHADOW : 0;
264  if( nStyle != m_aTextCursor.GetStyle() )
265  {
266  m_aTextCursor.SetStyle( nStyle );
268  }
269 
271  }
272 }
273 
275 {
276  return m_aTextCursor;
277 }
278 
280  : SwRects()
281  , m_pCursorShell( &rCSh )
282 #if HAVE_FEATURE_DESKTOP
283  , m_bShowTextInputFieldOverlay(true)
284 #endif
285 {
286 }
287 
289 {
290  Hide();
291 }
292 
294 {
295  SwRects::swap(rSwap);
296 
297 #if HAVE_FEATURE_DESKTOP
298  // #i75172# also swap m_pCursorOverlay
299  std::swap(m_pCursorOverlay, rSwap.m_pCursorOverlay);
302 #endif
303 }
304 
306 {
307 #if HAVE_FEATURE_DESKTOP
308  m_pCursorOverlay.reset();
309  m_pTextInputFieldOverlay.reset();
310 #endif
311 
312  SwRects::clear();
313 }
314 
323 static SwRect lcl_getLayoutRect(const Point& rPoint, const SwPosition& rPosition)
324 {
325  const SwContentNode* pNode = rPosition.nNode.GetNode().GetContentNode();
326  std::pair<Point, bool> const tmp(rPoint, true);
327  const SwContentFrame* pFrame = pNode->getLayoutFrame(
329  &rPosition, &tmp);
330  SwRect aRect;
331  pFrame->GetCharRect(aRect, rPosition);
332  return aRect;
333 }
334 
335 void SwShellCursor::FillStartEnd(SwRect& rStart, SwRect& rEnd) const
336 {
337  const SwShellCursor* pCursor = GetShell()->getShellCursor(false);
338  rStart = lcl_getLayoutRect(pCursor->GetSttPos(), *pCursor->Start());
339  rEnd = lcl_getLayoutRect(pCursor->GetEndPos(), *pCursor->End());
340 }
341 
342 void SwSelPaintRects::Show(std::vector<OString>* pSelectionRectangles)
343 {
344  SdrView *const pView = const_cast<SdrView*>(m_pCursorShell->GetDrawView());
345 
346  if(pView && pView->PaintWindowCount())
347  {
348  // reset rects
349  SwRects::clear();
350  FillRects();
351 
352 #if HAVE_FEATURE_DESKTOP
353  // get new rects
354  std::vector< basegfx::B2DRange > aNewRanges;
355  aNewRanges.reserve(size());
356  for(size_type a = 0; a < size(); ++a)
357  {
358  const SwRect aNextRect((*this)[a]);
359  const tools::Rectangle aPntRect(aNextRect.SVRect());
360 
361  aNewRanges.emplace_back(
362  aPntRect.Left(), aPntRect.Top(),
363  aPntRect.Right() + 1, aPntRect.Bottom() + 1);
364  }
365 
366  if (m_pCursorOverlay)
367  {
368  if(!aNewRanges.empty())
369  {
370  static_cast<sdr::overlay::OverlaySelection*>(m_pCursorOverlay.get())->setRanges(aNewRanges);
371  }
372  else
373  {
374  m_pCursorOverlay.reset();
375  }
376  }
377  else if(!empty())
378  {
379  SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
380  const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
381 
382  if (xTargetOverlay.is())
383  {
384  // get the system's highlight color
385  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
386  const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
387 
388  // create correct selection
389  m_pCursorOverlay.reset( new sdr::overlay::OverlaySelection(
391  aHighlight,
392  aNewRanges,
393  true) );
394 
395  xTargetOverlay->add(*m_pCursorOverlay);
396  }
397  }
398 
400 #endif
401 
402  // Tiled editing does not expose the draw and writer cursor, it just
403  // talks about "the" cursor at the moment. As long as that's true,
404  // don't say anything about the Writer cursor till a draw object is
405  // being edited.
407  {
408  // If pSelectionRectangles is set, we're just collecting the text selections -> don't emit start/end.
409  if (!empty() && !pSelectionRectangles)
410  {
411  // The selection may be a complex polygon, emit the logical
412  // start/end cursor rectangle of the selection as separate
413  // events, if there is a real selection.
414  // This can be used to easily show selection handles on the
415  // client side.
416  SwRect aStartRect;
417  SwRect aEndRect;
418  FillStartEnd(aStartRect, aEndRect);
419 
420  if (aStartRect.HasArea())
421  {
422  OString sRect = aStartRect.SVRect().toString();
423  GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr());
424  }
425  if (aEndRect.HasArea())
426  {
427  OString sRect = aEndRect.SVRect().toString();
428  GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr());
429  }
430  }
431 
432  std::vector<OString> aRect;
433  aRect.reserve(size());
434  for (size_type i = 0; i < size(); ++i)
435  {
436  const SwRect& rRect = (*this)[i];
437  aRect.push_back(rRect.SVRect().toString());
438  }
439  OString sRect = comphelper::string::join("; ", aRect);
440  if (!pSelectionRectangles)
441  {
442  GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr());
443  SfxLokHelper::notifyOtherViews(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect);
444  }
445  else
446  pSelectionRectangles->push_back(sRect);
447  }
448  }
449 }
450 
452 {
453  std::vector< basegfx::B2DRange > aInputFieldRanges;
454 
456  {
457  SwTextInputField* pCurTextInputFieldAtCursor =
458  dynamic_cast<SwTextInputField*>(SwCursorShell::GetTextFieldAtPos( GetShell()->GetCursor()->Start(), false ));
459  if ( pCurTextInputFieldAtCursor != nullptr )
460  {
461  SwTextNode* pTextNode = pCurTextInputFieldAtCursor->GetpTextNode();
462  std::unique_ptr<SwShellCursor> pCursorForInputTextField(
463  new SwShellCursor( *GetShell(), SwPosition( *pTextNode, pCurTextInputFieldAtCursor->GetStart() ) ) );
464  pCursorForInputTextField->SetMark();
465  pCursorForInputTextField->GetMark()->nNode = *pTextNode;
466  pCursorForInputTextField->GetMark()->nContent.Assign( pTextNode, *(pCurTextInputFieldAtCursor->End()) );
467 
468  pCursorForInputTextField->FillRects();
469  SwRects* pRects = static_cast<SwRects*>(pCursorForInputTextField.get());
470  for (const SwRect & rNextRect : *pRects)
471  {
472  const tools::Rectangle aPntRect(rNextRect.SVRect());
473 
474  aInputFieldRanges.emplace_back(
475  aPntRect.Left(), aPntRect.Top(),
476  aPntRect.Right() + 1, aPntRect.Bottom() + 1);
477  }
478  }
479  }
480 
481  if ( !aInputFieldRanges.empty() )
482  {
483  if (m_pTextInputFieldOverlay != nullptr)
484  {
485  m_pTextInputFieldOverlay->setRanges( aInputFieldRanges );
486  }
487  else
488  {
489  SdrView* pView = const_cast<SdrView*>(GetShell()->GetDrawView());
490  SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
491  const rtl::Reference<sdr::overlay::OverlayManager>& xTargetOverlay = pCandidate->GetOverlayManager();
492 
493  if (xTargetOverlay.is())
494  {
495  // use system's highlight color with decreased luminance as highlight color
496  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
497  Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
498  aHighlight.DecreaseLuminance( 128 );
499 
501  aHighlight, aInputFieldRanges ) );
502  xTargetOverlay->add( *m_pTextInputFieldOverlay );
503  }
504  }
505  }
506  else
507  {
508  m_pTextInputFieldOverlay.reset();
509  }
510 }
511 
513 {
514  size_type nSz = size();
515  if( !nSz )
516  return;
517 
518  SwRegionRects aReg( GetShell()->VisArea() );
519  aReg.assign( begin(), end() );
520  aReg -= rRect;
521  SwRects::erase( begin(), begin() + nSz );
522  SwRects::insert( begin(), aReg.begin(), aReg.end() );
523 
524  // If the selection is to the right or at the bottom, outside the
525  // visible area, it is never aligned on one pixel at the right/bottom.
526  // This has to be determined here and if that is the case the
527  // rectangle has to be expanded.
528  if( GetShell()->m_bVisPortChgd && 0 != ( nSz = size()) )
529  {
531  iterator it = begin();
532  for( ; nSz--; ++it )
533  {
534  SwRect& rRectIt = *it;
535  if( rRectIt.Right() == GetShell()->m_aOldRBPos.X() )
536  rRectIt.Right( rRectIt.Right() + s_nPixPtX );
537  if( rRectIt.Bottom() == GetShell()->m_aOldRBPos.Y() )
538  rRectIt.Bottom( rRectIt.Bottom() + s_nPixPtY );
539  }
540  }
541 }
542 
543 // check current MapMode of the shell and set possibly the static members.
544 // Optional set the parameters pX, pY
546  long* pX, long* pY )
547 {
548  const OutputDevice* pOut = rSh.GetWin();
549  if ( ! pOut )
550  pOut = rSh.GetOut();
551 
552  const MapMode& rMM = pOut->GetMapMode();
553  if (s_pMapMode->GetMapUnit() != rMM.GetMapUnit() ||
554  s_pMapMode->GetScaleX() != rMM.GetScaleX() ||
555  s_pMapMode->GetScaleY() != rMM.GetScaleY())
556  {
557  *s_pMapMode = rMM;
558  Size aTmp( 1, 1 );
559  aTmp = pOut->PixelToLogic( aTmp );
560  s_nPixPtX = aTmp.Width();
561  s_nPixPtY = aTmp.Height();
562  }
563  if( pX )
564  *pX = s_nPixPtX;
565  if( pY )
566  *pY = s_nPixPtY;
567 }
568 
570  const SwCursorShell& rCShell,
571  const SwPosition &rPos )
572  : SwCursor(rPos,nullptr)
573  , SwSelPaintRects(rCShell)
574  , m_pInitialPoint(SwPaM::GetPoint())
575 {}
576 
578  const SwCursorShell& rCShell,
579  const SwPosition &rPos,
580  const Point& rPtPos,
581  SwPaM* pRing )
582  : SwCursor(rPos, pRing)
583  , SwSelPaintRects(rCShell)
584  , m_MarkPt(rPtPos)
585  , m_PointPt(rPtPos)
586  , m_pInitialPoint(SwPaM::GetPoint())
587 {}
588 
590  : SwCursor(rICursor, &rICursor)
591  , SwSelPaintRects(*rICursor.GetShell())
592  , m_MarkPt(rICursor.GetMkPos())
593  , m_PointPt(rICursor.GetPtPos())
594  , m_pInitialPoint(SwPaM::GetPoint())
595 {}
596 
598 {}
599 
601 {
602  return GetShell()->IsReadOnlyAvailable();
603 }
604 
606 {
609  else
611  SwPaM::SetMark();
612 }
613 
615 {
616  // calculate the new rectangles
617  if( HasMark() &&
618  GetPoint()->nNode.GetNode().IsContentNode() &&
619  GetPoint()->nNode.GetNode().GetContentNode()->getLayoutFrame( GetShell()->GetLayout() ) &&
620  (GetMark()->nNode == GetPoint()->nNode ||
622  GetMark()->nNode.GetNode().GetContentNode()->getLayoutFrame( GetShell()->GetLayout() ) ) ))
623  GetShell()->GetLayout()->CalcFrameRects( *this );
624 }
625 
626 void SwShellCursor::Show(SfxViewShell const * pViewShell)
627 {
628  std::vector<OString> aSelectionRectangles;
629  for(SwPaM& rPaM : GetRingContainer())
630  {
631  SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM);
632  if(pShCursor)
633  pShCursor->SwSelPaintRects::Show(&aSelectionRectangles);
634  }
635 
637  {
638  std::vector<OString> aRect;
639  for (const OString & rSelectionRectangle : aSelectionRectangles)
640  {
641  if (rSelectionRectangle.isEmpty())
642  continue;
643  aRect.push_back(rSelectionRectangle);
644  }
645  OString sRect = comphelper::string::join("; ", aRect);
646  if (pViewShell)
647  {
648  // Just notify pViewShell about our existing selection.
649  if (pViewShell != GetShell()->GetSfxViewShell())
650  SfxLokHelper::notifyOtherView(GetShell()->GetSfxViewShell(), pViewShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect);
651  }
652  else
653  {
654  GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr());
655  SfxLokHelper::notifyOtherViews(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect);
656  }
657  }
658 }
659 
660 // This rectangle gets painted anew, therefore the SSelection in this
661 // area is invalid.
662 void SwShellCursor::Invalidate( const SwRect& rRect )
663 {
664  for(SwPaM& rPaM : GetRingContainer())
665  {
666  SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM);
667  // skip any non SwShellCursor objects in the ring
668  // see also: SwAutoFormat::DeleteSel()
669  if(pShCursor)
670  pShCursor->SwSelPaintRects::Invalidate(rRect);
671  }
672 }
673 
675 {
676  for(SwPaM& rPaM : GetRingContainer())
677  {
678  SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rPaM);
679  if(pShCursor)
680  pShCursor->SwSelPaintRects::Hide();
681  }
682 }
683 
685 {
686  return new SwShellCursor( *GetShell(), *GetPoint(), GetPtPos(), pRing );
687 }
688 
690 {
691  short nRet = RET_YES;
693  if( pDlg )
694  {
695  // Terminate old actions. The table-frames get constructed and
696  // a SSelection can be created.
697  std::vector<sal_uInt16> vActionCounts;
698  for(SwViewShell& rShell : const_cast< SwCursorShell* >( GetShell() )->GetRingContainer())
699  {
700  sal_uInt16 nActCnt = 0;
701  while(rShell.ActionPend())
702  {
703  rShell.EndAction();
704  ++nActCnt;
705  }
706  vActionCounts.push_back(nActCnt);
707  }
708  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDlg->getDialog(), "modules/swriter/ui/asksearchdialog.ui"));
709  std::unique_ptr<weld::MessageDialog> xDialog(xBuilder->weld_message_dialog("AskSearchDialog"));
710  nRet = xDialog->run();
711  auto pActionCount = vActionCounts.begin();
712  for(SwViewShell& rShell : const_cast< SwCursorShell* >( GetShell() )->GetRingContainer())
713  {
714  while(*pActionCount)
715  {
716  rShell.StartAction();
717  --(*pActionCount);
718  }
719  ++pActionCount;
720  }
721  }
722  else
723  // otherwise from the Basic, and then switch to RET_YES
724  nRet = RET_YES;
725 
726  return nRet;
727 }
728 
730 {
731  const_cast<SwCursorShell*>(GetShell())->SaveTableBoxContent( pPos );
732 }
733 
734 bool SwShellCursor::UpDown( bool bUp, sal_uInt16 nCnt )
735 {
736  return SwCursor::UpDown( bUp, nCnt,
737  &GetPtPos(), GetShell()->GetUpDownX(),
738  *GetShell()->GetLayout());
739 }
740 
741 // if <true> than the cursor can be set to the position.
742 bool SwShellCursor::IsAtValidPos( bool bPoint ) const
743 {
744  if( GetShell() && ( GetShell()->IsAllProtect() ||
745  GetShell()->GetViewOptions()->IsReadonly() ||
746  ( GetShell()->Imp()->GetDrawView() &&
747  GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )))
748  return true;
749 
750  return SwCursor::IsAtValidPos( bPoint );
751 }
752 
754  const SwPosition& rPos )
755  : SwCursor(rPos,nullptr), SwShellCursor(rCursorSh, rPos), SwTableCursor(rPos)
756 {
757 }
758 
760  const SwPosition& rMkPos, const Point& rMkPt,
761  const SwPosition& rPtPos, const Point& rPtPt )
762  : SwCursor(rPtPos,nullptr), SwShellCursor(rCursorSh, rPtPos), SwTableCursor(rPtPos)
763 {
764  SetMark();
765  *GetMark() = rMkPos;
766  GetMkPos() = rMkPt;
767  GetPtPos() = rPtPt;
768 }
769 
771 
773 
775 {
776  return SwShellCursor::Create( pRing );
777 }
778 
780 {
782 }
783 
785 {
787 }
788 
790 {
791  // Calculate the new rectangles. If the cursor is still "parked" do nothing
793  return;
794 
795  bool bStart = true;
796  SwRegionRects aReg( GetShell()->VisArea() );
799  SwNodes& rNds = GetDoc()->GetNodes();
800  SwFrame* pEndFrame = nullptr;
801  for (size_t n = 0; n < m_SelectedBoxes.size(); ++n)
802  {
803  const SwStartNode* pSttNd = m_SelectedBoxes[n]->GetSttNd();
804  const SwTableNode* pSelTableNd = pSttNd->FindTableNode();
805 
806  SwNodeIndex aIdx( *pSttNd );
807  SwContentNode* pCNd = rNds.GoNextSection( &aIdx, true, false );
808 
809  // table in table
810  // (see also lcl_FindTopLevelTable in unoobj2.cxx for a different
811  // version to do this)
812  const SwTableNode* pCurTableNd = pCNd ? pCNd->FindTableNode() : nullptr;
813  while ( pSelTableNd != pCurTableNd && pCurTableNd )
814  {
815  aIdx = pCurTableNd->EndOfSectionIndex();
816  pCNd = rNds.GoNextSection( &aIdx, true, false );
817  pCurTableNd = pCNd->FindTableNode();
818  }
819 
820  if( !pCNd )
821  continue;
822 
823  std::pair<Point, bool> const tmp(GetSttPos(), true);
824  SwFrame* pFrame = pCNd->getLayoutFrame(GetShell()->GetLayout(), nullptr, &tmp);
825  while( pFrame && !pFrame->IsCellFrame() )
826  pFrame = pFrame->GetUpper();
827 
828  OSL_ENSURE( pFrame, "Node not in a table" );
829 
830  while ( pFrame )
831  {
832  if( aReg.GetOrigin().IsOver( pFrame->getFrameArea() ) )
833  {
834  aReg -= pFrame->getFrameArea();
835  if (bStart)
836  {
837  bStart = false;
838  m_aStart = SwRect(pFrame->getFrameArea().Left(), pFrame->getFrameArea().Top(), 1, pFrame->getFrameArea().Height());
839  }
840  }
841 
842  pEndFrame = pFrame;
843  pFrame = pFrame->GetNextCellLeaf();
844  }
845  }
846  if (pEndFrame)
847  m_aEnd = SwRect(pEndFrame->getFrameArea().Right(), pEndFrame->getFrameArea().Top(), 1, pEndFrame->getFrameArea().Height());
848  aReg.Invert();
849  insert( begin(), aReg.begin(), aReg.end() );
850 }
851 
853 {
854  rStart = m_aStart;
855  rEnd = m_aEnd;
856 }
857 
858 // Check if the SPoint is within the Table-SSelection.
859 bool SwShellTableCursor::IsInside( const Point& rPt ) const
860 {
861  // Calculate the new rectangles. If the cursor is still "parked" do nothing
863  return false;
864 
865  SwNodes& rNds = GetDoc()->GetNodes();
866  for (size_t n = 0; n < m_SelectedBoxes.size(); ++n)
867  {
868  SwNodeIndex aIdx( *m_SelectedBoxes[n]->GetSttNd() );
869  SwContentNode* pCNd = rNds.GoNextSection( &aIdx, true, false );
870  if( !pCNd )
871  continue;
872 
873  std::pair<Point, bool> const tmp(GetPtPos(), true);
874  SwFrame* pFrame = pCNd->getLayoutFrame(GetShell()->GetLayout(), nullptr, &tmp);
875  while( pFrame && !pFrame->IsCellFrame() )
876  pFrame = pFrame->GetUpper();
877  OSL_ENSURE( pFrame, "Node not in a table" );
878  if( pFrame && pFrame->getFrameArea().IsInside( rPt ) )
879  return true;
880 
881  for ( SwCellFrame* pCellFrame = static_cast<SwCellFrame*>(pFrame); pCellFrame; pCellFrame = pCellFrame->GetFollowCell() )
882  {
883  if( pCellFrame->getFrameArea().IsInside( rPt ) )
884  return true;
885  }
886  }
887  return false;
888 }
889 
890 bool SwShellTableCursor::IsAtValidPos( bool bPoint ) const
891 {
892  return SwShellCursor::IsAtValidPos( bPoint );
893 }
894 
895 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:423
bool m_bIsVisible
Definition: viscrs.hxx:42
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
static SwRect lcl_getLayoutRect(const Point &rPoint, const SwPosition &rPosition)
Return a layout rectangle (typically with minimal width) that represents a cursor at rPosition...
Definition: viscrs.cxx:323
const Fraction & GetScaleX() const
long Width() const
virtual short MaxReplaceArived() override
Definition: viscrs.cxx:779
Starts a section of nodes in the document model.
Definition: node.hxx:303
Base class of the Writer layout elements.
Definition: frame.hxx:295
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
sal_uLong GetIndex() const
Definition: node.hxx:282
void SetOrientation(short nOrientation=0)
Marks a position in the document model.
Definition: pam.hxx:35
static long s_nPixPtY
Definition: viscrs.hxx:74
const SwRect & GetOrigin() const
Definition: swregion.hxx:47
const SwPosition * m_pInitialPoint
Definition: viscrs.hxx:122
SdrView * GetDrawView()
Definition: vnew.cxx:375
void SwCalcPixStatics(vcl::RenderContext const *pOut)
Set borders alignment statics Adjustment for 'small' twip-to-pixel relations: For 'small' twip-to-pix...
Definition: paintfrm.cxx:382
virtual bool IsAtValidPos(bool bPoint=true) const override
Return if cursor can be set to this position.
Definition: viscrs.cxx:742
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:188
void SetPos(const Point &rNewPos)
virtual const SwRootFrame * GetCurrentLayout() const =0
rtl::Reference< sdr::overlay::OverlayManager > const & GetOverlayManager() const
stay with the cursor inside text
Definition: crstate.hxx:127
long Height() const
SwNodeIndex nNode
Definition: pam.hxx:37
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3014
sal_uInt16 GetStyle() const
SdrTextObj * GetTextEditObject() const
virtual void SaveTableBoxContent(const SwPosition *pPos) override
Definition: viscrs.cxx:784
const StyleSettings & GetStyleSettings() const
const SwPosition * GetMark() const
Definition: pam.hxx:209
void SetWidth(long nNewWidth)
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1147
sal_Int64 n
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:605
static SvxSearchDialog * GetSearchDialog()
Definition: viewsrch.cxx:846
void Height(long nNew)
Definition: swrect.hxx:189
virtual SwCursor * Create(SwPaM *pRing=nullptr) const override
Definition: viscrs.cxx:774
sal_uInt8 GetCursorBidiLevel() const
Definition: swcrsr.hxx:209
const Point & GetSttPos() const
Definition: viscrs.hxx:146
const MapMode & GetMapMode() const
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwRect m_aEnd
Right edge of the selection end (bottom right cell).
Definition: viscrs.hxx:176
SwTextNode * GetpTextNode() const
Definition: txtfld.hxx:49
void Pos(const Point &rNew)
Definition: swrect.hxx:167
bool m_bVisPortChgd
in VisPortChg-Call
Definition: crsrsh.hxx:214
OString join(const OString &rSeparator, const std::vector< OString > &rSequence)
bool IsCellFrame() const
Definition: frame.hxx:1202
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:444
static void notifyOtherViews(SfxViewShell *pThisView, int nType, const OString &rKey, const OString &rPayload)
void Hide()
Definition: viscrs.cxx:674
virtual bool IsAtValidPos(bool bPoint=true) const override
Return if cursor can be set to this position.
Definition: viscrs.cxx:890
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:843
virtual void SaveTableBoxContent(const SwPosition *pPos) override
Definition: viscrs.cxx:729
SwWrtShell & GetWrtShell() const
Definition: view.hxx:400
void Invalidate(const SwRect &rRect)
Definition: viscrs.cxx:512
bool m_bShowTextInputFieldOverlay
Definition: viscrs.hxx:83
static long s_nPixPtX
Definition: viscrs.hxx:74
RET_YES
void Top(const long nTop)
Definition: swrect.hxx:202
Point m_PointPt
Definition: viscrs.hxx:121
void SwAlignRect(SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext *pRenderContext)
Function is also used outside this file.
Definition: paintfrm.cxx:1123
enumrange< T >::Iterator begin(enumrange< T >)
const SwRect & getFrameArea() const
Definition: frame.hxx:175
const Fraction & GetScaleY() const
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
void CalcFrameRects(SwShellCursor &)
Definition: trvlfrm.cxx:2011
void libreOfficeKitViewCallback(int nType, const char *pPayload) const override
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
void Invert()
invert current rectangle
Definition: swregion.cxx:121
oslFileHandle & pOut
virtual void FillRects() override
Definition: viscrs.cxx:789
SwShellTableCursor(const SwCursorShell &rCursorSh, const SwPosition &rPos)
Definition: viscrs.cxx:753
#define CURSOR_SHADOW
Point m_aOldRBPos
Right/Bottom of last VisArea.
Definition: crsrsh.hxx:170
virtual void FillRects() override
Definition: viscrs.cxx:614
void SetStyle(sal_uInt16 nStyle)
void Right(const long nRight)
Definition: swrect.hxx:198
virtual short MaxReplaceArived() override
Definition: viscrs.cxx:689
void Show(SfxViewShell const *pViewShell)
Definition: viscrs.cxx:626
size_type size() const
void Invalidate(const SwRect &rRect)
Definition: viscrs.cxx:662
if(nullptr==pCandidateA||nullptr==pCandidateB)
virtual void FillStartEnd(SwRect &rStart, SwRect &rEnd) const =0
Fill rStart and rEnd with a rectangle that represents the start and end for selection handles...
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1511
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:71
sal_uInt32 PaintWindowCount() const
long getY() const
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:332
static MapMode * s_pMapMode
Definition: viscrs.hxx:75
long getX() const
SwVisibleCursor(const SwCursorShell *pCShell)
Definition: viscrs.cxx:69
bool IsContentNode() const
Definition: node.hxx:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool IsSelection() const
Definition: crsrsh.hxx:883
virtual ~SwShellTableCursor() override
Definition: viscrs.cxx:770
const SwCursorShell * m_pCursorShell
Definition: viscrs.hxx:77
const SwCursorShell * GetShell() const
Definition: viscrs.hxx:109
SwShellCursor(const SwCursorShell &rCursorSh, const SwPosition &rPos)
Definition: viscrs.cxx:569
long GetCursorSize() const
void SetPosAndShow(SfxViewShell const *pViewShell)
Definition: viscrs.cxx:110
Shell * GetShell()
void DecreaseLuminance(sal_uInt8 cLumDec)
const SwRect & VisArea() const
Definition: viewsh.cxx:558
uno_Any a
const SwPosition * GetPoint() const
Definition: pam.hxx:207
bool UpDown(bool bUp, sal_uInt16 nCnt)
Definition: viscrs.cxx:734
int i
SwContentNode * GetContentNode()
Definition: node.hxx:615
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwDoc * GetDoc()
Definition: node.hxx:702
SwDoc * GetDoc() const
Definition: pam.hxx:243
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
virtual ~SwShellCursor() override
Definition: viscrs.cxx:597
bool HasArea() const
Definition: swrect.hxx:290
void Hide()
Definition: viscrs.cxx:99
void SetWindow(vcl::Window *pWindow)
SwGrammarMarkUp * GetGrammarCheck()
Definition: txtedt.cxx:2180
void HighlightInputField()
Definition: viscrs.cxx:451
bool IsCursorReadonly() const
Definition: crsrsh.cxx:3267
virtual void FillStartEnd(SwRect &rStart, SwRect &rEnd) const override
Definition: viscrs.cxx:852
bool IsInside(const Point &rPt) const
Definition: viscrs.cxx:859
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:772
const Point & GetMkPos() const
Definition: viscrs.hxx:144
size
Marks a node in the document model.
Definition: ndindex.hxx:31
void SetSize(const Size &rNewSize)
const AllSettings & GetSettings() const
bool IsOverwriteCursor() const
Definition: crsrsh.hxx:463
ring_container GetRingContainer()
MapUnit GetMapUnit() const
bool IsOnlineSpell() const
Definition: viewopt.hxx:332
bool empty() const
void SSize(const Size &rNew)
Definition: swrect.hxx:176
void Show(std::vector< OString > *pSelectionRectangles=nullptr)
Definition: viscrs.cxx:342
SwCellFrame * GetFollowCell() const
Definition: findfrm.cxx:1579
long X() const
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: viewsh.cxx:2588
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:404
enumrange< T >::Iterator end(enumrange< T >)
const SwPosition * Start() const
Definition: pam.hxx:212
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:408
SwSelPaintRects(const SwCursorShell &rCSh)
Definition: viscrs.cxx:279
Point PixelToLogic(const Point &rDevicePt) const
virtual void FillStartEnd(SwRect &rStart, SwRect &rEnd) const override
Definition: viscrs.cxx:335
virtual ~SwSelPaintRects()
Definition: viscrs.cxx:288
virtual void FillRects()=0
static void Get1PixelInLogic(const SwViewShell &rSh, long *pX=nullptr, long *pY=nullptr)
Definition: viscrs.cxx:545
void Left(const long nLeft)
Definition: swrect.hxx:193
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwSelBoxes m_SelectedBoxes
Definition: swcrsr.hxx:259
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:478
tools::Rectangle SVRect() const
Definition: swrect.hxx:282
Point m_aCursorHeight
height & offset from visible Cursor
Definition: crsrsh.hxx:169
bool UpDown(bool bUp, sal_uInt16 nCnt, Point const *pPt, long nUpDownX, SwRootFrame &rLayout)
Definition: swcrsr.cxx:1926
static void notifyVisCursorInvalidation(OutlinerViewShell const *pThisView, const OString &rRectangle, bool bMispelledWord=false)
bool m_bIsDragCursor
Definition: viscrs.hxx:43
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void SetCursor(vcl::Cursor *pCursor)
void Width(long nNew)
Definition: swrect.hxx:185
static void notifyOtherView(SfxViewShell *pThisView, SfxViewShell const *pOtherView, int nType, const OString &rKey, const OString &rPayload)
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
vcl::Cursor m_aTextCursor
Definition: viscrs.hxx:45
size_t CountDirChg() const
Definition: scriptinfo.hxx:134
bool InWrongWord(sal_Int32 &rChk, sal_Int32 &rLn) const
If a word is incorrectly selected, this method returns begin and length of it.
Definition: wrong.cxx:102
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:107
SwNodes & GetNodes()
Definition: doc.hxx:403
bool m_bParked
Definition: swcrsr.hxx:261
const SwPosition * End() const
Definition: pam.hxx:217
bool IsRightToLeft() const
Definition: frame.hxx:963
SwPostItMgr * GetPostItMgr()
Definition: view.hxx:623
const sal_Int32 * End() const
Definition: txatbase.hxx:148
virtual SwCursor * Create(SwPaM *pRing=nullptr) const override
Definition: viscrs.cxx:684
const Point & GetPtPos() const
Definition: viscrs.hxx:142
SwWrongList * GetWrong()
Definition: txtedt.cxx:2157
bool IsVisible() const
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:349
void Show()
Definition: viscrs.cxx:87
virtual bool IsAtValidPos(bool bPoint=true) const
Return if cursor can be set to this position.
Definition: swcrsr.cxx:696
const Point & GetEndPos() const
Definition: viscrs.hxx:148
SwRect m_aStart
Left edge of the selection start (top left cell).
Definition: viscrs.hxx:174
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile)
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!!!).
Definition: nodes.cxx:1900
sal_uInt16 m_nPageLastTime
For LibreOfficeKit only - remember what page we were at the last time.
Definition: viscrs.hxx:49
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:469
const SwCursorShell * m_pCursorShell
Definition: viscrs.hxx:46
virtual bool IsReadOnlyAvailable() const override
Definition: viscrs.cxx:600
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:168
Point m_MarkPt
Definition: viscrs.hxx:120
bool IsOver(const SwRect &rRect) const
Definition: swrect.cxx:125
rtl::OString toString() const
const vcl::Cursor & GetTextCursor() const
Definition: viscrs.cxx:274
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2062
void swapContent(SwSelPaintRects &rSwap)
Definition: viscrs.cxx:293
void SetDirection(CursorDirection nDirection=CursorDirection::NONE)
bool IsTextNode() const
Definition: node.hxx:636
std::unique_ptr< sw::overlay::OverlayRangesOutline > m_pTextInputFieldOverlay
Definition: viscrs.hxx:84
SdrPaintWindow * GetPaintWindow(sal_uInt32 nIndex) const
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
Definition: view.hxx:146
long Y() const
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
bool IsSelectionInReadonly() const
Definition: viewopt.hxx:427
Color getHilightColor() const
static SwTextField * GetTextFieldAtPos(const SwPosition *pPos, const bool bIncludeInputFieldAtStart)
Definition: crstrvl.cxx:879
Base class of the Writer document model elements.
Definition: node.hxx:79