LibreOffice Module sw (master)  1
edtwin.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 <swtypes.hxx>
23 #include <hintids.hxx>
24 #include <com/sun/star/accessibility/XAccessible.hpp>
25 #include <comphelper/string.hxx>
26 #include <com/sun/star/i18n/XBreakIterator.hpp>
27 #include <com/sun/star/i18n/ScriptType.hpp>
28 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
29 #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
30 
31 #include <com/sun/star/i18n/UnicodeScript.hpp>
32 #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
33 #include <com/sun/star/ui/ContextMenuExecuteEvent.hpp>
34 
35 #include <vcl/inputctx.hxx>
36 #include <vcl/help.hxx>
37 #include <vcl/graph.hxx>
38 #include <vcl/weld.hxx>
39 #include <vcl/ptrstyle.hxx>
40 #include <sot/storage.hxx>
41 #include <svl/macitem.hxx>
43 #include <basic/sbxvar.hxx>
44 #include <svl/ctloptions.hxx>
45 #include <basic/sbx.hxx>
46 #include <svl/eitem.hxx>
47 #include <svl/stritem.hxx>
48 #include <sfx2/ipclient.hxx>
49 #include <sfx2/viewfrm.hxx>
50 #include <sfx2/request.hxx>
51 #include <sfx2/bindings.hxx>
52 #include <sfx2/dispatch.hxx>
53 #include <svl/ptitem.hxx>
54 #include <editeng/sizeitem.hxx>
55 #include <editeng/langitem.hxx>
56 #include <sfx2/htmlmode.hxx>
57 #include <svx/svdview.hxx>
58 #include <svx/svdhdl.hxx>
59 #include <svx/svdoutl.hxx>
60 #include <svx/svxids.hrc>
61 #include <editeng/editeng.hxx>
62 #include <editeng/editview.hxx>
63 #include <editeng/svxacorr.hxx>
65 #include <editeng/flditem.hxx>
66 #include <editeng/colritem.hxx>
67 #include <editeng/brushitem.hxx>
68 #include <editeng/wghtitem.hxx>
69 #include <editeng/udlnitem.hxx>
70 #include <editeng/postitem.hxx>
71 #include <editeng/protitem.hxx>
72 #include <unotools/charclass.hxx>
75 
76 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
77 #include <comphelper/lok.hxx>
78 #include <sfx2/lokhelper.hxx>
79 
80 #include <editeng/acorrcfg.hxx>
81 #include <SwSmartTagMgr.hxx>
82 #include <edtdd.hxx>
83 #include <edtwin.hxx>
84 #include <view.hxx>
85 #include <wrtsh.hxx>
88 #include <IDocumentUndoRedo.hxx>
89 #include <textboxhelper.hxx>
90 #include <dcontact.hxx>
91 #include <fldbas.hxx>
92 #include <swmodule.hxx>
93 #include <docsh.hxx>
94 #include <viewopt.hxx>
95 #include <drawbase.hxx>
96 #include <dselect.hxx>
97 #include <textsh.hxx>
98 #include <shdwcrsr.hxx>
99 #include <txatbase.hxx>
100 #include <fmtanchr.hxx>
101 #include <fmtornt.hxx>
102 #include <fmtfsize.hxx>
103 #include <fmtclds.hxx>
104 #include <fmthdft.hxx>
105 #include <frmfmt.hxx>
106 #include <modcfg.hxx>
107 #include <fmtcol.hxx>
108 #include <wview.hxx>
109 #include <listsh.hxx>
110 #include <gloslst.hxx>
111 #include <inputwin.hxx>
112 #include <gloshdl.hxx>
113 #include <swundo.hxx>
114 #include <drwtxtsh.hxx>
115 #include <fchrfmt.hxx>
116 #include <fmturl.hxx>
117 #include "romenu.hxx"
118 #include <initui.hxx>
119 #include <frmatr.hxx>
120 #include <extinput.hxx>
121 #include <acmplwrd.hxx>
122 #include <swcalwrp.hxx>
123 #include <swdtflvr.hxx>
124 #include <wdocsh.hxx>
125 #include <breakit.hxx>
126 #include <checkit.hxx>
127 #include <pagefrm.hxx>
128 #include <HeaderFooterWin.hxx>
129 
130 #include <helpids.h>
131 #include <cmdid.h>
132 #include <uitool.hxx>
133 #include <fmtfollowtextflow.hxx>
135 #include <charfmt.hxx>
136 #include <numrule.hxx>
137 #include <pagedesc.hxx>
138 #include <svtools/ruler.hxx>
139 #include <formatclipboard.hxx>
140 #include <vcl/svapp.hxx>
141 #include <docstat.hxx>
142 #include <wordcountdialog.hxx>
143 #include <swwait.hxx>
144 #include <txtfld.hxx>
145 #include <fmtfld.hxx>
146 
147 #include <IMark.hxx>
148 #include <doc.hxx>
149 #include <xmloff/odffields.hxx>
150 
151 #include <PostItMgr.hxx>
152 #include <FrameControlsManager.hxx>
153 #include <AnnotationWin.hxx>
154 
155 #include <algorithm>
156 #include <vector>
157 
158 #include <rootfrm.hxx>
159 
161 #include <i18nlangtag/mslangid.hxx>
163 #include <sfx2/event.hxx>
164 #include <memory>
165 
166 using namespace sw::mark;
167 using namespace ::com::sun::star;
168 
172 static bool g_bInputLanguageSwitched = false;
173 
174 // Usually in MouseButtonUp a selection is revoked when the selection is
175 // not currently being pulled open. Unfortunately in MouseButtonDown there
176 // is being selected at double/triple click. That selection is completely
177 // finished in the Handler and thus can't be distinguished in the Up.
178 // To resolve this g_bHoldSelection is set in Down at evaluated in Up.
179 static bool g_bHoldSelection = false;
180 
181 bool g_bFrameDrag = false;
182 static bool g_bValidCursorPos = false;
183 static bool g_bModePushed = false;
184 bool g_bDDTimerStarted = false;
185 bool g_bFlushCharBuffer = false;
186 bool g_bDDINetAttr = false;
187 static SdrHdlKind g_eSdrMoveHdl = SdrHdlKind::User;
188 
190 
193 
194 static SfxShell* lcl_GetTextShellFromDispatcher( SwView const & rView );
195 
197 static bool lcl_goIntoTextBox(SwEditWin& rEditWin, SwWrtShell& rSh)
198 {
199  SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0);
200  if (!pMark)
201  return false;
202 
203  SdrObject* pSdrObject = pMark->GetMarkedSdrObj();
204  SwFrameFormat* pObjectFormat = ::FindFrameFormat(pSdrObject);
205  if (SwFrameFormat* pTextBoxFormat = SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat, RES_DRAWFRMFMT))
206  {
207  SdrObject* pTextBox = pTextBoxFormat->FindRealSdrObject();
208  SdrView* pSdrView = rSh.GetDrawView();
209  // Unmark the shape.
210  pSdrView->UnmarkAllObj();
211  // Mark the textbox.
212  rSh.SelectObj(Point(), SW_ALLOW_TEXTBOX, pTextBox);
213  // Clear the DrawFuncPtr.
214  rEditWin.StopInsFrame();
215  return true;
216  }
217  return false;
218 }
219 
221 {
223  Point const aHdlPos;
226 public:
227  explicit SwAnchorMarker( SdrHdl* pH )
228  : pHdl( pH )
229  , aHdlPos( pH->GetPos() )
230  , aLastPos( pH->GetPos() )
231  , bTopRightHandle( pH->GetKind() == SdrHdlKind::Anchor_TR )
232  {}
233  const Point& GetLastPos() const { return aLastPos; }
234  void SetLastPos( const Point& rNew ) { aLastPos = rNew; }
235  void SetPos( const Point& rNew ) { pHdl->SetPos( rNew ); }
236  const Point& GetHdlPos() { return aHdlPos; }
237  SdrHdl* GetHdl() const { return pHdl; }
238  void ChgHdl( SdrHdl* pNew )
239  {
240  pHdl = pNew;
241  if ( pHdl )
242  {
243  bTopRightHandle = (pHdl->GetKind() == SdrHdlKind::Anchor_TR);
244  }
245  }
246  const Point GetPosForHitTest( const OutputDevice& rOut )
247  {
248  Point aHitTestPos( pHdl->GetPos() );
249  aHitTestPos = rOut.LogicToPixel( aHitTestPos );
250  if ( bTopRightHandle )
251  {
252  aHitTestPos += Point( -1, 1 );
253  }
254  else
255  {
256  aHitTestPos += Point( 1, 1 );
257  }
258  aHitTestPos = rOut.PixelToLogic( aHitTestPos );
259 
260  return aHitTestPos;
261  }
262 };
263 
266 {
268  std::vector<OUString> m_aHelpStrings;
270  sal_uInt16 nCurArrPos;
272  sal_uInt16 nLen;
273 
277  bool m_bIsTip;
279  void* nTipId;
282 
285 
286  QuickHelpData() { ClearContent(); }
287 
288  void Move( QuickHelpData& rCpy );
289  void ClearContent();
290  void Start( SwWrtShell& rSh, sal_uInt16 nWrdLen );
291  void Stop( SwWrtShell& rSh );
292 
293  bool HasContent() const { return !m_aHelpStrings.empty() && 0 != nLen; }
294 
296  void Next( bool bEndLess )
297  {
298  if( ++nCurArrPos >= m_aHelpStrings.size() )
299  nCurArrPos = (bEndLess && !m_bIsAutoText ) ? 0 : nCurArrPos-1;
300  }
302  void Previous( bool bEndLess )
303  {
304  if( 0 == nCurArrPos-- )
305  nCurArrPos = (bEndLess && !m_bIsAutoText ) ? m_aHelpStrings.size()-1 : 0;
306  }
307 
308  // Fills internal structures with hopefully helpful information.
309  void FillStrArr( SwWrtShell const & rSh, const OUString& rWord );
310  void SortAndFilter(const OUString &rOrigWord);
311 };
312 
316 #define HIT_PIX 2 /* hit tolerance in pixel */
317 #define MIN_MOVE 4
318 
319 static bool IsMinMove(const Point &rStartPos, const Point &rLPt)
320 {
321  return std::abs(rStartPos.X() - rLPt.X()) > MIN_MOVE ||
322  std::abs(rStartPos.Y() - rLPt.Y()) > MIN_MOVE;
323 }
324 
331 static bool IsDrawObjSelectable( const SwWrtShell& rSh, const Point& rPt )
332 {
333  bool bRet = true;
334  SdrObject* pObj;
335  switch( rSh.GetObjCntType( rPt, pObj ))
336  {
337  case OBJCNT_NONE:
338  case OBJCNT_FLY:
339  case OBJCNT_GRF:
340  case OBJCNT_OLE:
341  bRet = false;
342  break;
343  default:; //prevent warning
344  }
345  return bRet;
346 }
347 
348 /*
349  * Switch pointer
350  */
351 void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 nModifier )
352 {
353  SwWrtShell &rSh = m_rView.GetWrtShell();
354  if( m_pApplyTempl )
355  {
356  PointerStyle eStyle = PointerStyle::Fill;
357  if ( rSh.IsOverReadOnlyPos( rLPt ) )
358  {
359  m_pUserMarker.reset();
360 
361  eStyle = PointerStyle::NotAllowed;
362  }
363  else
364  {
365  SwRect aRect;
366  SwRect* pRect = &aRect;
367  const SwFrameFormat* pFormat = nullptr;
368 
369  bool bFrameIsValidTarget = false;
370  if( m_pApplyTempl->m_pFormatClipboard )
371  bFrameIsValidTarget = m_pApplyTempl->m_pFormatClipboard->HasContentForThisType( SelectionType::Frame );
372  else if( !m_pApplyTempl->nColor )
373  bFrameIsValidTarget = ( m_pApplyTempl->eType == SfxStyleFamily::Frame );
374 
375  if( bFrameIsValidTarget &&
376  nullptr !=(pFormat = rSh.GetFormatFromObj( rLPt, &pRect )) &&
377  dynamic_cast<const SwFlyFrameFormat*>( pFormat) )
378  {
379  //turn on highlight for frame
380  tools::Rectangle aTmp( pRect->SVRect() );
381 
382  if ( !m_pUserMarker )
383  {
384  m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp ));
385  }
386  }
387  else
388  {
389  m_pUserMarker.reset();
390  }
391 
392  rSh.SwCursorShell::SetVisibleCursor( rLPt );
393  }
394  SetPointer( eStyle );
395  return;
396  }
397 
398  if( !rSh.VisArea().Width() )
399  return;
400 
401  SET_CURR_SHELL(&rSh);
402 
403  if ( IsChainMode() )
404  {
405  SwRect aRect;
406  SwChainRet nChainable = rSh.Chainable( aRect, *rSh.GetFlyFrameFormat(), rLPt );
407  PointerStyle eStyle = nChainable != SwChainRet::OK
408  ? PointerStyle::ChainNotAllowed : PointerStyle::Chain;
409  if ( nChainable == SwChainRet::OK )
410  {
411  tools::Rectangle aTmp( aRect.SVRect() );
412 
413  if ( !m_pUserMarker )
414  {
415  m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp ));
416  }
417  }
418  else
419  {
420  m_pUserMarker.reset();
421  }
422 
423  SetPointer( eStyle );
424  return;
425  }
426 
427  bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
428  if ( !bExecHyperlinks )
429  {
430  SvtSecurityOptions aSecOpts;
431  const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
432  if ( ( bSecureOption && nModifier == KEY_MOD1 ) ||
433  ( !bSecureOption && nModifier != KEY_MOD1 ) )
434  bExecHyperlinks = true;
435  }
436 
437  const bool bExecSmarttags = nModifier == KEY_MOD1;
438 
439  SdrView *pSdrView = rSh.GetDrawView();
440  bool bPrefSdrPointer = false;
441  bool bHitHandle = false;
442  bool bCntAtPos = false;
443  bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
444  rSh.IsCursorReadonly();
445  m_aActHitType = SdrHitKind::NONE;
446  PointerStyle eStyle = PointerStyle::Text;
447  if ( !pSdrView )
448  bCntAtPos = true;
449  else if ( (bHitHandle = (pSdrView->PickHandle(rLPt) != nullptr)) )
450  {
451  m_aActHitType = SdrHitKind::Object;
452  bPrefSdrPointer = true;
453  }
454  else
455  {
456  const bool bNotInSelObj = !rSh.IsInsideSelectedObj( rLPt );
457  if ( m_rView.GetDrawFuncPtr() && !m_bInsDraw && bNotInSelObj )
458  {
459  m_aActHitType = SdrHitKind::Object;
460  if (IsObjectSelect())
461  eStyle = PointerStyle::Arrow;
462  else
463  bPrefSdrPointer = true;
464  }
465  else
466  {
467  SdrPageView* pPV = nullptr;
468  pSdrView->SetHitTolerancePixel( HIT_PIX );
469  SdrObject* pObj = (bNotInSelObj && bExecHyperlinks) ?
470  pSdrView->PickObj(rLPt, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) :
471  nullptr;
472  if (pObj)
473  {
474  SdrObjMacroHitRec aTmp;
475  aTmp.aPos = rLPt;
476  aTmp.pPageView = pPV;
477  SetPointer( pObj->GetMacroPointer( aTmp ) );
478  return;
479  }
480  else
481  {
482  // dvo: IsObjSelectable() eventually calls SdrView::PickObj, so
483  // apparently this is used to determine whether this is a
484  // drawling layer object or not.
485  if ( rSh.IsObjSelectable( rLPt ) )
486  {
487  if (pSdrView->IsTextEdit())
488  {
489  m_aActHitType = SdrHitKind::NONE;
490  bPrefSdrPointer = true;
491  }
492  else
493  {
494  SdrViewEvent aVEvt;
495  SdrHitKind eHit = pSdrView->PickAnything(rLPt, aVEvt);
496 
497  if (eHit == SdrHitKind::UrlField && bExecHyperlinks)
498  {
499  m_aActHitType = SdrHitKind::Object;
500  bPrefSdrPointer = true;
501  }
502  else
503  {
504  // if we're over a selected object, we show an
505  // ARROW by default. We only show a MOVE if 1) the
506  // object is selected, and 2) it may be moved
507  // (i.e., position is not protected).
508  bool bMovable =
509  (!bNotInSelObj) &&
510  (rSh.IsObjSelected() || rSh.IsFrameSelected()) &&
512 
513  SdrObject* pSelectableObj = rSh.GetObjAt(rLPt);
514  // Don't update pointer if this is a background image only.
515  if (pSelectableObj->GetLayer() != rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId())
516  eStyle = bMovable ? PointerStyle::Move : PointerStyle::Arrow;
517  m_aActHitType = SdrHitKind::Object;
518  }
519  }
520  }
521  else
522  {
523  if ( rSh.IsFrameSelected() && !bNotInSelObj )
524  {
525  // dvo: this branch appears to be dead and should be
526  // removed in a future version. Reason: The condition
527  // !bNotInSelObj means that this branch will only be
528  // executed in the cursor points inside a selected
529  // object. However, if this is the case, the previous
530  // if( rSh.IsObjSelectable(rLPt) ) must always be true:
531  // rLPt is inside a selected object, then obviously
532  // rLPt is over a selectable object.
534  eStyle = PointerStyle::NotAllowed;
535  else
536  eStyle = PointerStyle::Move;
537  m_aActHitType = SdrHitKind::Object;
538  }
539  else
540  {
541  if ( m_rView.GetDrawFuncPtr() )
542  bPrefSdrPointer = true;
543  else
544  bCntAtPos = true;
545  }
546  }
547  }
548  }
549  }
550  if ( bPrefSdrPointer )
551  {
552  if (bIsDocReadOnly || (rSh.IsObjSelected() && rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE))
553  SetPointer( PointerStyle::NotAllowed );
554  else
555  {
556  if (m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->IsInsertForm() && !bHitHandle)
557  SetPointer( PointerStyle::DrawRect );
558  else
559  SetPointer( pSdrView->GetPreferredPointer( rLPt, rSh.GetOut() ) );
560  }
561  }
562  else
563  {
564  if( !rSh.IsPageAtPos( rLPt ) || m_pAnchorMarker )
565  eStyle = PointerStyle::Arrow;
566  else
567  {
568  // Even if we already have something, prefer URLs if possible.
570  if (bCntAtPos || rSh.GetContentAtPos(rLPt, aUrlPos))
571  {
572  SwContentAtPos aSwContentAtPos(
578  if( rSh.GetContentAtPos( rLPt, aSwContentAtPos) )
579  {
580  // Is edit inline input field
581  if (IsAttrAtPos::Field == aSwContentAtPos.eContentAtPos
582  && aSwContentAtPos.pFndTextAttr != nullptr
583  && aSwContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD)
584  {
585  const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr;
586  if (!(pCursorField && pCursorField == aSwContentAtPos.pFndTextAttr->GetFormatField().GetField()))
587  eStyle = PointerStyle::RefHand;
588  }
589  else
590  {
591  const bool bClickToFollow = IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos ||
592  IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos;
593  if( !bClickToFollow ||
594  (IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos && bExecHyperlinks) ||
595  (IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos && bExecSmarttags) )
596  eStyle = PointerStyle::RefHand;
597  }
598  }
599  }
600  }
601 
602  // which kind of text pointer have we to show - horz / vert - ?
603  if( PointerStyle::Text == eStyle && rSh.IsInVerticalText( &rLPt ))
604  eStyle = PointerStyle::TextVertical;
605  else if (rSh.GetViewOptions()->CanHideWhitespace() &&
606  rSh.GetLayout()->IsBetweenPages(rLPt))
607  {
609  eStyle = PointerStyle::ShowWhitespace;
610  else
611  eStyle = PointerStyle::HideWhitespace;
612  }
613 
614  SetPointer( eStyle );
615  }
616 }
617 
621 IMPL_LINK_NOARG(SwEditWin, TimerHandler, Timer *, void)
622 {
623  SwWrtShell &rSh = m_rView.GetWrtShell();
624  Point aModPt( m_aMovePos );
625  const SwRect aOldVis( rSh.VisArea() );
626  bool bDone = false;
627 
628  if ( !rSh.VisArea().IsInside( aModPt ) )
629  {
630  if ( m_bInsDraw )
631  {
632  const int nMaxScroll = 40;
633  m_rView.Scroll( tools::Rectangle(aModPt,Size(1,1)), nMaxScroll, nMaxScroll);
634  bDone = true;
635  }
636  else if ( g_bFrameDrag )
637  {
638  rSh.Drag(&aModPt, false);
639  bDone = true;
640  }
641  if ( !bDone )
642  aModPt = rSh.GetContentPos( aModPt,aModPt.Y() > rSh.VisArea().Bottom() );
643  }
644  if ( !bDone && !(g_bFrameDrag || m_bInsDraw) )
645  {
646  if ( m_xRowColumnSelectionStart )
647  {
648  Point aPos( aModPt );
649  rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag );
650  }
651  else
652  rSh.CallSetCursor( &aModPt, false );
653 
654  // It can be that a "jump" over a table cannot be accomplished like
655  // that. So we jump over the table by Up/Down here.
656  const SwRect& rVisArea = rSh.VisArea();
657  if( aOldVis == rVisArea && !rSh.IsStartOfDoc() && !rSh.IsEndOfDoc() )
658  {
659  // take the center point of VisArea to
660  // decide in which direction the user want.
661  if( aModPt.Y() < ( rVisArea.Top() + rVisArea.Height() / 2 ) )
662  rSh.Up( true );
663  else
664  rSh.Down( true );
665  }
666  }
667 
668  m_aMovePos += rSh.VisArea().Pos() - aOldVis.Pos();
669  JustifyAreaTimer();
670 }
671 
673 {
674  const tools::Rectangle &rVisArea = GetView().GetVisArea();
675 #ifdef UNX
676  const long coMinLen = 100;
677 #else
678  const long coMinLen = 50;
679 #endif
680  long const nTimeout = 800,
681  nDiff = std::max(
682  std::max( m_aMovePos.Y() - rVisArea.Bottom(), rVisArea.Top() - m_aMovePos.Y() ),
683  std::max( m_aMovePos.X() - rVisArea.Right(), rVisArea.Left() - m_aMovePos.X()));
684  m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff*2L) );
685 }
686 
687 void SwEditWin::LeaveArea(const Point &rPos)
688 {
689  m_aMovePos = rPos;
690  JustifyAreaTimer();
691  if( !m_aTimer.IsActive() )
692  m_aTimer.Start();
693  m_pShadCursor.reset();
694 }
695 
696 inline void SwEditWin::EnterArea()
697 {
698  m_aTimer.Stop();
699 }
700 
704 void SwEditWin::InsFrame(sal_uInt16 nCols)
705 {
706  StdDrawMode( OBJ_NONE, false );
707  m_bInsFrame = true;
708  m_nInsFrameColCount = nCols;
709 }
710 
711 void SwEditWin::StdDrawMode( SdrObjKind eSdrObjectKind, bool bObjSelect )
712 {
713  SetSdrDrawMode( eSdrObjectKind );
714 
715  if (bObjSelect)
716  m_rView.SetDrawFuncPtr(std::make_unique<DrawSelection>( &m_rView.GetWrtShell(), this, &m_rView ));
717  else
718  m_rView.SetDrawFuncPtr(std::make_unique<SwDrawBase>( &m_rView.GetWrtShell(), this, &m_rView ));
719 
720  m_rView.SetSelDrawSlot();
721  SetSdrDrawMode( eSdrObjectKind );
722  if (bObjSelect)
723  m_rView.GetDrawFuncPtr()->Activate( SID_OBJECT_SELECT );
724  else
725  m_rView.GetDrawFuncPtr()->Activate( sal::static_int_cast< sal_uInt16 >(eSdrObjectKind) );
726  m_bInsFrame = false;
727  m_nInsFrameColCount = 1;
728 }
729 
731 {
732  if (m_rView.GetDrawFuncPtr())
733  {
734  m_rView.GetDrawFuncPtr()->Deactivate();
735  m_rView.SetDrawFuncPtr(nullptr);
736  }
737  m_rView.LeaveDrawCreate(); // leave construction mode
738  m_bInsFrame = false;
739  m_nInsFrameColCount = 1;
740 }
741 
742 bool SwEditWin::IsInputSequenceCheckingRequired( const OUString &rText, const SwPaM& rCursor )
743 {
744  const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
745  if ( !rCTLOptions.IsCTLFontEnabled() ||
746  !rCTLOptions.IsCTLSequenceChecking() )
747  return false;
748 
749  if ( 0 == rCursor.Start()->nContent.GetIndex() ) /* first char needs not to be checked */
750  return false;
751 
752  SwBreakIt *pBreakIter = SwBreakIt::Get();
753  uno::Reference < i18n::XBreakIterator > xBI = pBreakIter->GetBreakIter();
754  assert(xBI.is());
755  long nCTLScriptPos = -1;
756 
757  if (xBI->getScriptType( rText, 0 ) == i18n::ScriptType::COMPLEX)
758  nCTLScriptPos = 0;
759  else
760  nCTLScriptPos = xBI->nextScript( rText, 0, i18n::ScriptType::COMPLEX );
761 
762  return (0 <= nCTLScriptPos && nCTLScriptPos <= rText.getLength());
763 }
764 
765 //return INVALID_HINT if language should not be explicitly overridden, the correct
766 //HintId to use for the eBufferLanguage otherwise
767 static sal_uInt16 lcl_isNonDefaultLanguage(LanguageType eBufferLanguage, SwView const & rView,
768  const OUString &rInBuffer)
769 {
770  sal_uInt16 nWhich = INVALID_HINT;
771 
772  //If the option to IgnoreLanguageChange is set, short-circuit this method
773  //which results in the document/paragraph language remaining the same
774  //despite a change to the keyboard/input language
775  SvtSysLocaleOptions aSysLocaleOptions;
776  if(aSysLocaleOptions.IsIgnoreLanguageChange())
777  {
778  return INVALID_HINT;
779  }
780 
781  bool bLang = true;
782  if(eBufferLanguage != LANGUAGE_DONTKNOW)
783  {
784  switch( SvtLanguageOptions::GetI18NScriptTypeOfLanguage( eBufferLanguage ))
785  {
786  case i18n::ScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break;
787  case i18n::ScriptType::COMPLEX: nWhich = RES_CHRATR_CTL_LANGUAGE; break;
788  case i18n::ScriptType::LATIN: nWhich = RES_CHRATR_LANGUAGE; break;
789  default: bLang = false;
790  }
791  if(bLang)
792  {
793  SfxItemSet aLangSet(rView.GetPool(), {{nWhich, nWhich}});
794  SwWrtShell& rSh = rView.GetWrtShell();
795  rSh.GetCurAttr(aLangSet);
796  if(SfxItemState::DEFAULT <= aLangSet.GetItemState(nWhich))
797  {
798  LanguageType eLang = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage();
799  if ( eLang == eBufferLanguage )
800  {
801  // current language attribute equal to language reported from system
802  bLang = false;
803  }
804  else if ( !g_bInputLanguageSwitched && RES_CHRATR_LANGUAGE == nWhich )
805  {
806  // special case: switching between two "LATIN" languages
807  // In case the current keyboard setting might be suitable
808  // for both languages we can't safely assume that the user
809  // wants to use the language reported from the system,
810  // except if we knew that it was explicitly switched (thus
811  // the check for "bInputLangeSwitched").
812 
813  // The language reported by the system could be just the
814  // system default language that the user is not even aware
815  // of, because no language selection tool is installed at
816  // all. In this case the OOo language should get preference
817  // as it might have been selected by the user explicitly.
818 
819  // Usually this case happens if the OOo language is
820  // different to the system language but the system keyboard
821  // is still suitable for the OOo language (e.g. writing
822  // English texts with a German keyboard).
823 
824  // For non-latin keyboards overwriting the attribute is
825  // still valid. We do this for cyrillic and greek ATM. In
826  // future versions of OOo this should be replaced by a
827  // configuration switch that allows to give the preference
828  // to the OOo setting or the system setting explicitly
829  // and/or a better handling of the script type.
830  i18n::UnicodeScript eType = !rInBuffer.isEmpty() ?
831  GetAppCharClass().getScript( rInBuffer, 0 ) :
832  i18n::UnicodeScript_kScriptCount;
833 
834  bool bSystemIsNonLatin = false;
835  switch ( eType )
836  {
837  case i18n::UnicodeScript_kGreek:
838  case i18n::UnicodeScript_kCyrillic:
839  // in case other UnicodeScripts require special
840  // keyboards they can be added here
841  bSystemIsNonLatin = true;
842  break;
843  default:
844  break;
845  }
846 
847  bool bOOoLangIsNonLatin = MsLangId::isNonLatinWestern( eLang);
848 
849  bLang = (bSystemIsNonLatin != bOOoLangIsNonLatin);
850  }
851  }
852  }
853  }
854  return bLang ? nWhich : INVALID_HINT;
855 }
856 
861 {
862  if ( m_aInBuffer.isEmpty() )
863  return;
864 
865  SwWrtShell& rSh = m_rView.GetWrtShell();
866 
867  // generate new sequence input checker if not already done
868  if ( !pCheckIt )
869  pCheckIt = new SwCheckIt;
870 
871  uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = pCheckIt->xCheck;
872  if ( xISC.is() && IsInputSequenceCheckingRequired( m_aInBuffer, *rSh.GetCursor() ) )
873  {
874 
875  // apply (Thai) input sequence checking/correction
876 
877  rSh.Push(); // push current cursor to stack
878 
879  // get text from the beginning (i.e left side) of current selection
880  // to the start of the paragraph
881  rSh.NormalizePam(); // make point be the first (left) one
882  if (!rSh.GetCursor()->HasMark())
883  rSh.GetCursor()->SetMark();
884  rSh.GetCursor()->GetMark()->nContent = 0;
885 
886  const OUString aOldText( rSh.GetCursor()->GetText() );
887  const sal_Int32 nOldLen = aOldText.getLength();
888 
889  SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
890 
891  sal_Int32 nExpandSelection = 0;
892  if (nOldLen > 0)
893  {
894  sal_Int32 nTmpPos = nOldLen;
895  sal_Int16 nCheckMode = rCTLOptions.IsCTLSequenceCheckingRestricted() ?
896  i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
897 
898  OUString aNewText( aOldText );
899  if (rCTLOptions.IsCTLSequenceCheckingTypeAndReplace())
900  {
901  for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k)
902  {
903  const sal_Unicode cChar = m_aInBuffer[k];
904  const sal_Int32 nPrevPos =xISC->correctInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode );
905 
906  // valid sequence or sequence could be corrected:
907  if (nPrevPos != aNewText.getLength())
908  nTmpPos = nPrevPos + 1;
909  }
910 
911  // find position of first character that has changed
912  sal_Int32 nNewLen = aNewText.getLength();
913  const sal_Unicode *pOldText = aOldText.getStr();
914  const sal_Unicode *pNewText = aNewText.getStr();
915  sal_Int32 nChgPos = 0;
916  while ( nChgPos < nOldLen && nChgPos < nNewLen &&
917  pOldText[nChgPos] == pNewText[nChgPos] )
918  ++nChgPos;
919 
920  const sal_Int32 nChgLen = nNewLen - nChgPos;
921  if (nChgLen)
922  {
923  m_aInBuffer = aNewText.copy( nChgPos, nChgLen );
924  nExpandSelection = nOldLen - nChgPos;
925  }
926  else
927  m_aInBuffer.clear();
928  }
929  else
930  {
931  for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k )
932  {
933  const sal_Unicode cChar = m_aInBuffer[k];
934  if (xISC->checkInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode ))
935  {
936  // character can be inserted:
937  aNewText += OUStringLiteral1( cChar );
938  ++nTmpPos;
939  }
940  }
941  m_aInBuffer = aNewText.copy( aOldText.getLength() ); // copy new text to be inserted to buffer
942  }
943  }
944 
945  // at this point now we will insert the buffer text 'normally' some lines below...
946 
948 
949  if (m_aInBuffer.isEmpty())
950  return;
951 
952  // if text prior to the original selection needs to be changed
953  // as well, we now expand the selection accordingly.
954  SwPaM &rCursor = *rSh.GetCursor();
955  const sal_Int32 nCursorStartPos = rCursor.Start()->nContent.GetIndex();
956  OSL_ENSURE( nCursorStartPos >= nExpandSelection, "cannot expand selection as specified!!" );
957  if (nExpandSelection && nCursorStartPos >= nExpandSelection)
958  {
959  if (!rCursor.HasMark())
960  rCursor.SetMark();
961  rCursor.Start()->nContent -= nExpandSelection;
962  }
963  }
964 
965  uno::Reference< frame::XDispatchRecorder > xRecorder =
966  m_rView.GetViewFrame()->GetBindings().GetRecorder();
967  if ( xRecorder.is() )
968  {
969  // determine shell
970  SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView );
971  // generate request and record
972  if (pSfxShell)
973  {
974  SfxRequest aReq( m_rView.GetViewFrame(), FN_INSERT_STRING );
975  aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, m_aInBuffer ) );
976  aReq.Done();
977  }
978  }
979 
980  sal_uInt16 nWhich = lcl_isNonDefaultLanguage(m_eBufferLanguage, m_rView, m_aInBuffer);
981  if (nWhich != INVALID_HINT )
982  {
983  SvxLanguageItem aLangItem( m_eBufferLanguage, nWhich );
984  rSh.SetAttrItem( aLangItem );
985  }
986 
987  rSh.Insert( m_aInBuffer );
988  m_eBufferLanguage = LANGUAGE_DONTKNOW;
989  m_aInBuffer.clear();
990  g_bFlushCharBuffer = false;
991 
992 }
993 
994 #define MOVE_LEFT_SMALL 0
995 #define MOVE_UP_SMALL 1
996 #define MOVE_RIGHT_BIG 2
997 #define MOVE_DOWN_BIG 3
998 #define MOVE_LEFT_BIG 4
999 #define MOVE_UP_BIG 5
1000 #define MOVE_RIGHT_SMALL 6
1001 #define MOVE_DOWN_SMALL 7
1002 
1003 // #i121236# Support for shift key in writer
1004 #define MOVE_LEFT_HUGE 8
1005 #define MOVE_UP_HUGE 9
1006 #define MOVE_RIGHT_HUGE 10
1007 #define MOVE_DOWN_HUGE 11
1008 
1009 void SwEditWin::ChangeFly( sal_uInt8 nDir, bool bWeb )
1010 {
1011  SwWrtShell &rSh = m_rView.GetWrtShell();
1012  SwRect aTmp = rSh.GetFlyRect();
1013  if( !aTmp.HasArea() ||
1015  return;
1016 
1017  SfxItemSet aSet(
1018  rSh.GetAttrPool(),
1019  svl::Items<
1023  RES_COL, RES_COL,
1024  RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW>{});
1025  rSh.GetFlyFrameAttr( aSet );
1026  RndStdIds eAnchorId = aSet.Get(RES_ANCHOR).GetAnchorId();
1027  Size aSnap;
1028  bool bHuge(MOVE_LEFT_HUGE == nDir ||
1029  MOVE_UP_HUGE == nDir ||
1030  MOVE_RIGHT_HUGE == nDir ||
1031  MOVE_DOWN_HUGE == nDir);
1032 
1033  if(MOVE_LEFT_SMALL == nDir ||
1034  MOVE_UP_SMALL == nDir ||
1035  MOVE_RIGHT_SMALL == nDir ||
1036  MOVE_DOWN_SMALL == nDir )
1037  {
1038  aSnap = PixelToLogic(Size(1,1));
1039  }
1040  else
1041  {
1042  aSnap = rSh.GetViewOptions()->GetSnapSize();
1043  short nDiv = rSh.GetViewOptions()->GetDivisionX();
1044  if ( nDiv > 0 )
1045  aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) );
1046  nDiv = rSh.GetViewOptions()->GetDivisionY();
1047  if ( nDiv > 0 )
1048  aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) );
1049  }
1050 
1051  if(bHuge)
1052  {
1053  // #i121236# 567twips == 1cm, but just take three times the normal snap
1054  aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
1055  }
1056 
1057  SwRect aBoundRect;
1058  Point aRefPoint;
1059  // adjustment for allowing vertical position
1060  // aligned to page for fly frame anchored to paragraph or to character.
1061  {
1062  const SwFormatVertOrient& aVert( aSet.Get(RES_VERT_ORIENT) );
1063  const bool bFollowTextFlow =
1064  aSet.Get(RES_FOLLOW_TEXT_FLOW).GetValue();
1065  const SwPosition* pToCharContentPos = aSet.Get(RES_ANCHOR).GetContentAnchor();
1066  rSh.CalcBoundRect( aBoundRect, eAnchorId,
1067  text::RelOrientation::FRAME, aVert.GetRelationOrient(),
1068  pToCharContentPos, bFollowTextFlow,
1069  false, &aRefPoint );
1070  }
1071  long nLeft = std::min( aTmp.Left() - aBoundRect.Left(), aSnap.Width() );
1072  long nRight = std::min( aBoundRect.Right() - aTmp.Right(), aSnap.Width() );
1073  long nUp = std::min( aTmp.Top() - aBoundRect.Top(), aSnap.Height() );
1074  long nDown = std::min( aBoundRect.Bottom() - aTmp.Bottom(), aSnap.Height() );
1075 
1076  switch ( nDir )
1077  {
1078  case MOVE_LEFT_BIG:
1079  case MOVE_LEFT_HUGE:
1080  case MOVE_LEFT_SMALL: aTmp.Left( aTmp.Left() - nLeft );
1081  break;
1082 
1083  case MOVE_UP_BIG:
1084  case MOVE_UP_HUGE:
1085  case MOVE_UP_SMALL: aTmp.Top( aTmp.Top() - nUp );
1086  break;
1087 
1088  case MOVE_RIGHT_SMALL:
1089  if( aTmp.Width() < aSnap.Width() + MINFLY )
1090  break;
1091  nRight = aSnap.Width();
1092  [[fallthrough]];
1093  case MOVE_RIGHT_HUGE:
1094  case MOVE_RIGHT_BIG: aTmp.Left( aTmp.Left() + nRight );
1095  break;
1096 
1097  case MOVE_DOWN_SMALL:
1098  if( aTmp.Height() < aSnap.Height() + MINFLY )
1099  break;
1100  nDown = aSnap.Height();
1101  [[fallthrough]];
1102  case MOVE_DOWN_HUGE:
1103  case MOVE_DOWN_BIG: aTmp.Top( aTmp.Top() + nDown );
1104  break;
1105 
1106  default: OSL_ENSURE(true, "ChangeFly: Unknown direction." );
1107  }
1108  bool bSet = false;
1109  if ((RndStdIds::FLY_AS_CHAR == eAnchorId) && ( nDir % 2 ))
1110  {
1111  long aDiff = aTmp.Top() - aRefPoint.Y();
1112  if( aDiff > 0 )
1113  aDiff = 0;
1114  else if ( aDiff < -aTmp.Height() )
1115  aDiff = -aTmp.Height();
1116  SwFormatVertOrient aVert( aSet.Get(RES_VERT_ORIENT) );
1117  sal_Int16 eNew;
1118  if( bWeb )
1119  {
1120  eNew = aVert.GetVertOrient();
1121  bool bDown = 0 != ( nDir & 0x02 );
1122  switch( eNew )
1123  {
1124  case text::VertOrientation::CHAR_TOP:
1125  if( bDown ) eNew = text::VertOrientation::CENTER;
1126  break;
1127  case text::VertOrientation::CENTER:
1128  eNew = bDown ? text::VertOrientation::TOP : text::VertOrientation::CHAR_TOP;
1129  break;
1131  if( !bDown ) eNew = text::VertOrientation::CENTER;
1132  break;
1133  case text::VertOrientation::LINE_TOP:
1134  if( bDown ) eNew = text::VertOrientation::LINE_CENTER;
1135  break;
1136  case text::VertOrientation::LINE_CENTER:
1137  eNew = bDown ? text::VertOrientation::LINE_BOTTOM : text::VertOrientation::LINE_TOP;
1138  break;
1139  case text::VertOrientation::LINE_BOTTOM:
1140  if( !bDown ) eNew = text::VertOrientation::LINE_CENTER;
1141  break;
1142  default:; //prevent warning
1143  }
1144  }
1145  else
1146  {
1147  aVert.SetPos( aDiff );
1149  }
1150  aVert.SetVertOrient( eNew );
1151  aSet.Put( aVert );
1152  bSet = true;
1153  }
1154  if (bWeb && (RndStdIds::FLY_AT_PARA == eAnchorId)
1155  && ( nDir==MOVE_LEFT_SMALL || nDir==MOVE_RIGHT_BIG ))
1156  {
1157  SwFormatHoriOrient aHori( aSet.Get(RES_HORI_ORIENT) );
1158  sal_Int16 eNew;
1159  eNew = aHori.GetHoriOrient();
1160  switch( eNew )
1161  {
1163  if( nDir==MOVE_LEFT_SMALL )
1165  break;
1167  if( nDir==MOVE_RIGHT_BIG )
1169  break;
1170  default:; //prevent warning
1171  }
1172  if( eNew != aHori.GetHoriOrient() )
1173  {
1174  aHori.SetHoriOrient( eNew );
1175  aSet.Put( aHori );
1176  bSet = true;
1177  }
1178  }
1179  rSh.StartAllAction();
1180  if( bSet )
1181  rSh.SetFlyFrameAttr( aSet );
1182  bool bSetPos = (RndStdIds::FLY_AS_CHAR != eAnchorId);
1183  if(bSetPos && bWeb)
1184  {
1185  bSetPos = RndStdIds::FLY_AT_PAGE == eAnchorId;
1186  }
1187  if( bSetPos )
1188  rSh.SetFlyPos( aTmp.Pos() );
1189  rSh.EndAllAction();
1190 
1191 }
1192 
1194 {
1195  // start undo action in order to get only one
1196  // undo action for this change.
1197  SwWrtShell &rSh = m_rView.GetWrtShell();
1198  rSh.StartUndo();
1199 
1200  long nX = 0;
1201  long nY = 0;
1202  const bool bOnePixel(
1203  MOVE_LEFT_SMALL == nDir ||
1204  MOVE_UP_SMALL == nDir ||
1205  MOVE_RIGHT_SMALL == nDir ||
1206  MOVE_DOWN_SMALL == nDir);
1207  const bool bHuge(
1208  MOVE_LEFT_HUGE == nDir ||
1209  MOVE_UP_HUGE == nDir ||
1210  MOVE_RIGHT_HUGE == nDir ||
1211  MOVE_DOWN_HUGE == nDir);
1212  SwMove nAnchorDir = SwMove::UP;
1213  switch(nDir)
1214  {
1215  case MOVE_LEFT_SMALL:
1216  case MOVE_LEFT_HUGE:
1217  case MOVE_LEFT_BIG:
1218  nX = -1;
1219  nAnchorDir = SwMove::LEFT;
1220  break;
1221  case MOVE_UP_SMALL:
1222  case MOVE_UP_HUGE:
1223  case MOVE_UP_BIG:
1224  nY = -1;
1225  break;
1226  case MOVE_RIGHT_SMALL:
1227  case MOVE_RIGHT_HUGE:
1228  case MOVE_RIGHT_BIG:
1229  nX = +1;
1230  nAnchorDir = SwMove::RIGHT;
1231  break;
1232  case MOVE_DOWN_SMALL:
1233  case MOVE_DOWN_HUGE:
1234  case MOVE_DOWN_BIG:
1235  nY = +1;
1236  nAnchorDir = SwMove::DOWN;
1237  break;
1238  }
1239 
1240  if(0 != nX || 0 != nY)
1241  {
1243  Size aSnap( rSh.GetViewOptions()->GetSnapSize() );
1244  short nDiv = rSh.GetViewOptions()->GetDivisionX();
1245  if ( nDiv > 0 )
1246  aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) );
1247  nDiv = rSh.GetViewOptions()->GetDivisionY();
1248  if ( nDiv > 0 )
1249  aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) );
1250 
1251  if(bOnePixel)
1252  {
1253  aSnap = PixelToLogic(Size(1,1));
1254  }
1255  else if(bHuge)
1256  {
1257  // #i121236# 567twips == 1cm, but just take three times the normal snap
1258  aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
1259  }
1260 
1261  nX *= aSnap.Width();
1262  nY *= aSnap.Height();
1263 
1264  SdrView *pSdrView = rSh.GetDrawView();
1265  const SdrHdlList& rHdlList = pSdrView->GetHdlList();
1266  SdrHdl* pHdl = rHdlList.GetFocusHdl();
1267  rSh.StartAllAction();
1268  if(nullptr == pHdl)
1269  {
1270  // now move the selected draw objects
1271  // if the object's position is not protected
1272  if(!(nProtect&FlyProtectFlags::Pos))
1273  {
1274  // Check if object is anchored as character and move direction
1275  bool bDummy1, bDummy2;
1276  const bool bVertAnchor = rSh.IsFrameVertical( true, bDummy1, bDummy2 );
1277  bool bHoriMove = !bVertAnchor == !( nDir % 2 );
1278  bool bMoveAllowed =
1279  !bHoriMove || (rSh.GetAnchorId() != RndStdIds::FLY_AS_CHAR);
1280  if ( bMoveAllowed )
1281  {
1282  pSdrView->MoveAllMarked(Size(nX, nY));
1283  rSh.SetModified();
1284  }
1285  }
1286  }
1287  else
1288  {
1289  // move handle with index nHandleIndex
1290  if (nX || nY)
1291  {
1292  if( SdrHdlKind::Anchor == pHdl->GetKind() ||
1293  SdrHdlKind::Anchor_TR == pHdl->GetKind() )
1294  {
1295  // anchor move cannot be allowed when position is protected
1296  if(!(nProtect&FlyProtectFlags::Pos))
1297  rSh.MoveAnchor( nAnchorDir );
1298  }
1299  //now resize if size is protected
1300  else if(!(nProtect&FlyProtectFlags::Size))
1301  {
1302  // now move the Handle (nX, nY)
1303  Point aStartPoint(pHdl->GetPos());
1304  Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
1305  const SdrDragStat& rDragStat = pSdrView->GetDragStat();
1306 
1307  // start dragging
1308  pSdrView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
1309 
1310  if(pSdrView->IsDragObj())
1311  {
1312  bool bWasNoSnap = rDragStat.IsNoSnap();
1313  bool bWasSnapEnabled = pSdrView->IsSnapEnabled();
1314 
1315  // switch snapping off
1316  if(!bWasNoSnap)
1317  const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
1318  if(bWasSnapEnabled)
1319  pSdrView->SetSnapEnabled(false);
1320 
1321  pSdrView->MovAction(aEndPoint);
1322  pSdrView->EndDragObj();
1323  rSh.SetModified();
1324 
1325  // restore snap
1326  if(!bWasNoSnap)
1327  const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
1328  if(bWasSnapEnabled)
1329  pSdrView->SetSnapEnabled(bWasSnapEnabled);
1330  }
1331  }
1332  }
1333  }
1334  rSh.EndAllAction();
1335  }
1336 
1337  rSh.EndUndo();
1338 }
1339 
1343 void SwEditWin::KeyInput(const KeyEvent &rKEvt)
1344 {
1345  SwWrtShell &rSh = m_rView.GetWrtShell();
1346 
1347  if (comphelper::LibreOfficeKit::isActive() && m_rView.GetPostItMgr())
1348  {
1349  if (vcl::Window* pWindow = m_rView.GetPostItMgr()->GetActiveSidebarWin())
1350  {
1351  pWindow->KeyInput(rKEvt);
1352  return;
1353  }
1354  }
1355 
1356  if( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE &&
1357  m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard )
1358  {
1359  m_pApplyTempl->m_pFormatClipboard->Erase();
1360  SetApplyTemplate(SwApplyTemplate());
1361  m_rView.GetViewFrame()->GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
1362  }
1363  else if ( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE &&
1364  rSh.IsHeaderFooterEdit( ) )
1365  {
1366  bool bHeader = bool(FrameTypeFlags::HEADER & rSh.GetFrameType(nullptr,false));
1367  if ( bHeader )
1368  rSh.SttPg();
1369  else
1370  rSh.EndPg();
1371  rSh.ToggleHeaderFooterEdit();
1372  }
1373 
1374  SfxObjectShell *pObjSh = m_rView.GetViewFrame()->GetObjectShell();
1375  if ( m_bLockInput || (pObjSh && pObjSh->GetProgress()) )
1376  // When the progress bar is active or a progress is
1377  // running on a document, no order is being taken
1378  return;
1379 
1380  m_pShadCursor.reset();
1381  m_aKeyInputFlushTimer.Stop();
1382 
1383  bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
1384  rSh.IsCursorReadonly();
1385 
1386  //if the language changes the buffer must be flushed
1387  LanguageType eNewLanguage = GetInputLanguage();
1388  if(!bIsDocReadOnly && m_eBufferLanguage != eNewLanguage && !m_aInBuffer.isEmpty())
1389  {
1390  FlushInBuffer();
1391  }
1392  m_eBufferLanguage = eNewLanguage;
1393 
1394  QuickHelpData aTmpQHD;
1395  if( m_pQuickHlpData->m_bIsDisplayed )
1396  {
1397  aTmpQHD.Move( *m_pQuickHlpData );
1398  m_pQuickHlpData->Stop( rSh );
1399  }
1400 
1401  // OS:the DrawView also needs a readonly-Flag as well
1402  if ( !bIsDocReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( rKEvt, this ) )
1403  {
1404  rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll( false );
1405  rSh.SetModified();
1406  return; // Event evaluated by SdrView
1407  }
1408 
1409  if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
1410  {
1411  StopInsFrame();
1412  rSh.Edit();
1413  }
1414 
1415  bool bFlushBuffer = false;
1416  bool bNormalChar = false;
1417  bool bAppendSpace = m_pQuickHlpData->m_bAppendSpace;
1418  m_pQuickHlpData->m_bAppendSpace = false;
1419 
1420  if ( getenv("SW_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 )
1421  {
1422  if( rKEvt.GetKeyCode().IsShift())
1423  {
1424  GetView().GetDocShell()->GetDoc()->dumpAsXml();
1425  return;
1426  }
1427  else
1428  {
1429  SwRootFrame* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout();
1430  pLayout->dumpAsXml( );
1431  return;
1432  }
1433  }
1434 
1435  KeyEvent aKeyEvent( rKEvt );
1436  // look for vertical mappings
1437  if( !bIsDocReadOnly && !rSh.IsSelFrameMode() && !rSh.IsObjSelected() )
1438  {
1439  // must changed from switch to if, because the Linux
1440  // compiler has problem with the code. Has to remove if the new general
1441  // handler exist.
1442  sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
1443 
1444  if( KEY_UP == nKey || KEY_DOWN == nKey ||
1445  KEY_LEFT == nKey || KEY_RIGHT == nKey )
1446  {
1447  // In general, we want to map the direction keys if we are inside
1448  // some vertical formatted text.
1449  // 1. Exception: For a table cursor in a horizontal table, the
1450  // directions should never be mapped.
1451  // 2. Exception: For a table cursor in a vertical table, the
1452  // directions should always be mapped.
1453  const bool bVertText = rSh.IsInVerticalText();
1454  const bool bTableCursor = rSh.GetTableCursor();
1455  const bool bVertTable = rSh.IsTableVertical();
1456  if( ( bVertText && ( !bTableCursor || bVertTable ) ) ||
1457  ( bTableCursor && bVertTable ) )
1458  {
1459  SvxFrameDirection eDirection = rSh.GetTextDirection();
1460  if (eDirection == SvxFrameDirection::Vertical_LR_BT)
1461  {
1462  // Map from physical to logical, so rotate clockwise.
1463  if (KEY_UP == nKey)
1464  nKey = KEY_RIGHT;
1465  else if (KEY_DOWN == nKey)
1466  nKey = KEY_LEFT;
1467  else if (KEY_LEFT == nKey)
1468  nKey = KEY_UP;
1469  else /* KEY_RIGHT == nKey */
1470  nKey = KEY_DOWN;
1471  }
1472  else
1473  {
1474  // Attempt to integrate cursor travelling for mongolian layout does not work.
1475  // Thus, back to previous mapping of cursor keys to direction keys.
1476  if( KEY_UP == nKey ) nKey = KEY_LEFT;
1477  else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT;
1478  else if( KEY_LEFT == nKey ) nKey = KEY_DOWN;
1479  else /* KEY_RIGHT == nKey */ nKey = KEY_UP;
1480  }
1481  }
1482 
1483  if ( rSh.IsInRightToLeftText() )
1484  {
1485  if( KEY_LEFT == nKey ) nKey = KEY_RIGHT;
1486  else if( KEY_RIGHT == nKey ) nKey = KEY_LEFT;
1487  }
1488 
1489  aKeyEvent = KeyEvent( rKEvt.GetCharCode(),
1490  vcl::KeyCode( nKey, rKEvt.GetKeyCode().GetModifier() ),
1491  rKEvt.GetRepeat() );
1492  }
1493  }
1494 
1495  const vcl::KeyCode& rKeyCode = aKeyEvent.GetKeyCode();
1496  sal_Unicode aCh = aKeyEvent.GetCharCode();
1497 
1498  // enable switching to notes anchor with Ctrl - Alt - Page Up/Down
1499  // pressing this inside a note will switch to next/previous note
1500  if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((rKeyCode.GetCode() == KEY_PAGEUP) || (rKeyCode.GetCode() == KEY_PAGEDOWN)))
1501  {
1502  const bool bNext = rKeyCode.GetCode()==KEY_PAGEDOWN;
1503  const SwFieldType* pFieldType = rSh.GetFieldType( 0, SwFieldIds::Postit );
1504  rSh.MoveFieldType( pFieldType, bNext );
1505  return;
1506  }
1507 
1508  const SwFrameFormat* pFlyFormat = rSh.GetFlyFrameFormat();
1509  if( pFlyFormat )
1510  {
1511  SvMacroItemId nEvent;
1512 
1513  if( 32 <= aCh &&
1514  0 == (( KEY_MOD1 | KEY_MOD2 ) & rKeyCode.GetModifier() ))
1515  nEvent = SvMacroItemId::SwFrmKeyInputAlpha;
1516  else
1517  nEvent = SvMacroItemId::SwFrmKeyInputNoAlpha;
1518 
1519  const SvxMacro* pMacro = pFlyFormat->GetMacro().GetMacroTable().Get( nEvent );
1520  if( pMacro )
1521  {
1522  SbxArrayRef xArgs = new SbxArray;
1523  SbxVariableRef xVar = new SbxVariable;
1524  xVar->PutString( pFlyFormat->GetName() );
1525  xArgs->Put( xVar.get(), 1 );
1526 
1527  xVar = new SbxVariable;
1528  if( SvMacroItemId::SwFrmKeyInputAlpha == nEvent )
1529  xVar->PutChar( aCh );
1530  else
1531  xVar->PutUShort( rKeyCode.GetModifier() | rKeyCode.GetCode() );
1532  xArgs->Put( xVar.get(), 2 );
1533 
1534  OUString sRet;
1535  rSh.ExecMacro( *pMacro, &sRet, xArgs.get() );
1536  if( !sRet.isEmpty() && sRet.toInt32()!=0 )
1537  return ;
1538  }
1539  }
1540  SelectionType nLclSelectionType;
1541  //A is converted to 1
1542  if( rKeyCode.GetFullCode() == (KEY_A | KEY_MOD1 |KEY_SHIFT)
1543  && rSh.HasDrawView() &&
1544  (bool(nLclSelectionType = rSh.GetSelectionType()) &&
1545  ((nLclSelectionType & (SelectionType::Frame|SelectionType::Graphic)) ||
1546  ((nLclSelectionType & (SelectionType::DrawObject|SelectionType::DbForm)) &&
1547  rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1))))
1548  {
1549  SdrHdlList& rHdlList = const_cast<SdrHdlList&>(rSh.GetDrawView()->GetHdlList());
1550  SdrHdl* pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor);
1551  if ( ! pAnchor )
1552  pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor_TR);
1553  if(pAnchor)
1554  rHdlList.SetFocusHdl(pAnchor);
1555  return;
1556  }
1557 
1558  SvxAutoCorrCfg* pACfg = nullptr;
1559  SvxAutoCorrect* pACorr = nullptr;
1560 
1561  uno::Reference< frame::XDispatchRecorder > xRecorder =
1562  m_rView.GetViewFrame()->GetBindings().GetRecorder();
1563  if ( !xRecorder.is() )
1564  {
1565  pACfg = &SvxAutoCorrCfg::Get();
1566  pACorr = pACfg->GetAutoCorrect();
1567  }
1568 
1569  SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
1570 
1571  OUString sFormulaEntry;
1572 
1573  enum class SwKeyState { CheckKey, InsChar, InsTab,
1574  NoNum, NumOff, NumOrNoNum, NumDown, NumUp,
1575  NumIndentInc, NumIndentDec,
1576 
1577  OutlineLvOff,
1578  NextCell, PrevCell, OutlineUp, OutlineDown,
1579  GlossaryExpand, NextPrevGlossary,
1580  AutoFormatByInput,
1581  NextObject, PrevObject,
1582  KeyToView,
1583  LaunchOLEObject, GoIntoFly, GoIntoDrawing,
1584  EnterDrawHandleMode,
1585  CheckDocReadOnlyKeys,
1586  CheckAutoCorrect, EditFormula,
1587  ColLeftBig, ColRightBig,
1588  ColLeftSmall, ColRightSmall,
1589  ColBottomBig,
1590  ColBottomSmall,
1591  CellLeftBig, CellRightBig,
1592  CellLeftSmall, CellRightSmall,
1593  CellTopBig, CellBottomBig,
1594  CellTopSmall, CellBottomSmall,
1595 
1596  Fly_Change, Draw_Change,
1597  SpecialInsert,
1598  EnterCharCell,
1599  GotoNextFieldMark,
1600  GotoPrevFieldMark,
1601  End };
1602 
1603  SwKeyState eKeyState = bIsDocReadOnly ? SwKeyState::CheckDocReadOnlyKeys : SwKeyState::CheckKey;
1604  SwKeyState eNextKeyState = SwKeyState::End;
1605  sal_uInt8 nDir = 0;
1606 
1607  if (m_nKS_NUMDOWN_Count > 0)
1608  m_nKS_NUMDOWN_Count--;
1609 
1610  if (m_nKS_NUMINDENTINC_Count > 0)
1611  m_nKS_NUMINDENTINC_Count--;
1612 
1613  while( SwKeyState::End != eKeyState )
1614  {
1615  SwKeyState eFlyState = SwKeyState::KeyToView;
1616 
1617  switch( eKeyState )
1618  {
1619  case SwKeyState::CheckKey:
1620  eKeyState = SwKeyState::KeyToView; // default forward to View
1621 
1622 #if OSL_DEBUG_LEVEL > 1
1623  // for switching cursor behaviour in ReadOnly regions
1625  if( 0x7210 == rKeyCode.GetFullCode() )
1627  else
1629 #endif
1630 
1632  !rKeyCode.IsMod2() && '=' == aCh &&
1633  !rSh.IsTableMode() && rSh.GetTableFormat() &&
1634  rSh.IsSttPara() &&
1635  !rSh.HasReadonlySel())
1636  {
1637  // at the beginning of the table's cell a '=' ->
1638  // call EditRow (F2-functionality)
1639  // [Avoid this for LibreOfficeKit, as the separate input window
1640  // steals the focus & things go wrong - the user never gets
1641  // the focus back.]
1642  rSh.Push();
1644  !rSh.IsTableBoxTextFormat() )
1645  {
1646  // is at the beginning of the box
1647  eKeyState = SwKeyState::EditFormula;
1648  if( rSh.HasMark() )
1649  rSh.SwapPam();
1650  else
1651  rSh.SttSelect();
1653  rSh.Pop();
1654  rSh.EndSelect();
1655  sFormulaEntry = "=";
1656  }
1657  else
1659  }
1660  else
1661  {
1662  if( pACorr && aTmpQHD.HasContent() && !rSh.HasSelection() &&
1663  !rSh.HasReadonlySel() && !aTmpQHD.m_bIsAutoText &&
1664  pACorr->GetSwFlags().nAutoCmpltExpandKey ==
1665  (rKeyCode.GetModifier() | rKeyCode.GetCode()) )
1666  {
1667  eKeyState = SwKeyState::GlossaryExpand;
1668  break;
1669  }
1670 
1671  switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
1672  {
1673  case KEY_RIGHT | KEY_MOD2:
1674  eKeyState = SwKeyState::ColRightBig;
1675  eFlyState = SwKeyState::Fly_Change;
1676  nDir = MOVE_RIGHT_SMALL;
1677  goto KEYINPUT_CHECKTABLE;
1678 
1679  case KEY_LEFT | KEY_MOD2:
1680  eKeyState = SwKeyState::ColRightSmall;
1681  eFlyState = SwKeyState::Fly_Change;
1682  nDir = MOVE_LEFT_SMALL;
1683  goto KEYINPUT_CHECKTABLE;
1684 
1685  case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT:
1686  eKeyState = SwKeyState::ColLeftSmall;
1687  goto KEYINPUT_CHECKTABLE;
1688 
1689  case KEY_LEFT | KEY_MOD2 | KEY_SHIFT:
1690  eKeyState = SwKeyState::ColLeftBig;
1691  goto KEYINPUT_CHECKTABLE;
1692 
1693  case KEY_RIGHT | KEY_MOD2 | KEY_MOD1:
1694  eKeyState = SwKeyState::CellRightBig;
1695  goto KEYINPUT_CHECKTABLE;
1696 
1697  case KEY_LEFT | KEY_MOD2 | KEY_MOD1:
1698  eKeyState = SwKeyState::CellRightSmall;
1699  goto KEYINPUT_CHECKTABLE;
1700 
1701  case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1702  eKeyState = SwKeyState::CellLeftSmall;
1703  goto KEYINPUT_CHECKTABLE;
1704 
1705  case KEY_LEFT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1706  eKeyState = SwKeyState::CellLeftBig;
1707  goto KEYINPUT_CHECKTABLE;
1708 
1709  case KEY_UP | KEY_MOD2:
1710  eKeyState = SwKeyState::ColBottomSmall;
1711  eFlyState = SwKeyState::Fly_Change;
1712  nDir = MOVE_UP_SMALL;
1713  goto KEYINPUT_CHECKTABLE;
1714 
1715  case KEY_DOWN | KEY_MOD2:
1716  eKeyState = SwKeyState::ColBottomBig;
1717  eFlyState = SwKeyState::Fly_Change;
1718  nDir = MOVE_DOWN_SMALL;
1719  goto KEYINPUT_CHECKTABLE;
1720 
1721  case KEY_UP | KEY_MOD2 | KEY_MOD1:
1722  eKeyState = SwKeyState::CellBottomSmall;
1723  goto KEYINPUT_CHECKTABLE;
1724 
1725  case KEY_DOWN | KEY_MOD2 | KEY_MOD1:
1726  eKeyState = SwKeyState::CellBottomBig;
1727  goto KEYINPUT_CHECKTABLE;
1728 
1729  case KEY_UP | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1730  eKeyState = SwKeyState::CellTopBig;
1731  goto KEYINPUT_CHECKTABLE;
1732 
1733  case KEY_DOWN | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1734  eKeyState = SwKeyState::CellTopSmall;
1735  goto KEYINPUT_CHECKTABLE;
1736 
1737 KEYINPUT_CHECKTABLE:
1738  if( rSh.IsTableMode() || !rSh.GetTableFormat() )
1739  {
1740  if(!pFlyFormat && SwKeyState::KeyToView != eFlyState &&
1742  rSh.GetDrawView()->AreObjectsMarked())
1743  eKeyState = SwKeyState::Draw_Change;
1744 
1745  if( pFlyFormat )
1746  eKeyState = eFlyState;
1747  else if( SwKeyState::Draw_Change != eKeyState)
1748  eKeyState = SwKeyState::EnterCharCell;
1749  }
1750  break;
1751 
1752  // huge object move
1753  case KEY_RIGHT | KEY_SHIFT:
1754  case KEY_LEFT | KEY_SHIFT:
1755  case KEY_UP | KEY_SHIFT:
1756  case KEY_DOWN | KEY_SHIFT:
1757  {
1758  const SelectionType nSelectionType = rSh.GetSelectionType();
1759  if ( ( pFlyFormat
1761  || ( ( nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm) )
1762  && rSh.GetDrawView()->AreObjectsMarked() ) )
1763  {
1764  eKeyState = pFlyFormat ? SwKeyState::Fly_Change : SwKeyState::Draw_Change;
1765  switch ( rKeyCode.GetCode() )
1766  {
1767  case KEY_RIGHT: nDir = MOVE_RIGHT_HUGE; break;
1768  case KEY_LEFT: nDir = MOVE_LEFT_HUGE; break;
1769  case KEY_UP: nDir = MOVE_UP_HUGE; break;
1770  case KEY_DOWN: nDir = MOVE_DOWN_HUGE; break;
1771  }
1772  }
1773  break;
1774  }
1775 
1776  case KEY_LEFT:
1777  case KEY_LEFT | KEY_MOD1:
1778  {
1779  bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1780  if(!bMod1)
1781  {
1782  eFlyState = SwKeyState::Fly_Change;
1783  nDir = MOVE_LEFT_BIG;
1784  }
1785  goto KEYINPUT_CHECKTABLE_INSDEL;
1786  }
1787  case KEY_RIGHT | KEY_MOD1:
1788  {
1789  goto KEYINPUT_CHECKTABLE_INSDEL;
1790  }
1791  case KEY_UP:
1792  case KEY_UP | KEY_MOD1:
1793  {
1794  bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1795  if(!bMod1)
1796  {
1797  eFlyState = SwKeyState::Fly_Change;
1798  nDir = MOVE_UP_BIG;
1799  }
1800  goto KEYINPUT_CHECKTABLE_INSDEL;
1801  }
1802  case KEY_DOWN:
1803  case KEY_DOWN | KEY_MOD1:
1804  {
1805  bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1806  if(!bMod1)
1807  {
1808  eFlyState = SwKeyState::Fly_Change;
1809  nDir = MOVE_DOWN_BIG;
1810  }
1811  goto KEYINPUT_CHECKTABLE_INSDEL;
1812  }
1813 
1814 KEYINPUT_CHECKTABLE_INSDEL:
1815  if( rSh.IsTableMode() || !rSh.GetTableFormat() )
1816  {
1817  const SelectionType nSelectionType = rSh.GetSelectionType();
1818 
1819  eKeyState = SwKeyState::KeyToView;
1820  if(SwKeyState::KeyToView != eFlyState)
1821  {
1822  if((nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm)) &&
1823  rSh.GetDrawView()->AreObjectsMarked())
1824  eKeyState = SwKeyState::Draw_Change;
1826  eKeyState = SwKeyState::Fly_Change;
1827  }
1828  }
1829  break;
1830 
1831 
1832  case KEY_DELETE:
1833  if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField())
1834  {
1835  if (rSh.IsInFrontOfLabel() && rSh.NumOrNoNum())
1836  eKeyState = SwKeyState::NumOrNoNum;
1837  }
1838  else if (!rSh.IsCursorInParagraphMetadataField())
1839  {
1840  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
1841  std::unique_ptr<weld::MessageDialog> xInfo(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
1842  xInfo->run();
1843  eKeyState = SwKeyState::End;
1844  }
1845  break;
1846 
1847  case KEY_RETURN:
1848  {
1849  if ( !rSh.HasReadonlySel()
1850  && !rSh.CursorInsideInputField() )
1851  {
1852  const SelectionType nSelectionType = rSh.GetSelectionType();
1853  if(nSelectionType & SelectionType::Ole)
1854  eKeyState = SwKeyState::LaunchOLEObject;
1855  else if(nSelectionType & SelectionType::Frame)
1856  eKeyState = SwKeyState::GoIntoFly;
1857  else if((nSelectionType & SelectionType::DrawObject) &&
1858  !(nSelectionType & SelectionType::DrawObjectEditMode) &&
1860  {
1861  eKeyState = SwKeyState::GoIntoDrawing;
1862  if (lcl_goIntoTextBox(*this, rSh))
1863  eKeyState = SwKeyState::GoIntoFly;
1864  }
1865  else if( aTmpQHD.HasContent() && !rSh.HasSelection() &&
1866  aTmpQHD.m_bIsAutoText )
1867  eKeyState = SwKeyState::GlossaryExpand;
1868 
1869  //RETURN and empty paragraph in numbering -> end numbering
1870  else if( m_aInBuffer.isEmpty() &&
1871  rSh.GetNumRuleAtCurrCursorPos() &&
1873  !rSh.HasSelection() &&
1874  rSh.IsSttPara() && rSh.IsEndPara() )
1875  {
1876  eKeyState = SwKeyState::NumOff;
1877  eNextKeyState = SwKeyState::OutlineLvOff;
1878  }
1879  //RETURN for new paragraph with AutoFormatting
1880  else if( pACfg && pACfg->IsAutoFormatByInput() &&
1881  !(nSelectionType & (SelectionType::Graphic |
1882  SelectionType::Ole | SelectionType::Frame |
1883  SelectionType::TableCell | SelectionType::DrawObject |
1885  {
1886  eKeyState = SwKeyState::AutoFormatByInput;
1887  }
1888  else
1889  {
1890  eNextKeyState = eKeyState;
1891  eKeyState = SwKeyState::CheckAutoCorrect;
1892  }
1893  }
1894  }
1895  break;
1896  case KEY_RETURN | KEY_MOD2:
1897  {
1898  if ( !rSh.HasReadonlySel()
1899  && !rSh.IsSttPara()
1900  && rSh.GetNumRuleAtCurrCursorPos()
1901  && !rSh.CursorInsideInputField() )
1902  {
1903  eKeyState = SwKeyState::NoNum;
1904  }
1905  else if( rSh.CanSpecialInsert() )
1906  eKeyState = SwKeyState::SpecialInsert;
1907  }
1908  break;
1909  case KEY_BACKSPACE:
1910  case KEY_BACKSPACE | KEY_SHIFT:
1911  if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField())
1912  {
1913  bool bDone = false;
1914  // try to add comment for code snip:
1915  // Remove the paragraph indent, if the cursor is at the
1916  // beginning of a paragraph, there is no selection
1917  // and no numbering rule found at the current paragraph
1918  // Also try to remove indent, if current paragraph
1919  // has numbering rule, but isn't counted and only
1920  // key <backspace> is hit.
1921  const bool bOnlyBackspaceKey( KEY_BACKSPACE == rKeyCode.GetFullCode() );
1922  if ( rSh.IsSttPara()
1923  && !rSh.HasSelection()
1924  && ( rSh.GetNumRuleAtCurrCursorPos() == nullptr
1925  || ( rSh.IsNoNum() && bOnlyBackspaceKey ) ) )
1926  {
1927  bDone = rSh.TryRemoveIndent();
1928  }
1929 
1930  if (bDone)
1931  eKeyState = SwKeyState::End;
1932  else
1933  {
1934  if ( rSh.IsSttPara() && !rSh.IsNoNum() )
1935  {
1936  if (m_nKS_NUMDOWN_Count > 0 &&
1937  0 < rSh.GetNumLevel())
1938  {
1939  eKeyState = SwKeyState::NumUp;
1940  m_nKS_NUMDOWN_Count = 2;
1941  bDone = true;
1942  }
1943  else if (m_nKS_NUMINDENTINC_Count > 0)
1944  {
1945  eKeyState = SwKeyState::NumIndentDec;
1946  m_nKS_NUMINDENTINC_Count = 2;
1947  bDone = true;
1948  }
1949  }
1950 
1951  // If the cursor is in an empty paragraph, which has
1952  // a numbering, but not the outline numbering, and
1953  // there is no selection, the numbering has to be
1954  // deleted on key <Backspace>.
1955  // Otherwise method <SwEditShell::NumOrNoNum(..)>
1956  // should only change the <IsCounted()> state of
1957  // the current paragraph depending of the key.
1958  // On <backspace> it is set to <false>,
1959  // on <shift-backspace> it is set to <true>.
1960  // Thus, assure that method <SwEditShell::NumOrNum(..)>
1961  // is only called for the intended purpose.
1962  if ( !bDone && rSh.IsSttPara() )
1963  {
1964  bool bCallNumOrNoNum( false );
1965  if ( bOnlyBackspaceKey && !rSh.IsNoNum() )
1966  {
1967  bCallNumOrNoNum = true;
1968  }
1969  else if ( !bOnlyBackspaceKey && rSh.IsNoNum() )
1970  {
1971  bCallNumOrNoNum = true;
1972  }
1973  else if ( bOnlyBackspaceKey
1974  && rSh.IsSttPara()
1975  && rSh.IsEndPara()
1976  && !rSh.HasSelection() )
1977  {
1978  const SwNumRule* pCurrNumRule( rSh.GetNumRuleAtCurrCursorPos() );
1979  if ( pCurrNumRule != nullptr
1980  && pCurrNumRule != rSh.GetOutlineNumRule() )
1981  {
1982  bCallNumOrNoNum = true;
1983  }
1984  }
1985  if ( bCallNumOrNoNum
1986  && rSh.NumOrNoNum( !bOnlyBackspaceKey ) )
1987  {
1988  eKeyState = SwKeyState::NumOrNoNum;
1989  }
1990  }
1991  }
1992  }
1993  else if (!rSh.IsCursorInParagraphMetadataField())
1994  {
1995  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
1996  std::unique_ptr<weld::MessageDialog> xInfo(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
1997  xInfo->run();
1998  eKeyState = SwKeyState::End;
1999  }
2000  break;
2001 
2002  case KEY_RIGHT:
2003  {
2004  eFlyState = SwKeyState::Fly_Change;
2005  nDir = MOVE_RIGHT_BIG;
2006  goto KEYINPUT_CHECKTABLE_INSDEL;
2007  }
2008  case KEY_TAB:
2009  {
2010 
2011  if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark() || rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2012  {
2013  eKeyState = SwKeyState::GotoNextFieldMark;
2014  }
2015  else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2016  {
2017  GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_NEXT_INPUTFLD );
2018  eKeyState = SwKeyState::End;
2019  }
2020  else if( rSh.GetNumRuleAtCurrCursorPos()
2021  && rSh.IsSttOfPara()
2022  && !rSh.HasReadonlySel() )
2023  {
2024  if ( !rSh.IsMultiSelection()
2027  eKeyState = SwKeyState::NumIndentInc;
2028  else
2029  eKeyState = SwKeyState::NumDown;
2030  }
2031  else if ( rSh.GetTableFormat() )
2032  {
2033  if( rSh.HasSelection() || rSh.HasReadonlySel() )
2034  eKeyState = SwKeyState::NextCell;
2035  else
2036  {
2037  eKeyState = SwKeyState::CheckAutoCorrect;
2038  eNextKeyState = SwKeyState::NextCell;
2039  }
2040  }
2041  else if ( rSh.GetSelectionType() &
2047 
2048  eKeyState = SwKeyState::NextObject;
2049  else
2050  {
2051  eKeyState = SwKeyState::InsTab;
2052  if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
2053  {
2054  SwTextFormatColl* pColl = rSh.GetCurTextFormatColl();
2055  if( pColl &&
2056 
2058  && MAXLEVEL-1 > pColl->GetAssignedOutlineStyleLevel() )
2059  eKeyState = SwKeyState::OutlineDown;
2060  }
2061  }
2062  }
2063  break;
2064  case KEY_TAB | KEY_SHIFT:
2065  {
2066  if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark()|| rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2067  {
2068  eKeyState = SwKeyState::GotoPrevFieldMark;
2069  }
2070  else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2071  {
2072  GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_PREV_INPUTFLD );
2073  eKeyState = SwKeyState::End;
2074  }
2075  else if( rSh.GetNumRuleAtCurrCursorPos()
2076  && rSh.IsSttOfPara()
2077  && !rSh.HasReadonlySel() )
2078  {
2079  if ( !rSh.IsMultiSelection()
2082  eKeyState = SwKeyState::NumIndentDec;
2083  else
2084  eKeyState = SwKeyState::NumUp;
2085  }
2086  else if ( rSh.GetTableFormat() )
2087  {
2088  if( rSh.HasSelection() || rSh.HasReadonlySel() )
2089  eKeyState = SwKeyState::PrevCell;
2090  else
2091  {
2092  eKeyState = SwKeyState::CheckAutoCorrect;
2093  eNextKeyState = SwKeyState::PrevCell;
2094  }
2095  }
2096  else if ( rSh.GetSelectionType() &
2102 
2103  eKeyState = SwKeyState::PrevObject;
2104  else
2105  {
2106  eKeyState = SwKeyState::End;
2107  if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
2108  {
2109  SwTextFormatColl* pColl = rSh.GetCurTextFormatColl();
2110  if( pColl &&
2112  0 < pColl->GetAssignedOutlineStyleLevel())
2113  eKeyState = SwKeyState::OutlineUp;
2114  }
2115  }
2116  }
2117  break;
2118  case KEY_TAB | KEY_MOD1:
2119  case KEY_TAB | KEY_MOD2:
2120  if( !rSh.HasReadonlySel() )
2121  {
2122  if( aTmpQHD.HasContent() && !rSh.HasSelection() )
2123  {
2124  // Next auto-complete suggestion
2125  aTmpQHD.Next( pACorr &&
2126  pACorr->GetSwFlags().bAutoCmpltEndless );
2127  eKeyState = SwKeyState::NextPrevGlossary;
2128  }
2129  else if( rSh.GetTableFormat() )
2130  eKeyState = SwKeyState::InsTab;
2131  else if((rSh.GetSelectionType() &
2134  rSh.GetDrawView()->AreObjectsMarked())
2135  eKeyState = SwKeyState::EnterDrawHandleMode;
2136  else
2137  {
2138  eKeyState = SwKeyState::InsTab;
2139  }
2140  }
2141  break;
2142 
2143  case KEY_TAB | KEY_MOD1 | KEY_SHIFT:
2144  {
2145  if( aTmpQHD.HasContent() && !rSh.HasSelection() &&
2146  !rSh.HasReadonlySel() )
2147  {
2148  // Previous auto-complete suggestion.
2149  aTmpQHD.Previous( pACorr &&
2150  pACorr->GetSwFlags().bAutoCmpltEndless );
2151  eKeyState = SwKeyState::NextPrevGlossary;
2152  }
2155  rSh.GetDrawView()->AreObjectsMarked())
2156  {
2157  eKeyState = SwKeyState::EnterDrawHandleMode;
2158  }
2159  }
2160  break;
2161  case KEY_F2 :
2162  if( !rSh.HasReadonlySel() )
2163  {
2164  const SelectionType nSelectionType = rSh.GetSelectionType();
2165  if(nSelectionType & SelectionType::Frame)
2166  eKeyState = SwKeyState::GoIntoFly;
2167  else if(nSelectionType & SelectionType::DrawObject)
2168  {
2169  eKeyState = SwKeyState::GoIntoDrawing;
2170  if (lcl_goIntoTextBox(*this, rSh))
2171  eKeyState = SwKeyState::GoIntoFly;
2172  }
2173  }
2174  break;
2175  }
2176  }
2177  break;
2178  case SwKeyState::CheckDocReadOnlyKeys:
2179  {
2180  eKeyState = SwKeyState::KeyToView;
2181  switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
2182  {
2183  case KEY_TAB:
2184  case KEY_TAB | KEY_SHIFT:
2185  bNormalChar = false;
2186  eKeyState = SwKeyState::End;
2187  if ( rSh.GetSelectionType() &
2193 
2194  {
2195  eKeyState = (rKeyCode.GetModifier() & KEY_SHIFT) ?
2196  SwKeyState::PrevObject : SwKeyState::NextObject;
2197  }
2198  else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2199  {
2200  GetView().GetViewFrame()->GetDispatcher()->Execute(
2202  }
2203  else
2204  {
2205  rSh.SelectNextPrevHyperlink( KEY_SHIFT != rKeyCode.GetModifier() );
2206  }
2207  break;
2208  case KEY_RETURN:
2209  {
2210  const SelectionType nSelectionType = rSh.GetSelectionType();
2211  if(nSelectionType & SelectionType::Frame)
2212  eKeyState = SwKeyState::GoIntoFly;
2213  else
2214  {
2216  rSh.GetCurAttr(aSet);
2217  if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false))
2218  {
2219  const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT);
2220  bNormalChar = false;
2221  eKeyState = SwKeyState::End;
2222  rSh.ClickToINetAttr(static_cast<const SwFormatINetFormat&>(rItem));
2223  }
2224  }
2225  }
2226  break;
2227  }
2228  }
2229  break;
2230 
2231  case SwKeyState::EnterCharCell:
2232  {
2233  eKeyState = SwKeyState::KeyToView;
2234  switch ( rKeyCode.GetModifier() | rKeyCode.GetCode() )
2235  {
2236  case KEY_RIGHT | KEY_MOD2:
2237  rSh.Right( CRSR_SKIP_CHARS, false, 1, false );
2238  eKeyState = SwKeyState::End;
2239  FlushInBuffer();
2240  break;
2241  case KEY_LEFT | KEY_MOD2:
2242  rSh.Left( CRSR_SKIP_CHARS, false, 1, false );
2243  eKeyState = SwKeyState::End;
2244  FlushInBuffer();
2245  break;
2246  }
2247  }
2248  break;
2249 
2250  case SwKeyState::KeyToView:
2251  {
2252  eKeyState = SwKeyState::End;
2253  bNormalChar =
2254  !rKeyCode.IsMod2() &&
2255  rKeyCode.GetModifier() != (KEY_MOD1) &&
2256  rKeyCode.GetModifier() != (KEY_MOD1|KEY_SHIFT) &&
2257  SW_ISPRINTABLE( aCh );
2258 
2259  if( bNormalChar && rSh.IsInFrontOfLabel() )
2260  {
2261  rSh.NumOrNoNum();
2262  }
2263 
2264  if( !m_aInBuffer.isEmpty() && ( !bNormalChar || bIsDocReadOnly ))
2265  FlushInBuffer();
2266 
2267  if (rSh.HasReadonlySel() && rKeyCode.GetFunction() == KeyFuncType::PASTE)
2268  {
2269  auto xInfo(std::make_shared<weld::GenericDialogController>(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog"));
2270  weld::DialogController::runAsync(xInfo, [](int) {});
2271  eKeyState = SwKeyState::End;
2272  }
2273  else if( m_rView.KeyInput( aKeyEvent ) )
2274  {
2275  bFlushBuffer = true;
2276  bNormalChar = false;
2277  }
2278  else
2279  {
2280  // Because Sfx accelerators are only called when they were
2281  // enabled at the last status update, copy has to called
2282  // 'forcefully' by us if necessary.
2283  if( rKeyCode.GetFunction() == KeyFuncType::COPY )
2284  GetView().GetViewFrame()->GetBindings().Execute(SID_COPY);
2285 
2286  if( !bIsDocReadOnly && bNormalChar )
2287  {
2288  const SelectionType nSelectionType = rSh.GetSelectionType();
2289  const bool bDrawObject = (nSelectionType & SelectionType::DrawObject) &&
2290  !(nSelectionType & SelectionType::DrawObjectEditMode) &&
2292 
2293  bool bTextBox = false;
2294  if (bDrawObject && lcl_goIntoTextBox(*this, rSh))
2295  // A draw shape was selected, but it has a TextBox,
2296  // start editing that instead when the normal
2297  // character is pressed.
2298  bTextBox = true;
2299 
2300  if (bDrawObject && !bTextBox)
2301  {
2303  if(pObj)
2304  {
2305  EnterDrawTextMode(pObj->GetLogicRect().Center());
2306  if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr )
2307  static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init();
2308  rSh.GetDrawView()->KeyInput( rKEvt, this );
2309  }
2310  }
2311  else if (nSelectionType & SelectionType::Frame || bTextBox)
2312  {
2313  rSh.UnSelectFrame();
2314  rSh.LeaveSelFrameMode();
2315  m_rView.AttrChangedNotify(&rSh);
2317  }
2318  eKeyState = SwKeyState::InsChar;
2319  }
2320  else
2321  {
2322  bNormalChar = false;
2323  Window::KeyInput( aKeyEvent );
2324  }
2325  }
2326  }
2327  break;
2328  case SwKeyState::LaunchOLEObject:
2329  {
2330  rSh.LaunchOLEObj();
2331  eKeyState = SwKeyState::End;
2332  }
2333  break;
2334  case SwKeyState::GoIntoFly:
2335  {
2336  rSh.UnSelectFrame();
2337  rSh.LeaveSelFrameMode();
2338  m_rView.AttrChangedNotify(&rSh);
2340  eKeyState = SwKeyState::End;
2341  }
2342  break;
2343  case SwKeyState::GoIntoDrawing:
2344  {
2345  if (SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0))
2346  {
2347  SdrObject* pObj = pMark->GetMarkedSdrObj();
2348  if(pObj)
2349  {
2350  EnterDrawTextMode(pObj->GetLogicRect().Center());
2351  if (dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr )
2352  static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init();
2353  }
2354  }
2355  eKeyState = SwKeyState::End;
2356  }
2357  break;
2358  case SwKeyState::EnterDrawHandleMode:
2359  {
2360  const SdrHdlList& rHdlList = rSh.GetDrawView()->GetHdlList();
2361  bool bForward(!aKeyEvent.GetKeyCode().IsShift());
2362 
2363  const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
2364  eKeyState = SwKeyState::End;
2365  }
2366  break;
2367  case SwKeyState::InsTab:
2368  if( dynamic_cast<const SwWebView*>( &m_rView) != nullptr) // no Tab for WebView
2369  {
2370  // then it should be passed along
2371  Window::KeyInput( aKeyEvent );
2372  eKeyState = SwKeyState::End;
2373  break;
2374  }
2375  aCh = '\t';
2376  [[fallthrough]];
2377  case SwKeyState::InsChar:
2378  if (rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2379  {
2380  ::sw::mark::ICheckboxFieldmark* pFieldmark =
2381  dynamic_cast< ::sw::mark::ICheckboxFieldmark* >
2382  (rSh.GetCurrentFieldmark());
2383  OSL_ENSURE(pFieldmark,
2384  "Where is my FieldMark??");
2385  if(pFieldmark)
2386  {
2387  pFieldmark->SetChecked(!pFieldmark->IsChecked());
2388  OSL_ENSURE(pFieldmark->IsExpanded(),
2389  "where is the otherpos?");
2390  if (pFieldmark->IsExpanded())
2391  {
2392  rSh.CalcLayout();
2393  }
2394  }
2395  eKeyState = SwKeyState::End;
2396  }
2397  else if ( !rSh.HasReadonlySel()
2398  || rSh.CursorInsideInputField() )
2399  {
2400  const bool bIsNormalChar =
2401  GetAppCharClass().isLetterNumeric( OUString( aCh ), 0 );
2402  if( bAppendSpace && bIsNormalChar &&
2403  (!m_aInBuffer.isEmpty() || !rSh.IsSttPara() || !rSh.IsEndPara() ))
2404  {
2405  // insert a blank ahead of the character. this ends up
2406  // between the expanded text and the new "non-word-separator".
2407  m_aInBuffer += " ";
2408  }
2409 
2410  const bool bIsAutoCorrectChar = SvxAutoCorrect::IsAutoCorrectChar( aCh );
2411  if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) &&
2412  pACfg->IsAutoFormatByInput() &&
2413  (( pACorr->IsAutoCorrFlag( ACFlags::ChgWeightUnderl ) &&
2414  ( '*' == aCh || '_' == aCh ) ) ||
2415  ( pACorr->IsAutoCorrFlag( ACFlags::ChgQuotes ) && ('\"' == aCh ))||
2416  ( pACorr->IsAutoCorrFlag( ACFlags::ChgSglQuotes ) && ( '\'' == aCh))))
2417  {
2418  FlushInBuffer();
2419  rSh.AutoCorrect( *pACorr, aCh );
2420  if( '\"' != aCh && '\'' != aCh ) // only call when "*_"!
2421  rSh.UpdateAttr();
2422  }
2423  else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) &&
2424  pACfg->IsAutoFormatByInput() &&
2425  pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2426  ACFlags::ChgOrdinalNumber | ACFlags::AddNonBrkSpace |
2427  ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr |
2428  ACFlags::Autocorrect ) &&
2429  '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh
2430  )
2431  {
2432  FlushInBuffer();
2433  rSh.AutoCorrect( *pACorr, aCh );
2434  }
2435  else
2436  {
2437  OUStringBuffer aBuf(m_aInBuffer);
2439  m_aInBuffer.getLength() + aKeyEvent.GetRepeat() + 1, aCh);
2440  m_aInBuffer = aBuf.makeStringAndClear();
2441  g_bFlushCharBuffer = Application::AnyInput( VclInputFlags::KEYBOARD );
2442  bFlushBuffer = !g_bFlushCharBuffer;
2443  if( g_bFlushCharBuffer )
2444  m_aKeyInputFlushTimer.Start();
2445  }
2446  eKeyState = SwKeyState::End;
2447  }
2448  else
2449  {
2450  auto xInfo(std::make_shared<weld::GenericDialogController>(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog"));
2451  weld::DialogController::runAsync(xInfo, [](int) {});
2452  eKeyState = SwKeyState::End;
2453  }
2454  break;
2455 
2456  case SwKeyState::CheckAutoCorrect:
2457  {
2458  if( pACorr && pACfg->IsAutoFormatByInput() &&
2459  pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2460  ACFlags::ChgOrdinalNumber |
2461  ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr |
2462  ACFlags::Autocorrect ) &&
2463  !rSh.HasReadonlySel() )
2464  {
2465  FlushInBuffer();
2466  rSh.AutoCorrect( *pACorr, u'\0' );
2467  }
2468  eKeyState = eNextKeyState;
2469  }
2470  break;
2471 
2472  default:
2473  {
2474  sal_uInt16 nSlotId = 0;
2475  FlushInBuffer();
2476  switch( eKeyState )
2477  {
2478  case SwKeyState::SpecialInsert:
2479  rSh.DoSpecialInsert();
2480  break;
2481 
2482  case SwKeyState::NoNum:
2483  rSh.NoNum();
2484  break;
2485 
2486  case SwKeyState::NumOff:
2487  // shell change - so record in advance
2488  rSh.DelNumRules();
2489  break;
2490  case SwKeyState::OutlineLvOff: // delete autofmt outlinelevel later
2491  break;
2492 
2493  case SwKeyState::NumDown:
2494  rSh.NumUpDown();
2495  m_nKS_NUMDOWN_Count = 2;
2496  break;
2497  case SwKeyState::NumUp:
2498  rSh.NumUpDown( false );
2499  break;
2500 
2501  case SwKeyState::NumIndentInc:
2502  rSh.ChangeIndentOfAllListLevels(360);
2503  m_nKS_NUMINDENTINC_Count = 2;
2504  break;
2505 
2506  case SwKeyState::GotoNextFieldMark:
2507  {
2508  ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkAfter();
2509  if(pFieldmark) rSh.GotoFieldmark(pFieldmark);
2510  }
2511  break;
2512 
2513  case SwKeyState::GotoPrevFieldMark:
2514  {
2515  ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkBefore();
2516  if( pFieldmark )
2517  rSh.GotoFieldmark(pFieldmark);
2518  }
2519  break;
2520 
2521  case SwKeyState::NumIndentDec:
2522  rSh.ChangeIndentOfAllListLevels(-360);
2523  break;
2524 
2525  case SwKeyState::OutlineDown:
2526  rSh.OutlineUpDown();
2527  break;
2528  case SwKeyState::OutlineUp:
2529  rSh.OutlineUpDown( -1 );
2530  break;
2531 
2532  case SwKeyState::NextCell:
2533  // always 'flush' in tables
2534  rSh.GoNextCell(!rSh.HasReadonlySel());
2535  nSlotId = FN_GOTO_NEXT_CELL;
2536  break;
2537  case SwKeyState::PrevCell:
2538  rSh.GoPrevCell();
2539  nSlotId = FN_GOTO_PREV_CELL;
2540  break;
2541  case SwKeyState::AutoFormatByInput:
2542  rSh.SplitNode( true );
2543  break;
2544 
2545  case SwKeyState::NextObject:
2546  case SwKeyState::PrevObject:
2547  if(rSh.GotoObj( SwKeyState::NextObject == eKeyState, GotoObjFlags::Any))
2548  {
2549  if( rSh.IsFrameSelected() &&
2550  m_rView.GetDrawFuncPtr() )
2551  {
2552  m_rView.GetDrawFuncPtr()->Deactivate();
2553  m_rView.SetDrawFuncPtr(nullptr);
2554  m_rView.LeaveDrawCreate();
2555  m_rView.AttrChangedNotify( &rSh );
2556  }
2557  rSh.HideCursor();
2558  rSh.EnterSelFrameMode();
2559  }
2560  break;
2561  case SwKeyState::GlossaryExpand:
2562  {
2563  // replace the word or abbreviation with the auto text
2564  rSh.StartUndo( SwUndoId::START );
2565 
2566  OUString sFnd( aTmpQHD.m_aHelpStrings[ aTmpQHD.nCurArrPos ] );
2567  if( aTmpQHD.m_bIsAutoText )
2568  {
2569  SwGlossaryList* pList = ::GetGlossaryList();
2570  OUString sShrtNm;
2571  OUString sGroup;
2572  if(pList->GetShortName( sFnd, sShrtNm, sGroup))
2573  {
2574  rSh.SttSelect();
2575  rSh.ExtendSelection( false, aTmpQHD.nLen );
2576  SwGlossaryHdl* pGlosHdl = GetView().GetGlosHdl();
2577  pGlosHdl->SetCurGroup(sGroup, true);
2578  pGlosHdl->InsertGlossary( sShrtNm);
2579  m_pQuickHlpData->m_bAppendSpace = true;
2580  }
2581  }
2582  else
2583  {
2584  sFnd = sFnd.copy( aTmpQHD.nLen );
2585  rSh.Insert( sFnd );
2586  m_pQuickHlpData->m_bAppendSpace = !pACorr ||
2588  }
2589  rSh.EndUndo( SwUndoId::END );
2590  }
2591  break;
2592 
2593  case SwKeyState::NextPrevGlossary:
2594  m_pQuickHlpData->Move( aTmpQHD );
2595  m_pQuickHlpData->Start( rSh, USHRT_MAX );
2596  break;
2597 
2598  case SwKeyState::EditFormula:
2599  {
2600  const sal_uInt16 nId = SwInputChild::GetChildWindowId();
2601 
2602  SfxViewFrame* pVFrame = GetView().GetViewFrame();
2603  pVFrame->ToggleChildWindow( nId );
2604  SwInputChild* pChildWin = static_cast<SwInputChild*>(pVFrame->
2605  GetChildWindow( nId ));
2606  if( pChildWin )
2607  pChildWin->SetFormula( sFormulaEntry );
2608  }
2609  break;
2610 
2611  case SwKeyState::ColLeftBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break;
2612  case SwKeyState::ColRightBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break;
2613  case SwKeyState::ColLeftSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft, pModOpt->GetTableHMove() ); break;
2614  case SwKeyState::ColRightSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight, pModOpt->GetTableHMove() ); break;
2615  case SwKeyState::ColBottomBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break;
2616  case SwKeyState::ColBottomSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom, pModOpt->GetTableVMove() ); break;
2617  case SwKeyState::CellLeftBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break;
2618  case SwKeyState::CellRightBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break;
2619  case SwKeyState::CellLeftSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft, pModOpt->GetTableHMove() ); break;
2620  case SwKeyState::CellRightSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight, pModOpt->GetTableHMove() ); break;
2621  case SwKeyState::CellTopBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break;
2622  case SwKeyState::CellBottomBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break;
2623  case SwKeyState::CellTopSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop, pModOpt->GetTableVMove() ); break;
2624  case SwKeyState::CellBottomSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom, pModOpt->GetTableVMove() ); break;
2625 
2626  case SwKeyState::Fly_Change:
2627  {
2628  SdrView *pSdrView = rSh.GetDrawView();
2629  const SdrHdlList& rHdlList = pSdrView->GetHdlList();
2630  if(rHdlList.GetFocusHdl())
2631  ChangeDrawing( nDir );
2632  else
2633  ChangeFly( nDir, dynamic_cast<const SwWebView*>( &m_rView) != nullptr );
2634  }
2635  break;
2636  case SwKeyState::Draw_Change :
2637  ChangeDrawing( nDir );
2638  break;
2639  default:
2640  break;
2641  }
2642  if( nSlotId && m_rView.GetViewFrame()->GetBindings().GetRecorder().is() )
2643  {
2644  SfxRequest aReq(m_rView.GetViewFrame(), nSlotId );
2645  aReq.Done();
2646  }
2647  eKeyState = SwKeyState::End;
2648  }
2649  }
2650  }
2651 
2652  // in case the buffered characters are inserted
2653  if( bFlushBuffer && !m_aInBuffer.isEmpty() )
2654  {
2655  // bFlushCharBuffer was not resetted here
2656  // why not?
2657  bool bSave = g_bFlushCharBuffer;
2658  FlushInBuffer();
2659  g_bFlushCharBuffer = bSave;
2660 
2661  // maybe show Tip-Help
2662  OUString sWord;
2663  if( bNormalChar && pACfg && pACorr &&
2664  ( pACfg->IsAutoTextTip() ||
2665  pACorr->GetSwFlags().bAutoCompleteWords ) &&
2666  rSh.GetPrevAutoCorrWord( *pACorr, sWord ) )
2667  {
2668  ShowAutoTextCorrectQuickHelp(sWord, pACfg, pACorr);
2669  }
2670  }
2671 
2672  // get the word count dialog to update itself
2673  SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
2674  if( pWrdCnt )
2675  pWrdCnt->UpdateCounts();
2676 
2677 }
2678 
2683 {
2684  // Not on all systems a MouseButtonUp is used ahead
2685  // of the modal dialog (like on WINDOWS).
2686  // So reset the statuses here and release the mouse
2687  // for the dialog.
2688  m_bMBPressed = false;
2689  g_bNoInterrupt = false;
2690  EnterArea();
2691  ReleaseMouse();
2692 }
2693 
2698 static bool lcl_urlOverBackground(SwWrtShell& rSh, const Point& rDocPos)
2699 {
2700  SwContentAtPos aSwContentAtPos(IsAttrAtPos::InetAttr);
2701  SdrObject* pSelectableObj = rSh.GetObjAt(rDocPos);
2702 
2703  return rSh.GetContentAtPos(rDocPos, aSwContentAtPos) && pSelectableObj->GetLayer() == rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId();
2704 }
2705 
2706 void SwEditWin::MoveCursor( SwWrtShell &rSh, const Point& rDocPos,
2707  const bool bOnlyText, bool bLockView )
2708 {
2709  const bool bTmpNoInterrupt = g_bNoInterrupt;
2710  g_bNoInterrupt = false;
2711 
2712  int nTmpSetCursor = 0;
2713 
2714  if( !rSh.IsViewLocked() && bLockView )
2715  rSh.LockView( true );
2716  else
2717  bLockView = false;
2718 
2719  {
2720  // only temporary generate move context because otherwise
2721  // the query to the content form doesn't work!!!
2722  SwMvContext aMvContext( &rSh );
2723  nTmpSetCursor = rSh.CallSetCursor(&rDocPos, bOnlyText);
2724  g_bValidCursorPos = !(CRSR_POSCHG & nTmpSetCursor);
2725  }
2726 
2727  // notify the edit window that from now on we do not use the input language
2728  if ( !(CRSR_POSOLD & nTmpSetCursor) )
2729  SetUseInputLanguage( false );
2730 
2731  if( bLockView )
2732  rSh.LockView( false );
2733 
2734  g_bNoInterrupt = bTmpNoInterrupt;
2735 }
2736 
2738 {
2739  SwWrtShell &rSh = m_rView.GetWrtShell();
2740  const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr;
2741 
2742  // We have to check if a context menu is shown and we have an UI
2743  // active inplace client. In that case we have to ignore the mouse
2744  // button down event. Otherwise we would crash (context menu has been
2745  // opened by inplace client and we would deactivate the inplace client,
2746  // the contex menu is closed by VCL asynchronously which in the end
2747  // would work on deleted objects or the context menu has no parent anymore)
2748  SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient();
2749  bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() );
2750 
2751  if ( bIsOleActive && PopupMenu::IsInExecute() )
2752  return;
2753 
2754  MouseEvent rMEvt(_rMEvt);
2755 
2756  if (m_rView.GetPostItMgr()->IsHit(rMEvt.GetPosPixel()))
2757  return;
2758 
2760  {
2761  if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel()))
2762  {
2763  pWindow->MouseButtonDown(rMEvt);
2764  return;
2765  }
2766  }
2767 
2768  m_rView.GetPostItMgr()->SetActiveSidebarWin(nullptr);
2769 
2770  GrabFocus();
2771 
2772  //ignore key modifiers for format paintbrush
2773  {
2774  bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
2775  && m_pApplyTempl->m_pFormatClipboard->HasContent();
2776  if( bExecFormatPaintbrush )
2777  rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(),
2778  _rMEvt.GetMode(), _rMEvt.GetButtons() );
2779  }
2780 
2781  m_bWasShdwCursor = nullptr != m_pShadCursor;
2782  m_pShadCursor.reset();
2783 
2784  const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) );
2785 
2786  FrameControlType eControl;
2787  bool bOverFly = false;
2788  bool bPageAnchored = false;
2789  bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored );
2790 
2791  bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
2792  if (bOverHeaderFooterFly && (!bIsDocReadOnly && rSh.GetCurField()))
2793  // We have a field here, that should have priority over header/footer fly.
2794  bOverHeaderFooterFly = false;
2795 
2796  // Are we clicking on a blank header/footer area?
2797  if ( IsInHeaderFooter( aDocPos, eControl ) || bOverHeaderFooterFly )
2798  {
2799  const SwPageFrame* pPageFrame = rSh.GetLayout()->GetPageAtPos( aDocPos );
2800 
2801  // Is it active?
2802  bool bActive = true;
2803  const SwPageDesc* pDesc = pPageFrame->GetPageDesc();
2804 
2805  const SwFrameFormat* pFormat = pDesc->GetLeftFormat();
2806  if ( pPageFrame->OnRightPage() )
2807  pFormat = pDesc->GetRightFormat();
2808 
2809  if ( pFormat )
2810  {
2811  if ( eControl == Header )
2812  bActive = pFormat->GetHeader().IsActive();
2813  else
2814  bActive = pFormat->GetFooter().IsActive();
2815  }
2816 
2817  if ( !bActive )
2818  {
2819  // When in Hide-Whitespace mode, we don't want header
2820  // and footer controls.
2821  if (!rSh.GetViewOptions()->IsHideWhitespaceMode())
2822  {
2823  SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint());
2824  const bool bWasInHeader = aPam.GetPoint()->nNode.GetNode().FindHeaderStartNode() != nullptr;
2825  const bool bWasInFooter = aPam.GetPoint()->nNode.GetNode().FindFooterStartNode() != nullptr;
2826 
2827  // Is the cursor in a part like similar to the one we clicked on? For example,
2828  // if the cursor is in a header and we click on an empty header... don't change anything to
2829  // keep consistent behaviour due to header edit mode (and the same for the footer as well).
2830 
2831  // Otherwise, we hide the header/footer control if a separator is shown, and vice versa.
2832  if (!(bWasInHeader && eControl == Header) &&
2833  !(bWasInFooter && eControl == Footer))
2834  {
2835  rSh.SetShowHeaderFooterSeparator(eControl, !rSh.IsShowHeaderFooterSeparator(eControl));
2836 
2837  // Repaint everything
2838  Invalidate();
2839  }
2840  }
2841  }
2842  else
2843  {
2844  // Make sure we have the proper Header/Footer separators shown
2845  // as these may be changed if clicking on an empty Header/Footer
2846  rSh.SetShowHeaderFooterSeparator( Header, eControl == Header );
2847  rSh.SetShowHeaderFooterSeparator( Footer, eControl == Footer );
2848 
2849  if ( !rSh.IsHeaderFooterEdit() )
2850  {
2851  rSh.ToggleHeaderFooterEdit();
2852 
2853  // Repaint everything
2854  rSh.GetWin()->Invalidate();
2855  }
2856  }
2857  }
2858  else
2859  {
2860  if ( rSh.IsHeaderFooterEdit( ) )
2861  rSh.ToggleHeaderFooterEdit( );
2862  else
2863  {
2864  // Make sure that the separators are hidden
2865  rSh.SetShowHeaderFooterSeparator( Header, false );
2866  rSh.SetShowHeaderFooterSeparator( Footer, false );
2867 
2868  // Repaint everything
2869  // FIXME fdo#67358 for unknown reasons this causes painting
2870  // problems when resizing table columns, so disable it
2871 // rSh.GetWin()->Invalidate();
2872  }
2873 
2874  // Toggle Hide-Whitespace if between pages.
2875  if (rSh.GetViewOptions()->CanHideWhitespace() &&
2876  rSh.GetLayout()->IsBetweenPages(aDocPos))
2877  {
2878  if (_rMEvt.GetClicks() >= 2)
2879  {
2880  SwViewOption aOpt(*rSh.GetViewOptions());
2881  aOpt.SetHideWhitespaceMode(!aOpt.IsHideWhitespaceMode());
2882  rSh.ApplyViewOptions(aOpt);
2883  }
2884 
2885  return;
2886  }
2887  }
2888 
2889  if ( IsChainMode() )
2890  {
2891  SetChainMode( false );
2892  SwRect aDummy;
2893  SwFlyFrameFormat *pFormat = static_cast<SwFlyFrameFormat*>(rSh.GetFlyFrameFormat());
2894  if ( rSh.Chainable( aDummy, *pFormat, aDocPos ) == SwChainRet::OK )
2895  rSh.Chain( *pFormat, aDocPos );
2896  UpdatePointer( aDocPos, rMEvt.GetModifier() );
2897  return;
2898  }
2899 
2900  // After GrabFocus a shell should be pushed. That should actually
2901  // work but in practice ...
2902  m_rView.SelectShellForDrop();
2903 
2904  bool bCallBase = true;
2905 
2906  if( m_pQuickHlpData->m_bIsDisplayed )
2907  m_pQuickHlpData->Stop( rSh );
2908  m_pQuickHlpData->m_bAppendSpace = false;
2909 
2910  if( rSh.FinishOLEObj() )
2911  return; // end InPlace and the click doesn't count anymore
2912 
2913  SET_CURR_SHELL( &rSh );
2914 
2915  SdrView *pSdrView = rSh.GetDrawView();
2916  if ( pSdrView )
2917  {
2918  if (pSdrView->MouseButtonDown( rMEvt, this ) )
2919  {
2920  rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
2921  return; // SdrView's event evaluated
2922  }
2923  }
2924 
2925  m_bIsInMove = false;
2926  m_aStartPos = rMEvt.GetPosPixel();
2927  m_aRszMvHdlPt.setX( 0 );
2928  m_aRszMvHdlPt.setY( 0 );
2929 
2930  SwTab nMouseTabCol = SwTab::COL_NONE;
2931  const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && !rSh.IsInSelect() &&
2932  rMEvt.GetClicks() == 1 && MOUSE_LEFT == rMEvt.GetButtons();
2933  if ( bTmp &&
2934  SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) &&
2935  !rSh.IsObjSelectable( aDocPos ) )
2936  {
2937  // Enhanced table selection
2938  if ( SwTab::SEL_HORI <= nMouseTabCol && SwTab::COLSEL_VERT >= nMouseTabCol )
2939  {
2940  rSh.EnterStdMode();
2941  rSh.SelectTableRowCol( aDocPos );
2942  if( SwTab::SEL_HORI != nMouseTabCol && SwTab::SEL_HORI_RTL != nMouseTabCol)
2943  {
2944  m_xRowColumnSelectionStart = aDocPos;
2945  m_bIsRowDrag = SwTab::ROWSEL_HORI == nMouseTabCol||
2946  SwTab::ROWSEL_HORI_RTL == nMouseTabCol ||
2947  SwTab::COLSEL_VERT == nMouseTabCol;
2948  m_bMBPressed = true;
2949  CaptureMouse();
2950  }
2951  return;
2952  }
2953 
2954  if ( !rSh.IsTableMode() )
2955  {
2956  // comes from table columns out of the document.
2957  if(SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol)
2958  m_rView.SetTabColFromDoc( true );
2959  else
2960  m_rView.SetTabRowFromDoc( true );
2961 
2962  m_rView.SetTabColFromDocPos( aDocPos );
2963  m_rView.InvalidateRulerPos();
2964  SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
2965  rBind.Update();
2966  if ( RulerColumnDrag( rMEvt,
2967  (SwTab::COL_VERT == nMouseTabCol || SwTab::ROW_HORI == nMouseTabCol)) )
2968  {
2969  m_rView.SetTabColFromDoc( false );
2970  m_rView.SetTabRowFromDoc( false );
2971  m_rView.InvalidateRulerPos();
2972  rBind.Update();
2973  bCallBase = false;
2974  }
2975  else
2976  {
2977  return;
2978  }
2979  }
2980  }
2981  else if (bTmp &&
2982  rSh.IsNumLabel(aDocPos))
2983  {
2984  SwTextNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPos );
2985  m_rView.SetNumRuleNodeFromDoc( pNodeAtPos );
2986  m_rView.InvalidateRulerPos();
2987  SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
2988  rBind.Update();
2989 
2990  if ( RulerMarginDrag( rMEvt,
2991  SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos, aDocPos ) ) )
2992  {
2993  m_rView.SetNumRuleNodeFromDoc( nullptr );
2994  m_rView.InvalidateRulerPos();
2995  rBind.Update();
2996  bCallBase = false;
2997  }
2998  else
2999  {
3000  // Make sure the pointer is set to 0, otherwise it may point to
3001  // nowhere after deleting the corresponding text node.
3002  m_rView.SetNumRuleNodeFromDoc( nullptr );
3003  return;
3004  }
3005  }
3006 
3007  if ( rSh.IsInSelect() )
3008  rSh.EndSelect();
3009 
3010  // query against LEFT because otherwise for example also a right
3011  // click releases the selection.
3012  if ( MOUSE_LEFT == rMEvt.GetButtons() )
3013  {
3014  bool bOnlyText = false;
3015  m_bMBPressed = true;
3016  g_bNoInterrupt = true;
3017  m_nKS_NUMDOWN_Count = 0;
3018 
3019  CaptureMouse();
3020 
3021  // reset cursor position if applicable
3022  rSh.ResetCursorStack();
3023 
3024  switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
3025  {
3026  case MOUSE_LEFT:
3027  case MOUSE_LEFT + KEY_SHIFT:
3028  case MOUSE_LEFT + KEY_MOD2:
3029  if( rSh.IsObjSelected() )
3030  {
3031  SdrHdl* pHdl;
3032  if( !bIsDocReadOnly &&
3033  !m_pAnchorMarker &&
3034  pSdrView &&
3035  nullptr != ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
3036  ( pHdl->GetKind() == SdrHdlKind::Anchor ||
3037  pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
3038  {
3039  // #i121463# Set selected during drag
3040  pHdl->SetSelected();
3041  m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) );
3042  UpdatePointer( aDocPos, rMEvt.GetModifier() );
3043  return;
3044  }
3045  }
3046  if ( EnterDrawMode( rMEvt, aDocPos ) )
3047  {
3048  g_bNoInterrupt = false;
3049  return;
3050  }
3051  else if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
3052  {
3053  StopInsFrame();
3054  rSh.Edit();
3055  }
3056 
3057  // Without SHIFT because otherwise Toggle doesn't work at selection
3058  if (rMEvt.GetClicks() == 1)
3059  {
3060  if ( rSh.IsSelFrameMode())
3061  {
3062  SdrHdl* pHdl = rSh.GetDrawView()->PickHandle(aDocPos);
3063  bool bHitHandle = pHdl && pHdl->GetKind() != SdrHdlKind::Anchor &&
3064  pHdl->GetKind() != SdrHdlKind::Anchor_TR;
3065 
3066  if ((rSh.IsInsideSelectedObj(aDocPos) || bHitHandle) &&
3067  !(rMEvt.GetModifier() == KEY_SHIFT && !bHitHandle))
3068  {
3069  rSh.EnterSelFrameMode( &aDocPos );
3070  if ( !m_pApplyTempl )
3071  {
3072  // only if no position to size was hit.
3073  if (!bHitHandle)
3074  {
3075  StartDDTimer();
3076  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3077  SwEditWin::m_nDDStartPosX = aDocPos.X();
3078  }
3079  g_bFrameDrag = true;
3080  }
3081  g_bNoInterrupt = false;
3082  return;
3083  }
3084  }
3085  }
3086  }
3087 
3088  bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
3089  if ( !bExecHyperlinks )
3090  {
3091  SvtSecurityOptions aSecOpts;
3092  const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
3093  if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) ||
3094  ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) )
3095  bExecHyperlinks = true;
3096  }
3097 
3098  // Enhanced selection
3099  sal_uInt8 nNumberOfClicks = static_cast< sal_uInt8 >(rMEvt.GetClicks() % 4);
3100  if ( 0 == nNumberOfClicks && 0 < rMEvt.GetClicks() )
3101  nNumberOfClicks = 4;
3102 
3103  bool bExecDrawTextLink = false;
3104 
3105  switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
3106  {
3107  case MOUSE_LEFT:
3108  case MOUSE_LEFT + KEY_MOD1:
3109  case MOUSE_LEFT + KEY_MOD2:
3110  {
3111 
3112  // fdo#79604: first, check if a link has been clicked - do not
3113  // select fly in this case!
3114  if (1 == nNumberOfClicks)
3115  {
3116  UpdatePointer( aDocPos, rMEvt.GetModifier() );
3117  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3118  SwEditWin::m_nDDStartPosX = aDocPos.X();
3119 
3120  // hit a URL in DrawText object?
3121  if (bExecHyperlinks && pSdrView)
3122  {
3123  SdrViewEvent aVEvt;
3124  pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
3125 
3126  if (aVEvt.eEvent == SdrEventKind::ExecuteUrl)
3127  bExecDrawTextLink = true;
3128  }
3129  }
3130 
3131  if (1 == nNumberOfClicks && !bExecDrawTextLink)
3132  {
3133  // only try to select frame, if pointer already was
3134  // switched accordingly
3135  if ( m_aActHitType != SdrHitKind::NONE && !rSh.IsSelFrameMode() &&
3136  !GetView().GetViewFrame()->GetDispatcher()->IsLocked())
3137  {
3138  // Test if there is a draw object at that position and if it should be selected.
3139  bool bShould = rSh.ShouldObjectBeSelected(aDocPos);
3140 
3141  if(bShould)
3142  {
3143  m_rView.NoRotate();
3144  rSh.HideCursor();
3145 
3146  bool bUnLockView = !rSh.IsViewLocked();
3147  rSh.LockView( true );
3148  bool bSelObj = rSh.SelectObj( aDocPos,
3149  rMEvt.IsMod1() ? SW_ENTER_GROUP : 0);
3150  if( bUnLockView )
3151  rSh.LockView( false );
3152 
3153  if( bSelObj )
3154  {
3155  // if the frame was deselected in the macro
3156  // the cursor just has to be displayed again
3157  if( FrameTypeFlags::NONE == rSh.GetSelFrameType() )
3158  rSh.ShowCursor();
3159  else
3160  {
3161  if (rSh.IsFrameSelected() && m_rView.GetDrawFuncPtr())
3162  {
3163  m_rView.GetDrawFuncPtr()->Deactivate();
3164  m_rView.SetDrawFuncPtr(nullptr);
3165  m_rView.LeaveDrawCreate();
3166  m_rView.AttrChangedNotify( &rSh );
3167  }
3168 
3169  rSh.EnterSelFrameMode( &aDocPos );
3170  g_bFrameDrag = true;
3171  UpdatePointer( aDocPos, rMEvt.GetModifier() );
3172  }
3173  return;
3174  }
3175  else
3176  bOnlyText = rSh.IsObjSelectable( aDocPos );
3177 
3178  if (!m_rView.GetDrawFuncPtr())
3179  rSh.ShowCursor();
3180  }
3181  else
3182  bOnlyText = KEY_MOD1 != rMEvt.GetModifier();
3183  }
3184  else if ( rSh.IsSelFrameMode() &&
3185  (m_aActHitType == SdrHitKind::NONE ||
3186  !rSh.IsInsideSelectedObj( aDocPos )))
3187  {
3188  m_rView.NoRotate();
3189  SdrHdl *pHdl;
3190  if( !bIsDocReadOnly && !m_pAnchorMarker && nullptr !=
3191  ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
3192  ( pHdl->GetKind() == SdrHdlKind::Anchor ||
3193  pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
3194  {
3195  m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) );
3196  UpdatePointer( aDocPos, rMEvt.GetModifier() );
3197  return;
3198  }
3199  else
3200  {
3201  bool bUnLockView = !rSh.IsViewLocked();
3202  rSh.LockView( true );
3203  sal_uInt8 nFlag = rMEvt.IsShift() ? SW_ADD_SELECT :0;
3204  if( rMEvt.IsMod1() )
3205  nFlag = nFlag | SW_ENTER_GROUP;
3206 
3207  if ( rSh.IsSelFrameMode() )
3208  {
3209  rSh.UnSelectFrame();
3210  rSh.LeaveSelFrameMode();
3211  m_rView.AttrChangedNotify(&rSh);
3212  }
3213 
3214  bool bSelObj = rSh.SelectObj( aDocPos, nFlag );
3215  if( bUnLockView )
3216  rSh.LockView( false );
3217 
3218  if( !bSelObj )
3219  {
3220  // move cursor here so that it is not drawn in the
3221  // frame first; ShowCursor() happens in LeaveSelFrameMode()
3222  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
3223  rSh.LeaveSelFrameMode();
3224  m_rView.AttrChangedNotify( &rSh );
3225  bCallBase = false;
3226  }
3227  else
3228  {
3229  rSh.HideCursor();
3230  rSh.EnterSelFrameMode( &aDocPos );
3231  rSh.SelFlyGrabCursor();
3232  rSh.MakeSelVisible();
3233  g_bFrameDrag = true;
3234  if( rSh.IsFrameSelected() &&
3235  m_rView.GetDrawFuncPtr() )
3236  {
3237  m_rView.GetDrawFuncPtr()->Deactivate();
3238  m_rView.SetDrawFuncPtr(nullptr);
3239  m_rView.LeaveDrawCreate();
3240  m_rView.AttrChangedNotify( &rSh );
3241  }
3242  UpdatePointer( aDocPos, rMEvt.GetModifier() );
3243  return;
3244  }
3245  }
3246  }
3247  }
3248 
3249  switch ( nNumberOfClicks )
3250  {
3251  case 1:
3252  break;
3253  case 2:
3254  {
3255  g_bFrameDrag = false;
3256  if ( !bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos) &&
3258  {
3259  /* This is no good: on the one hand GetSelectionType is used as flag field
3260  * (take a look into the GetSelectionType method) and on the other hand the
3261  * return value is used in a switch without proper masking (very nice), this must lead to trouble
3262  */
3264  {
3266  RstMBDownFlags();
3268  {
3269  GetView().GetViewFrame()->GetBindings().Execute(
3270  FN_FORMAT_GRAFIC_DLG, nullptr,
3271  SfxCallMode::RECORD|SfxCallMode::SLOT);
3272  }
3273  return;
3274 
3275  // double click on OLE object --> OLE-InPlace
3276  case SelectionType::Ole:
3278  {
3279  RstMBDownFlags();
3280  rSh.LaunchOLEObj();
3281  }
3282  return;
3283 
3284  case SelectionType::Frame:
3285  RstMBDownFlags();
3287  {
3288  GetView().GetViewFrame()->GetBindings().Execute(
3289  FN_FORMAT_FRAME_DLG, nullptr,
3290  SfxCallMode::RECORD|SfxCallMode::SLOT);
3291  }
3292  return;
3293 
3295  RstMBDownFlags();
3296  EnterDrawTextMode(aDocPos);
3297  if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr )
3298  static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init();
3299  return;
3300 
3301  default: break;
3302  }
3303  }
3304 
3305  // if the cursor position was corrected or if a Fly
3306  // was selected in ReadOnlyMode, no word selection, except when tiled rendering.
3308  return;
3309 
3310  SwField *pField;
3311  bool bFootnote = false;
3312 
3313  if( !bIsDocReadOnly &&
3314  ( nullptr != ( pField = rSh.GetCurField() ) ||
3315  ( bFootnote = rSh.GetCurFootnote() ) ) )
3316  {
3317  RstMBDownFlags();
3318  if( bFootnote )
3319  GetView().GetViewFrame()->GetBindings().Execute( FN_EDIT_FOOTNOTE );
3320  else
3321  {
3322  sal_uInt16 nTypeId = pField->GetTypeId();
3323  SfxViewFrame* pVFrame = GetView().GetViewFrame();
3324  switch( nTypeId )
3325  {
3326  case TYP_POSTITFLD:
3327  case TYP_SCRIPTFLD:
3328  {
3329  // if it's a Readonly region, status has to be enabled
3330  sal_uInt16 nSlot = TYP_POSTITFLD == nTypeId ? FN_POSTIT : FN_JAVAEDIT;
3331  SfxBoolItem aItem(nSlot, true);
3332  pVFrame->GetBindings().SetState(aItem);
3333  pVFrame->GetBindings().Execute(nSlot);
3334  break;
3335  }
3336  case TYP_AUTHORITY :
3338  break;
3339  case TYP_INPUTFLD:
3340  case TYP_DROPDOWN:
3341  case TYP_SETINPFLD:
3343  break;
3344  default:
3345  pVFrame->GetBindings().Execute(FN_EDIT_FIELD);
3346  }
3347  }
3348  return;
3349  }
3350  // in extended mode double and triple
3351  // click has no effect.
3352  if ( rSh.IsExtMode() || rSh.IsBlockMode() )
3353  return;
3354 
3355  // select word, AdditionalMode if applicable
3356  if ( KEY_MOD1 == rMEvt.GetModifier() && !rSh.IsAddMode() )
3357  {
3358  rSh.EnterAddMode();
3359  rSh.SelWrd( &aDocPos );
3360  rSh.LeaveAddMode();
3361  }
3362  else
3363  {
3364  if (!rSh.SelWrd(&aDocPos) && comphelper::LibreOfficeKit::isActive())
3365  // Double click did not select any word: try to
3366  // select the current cell in case we are in a
3367  // table.
3368  rSh.SelTableBox();
3369  }
3370 
3372  if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) &&
3373  aContentAtPos.aFnd.pFieldmark != nullptr)
3374  {
3375  IFieldmark *pFieldBM = const_cast< IFieldmark* > ( aContentAtPos.aFnd.pFieldmark );
3376  if ( pFieldBM->GetFieldname( ) == ODF_FORMDROPDOWN )
3377  {
3378  RstMBDownFlags();
3380  GetView().GetViewFrame()->GetBindings().Execute(SID_FM_CTL_PROPERTIES);
3381  return;
3382  }
3383  }
3384 
3385  g_bHoldSelection = true;
3386  return;
3387  }
3388  case 3:
3389  case 4:
3390  {
3391  g_bFrameDrag = false;
3392  // in extended mode double and triple
3393  // click has no effect.
3394  if ( rSh.IsExtMode() )
3395  return;
3396 
3397  // if the cursor position was corrected or if a Fly
3398  // was selected in ReadOnlyMode, no word selection.
3399  if ( !g_bValidCursorPos || rSh.IsFrameSelected() )
3400  return;
3401 
3402  // select line, AdditionalMode if applicable
3403  const bool bMod = KEY_MOD1 == rMEvt.GetModifier() &&
3404  !rSh.IsAddMode();
3405 
3406  if ( bMod )
3407  rSh.EnterAddMode();
3408 
3409  // Enhanced selection
3410  if ( 3 == nNumberOfClicks )
3411  rSh.SelSentence( &aDocPos );
3412  else
3413  rSh.SelPara( &aDocPos );
3414 
3415  if ( bMod )
3416  rSh.LeaveAddMode();
3417 
3418  g_bHoldSelection = true;
3419  return;
3420  }
3421 
3422  default:
3423  return;
3424  }
3425 
3426  [[fallthrough]];
3427  }
3428  case MOUSE_LEFT + KEY_SHIFT:
3429  case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
3430  {
3431  bool bLockView = m_bWasShdwCursor;
3432 
3433  switch ( rMEvt.GetModifier() )
3434  {
3435  case KEY_MOD1 + KEY_SHIFT:
3436  {
3437  if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
3438  {
3439  m_rView.NoRotate();
3440  rSh.HideCursor();
3441  if ( rSh.IsSelFrameMode() )
3442  rSh.SelectObj(aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP);
3443  else
3444  { if ( rSh.SelectObj( aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP ) )
3445  {
3446  rSh.EnterSelFrameMode( &aDocPos );
3447  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3448  SwEditWin::m_nDDStartPosX = aDocPos.X();
3449  g_bFrameDrag = true;
3450  return;
3451  }
3452  }
3453  }
3454  else if( rSh.IsSelFrameMode() &&
3455  rSh.GetDrawView()->PickHandle( aDocPos ))
3456  {
3457  g_bFrameDrag = true;
3458  g_bNoInterrupt = false;
3459  return;
3460  }
3461  }
3462  break;
3463  case KEY_MOD1:
3464  if ( !bExecDrawTextLink )
3465  {
3466  if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) && !lcl_urlOverBackground( rSh, aDocPos ) )
3467  {
3468  m_rView.NoRotate();
3469  rSh.HideCursor();
3470  if ( rSh.IsSelFrameMode() )
3471  rSh.SelectObj(aDocPos, SW_ENTER_GROUP);
3472  else
3473  { if ( rSh.SelectObj( aDocPos, SW_ENTER_GROUP ) )
3474  {
3475  rSh.EnterSelFrameMode( &aDocPos );
3476  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3477  SwEditWin::m_nDDStartPosX = aDocPos.X();
3478  g_bFrameDrag = true;
3479  return;
3480  }
3481  }
3482  }
3483  else if( rSh.IsSelFrameMode() &&
3484  rSh.GetDrawView()->PickHandle( aDocPos ))
3485  {
3486  g_bFrameDrag = true;
3487  g_bNoInterrupt = false;
3488  return;
3489  }
3490  else
3491  {
3492  if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
3493  {
3494  rSh.PushMode();
3495  g_bModePushed = true;
3496 
3497  bool bUnLockView = !rSh.IsViewLocked();
3498  rSh.LockView( true );
3499  rSh.EnterAddMode();
3500  if( bUnLockView )
3501  rSh.LockView( false );
3502  }
3503  bCallBase = false;
3504  }
3505  }
3506  break;
3507  case KEY_MOD2:
3508  {
3509  if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
3510  {
3511  rSh.PushMode();
3512  g_bModePushed = true;
3513  bool bUnLockView = !rSh.IsViewLocked();
3514  rSh.LockView( true );
3515  rSh.EnterBlockMode();
3516  if( bUnLockView )
3517  rSh.LockView( false );
3518  }
3519  bCallBase = false;
3520  }
3521  break;
3522  case KEY_SHIFT:
3523  {
3524  if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
3525  {
3526  m_rView.NoRotate();
3527  rSh.HideCursor();
3528  if ( rSh.IsSelFrameMode() )
3529  {
3530  rSh.SelectObj(aDocPos, SW_ADD_SELECT);
3531 
3532  const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
3533  if (rMarkList.GetMark(0) == nullptr)
3534  {
3535  rSh.LeaveSelFrameMode();
3536  m_rView.AttrChangedNotify(&rSh);
3537  g_bFrameDrag = false;
3538  }
3539  }
3540  else
3541  { if ( rSh.SelectObj( aDocPos ) )
3542  {
3543  rSh.EnterSelFrameMode( &aDocPos );
3544  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3545  SwEditWin::m_nDDStartPosX = aDocPos.X();
3546  g_bFrameDrag = true;
3547  return;
3548  }
3549  }
3550  }
3551  else
3552  {
3553  if ( rSh.IsSelFrameMode() &&
3554  rSh.IsInsideSelectedObj( aDocPos ) )
3555  {
3556  rSh.EnterSelFrameMode( &aDocPos );
3557  SwEditWin::m_nDDStartPosY = aDocPos.Y();
3558  SwEditWin::m_nDDStartPosX = aDocPos.X();
3559  g_bFrameDrag = true;
3560  return;
3561  }
3562  if ( rSh.IsSelFrameMode() )
3563  {
3564  rSh.UnSelectFrame();
3565  rSh.LeaveSelFrameMode();
3566  m_rView.AttrChangedNotify(&rSh);
3567  g_bFrameDrag = false;
3568  }
3569  if ( !rSh.IsExtMode() )
3570  {
3571  // don't start a selection when an
3572  // URL field or a graphic is clicked
3573  bool bSttSelect = rSh.HasSelection() ||
3574  PointerStyle::RefHand != GetPointer();
3575 
3576  if( !bSttSelect )
3577  {
3578  bSttSelect = true;
3579  if( bExecHyperlinks )
3580  {
3581  SwContentAtPos aContentAtPos(
3584 
3585  if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) )
3586  {
3587  if( !rSh.IsViewLocked() &&
3588  !rSh.IsReadOnlyAvailable() &&
3589  aContentAtPos.IsInProtectSect() )
3590  bLockView = true;
3591 
3592  bSttSelect = false;
3593  }
3594  else if( rSh.IsURLGrfAtPos( aDocPos ))
3595  bSttSelect = false;
3596  }
3597  }
3598 
3599  if( bSttSelect )
3600  rSh.SttSelect();
3601  }
3602  }
3603  bCallBase = false;
3604  break;
3605  }
3606  default:
3607  if( !rSh.IsViewLocked() )
3608  {
3609  SwContentAtPos aContentAtPos( IsAttrAtPos::ClickField |
3611  if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) &&
3612  !rSh.IsReadOnlyAvailable() &&
3613  aContentAtPos.IsInProtectSect() )
3614  bLockView = true;
3615  }
3616  }
3617 
3618  if ( rSh.IsGCAttr() )
3619  {
3620  rSh.GCAttr();
3621  rSh.ClearGCAttr();
3622  }
3623 
3624  SwContentAtPos aFieldAtPos(IsAttrAtPos::Field);
3625  bool bEditableFieldClicked = false;
3626 
3627  // Are we clicking on a field?
3628  if (rSh.GetContentAtPos(aDocPos, aFieldAtPos))
3629  {
3630  bool bEditableField = (aFieldAtPos.pFndTextAttr != nullptr
3631  && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD);
3632 
3633  if (!bEditableField)
3634  {
3635  rSh.CallSetCursor(&aDocPos, bOnlyText);
3636  // Unfortunately the cursor may be on field
3637  // position or on position after field depending on which
3638  // half of the field was clicked on.
3639  SwTextAttr const*const pTextField(aFieldAtPos.pFndTextAttr);
3641  .GetIndex() != pTextField->GetStart())
3642  {
3643  assert(rSh.GetCurrentShellCursor().GetPoint()->nContent
3644  .GetIndex() == (pTextField->GetStart() + 1));
3645  rSh.Left( CRSR_SKIP_CHARS, false, 1, false );
3646  }
3647  // don't go into the !bOverSelect block below - it moves
3648  // the cursor
3649  break;
3650  }
3651  else
3652  {
3653  bEditableFieldClicked = true;
3654  }
3655  }
3656 
3657  bool bOverSelect = rSh.TestCurrPam( aDocPos );
3658  bool bOverURLGrf = false;
3659  if( !bOverSelect )
3660  bOverURLGrf = bOverSelect = nullptr != rSh.IsURLGrfAtPos( aDocPos );
3661 
3662  if ( !bOverSelect )
3663  {
3664  MoveCursor( rSh, aDocPos, bOnlyText, bLockView );
3665  bCallBase = false;
3666  }
3667  if (!bOverURLGrf && !bExecDrawTextLink && !bOnlyText)
3668  {
3669  const SelectionType nSelType = rSh.GetSelectionType();
3670  // Check in general, if an object is selectable at given position.
3671  // Thus, also text fly frames in background become selectable via Ctrl-Click.
3672  if ( ( nSelType & SelectionType::Ole ||
3673  nSelType & SelectionType::Graphic ||
3674  rSh.IsObjSelectable( aDocPos ) ) && !lcl_urlOverBackground( rSh, aDocPos ) )
3675  {
3676  SwMvContext aMvContext( &rSh );
3677  rSh.EnterSelFrameMode();
3678  bCallBase = false;
3679  }
3680  }
3681  if ( !bOverSelect && bEditableFieldClicked && (!pCursorField ||
3682  pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField()))
3683  {
3684  // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
3685  // and CH_TXT_ATR_INPUTFIELDEND
3686  rSh.SttSelect();
3687  rSh.SelectText( aFieldAtPos.pFndTextAttr->GetStart() + 1,
3688  *(aFieldAtPos.pFndTextAttr->End()) - 1 );
3689  }
3690  // don't reset here any longer so that, in case through MouseMove
3691  // with pressed Ctrl key a multiple-selection should happen,
3692  // the previous selection is not released in Drag.
3693  break;
3694  }
3695  }
3696  }
3697  else if ( MOUSE_RIGHT == rMEvt.GetButtons() && !rMEvt.GetModifier()
3698  && static_cast< sal_uInt8 >(rMEvt.GetClicks() % 4) == 1
3699  && !rSh.TestCurrPam( aDocPos ) )
3700  {
3701  SwContentAtPos aFieldAtPos(IsAttrAtPos::Field);
3702 
3703  // Are we clicking on a field?
3704  if (g_bValidCursorPos
3705  && rSh.GetContentAtPos(aDocPos, aFieldAtPos)
3706  && aFieldAtPos.pFndTextAttr != nullptr
3707  && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD
3708  && (!pCursorField || pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField()))
3709  {
3710  // Move the cursor
3711  MoveCursor( rSh, aDocPos, rSh.IsObjSelectable( aDocPos ), m_bWasShdwCursor );
3712  bCallBase = false;
3713 
3714  // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
3715  // and CH_TXT_ATR_INPUTFIELDEND
3716  rSh.SttSelect();
3717  rSh.SelectText( aFieldAtPos.pFndTextAttr->GetStart() + 1,
3718  *(aFieldAtPos.pFndTextAttr->End()) - 1 );
3719  }
3720  }
3721 
3722  if (bCallBase)
3723  Window::MouseButtonDown(rMEvt);
3724 }
3725 
3727 {
3728  MouseEvent rMEvt(_rMEvt);
3729 
3731  {
3732  if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel()))
3733  {
3734  pWindow->MouseMove(rMEvt);
3735  return;
3736  }
3737  }
3738 
3739  //ignore key modifiers for format paintbrush
3740  {
3741  bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
3742  && m_pApplyTempl->m_pFormatClipboard->HasContent();
3743  if( bExecFormatPaintbrush )
3744  rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(),
3745  _rMEvt.GetMode(), _rMEvt.GetButtons() );
3746  }
3747 
3748  // as long as an action is running the MouseMove should be disconnected
3749  // otherwise bug 40102 occurs
3750  SwWrtShell &rSh = m_rView.GetWrtShell();
3751  if( rSh.ActionPend() )
3752  return ;
3753 
3754  if( m_pShadCursor && 0 != (rMEvt.GetModifier() + rMEvt.GetButtons() ) )
3755  {
3756  m_pShadCursor.reset();
3757  }
3758 
3759  bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
3760 
3761  SET_CURR_SHELL( &rSh );
3762 
3763  //aPixPt == Point in Pixel, relative to ChildWin
3764  //aDocPt == Point in Twips, document coordinates
3765  const Point aPixPt( rMEvt.GetPosPixel() );
3766  const Point aDocPt( PixelToLogic( aPixPt ) );
3767 
3768  if ( IsChainMode() )
3769  {
3770  UpdatePointer( aDocPt, rMEvt.GetModifier() );
3771  return;
3772  }
3773 
3774  SdrView *pSdrView = rSh.GetDrawView();
3775 
3776  const SwCallMouseEvent aLastCallEvent( m_aSaveCallEvent );
3777  m_aSaveCallEvent.Clear();
3778 
3779  if ( !bIsDocReadOnly && pSdrView && pSdrView->MouseMove(rMEvt,this) )
3780  {
3781  SetPointer( PointerStyle::Text );
3782  return; // evaluate SdrView's event
3783  }
3784 
3785  const Point aOldPt( rSh.VisArea().Pos() );
3786  const bool bInsWin = rSh.VisArea().IsInside( aDocPt ) || comphelper::LibreOfficeKit::isActive();
3787 
3788  if( m_pShadCursor && !bInsWin )
3789  {
3790  m_pShadCursor.reset();
3791  }
3792 
3793  if( bInsWin && m_xRowColumnSelectionStart )
3794  {
3795  EnterArea();
3796  Point aPos( aDocPt );
3797  if( rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag ))
3798  return;
3799  }
3800 
3801  // position is necessary for OS/2 because obviously after a MB-Down
3802  // a MB-Move is called immediately.
3803  if( g_bDDTimerStarted )
3804  {
3806  aDD = LogicToPixel( aDD );
3807  tools::Rectangle aRect( aDD.X()-3, aDD.Y()-3, aDD.X()+3, aDD.Y()+3 );
3808  if ( !aRect.IsInside( aPixPt ) )
3809  StopDDTimer( &rSh, aDocPt );
3810  }
3811 
3812  if(m_rView.GetDrawFuncPtr())
3813  {
3814  if( m_bInsDraw )
3815  {
3816  m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
3817  if ( !bInsWin )
3818  {
3819  Point aTmp( aDocPt );
3820  aTmp += rSh.VisArea().Pos() - aOldPt;
3821  LeaveArea( aTmp );
3822  }
3823  else
3824  EnterArea();
3825  return;
3826  }
3827  else if(!rSh.IsFrameSelected() && !rSh.IsObjSelected())
3828  {
3829  SfxBindings &rBnd = rSh.GetView().GetViewFrame()->GetBindings();
3830  Point aRelPos = rSh.GetRelativePagePosition(aDocPt);
3831  if(aRelPos.X() >= 0)
3832  {
3833  FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &GetView()) != nullptr );
3834  SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
3835  const SfxPointItem aTmp1( SID_ATTR_POSITION, aRelPos );
3836  rBnd.SetState( aTmp1 );
3837  }
3838  else
3839  {
3840  rBnd.Invalidate(SID_ATTR_POSITION);
3841  }
3842  rBnd.Invalidate(SID_ATTR_SIZE);
3843  const SfxStringItem aCell( SID_TABLE_CELL, OUString() );
3844  rBnd.SetState( aCell );
3845  }
3846  }
3847 
3848  SwTab nMouseTabCol;
3849  if( !bIsDocReadOnly && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() )
3850  {
3851  if ( SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPt ) ) &&
3852  !rSh.IsObjSelectable( aDocPt ) )
3853  {
3854  PointerStyle nPointer = PointerStyle::Null;
3855  bool bChkTableSel = false;
3856 
3857  switch ( nMouseTabCol )
3858  {
3859  case SwTab::COL_VERT :
3860  case SwTab::ROW_HORI :
3861  nPointer = PointerStyle::VSizeBar;
3862  bChkTableSel = true;
3863  break;
3864  case SwTab::ROW_VERT :
3865  case SwTab::COL_HORI :
3866  nPointer = PointerStyle::HSizeBar;
3867  bChkTableSel = true;
3868  break;
3869  // Enhanced table selection
3870  case SwTab::SEL_HORI :
3871  nPointer = PointerStyle::TabSelectSE;
3872  break;
3873  case SwTab::SEL_HORI_RTL :
3874  case SwTab::SEL_VERT :
3875  nPointer = PointerStyle::TabSelectSW;
3876  break;
3877  case SwTab::COLSEL_HORI :
3878  case SwTab::ROWSEL_VERT :
3879  nPointer = PointerStyle::TabSelectS;
3880  break;
3881  case SwTab::ROWSEL_HORI :
3882  nPointer = PointerStyle::TabSelectE;
3883  break;
3884  case SwTab::ROWSEL_HORI_RTL :
3885  case SwTab::COLSEL_VERT :
3886  nPointer = PointerStyle::TabSelectW;
3887  break;
3888  default: break; // prevent compiler warning
3889  }
3890 
3891  if ( PointerStyle::Null != nPointer &&
3892  // i#35543 - Enhanced table selection is explicitly allowed in table mode
3893  ( !bChkTableSel || !rSh.IsTableMode() ) )
3894  {
3895  SetPointer( nPointer );
3896  }
3897 
3898  return;
3899  }
3900  else if (rSh.IsNumLabel(aDocPt, RULER_MOUSE_MARGINWIDTH))
3901  {
3902  // i#42921 - consider vertical mode
3903  SwTextNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPt );
3904  const PointerStyle nPointer =
3905  SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos, aDocPt )
3906  ? PointerStyle::VSizeBar
3907  : PointerStyle::HSizeBar;
3908  SetPointer( nPointer );
3909 
3910  return;
3911  }
3912  }
3913 
3914  bool bDelShadCursor = true;
3915 
3916  switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
3917  {
3918  case MOUSE_LEFT:
3919  if( m_pAnchorMarker )
3920  {
3921  // Now we need to refresh the SdrHdl pointer of m_pAnchorMarker.
3922  // This looks a little bit tricky, but it solves the following
3923  // problem: the m_pAnchorMarker contains a pointer to an SdrHdl,
3924  // if the FindAnchorPos-call cause a scrolling of the visible
3925  // area, it's possible that the SdrHdl will be destroyed and a
3926  // new one will initialized at the original position(GetHdlPos).
3927  // So the m_pAnchorMarker has to find the right SdrHdl, if it's
3928  // the old one, it will find it with position aOld, if this one
3929  // is destroyed, it will find a new one at position GetHdlPos().
3930 
3931  const Point aOld = m_pAnchorMarker->GetPosForHitTest( *(rSh.GetOut()) );
3932  Point aNew = rSh.FindAnchorPos( aDocPt );
3933  SdrHdl* pHdl;
3934  if( pSdrView && (nullptr!=( pHdl = pSdrView->PickHandle( aOld ) )||
3935  nullptr !=(pHdl = pSdrView->PickHandle( m_pAnchorMarker->GetHdlPos()) ) ) &&
3936  ( pHdl->GetKind() == SdrHdlKind::Anchor ||
3937  pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
3938  {
3939  m_pAnchorMarker->ChgHdl( pHdl );
3940  if( aNew.X() || aNew.Y() )
3941  {
3942  m_pAnchorMarker->SetPos( aNew );
3943  m_pAnchorMarker->SetLastPos( aDocPt );
3944  }
3945  }
3946  else
3947  {
3948  m_pAnchorMarker.reset();
3949  }
3950  }
3951  if ( m_bInsDraw )
3952  {
3953  if ( !m_bMBPressed )
3954  break;
3955  if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
3956  {
3957  if ( !bInsWin )
3958  LeaveArea( aDocPt );
3959  else
3960  EnterArea();
3961  if ( m_rView.GetDrawFuncPtr() )
3962  {
3963  pSdrView->SetOrtho(false);
3964  m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
3965  }
3966  m_bIsInMove = true;
3967  }
3968  return;
3969  }
3970 
3971  {
3972  SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
3973  if (pWrdCnt)
3974  pWrdCnt->UpdateCounts();
3975  }
3976  [[fallthrough]];
3977 
3978  case MOUSE_LEFT + KEY_SHIFT:
3979  case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
3980  if ( !m_bMBPressed )
3981  break;
3982  [[fallthrough]];
3983  case MOUSE_LEFT + KEY_MOD1:
3984  if ( g_bFrameDrag && rSh.IsSelFrameMode() )
3985  {
3986  if( !m_bMBPressed )
3987  break;
3988 
3989  if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
3990  {
3991  // event processing for resizing
3992  if (pSdrView && pSdrView->AreObjectsMarked())
3993  {
3994  const Point aSttPt( PixelToLogic( m_aStartPos ) );
3995 
3996  // can we start?
3997  if( SdrHdlKind::User == g_eSdrMoveHdl )
3998  {
3999  SdrHdl* pHdl = pSdrView->PickHandle( aSttPt );
4000  g_eSdrMoveHdl = pHdl ? pHdl->GetKind() : SdrHdlKind::Move;
4001  }
4002 
4003  const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat());
4004  const SvxMacro* pMacro = nullptr;
4005 
4006  SvMacroItemId nEvent = SdrHdlKind::Move == g_eSdrMoveHdl
4007  ? SvMacroItemId::SwFrmMove
4008  : SvMacroItemId::SwFrmResize;
4009 
4010  if (nullptr != pFlyFormat)
4011  pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent);
4012  if (nullptr != pMacro &&
4013  // or notify only e.g. every 20 Twip?
4014  m_aRszMvHdlPt != aDocPt )
4015  {
4016  m_aRszMvHdlPt = aDocPt;
4017  sal_uInt16 nPos = 0;
4018  SbxArrayRef xArgs = new SbxArray;
4019  SbxVariableRef xVar = new SbxVariable;
4020  xVar->PutString( pFlyFormat->GetName() );
4021  xArgs->Put( xVar.get(), ++nPos );
4022 
4023  if( SvMacroItemId::SwFrmResize == nEvent )
4024  {
4025  xVar = new SbxVariable;
4026  xVar->PutUShort( static_cast< sal_uInt16 >(g_eSdrMoveHdl) );
4027  xArgs->Put( xVar.get(), ++nPos );
4028  }
4029 
4030  xVar = new SbxVariable;
4031  xVar->PutLong( aDocPt.X() - aSttPt.X() );
4032  xArgs->Put( xVar.get(), ++nPos );
4033  xVar = new SbxVariable;
4034  xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
4035  xArgs->Put( xVar.get(), ++nPos );
4036 
4037  OUString sRet;
4038 
4039  ReleaseMouse();
4040 
4041  rSh.ExecMacro( *pMacro, &sRet, xArgs.get() );
4042 
4043  CaptureMouse();
4044 
4045  if( !sRet.isEmpty() && sRet.toInt32()!=0 )
4046  return ;
4047  }
4048  }
4049  // event processing for resizing
4050 
4051  if( bIsDocReadOnly )
4052  break;
4053 
4054  bool bResizeKeepRatio = rSh.GetSelectionType() & SelectionType::Graphic ||
4057  bool bisResize = g_eSdrMoveHdl != SdrHdlKind::Move;
4058 
4059  if (pSdrView)
4060  {
4061  // Resize proportionally when media is selected and the user drags on a corner
4062  const Point aSttPt(PixelToLogic(m_aStartPos));
4063  SdrHdl* pHdl = pSdrView->PickHandle(aSttPt);
4064  if (pHdl)
4065  bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl();
4066 
4067  if (pSdrView->GetDragMode() == SdrDragMode::Crop)
4068  bisResize = false;
4069  if (rMEvt.IsShift())
4070  {
4071  pSdrView->SetAngleSnapEnabled(!bResizeKeepRatio);
4072  if (bisResize)
4073  pSdrView->SetOrtho(!bResizeKeepRatio);
4074  else
4075  pSdrView->SetOrtho(true);
4076  }
4077  else
4078  {
4079  pSdrView->SetAngleSnapEnabled(bResizeKeepRatio);
4080  if (bisResize)
4081  pSdrView->SetOrtho(bResizeKeepRatio);
4082  else
4083  pSdrView->SetOrtho(false);
4084  }
4085  }
4086 
4087  rSh.Drag( &aDocPt, rMEvt.IsShift() );
4088  m_bIsInMove = true;
4089  }
4090  else if( bIsDocReadOnly )
4091  break;
4092 
4093  if ( !bInsWin )
4094  {
4095  Point aTmp( aDocPt );
4096  aTmp += rSh.VisArea().Pos() - aOldPt;
4097  LeaveArea( aTmp );
4098  }
4099  else if(m_bIsInMove)
4100  EnterArea();
4101  return;
4102  }
4103  if ( !rSh.IsSelFrameMode() && !g_bDDINetAttr &&
4104  (IsMinMove( m_aStartPos,aPixPt ) || m_bIsInMove) &&
4105  (rSh.IsInSelect() || !rSh.TestCurrPam( aDocPt )) )
4106  {
4107  if ( pSdrView )
4108  {
4109  if ( rMEvt.IsShift() )
4110  pSdrView->SetOrtho(true);
4111  else
4112  pSdrView->SetOrtho(false);
4113  }
4114  if ( !bInsWin )
4115  {
4116  Point aTmp( aDocPt );
4117  aTmp += rSh.VisArea().Pos() - aOldPt;
4118  LeaveArea( aTmp );
4119  }
4120  else
4121  {
4122  if( !rMEvt.IsSynthetic() &&
4123  !(( MOUSE_LEFT + KEY_MOD1 ==
4124  rMEvt.GetModifier() + rMEvt.GetButtons() ) &&
4125  rSh.Is_FnDragEQBeginDrag() && !rSh.IsAddMode() ))
4126  {
4127  rSh.Drag( &aDocPt, false );
4128 
4129  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false));
4130  EnterArea();
4131  }
4132  }
4133  }
4134  g_bDDINetAttr = false;
4135  break;
4136  case 0:
4137  {
4138  if ( m_pApplyTempl )
4139  {
4140  UpdatePointer(aDocPt); // maybe a frame has to be marked here
4141  break;
4142  }
4143  // change ui if mouse is over SwPostItField
4144  // TODO: do the same thing for redlines IsAttrAtPos::Redline
4145  SwContentAtPos aContentAtPos( IsAttrAtPos::Field);
4146  if (rSh.GetContentAtPos(aDocPt, aContentAtPos, false))
4147  {
4148  const SwField* pField = aContentAtPos.aFnd.pField;
4149  if (pField->Which()== SwFieldIds::Postit)
4150  {
4151  m_rView.GetPostItMgr()->SetShadowState(reinterpret_cast<const SwPostItField*>(pField),false);
4152  }
4153  else
4154  m_rView.GetPostItMgr()->SetShadowState(nullptr,false);
4155  }
4156  else
4157  m_rView.GetPostItMgr()->SetShadowState(nullptr,false);
4158  [[fallthrough]];
4159  }
4160  case KEY_SHIFT:
4161  case KEY_MOD2:
4162  case KEY_MOD1:
4163  if ( !m_bInsDraw )
4164  {
4165  bool bTstShdwCursor = true;
4166 
4167  UpdatePointer( aDocPt, rMEvt.GetModifier() );
4168 
4169  const SwFrameFormat* pFormat = nullptr;
4170  const SwFormatINetFormat* pINet = nullptr;
4171  SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
4172  if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) )
4173  pINet = static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr);
4174 
4175  const void* pTmp = pINet;
4176 
4177  if( pINet ||
4178  nullptr != ( pTmp = pFormat = rSh.GetFormatFromAnyObj( aDocPt )))
4179  {
4180  bTstShdwCursor = false;
4181  if( pTmp == pINet )
4182  m_aSaveCallEvent.Set( pINet );
4183  else
4184  {
4185  IMapObject* pIMapObj = pFormat->GetIMapObject( aDocPt );
4186  if( pIMapObj )
4187  m_aSaveCallEvent.Set( pFormat, pIMapObj );
4188  else
4189  m_aSaveCallEvent.Set( EVENT_OBJECT_URLITEM, pFormat );
4190  }
4191 
4192  // should be over a InternetField with an
4193  // embedded macro?
4194  if( m_aSaveCallEvent != aLastCallEvent )
4195  {
4196  if( aLastCallEvent.HasEvent() )
4197  rSh.CallEvent( SvMacroItemId::OnMouseOut,
4198  aLastCallEvent, true );
4199  // 0 says that the object doesn't have any table
4200  if( !rSh.CallEvent( SvMacroItemId::OnMouseOver,
4201  m_aSaveCallEvent ))
4202  m_aSaveCallEvent.Clear();
4203  }
4204  }
4205  else if( aLastCallEvent.HasEvent() )
4206  {
4207  // cursor was on an object
4208  rSh.CallEvent( SvMacroItemId::OnMouseOut,
4209  aLastCallEvent, true );
4210  }
4211 
4212  if( bTstShdwCursor && bInsWin && !bIsDocReadOnly &&
4213  !m_bInsFrame &&
4214  !rSh.GetViewOptions()->getBrowseMode() &&
4215  rSh.GetViewOptions()->IsShadowCursor() &&
4216  !(rMEvt.GetModifier() + rMEvt.GetButtons()) &&
4217  !rSh.HasSelection() && !GetConnectMetaFile() )
4218  {
4219  SwRect aRect;
4220  sal_Int16 eOrient;
4221  SwFillMode eMode = static_cast<SwFillMode>(rSh.GetViewOptions()->GetShdwCursorFillMode());
4222  if( rSh.GetShadowCursorPos( aDocPt, eMode, aRect, eOrient ))
4223  {
4224  if( !m_pShadCursor )
4225  m_pShadCursor.reset( new SwShadowCursor( *this,
4227  if( text::HoriOrientation::RIGHT != eOrient && text::HoriOrientation::CENTER != eOrient )
4228  eOrient = text::HoriOrientation::LEFT;
4229  m_pShadCursor->SetPos( aRect.Pos(), aRect.Height(), static_cast< sal_uInt16 >(eOrient) );
4230  bDelShadCursor = false;
4231  }
4232  }
4233  }
4234  break;
4235  case MOUSE_LEFT + KEY_MOD2:
4236  if( rSh.IsBlockMode() && !rMEvt.IsSynthetic() )
4237  {
4238  rSh.Drag( &aDocPt, false );
4239  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false));
4240  EnterArea();
4241  }
4242  break;
4243  }
4244 
4245  if( bDelShadCursor && m_pShadCursor )
4246  {
4247  m_pShadCursor.reset();
4248  }
4249  m_bWasShdwCursor = false;
4250 }
4251 
4256 {
4258  {
4259  if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel()))
4260  {
4261  pWindow->MouseButtonUp(rMEvt);
4262  return;
4263  }
4264  }
4265 
4266  bool bCallBase = true;
4267 
4268  bool bCallShadowCursor = m_bWasShdwCursor;
4269  m_bWasShdwCursor = false;
4270  if( m_pShadCursor )
4271  {
4272  m_pShadCursor.reset();
4273  }
4274 
4275  m_xRowColumnSelectionStart.reset();
4276 
4277  SdrHdlKind eOldSdrMoveHdl = g_eSdrMoveHdl;
4278  g_eSdrMoveHdl = SdrHdlKind::User; // for MoveEvents - reset again
4279 
4280  // preventively reset
4281  m_rView.SetTabColFromDoc( false );
4282  m_rView.SetNumRuleNodeFromDoc(nullptr);
4283 
4284  SwWrtShell &rSh = m_rView.GetWrtShell();
4285  SET_CURR_SHELL( &rSh );
4286  SdrView *pSdrView = rSh.GetDrawView();
4287  if ( pSdrView )
4288  {
4289  // tdf34555: ortho was always reset before being used in EndSdrDrag
4290  // Now, it is reset only if not in Crop mode.
4291  if (pSdrView->GetDragMode() != SdrDragMode::Crop && !rMEvt.IsShift())
4292  pSdrView->SetOrtho(false);
4293 
4294  if ( pSdrView->MouseButtonUp( rMEvt,this ) )
4295  {
4296  rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
4297  return; // SdrView's event evaluated
4298  }
4299  }
4300  // only process MouseButtonUp when the Down went to that windows as well.
4301  if ( !m_bMBPressed )
4302  {
4303  // Undo for the watering can is already in CommandHdl
4304  // that's the way it should be!
4305 
4306  return;
4307  }
4308 
4309  Point aDocPt( PixelToLogic( rMEvt.GetPosPixel() ) );
4310 
4311  if ( g_bDDTimerStarted )
4312  {
4313  StopDDTimer( &rSh, aDocPt );
4314  m_bMBPressed = false;
4315  if ( rSh.IsSelFrameMode() )
4316  {
4317  rSh.EndDrag( &aDocPt, false );
4318  g_bFrameDrag = false;
4319  }
4320  g_bNoInterrupt = false;
4321  const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) );
4322  if ((PixelToLogic(m_aStartPos).Y() == (aDocPos.Y())) && (PixelToLogic(m_aStartPos).X() == (aDocPos.X())))//To make sure it was not moved
4323  {
4324  SdrPageView* pPV = nullptr;
4325  SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr;
4326  if (pObj)
4327  {
4328  SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat();
4330  if (!pShapeFormat)
4331  {
4332  pSdrView->UnmarkAllObj();
4333  pSdrView->MarkObj(pObj,pPV);
4334  }
4335  else
4336  {
4337  // If the fly frame is a textbox of a shape, then select the shape instead.
4338  SdrObject* pShape = pShapeFormat->FindSdrObject();
4339  pSdrView->UnmarkAllObj();
4340  pSdrView->MarkObj(pShape, pPV);
4341  }
4342  }
4343  }
4344  ReleaseMouse();
4345  return;
4346  }
4347 
4348  if( m_pAnchorMarker )
4349  {
4350  if(m_pAnchorMarker->GetHdl())
4351  {
4352  // #i121463# delete selected after drag
4353  m_pAnchorMarker->GetHdl()->SetSelected(false);
4354  }
4355 
4356  Point aPnt( m_pAnchorMarker->GetLastPos() );
4357  m_pAnchorMarker.reset();
4358  if( aPnt.X() || aPnt.Y() )
4359  rSh.FindAnchorPos( aPnt, true );
4360  }
4361  if ( m_bInsDraw && m_rView.GetDrawFuncPtr() )
4362  {
4363  if ( m_rView.GetDrawFuncPtr()->MouseButtonUp( rMEvt ) )
4364  {
4365  if (m_rView.GetDrawFuncPtr()) // could have been destroyed in MouseButtonUp
4366  {
4367  m_rView.GetDrawFuncPtr()->Deactivate();
4368 
4369  if (!m_rView.IsDrawMode())
4370  {
4371  m_rView.SetDrawFuncPtr(nullptr);
4372  SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
4373  rBind.Invalidate( SID_ATTR_SIZE );
4374  rBind.Invalidate( SID_TABLE_CELL );
4375  }
4376  }
4377 
4378  if ( rSh.IsObjSelected() )
4379  {
4380  rSh.EnterSelFrameMode();
4381  if (!m_rView.GetDrawFuncPtr())
4382  StdDrawMode( OBJ_NONE, true );
4383  }
4384  else if ( rSh.IsFrameSelected() )
4385  {
4386  rSh.EnterSelFrameMode();
4387  StopInsFrame();
4388  }
4389  else
4390  {
4391  const Point aDocPos( PixelToLogic( m_aStartPos ) );
4392  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
4393  rSh.Edit();
4394  }
4395 
4396  m_rView.AttrChangedNotify( &rSh );
4397  }
4398  else if (rMEvt.GetButtons() == MOUSE_RIGHT && rSh.IsDrawCreate())
4399  m_rView.GetDrawFuncPtr()->BreakCreate(); // abort drawing
4400 
4401  g_bNoInterrupt = false;
4402  if (IsMouseCaptured())
4403  ReleaseMouse();
4404  return;
4405  }
4406  bool bPopMode = false;
4407  switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
4408  {
4409  case MOUSE_LEFT:
4410  if ( m_bInsDraw && rSh.IsDrawCreate() )
4411  {
4412  if ( m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->MouseButtonUp(rMEvt) )
4413  {
4414  m_rView.GetDrawFuncPtr()->Deactivate();
4415  m_rView.AttrChangedNotify( &rSh );
4416  if ( rSh.IsObjSelected() )
4417  rSh.EnterSelFrameMode();
4418  if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
4419  StopInsFrame();
4420  }
4421  bCallBase = false;
4422  break;
4423  }
4424  [[fallthrough]];
4425  case MOUSE_LEFT + KEY_MOD1:
4426  case MOUSE_LEFT + KEY_MOD2:
4427  case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
4428  if ( g_bFrameDrag && rSh.IsSelFrameMode() )
4429  {
4430  if ( rMEvt.IsMod1() ) // copy and don't move.
4431  {
4432  // abort drag, use internal Copy instead
4433  tools::Rectangle aRect;
4434  rSh.GetDrawView()->TakeActionRect( aRect );
4435  if (!aRect.IsEmpty())
4436  {
4437  rSh.BreakDrag();
4438  Point aEndPt, aSttPt;
4440  {
4441  aEndPt = aRect.TopLeft();
4442  aSttPt = rSh.GetDrawView()->GetAllMarkedRect().TopLeft();
4443  }
4444  else
4445  {
4446  aEndPt = aRect.Center();
4447  aSttPt = rSh.GetDrawView()->GetAllMarkedRect().Center();
4448  }
4449  if ( aSttPt != aEndPt )
4450  {
4452  rSh.Copy(&rSh, aSttPt, aEndPt);
4454  }
4455  }
4456  else {
4457  rSh.EndDrag( &aDocPt, false );
4458  }
4459  }
4460  else
4461  {
4462  {
4463  const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat());
4464  const SvxMacro* pMacro = nullptr;
4465 
4466  SvMacroItemId nEvent = SdrHdlKind::Move == eOldSdrMoveHdl
4467  ? SvMacroItemId::SwFrmMove
4468  : SvMacroItemId::SwFrmResize;
4469 
4470  if (nullptr != pFlyFormat)
4471  pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent);
4472  if (nullptr != pMacro)
4473  {
4474  const Point aSttPt( PixelToLogic( m_aStartPos ) );
4475  m_aRszMvHdlPt = aDocPt;
4476  sal_uInt16 nPos = 0;
4477  SbxArrayRef xArgs = new SbxArray;
4478  SbxVariableRef xVar = new SbxVariable;
4479  xVar->PutString( pFlyFormat->GetName() );
4480  xArgs->Put( xVar.get(), ++nPos );
4481 
4482  if( SvMacroItemId::SwFrmResize == nEvent )
4483  {
4484  xVar = new SbxVariable;
4485  xVar->PutUShort( static_cast< sal_uInt16 >(eOldSdrMoveHdl) );
4486  xArgs->Put( xVar.get(), ++nPos );
4487  }
4488 
4489  xVar = new SbxVariable;
4490  xVar->PutLong( aDocPt.X() - aSttPt.X() );
4491  xArgs->Put( xVar.get(), ++nPos );
4492  xVar = new SbxVariable;
4493  xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
4494  xArgs->Put( xVar.get(), ++nPos );
4495 
4496  xVar = new SbxVariable;
4497  xVar->PutUShort( 1 );
4498  xArgs->Put( xVar.get(), ++nPos );
4499 
4500  ReleaseMouse();
4501 
4502  rSh.ExecMacro( *pMacro, nullptr, xArgs.get() );
4503 
4504  CaptureMouse();
4505  }
4506  }
4507  rSh.EndDrag( &aDocPt, false );
4508  }
4509  g_bFrameDrag = false;
4510  bCallBase = false;
4511  break;
4512  }
4513  bPopMode = true;
4514  [[fallthrough]];
4515  case MOUSE_LEFT + KEY_SHIFT:
4516  if (rSh.IsSelFrameMode())
4517  {
4518 
4519  rSh.EndDrag( &aDocPt, false );
4520  g_bFrameDrag = false;
4521  bCallBase = false;
4522  break;
4523  }
4524 
4525  if( g_bHoldSelection )
4526  {
4527  // the EndDrag should be called in any case
4528  g_bHoldSelection = false;
4529  rSh.EndDrag( &aDocPt, false );
4530  }
4531  else
4532  {
4533  SwContentAtPos aFieldAtPos ( IsAttrAtPos::Field );
4534  if ( !rSh.IsInSelect() && rSh.TestCurrPam( aDocPt ) &&
4535  !rSh.GetContentAtPos( aDocPt, aFieldAtPos ) )
4536  {
4537  const bool bTmpNoInterrupt = g_bNoInterrupt;
4538  g_bNoInterrupt = false;
4539  { // create only temporary move context because otherwise
4540  // the query to the content form doesn't work!!!
4541  SwMvContext aMvContext( &rSh );
4542  const Point aDocPos( PixelToLogic( m_aStartPos ) );
4543  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
4544  }
4545  g_bNoInterrupt = bTmpNoInterrupt;
4546 
4547  }
4548  else
4549  {
4550  bool bInSel = rSh.IsInSelect();
4551  rSh.EndDrag( &aDocPt, false );
4552 
4553  // Internetfield? --> call link (load doc!!)
4554  if( !bInSel )
4555  {
4556  LoadUrlFlags nFilter = LoadUrlFlags::NONE;
4557  if( KEY_MOD1 == rMEvt.GetModifier() )
4558  nFilter |= LoadUrlFlags::NewView;
4559 
4560  bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
4561  if ( !bExecHyperlinks )
4562  {
4563  SvtSecurityOptions aSecOpts;
4564  const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
4565  if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) ||
4566  ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) )
4567  bExecHyperlinks = true;
4568  }
4569 
4570  const bool bExecSmarttags = rMEvt.GetModifier() == KEY_MOD1;
4571 
4572  if(m_pApplyTempl)
4573  bExecHyperlinks = false;
4574 
4575  SwContentAtPos aContentAtPos( IsAttrAtPos::Field |
4578 
4579  if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) )
4580  {
4581  // Do it again if we're not on a field/hyperlink to update the cursor accordingly
4582  if ( IsAttrAtPos::Field != aContentAtPos.eContentAtPos
4583  && IsAttrAtPos::InetAttr != aContentAtPos.eContentAtPos )
4584  rSh.GetContentAtPos( aDocPt, aContentAtPos, true );
4585 
4586  bool bViewLocked = rSh.IsViewLocked();
4587  if( !bViewLocked && !rSh.IsReadOnlyAvailable() &&
4588  aContentAtPos.IsInProtectSect() )
4589  rSh.LockView( true );
4590 
4591  ReleaseMouse();
4592 
4593  if( IsAttrAtPos::Field == aContentAtPos.eContentAtPos )
4594  {
4595  bool bAddMode(false);
4596  // AdditionalMode if applicable
4597  if (KEY_MOD1 == rMEvt.GetModifier()
4598  && !rSh.IsAddMode())
4599  {
4600  bAddMode = true;
4601  rSh.EnterAddMode();
4602  }
4603  if ( aContentAtPos.pFndTextAttr != nullptr
4604  && aContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD )
4605  {
4606  if (!rSh.IsInSelect())
4607  {
4608  // create only temporary move context because otherwise
4609  // the query to the content form doesn't work!!!
4610  SwMvContext aMvContext( &rSh );
4611  const Point aDocPos( PixelToLogic( m_aStartPos ) );
4612  g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
4613  }
4614  else
4615  {
4616  g_bValidCursorPos = true;
4617  }
4618  }
4619  else
4620  {
4621  rSh.ClickToField( *aContentAtPos.aFnd.pField );
4622  // a bit of a mystery what this is good for?
4623  // in this case we assume it's valid since we
4624  // just selected a field
4625  g_bValidCursorPos = true;
4626  }
4627  if (bAddMode)
4628  {
4629  rSh.LeaveAddMode();
4630  }
4631  }
4632  else if ( IsAttrAtPos::SmartTag == aContentAtPos.eContentAtPos )
4633  {
4634  // execute smarttag menu
4635  if ( bExecSmarttags && SwSmartTagMgr::Get().IsSmartTagsEnabled() )
4636  m_rView.ExecSmartTagPopup( aDocPt );
4637  }
4638  else if ( IsAttrAtPos::FormControl == aContentAtPos.eContentAtPos )
4639  {
4640  OSL_ENSURE( aContentAtPos.aFnd.pFieldmark != nullptr, "where is my field ptr???");
4641  if ( aContentAtPos.aFnd.pFieldmark != nullptr)
4642  {
4643  IFieldmark *fieldBM = const_cast< IFieldmark* > ( aContentAtPos.aFnd.pFieldmark );
4644  if ( fieldBM->GetFieldname( ) == ODF_FORMCHECKBOX )
4645  {
4646  ICheckboxFieldmark& rCheckboxFm = dynamic_cast<ICheckboxFieldmark&>(*fieldBM);
4647  rCheckboxFm.SetChecked(!rCheckboxFm.IsChecked());
4648  rCheckboxFm.Invalidate();
4649  rSh.InvalidateWindows( m_rView.GetVisArea() );
4650  }
4651  }
4652  }
4653  else if ( IsAttrAtPos::InetAttr == aContentAtPos.eContentAtPos )
4654  {
4655  if ( bExecHyperlinks && aContentAtPos.aFnd.pAttr )
4656  rSh.ClickToINetAttr( *static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr), nFilter );
4657  }
4658 
4659  rSh.LockView( bViewLocked );
4660  bCallShadowCursor = false;
4661  }
4662  else
4663  {
4664  aContentAtPos = SwContentAtPos( IsAttrAtPos::Ftn );
4665  if( !rSh.GetContentAtPos( aDocPt, aContentAtPos, true ) && bExecHyperlinks )
4666  {
4667  SdrViewEvent aVEvt;
4668 
4669  if (pSdrView)
4670  pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
4671 
4672  if (pSdrView && aVEvt.eEvent == SdrEventKind::ExecuteUrl)
4673  {
4674  // hit URL field
4675  const SvxURLField *pField = aVEvt.pURLField;
4676  if (pField)
4677  {
4678  const OUString& sURL(pField->GetURL());
4679  const OUString& sTarget(pField->GetTargetFrame());
4680  ::LoadURL(rSh, sURL, nFilter, sTarget);
4681  }
4682  bCallShadowCursor = false;
4683  }
4684  else
4685  {
4686  // hit graphic
4687  ReleaseMouse();
4688  if( rSh.ClickToINetGrf( aDocPt, nFilter ))
4689  bCallShadowCursor = false;
4690  }
4691  }
4692  }
4693 
4694  if( bCallShadowCursor &&
4695  rSh.GetViewOptions()->IsShadowCursor() &&
4696  MOUSE_LEFT == (rMEvt.GetModifier() + rMEvt.GetButtons()) &&
4697  !rSh.HasSelection() &&
4698  !GetConnectMetaFile() &&
4699  rSh.VisArea().IsInside( aDocPt ))
4700  {
4701  SwUndoId nLastUndoId(SwUndoId::EMPTY);
4702  if (rSh.GetLastUndoInfo(nullptr, & nLastUndoId))
4703  {
4704  if (SwUndoId::INS_FROM_SHADOWCRSR == nLastUndoId)
4705  {
4706  rSh.Undo();
4707  }
4708  }
4709  SwFillMode eMode = static_cast<SwFillMode>(rSh.GetViewOptions()->GetShdwCursorFillMode());
4710  rSh.SetShadowCursorPos( aDocPt, eMode );
4711  }
4712  }
4713  }
4714  bCallBase = false;
4715 
4716  }
4717 
4718  // reset pushed mode in Down again if applicable
4719  if ( bPopMode && g_bModePushed )
4720  {
4721  rSh.PopMode();
4722  g_bModePushed = false;
4723  bCallBase = false;
4724  }
4725  break;
4726 
4727  default:
4728  ReleaseMouse();
4729  return;
4730  }
4731 
4732  if( m_pApplyTempl )
4733  {
4734  SelectionType eSelection = rSh.GetSelectionType();
4735  SwFormatClipboard* pFormatClipboard = m_pApplyTempl->m_pFormatClipboard;
4736  if( pFormatClipboard )//apply format paintbrush
4737  {
4738  //get some parameters
4739  SwWrtShell& rWrtShell = m_rView.GetWrtShell();
4740  SfxStyleSheetBasePool* pPool=nullptr;
4741  bool bNoCharacterFormats = false;
4742  bool bNoParagraphFormats = true;
4743  {
4744  SwDocShell* pDocSh = m_rView.GetDocShell();
4745  if(pDocSh)
4746  pPool = pDocSh->GetStyleSheetPool();
4747  if( (rMEvt.GetModifier()&KEY_MOD1) && (rMEvt.GetModifier()&KEY_SHIFT) )
4748  {
4749  bNoCharacterFormats = true;
4750  bNoParagraphFormats = false;
4751  }
4752  else if( rMEvt.GetModifier() & KEY_MOD1 )
4753  bNoParagraphFormats = false;
4754  }
4755  //execute paste
4756  pFormatClipboard->Paste( rWrtShell, pPool, bNoCharacterFormats, bNoParagraphFormats );
4757 
4758  //if the clipboard is empty after paste remove the ApplyTemplate
4759  if(!pFormatClipboard->HasContent())
4760  SetApplyTemplate(SwApplyTemplate());
4761 
4762  //tdf#38101 remove temporary highlighting
4763  m_pUserMarker.reset();
4764  }
4765  else if( m_pApplyTempl->nColor )
4766  {
4767  sal_uInt16 nId = 0;
4768  switch( m_pApplyTempl->nColor )
4769  {
4770  case SID_ATTR_CHAR_COLOR_EXT:
4771  nId = RES_CHRATR_COLOR;
4772  break;
4773  case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT:
4774  nId = RES_CHRATR_BACKGROUND;
4775  break;
4776  }
4777  if( nId && (SelectionType::Text|SelectionType::Table) & eSelection)
4778  {
4779  if( rSh.IsSelection() && !rSh.HasReadonlySel() )
4780  {
4781  m_pApplyTempl->nUndo =
4782  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4783  if (nId == RES_CHRATR_BACKGROUND)
4784  ApplyCharBackground(m_aWaterCanTextBackColor, rSh);
4785  else
4786  rSh.SetAttrItem( SvxColorItem( m_aWaterCanTextColor, nId ) );
4787  rSh.UnSetVisibleCursor();
4788  rSh.EnterStdMode();
4789  rSh.SetVisibleCursor(aDocPt);
4790  bCallBase = false;
4791  m_aTemplateTimer.Stop();
4792  }
4793  else if(rMEvt.GetClicks() == 1)
4794  {
4795  // no selection -> so turn off watering can
4796  m_aTemplateTimer.Start();
4797  }
4798  }
4799  }
4800  else
4801  {
4802  OUString aStyleName;
4803  switch ( m_pApplyTempl->eType )
4804  {
4805  case SfxStyleFamily::Para:
4807  & eSelection ) && !rSh.HasReadonlySel() )
4808  {
4809  rSh.SetTextFormatColl( m_pApplyTempl->aColl.pTextColl );
4810  m_pApplyTempl->nUndo =
4811  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4812  bCallBase = false;
4813  if ( m_pApplyTempl->aColl.pTextColl )
4814  aStyleName = m_pApplyTempl->aColl.pTextColl->GetName();
4815  }
4816  break;
4817  case SfxStyleFamily::Char:
4819  & eSelection ) && !rSh.HasReadonlySel() )
4820  {
4821  rSh.SetAttrItem( SwFormatCharFormat(m_pApplyTempl->aColl.pCharFormat) );
4822  rSh.UnSetVisibleCursor();
4823  rSh.EnterStdMode();
4824  rSh.SetVisibleCursor(aDocPt);
4825  m_pApplyTempl->nUndo =
4826  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4827  bCallBase = false;
4828  if ( m_pApplyTempl->aColl.pCharFormat )
4829  aStyleName = m_pApplyTempl->aColl.pCharFormat->GetName();
4830  }
4831  break;
4832  case SfxStyleFamily::Frame :
4833  {
4834  const SwFrameFormat* pFormat = rSh.GetFormatFromObj( aDocPt );
4835  if(dynamic_cast<const SwFlyFrameFormat*>( pFormat) )
4836  {
4837  rSh.SetFrameFormat( m_pApplyTempl->aColl.pFrameFormat, false, &aDocPt );
4838  m_pApplyTempl->nUndo =
4839  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4840  bCallBase = false;
4841  if( m_pApplyTempl->aColl.pFrameFormat )
4842  aStyleName = m_pApplyTempl->aColl.pFrameFormat->GetName();
4843  }
4844  break;
4845  }
4846  case SfxStyleFamily::Page:
4847  // no Undo with page templates
4848  rSh.ChgCurPageDesc( *m_pApplyTempl->aColl.pPageDesc );
4849  if ( m_pApplyTempl->aColl.pPageDesc )
4850  aStyleName = m_pApplyTempl->aColl.pPageDesc->GetName();
4851  m_pApplyTempl->nUndo =
4852  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4853  bCallBase = false;
4854  break;
4855  case SfxStyleFamily::Pseudo:
4856  if( !rSh.HasReadonlySel() )
4857  {
4858  rSh.SetCurNumRule( *m_pApplyTempl->aColl.pNumRule,
4859  false,
4860  m_pApplyTempl->aColl.pNumRule->GetDefaultListId() );
4861  bCallBase = false;
4862  m_pApplyTempl->nUndo =
4863  std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
4864  if( m_pApplyTempl->aColl.pNumRule )
4865  aStyleName = m_pApplyTempl->aColl.pNumRule->GetName();
4866  }
4867  break;
4868  default: break;
4869  }
4870 
4871  uno::Reference< frame::XDispatchRecorder > xRecorder =
4872  m_rView.GetViewFrame()->GetBindings().GetRecorder();
4873  if ( !aStyleName.isEmpty() && xRecorder.is() )
4874  {
4875  SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView );
4876  if ( pSfxShell )
4877  {
4878  SfxRequest aReq( m_rView.GetViewFrame(), SID_STYLE_APPLY );
4879  aReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aStyleName ) );
4880  aReq.AppendItem( SfxUInt16Item( SID_STYLE_FAMILY, static_cast<sal_uInt16>(m_pApplyTempl->eType) ) );
4881  aReq.Done();
4882  }
4883  }
4884  }
4885 
4886  }
4887  ReleaseMouse();
4888  // Only processed MouseEvents arrive here; only at these this mode can
4889  // be resetted.
4890  m_bMBPressed = false;
4891 
4892  // Make this call just to be sure. Selecting has finished surely by now.
4893  // Otherwise the timeout's timer could give problems.
4894  EnterArea();
4895  g_bNoInterrupt = false;
4896 
4897  if (bCallBase)
4898  Window::MouseButtonUp(rMEvt);
4899 
4900  if (pSdrView && rMEvt.GetClicks() == 1 && comphelper::LibreOfficeKit::isActive())
4901  {
4902  // When tiled rendering, single click on a shape text starts editing already.
4903  SdrViewEvent aViewEvent;
4904  SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aViewEvent);
4905  const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
4906  if (eHit == SdrHitKind::TextEditObj && rMarkList.GetMarkCount() == 1)
4907  {
4908  if (SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj())
4909  {
4910  EnterDrawTextMode(pObj->GetLogicRect().Center());
4911  if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr )
4912  static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init();
4913  }
4914  }
4915  }
4916 }
4917 
4922 {
4923  static bool bIdle = false;
4924  m_pApplyTempl.reset();
4925  SwWrtShell &rSh = m_rView.GetWrtShell();
4926 
4927  if(rTempl.m_pFormatClipboard)
4928  {
4929  m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
4930  m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
4931  SetPointer( PointerStyle::Fill );//@todo #i20119# maybe better a new brush pointer here in future
4932  rSh.NoEdit( false );
4933  bIdle = rSh.GetViewOptions()->IsIdle();
4934  rSh.GetViewOptions()->SetIdle( false );
4935  }
4936  else if(rTempl.nColor)
4937  {
4938  m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
4939  m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
4940  SetPointer( PointerStyle::Fill );
4941  rSh.NoEdit( false );
4942  bIdle = rSh.GetViewOptions()->IsIdle();
4943  rSh.GetViewOptions()->SetIdle( false );
4944  }
4945  else if( rTempl.eType != SfxStyleFamily::None )
4946  {
4947  m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
4948  m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
4949  SetPointer( PointerStyle::Fill );
4950  rSh.NoEdit( false );
4951  bIdle = rSh.GetViewOptions()->IsIdle();
4952  rSh.GetViewOptions()->SetIdle( false );
4953  }
4954  else
4955  {
4956  SetPointer( PointerStyle::Text );
4957  rSh.UnSetVisibleCursor();
4958 
4959  rSh.GetViewOptions()->SetIdle( bIdle );
4960  if ( !rSh.IsSelFrameMode() )
4961  rSh.Edit();
4962  }
4963 
4964  static sal_uInt16 aInva[] =
4965  {
4966  SID_STYLE_WATERCAN,
4967  SID_ATTR_CHAR_COLOR_EXT,
4968  SID_ATTR_CHAR_COLOR_BACKGROUND_EXT,
4969  0
4970  };
4971  m_rView.GetViewFrame()->GetBindings().Invalidate(aInva);
4972 }
4973 
4979  DropTargetHelper( this ),
4980  DragSourceHelper( this ),
4981 
4982  m_eBufferLanguage(LANGUAGE_DONTKNOW),
4983  m_pUserMarkerObj( nullptr ),
4984 
4985  m_rView( rMyView ),
4986 
4987  m_aActHitType(SdrHitKind::NONE),
4988  m_nDropFormat( SotClipboardFormatId::NONE ),
4989  m_nDropAction( 0 ),
4990  m_nDropDestination( SotExchangeDest::NONE ),
4991 
4992  m_eBezierMode(SID_BEZIER_INSERT),
4993  m_nInsFrameColCount( 1 ),
4994  m_eDrawMode(OBJ_NONE),
4995 
4996  m_bMBPressed(false),
4997  m_bInsDraw(false),
4998  m_bInsFrame(false),
4999  m_bIsInMove(false),
5000  m_bIsInDrag(false),
5001  m_bOldIdle(false),
5002  m_bOldIdleSet(false),
5003  m_bChainMode(false),
5004  m_bWasShdwCursor(false),
5005  m_bLockInput(false),
5006  m_bIsRowDrag(false),
5007  m_bUseInputLanguage(false),
5008  m_bObjectSelect(false),
5009  m_nKS_NUMDOWN_Count(0),
5010  m_nKS_NUMINDENTINC_Count(0),
5011  m_pFrameControlsManager(new SwFrameControlsManager(this))
5012 {
5013  set_id("writer_edit");
5016  SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
5017 
5020  // initially use the input language
5021  m_bUseInputLanguage = true;
5022 
5023  SetMapMode(MapMode(MapUnit::MapTwip));
5024 
5025  SetPointer( PointerStyle::Text );
5026  m_aTimer.SetInvokeHandler(LINK(this, SwEditWin, TimerHandler));
5027 
5029  m_aKeyInputFlushTimer.SetInvokeHandler(LINK(this, SwEditWin, KeyInputFlushHandler));
5030 
5031  // TemplatePointer for colors should be resetted without
5032  // selection after single click, but not after double-click (tdf#122442)
5033  m_aTemplateTimer.SetTimeout(GetSettings().GetMouseSettings().GetDoubleClickTime());
5034  m_aTemplateTimer.SetInvokeHandler(LINK(this, SwEditWin, TemplateTimerHdl));
5035 
5036  // temporary solution!!! Should set the font of the current
5037  // insert position at every cursor movement!
5038  if( !rMyView.GetDocShell()->IsReadOnly() )
5039  {
5040  vcl::Font aFont;
5041  SetInputContext( InputContext( aFont, InputContextFlags::Text |
5042  InputContextFlags::ExtText ) );
5043  }
5044 }
5045 
5047 {
5048  disposeOnce();
5049 }
5050 
5052 {
5053  m_pShadCursor.reset();
5054 
5057  g_bExecuteDrag = false;
5058  m_pApplyTempl.reset();
5059 
5060  m_rView.SetDrawFuncPtr(nullptr);
5061 
5062  m_pUserMarker.reset();
5063 
5064  m_pAnchorMarker.reset();
5065 
5066  m_pFrameControlsManager->dispose();
5067  m_pFrameControlsManager.reset();
5068