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