1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_wasm_strip.h>
22 #include <swtypes.hxx>
23 #include <hintids.hxx>
25 #include <com/sun/star/accessibility/XAccessible.hpp>
26 #include <com/sun/star/awt/PopupMenuDirection.hpp>
27 #include <com/sun/star/awt/XPopupMenu.hpp>
28 #include <com/sun/star/i18n/XBreakIterator.hpp>
29 #include <com/sun/star/i18n/ScriptType.hpp>
30 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
31 #include <com/sun/star/i18n/UnicodeScript.hpp>
32 #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
33 #include <com/sun/star/ui/ContextMenuExecuteEvent.hpp>
35 #include <comphelper/scopeguard.hxx>
36 #include <comphelper/string.hxx>
38 #include <vcl/dialoghelper.hxx>
39 #include <vcl/inputctx.hxx>
40 #include <vcl/help.hxx>
41 #include <vcl/weld.hxx>
42 #include <vcl/ptrstyle.hxx>
43 #include <svl/macitem.hxx>
44 #include <unotools/securityoptions.hxx>
45 #include <basic/sbxvar.hxx>
46 #include <svl/ctloptions.hxx>
47 #include <basic/sbx.hxx>
48 #include <svl/eitem.hxx>
49 #include <svl/stritem.hxx>
50 #include <sfx2/ipclient.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <sfx2/request.hxx>
53 #include <sfx2/bindings.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <svl/ptitem.hxx>
56 #include <editeng/sizeitem.hxx>
57 #include <editeng/langitem.hxx>
58 #include <svx/statusitem.hxx>
59 #include <svx/svdview.hxx>
60 #include <svx/svdhdl.hxx>
61 #include <svx/svdoutl.hxx>
62 #include <editeng/editeng.hxx>
63 #include <editeng/editview.hxx>
64 #include <editeng/svxacorr.hxx>
65 #include <editeng/flditem.hxx>
66 #include <editeng/colritem.hxx>
67 #include <unotools/charclass.hxx>
68 #include <unotools/datetime.hxx>
70 #include <comphelper/lok.hxx>
71 #include <sfx2/lokhelper.hxx>
73 #include <editeng/acorrcfg.hxx>
74 #include <bookmark.hxx>
75 #include <SwSmartTagMgr.hxx>
80 #include <IDocumentDrawModelAccess.hxx>
81 #include <IDocumentUndoRedo.hxx>
82 #include <textboxhelper.hxx>
83 #include <dcontact.hxx>
85 #include <swmodule.hxx>
87 #include <viewopt.hxx>
88 #include <drawbase.hxx>
89 #include <dselect.hxx>
91 #include <shdwcrsr.hxx>
92 #include <txatbase.hxx>
93 #include <fmtanchr.hxx>
94 #include <fmtornt.hxx>
95 #include <fmthdft.hxx>
100 #include <gloslst.hxx>
101 #include <inputwin.hxx>
102 #include <gloshdl.hxx>
103 #include <swundo.hxx>
104 #include <drwtxtsh.hxx>
105 #include <fchrfmt.hxx>
106 #include "romenu.hxx"
107 #include <initui.hxx>
108 #include <frmatr.hxx>
109 #include <extinput.hxx>
110 #include <acmplwrd.hxx>
111 #include <swcalwrp.hxx>
112 #include <swdtflvr.hxx>
113 #include <breakit.hxx>
114 #include <checkit.hxx>
115 #include <pagefrm.hxx>
119 #include <uitool.hxx>
120 #include <fmtfollowtextflow.hxx>
121 #include <toolkit/helper/vclunohelper.hxx>
122 #include <charfmt.hxx>
123 #include <numrule.hxx>
124 #include <pagedesc.hxx>
125 #include <svtools/ruler.hxx>
126 #include <formatclipboard.hxx>
127 #include <vcl/svapp.hxx>
128 #include <wordcountdialog.hxx>
129 #include <fmtfld.hxx>
133 #include <xmloff/odffields.hxx>
135 #include <PostItMgr.hxx>
136 #include <FrameControlsManager.hxx>
137 #include <AnnotationWin.hxx>
142 #include <rootfrm.hxx>
144 #include <unotools/syslocaleoptions.hxx>
145 #include <i18nlangtag/mslangid.hxx>
146 #include <salhelper/singletonref.hxx>
147 #include <sfx2/event.hxx>
150 #include "../../core/crsr/callnk.hxx"
151 #include <IDocumentOutlineNodes.hxx>
153 #include <cntfrm.hxx>
154 #include <txtfrm.hxx>
155 #include <strings.hrc>
156 #include <textcontentcontrol.hxx>
157 #include <contentcontrolbutton.hxx>
159 using namespace sw::mark
;
160 using namespace ::com::sun::star
;
165 static bool g_bInputLanguageSwitched
= false;
167 // Usually in MouseButtonUp a selection is revoked when the selection is
168 // not currently being pulled open. Unfortunately in MouseButtonDown there
169 // is being selected at double/triple click. That selection is completely
170 // finished in the Handler and thus can't be distinguished in the Up.
171 // To resolve this g_bHoldSelection is set in Down and evaluated in Up.
172 static bool g_bHoldSelection
= false;
174 bool g_bFrameDrag
= false;
175 static bool g_bValidCursorPos
= false;
176 bool g_bModePushed
= false;
177 bool g_bDDTimerStarted
= false;
178 bool g_bDDINetAttr
= false;
179 static SdrHdlKind g_eSdrMoveHdl
= SdrHdlKind::User
;
181 QuickHelpData
* SwEditWin::s_pQuickHlpData
= nullptr;
183 tools::Long
SwEditWin::s_nDDStartPosY
= 0;
184 tools::Long
SwEditWin::s_nDDStartPosX
= 0;
186 static SfxShell
* lcl_GetTextShellFromDispatcher( SwView
const & rView
);
188 /// Check if the selected shape has a TextBox: if so, go into that instead.
189 static bool lcl_goIntoTextBox(SwEditWin
& rEditWin
, SwWrtShell
& rSh
)
191 SdrMark
* pMark
= rSh
.GetDrawView()->GetMarkedObjectList().GetMark(0);
195 SdrObject
* pSdrObject
= pMark
->GetMarkedSdrObj();
196 SwFrameFormat
* pObjectFormat
= ::FindFrameFormat(pSdrObject
);
197 if (SwFrameFormat
* pTextBoxFormat
= SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat
, RES_DRAWFRMFMT
))
199 SdrObject
* pTextBox
= pTextBoxFormat
->FindRealSdrObject();
200 SdrView
* pSdrView
= rSh
.GetDrawView();
202 pSdrView
->UnmarkAllObj();
204 rSh
.SelectObj(Point(), SW_ALLOW_TEXTBOX
, pTextBox
);
205 // Clear the DrawFuncPtr.
206 rEditWin
.StopInsFrame();
217 bool m_bTopRightHandle
;
219 explicit SwAnchorMarker( SdrHdl
* pH
)
221 , m_aHdlPos( pH
->GetPos() )
222 , m_aLastPos( pH
->GetPos() )
223 , m_bTopRightHandle( pH
->GetKind() == SdrHdlKind::Anchor_TR
)
225 const Point
& GetLastPos() const { return m_aLastPos
; }
226 void SetLastPos( const Point
& rNew
) { m_aLastPos
= rNew
; }
227 void SetPos( const Point
& rNew
) { m_pHdl
->SetPos( rNew
); }
228 const Point
& GetHdlPos() const { return m_aHdlPos
; }
229 SdrHdl
* GetHdl() const { return m_pHdl
; }
230 void ChgHdl( SdrHdl
* pNew
)
235 m_bTopRightHandle
= (m_pHdl
->GetKind() == SdrHdlKind::Anchor_TR
);
238 Point
GetPosForHitTest( const OutputDevice
& rOut
)
240 Point
aHitTestPos( m_pHdl
->GetPos() );
241 aHitTestPos
= rOut
.LogicToPixel( aHitTestPos
);
242 if ( m_bTopRightHandle
)
244 aHitTestPos
+= Point( -1, 1 );
248 aHitTestPos
+= Point( 1, 1 );
250 aHitTestPos
= rOut
.PixelToLogic( aHitTestPos
);
256 /// Assists with auto-completion of AutoComplete words and AutoText names.
259 /// Strings that at least partially match an input word, and match length.
260 std::vector
<std::pair
<OUString
, sal_uInt16
>> m_aHelpStrings
;
261 /// Index of the current help string.
262 sal_uInt16 nCurArrPos
;
263 static constexpr sal_uInt16 nNoPos
= std::numeric_limits
<sal_uInt16
>::max();
265 /// Help data stores AutoText names rather than AutoComplete words.
267 /// Display help string as a tip rather than inline.
269 /// Tip ID when a help string is displayed as a tip.
271 /// Append a space character to the displayed help string (if appropriate).
274 /// Help string is currently displayed.
277 QuickHelpData() { ClearContent(); }
279 void Move( QuickHelpData
& rCpy
);
281 void Start(SwWrtShell
& rSh
, bool bRestart
);
282 void Stop( SwWrtShell
& rSh
);
284 bool HasContent() const { return !m_aHelpStrings
.empty() && nCurArrPos
!= nNoPos
; }
285 const OUString
& CurStr() const { return m_aHelpStrings
[nCurArrPos
].first
; }
286 sal_uInt16
CurLen() const { return m_aHelpStrings
[nCurArrPos
].second
; }
288 /// Next help string.
289 void Next( bool bEndLess
)
291 if( ++nCurArrPos
>= m_aHelpStrings
.size() )
292 nCurArrPos
= (bEndLess
&& !m_bIsAutoText
) ? 0 : nCurArrPos
-1;
294 /// Previous help string.
295 void Previous( bool bEndLess
)
297 if( 0 == nCurArrPos
-- )
298 nCurArrPos
= (bEndLess
&& !m_bIsAutoText
) ? m_aHelpStrings
.size()-1 : 0;
301 // Fills internal structures with hopefully helpful information.
302 void FillStrArr( SwWrtShell
const & rSh
, const OUString
& rWord
);
303 void SortAndFilter(const OUString
&rOrigWord
);
307 * Avoid minimal movement shiver
309 #define HIT_PIX 2 /* hit tolerance in pixel */
312 static bool IsMinMove(const Point
&rStartPos
, const Point
&rLPt
)
314 return std::abs(rStartPos
.X() - rLPt
.X()) > MIN_MOVE
||
315 std::abs(rStartPos
.Y() - rLPt
.Y()) > MIN_MOVE
;
319 * For MouseButtonDown - determine whether a DrawObject
320 * a NO SwgFrame was hit! Shift/Ctrl should only result
321 * in selecting, with DrawObjects; at SwgFlys to trigger
322 * hyperlinks if applicable (Download/NewWindow!)
324 static bool IsDrawObjSelectable( const SwWrtShell
& rSh
, const Point
& rPt
)
328 switch( rSh
.GetObjCntType( rPt
, pObj
))
336 default:; //prevent warning
344 void SwEditWin::UpdatePointer(const Point
&rLPt
, sal_uInt16 nModifier
)
346 SetQuickHelpText(OUString());
347 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
350 PointerStyle eStyle
= PointerStyle::Fill
;
351 if ( rSh
.IsOverReadOnlyPos( rLPt
) )
353 m_pUserMarker
.reset();
355 eStyle
= PointerStyle::NotAllowed
;
360 SwRect
* pRect
= &aRect
;
361 const SwFrameFormat
* pFormat
= nullptr;
363 bool bFrameIsValidTarget
= false;
364 if( m_pApplyTempl
->m_pFormatClipboard
)
365 bFrameIsValidTarget
= m_pApplyTempl
->m_pFormatClipboard
->HasContentForThisType( SelectionType::Frame
);
366 else if( !m_pApplyTempl
->nColor
)
367 bFrameIsValidTarget
= ( m_pApplyTempl
->eType
== SfxStyleFamily::Frame
);
369 if( bFrameIsValidTarget
&&
370 nullptr !=(pFormat
= rSh
.GetFormatFromObj( rLPt
, &pRect
)) &&
371 dynamic_cast<const SwFlyFrameFormat
*>( pFormat
) )
373 //turn on highlight for frame
374 tools::Rectangle
aTmp( pRect
->SVRect() );
376 if ( !m_pUserMarker
)
378 m_pUserMarker
.reset(new SdrDropMarkerOverlay( *rSh
.GetDrawView(), aTmp
));
383 m_pUserMarker
.reset();
386 rSh
.SwCursorShell::SetVisibleCursor( rLPt
);
388 SetPointer( eStyle
);
392 if( !rSh
.VisArea().Width() )
395 CurrShell
aCurr(&rSh
);
400 SwChainRet nChainable
= rSh
.Chainable( aRect
, *rSh
.GetFlyFrameFormat(), rLPt
);
401 PointerStyle eStyle
= nChainable
!= SwChainRet::OK
402 ? PointerStyle::ChainNotAllowed
: PointerStyle::Chain
;
403 if ( nChainable
== SwChainRet::OK
)
405 tools::Rectangle
aTmp( aRect
.SVRect() );
407 if ( !m_pUserMarker
)
409 m_pUserMarker
.reset(new SdrDropMarkerOverlay( *rSh
.GetDrawView(), aTmp
));
414 m_pUserMarker
.reset();
417 SetPointer( eStyle
);
421 bool bExecHyperlinks
= m_rView
.GetDocShell()->IsReadOnly();
422 if ( !bExecHyperlinks
)
424 const bool bSecureOption
= SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink
);
425 if ( ( bSecureOption
&& nModifier
== KEY_MOD1
) ||
426 ( !bSecureOption
&& nModifier
!= KEY_MOD1
) )
427 bExecHyperlinks
= true;
430 const bool bExecSmarttags
= nModifier
== KEY_MOD1
;
432 SdrView
*pSdrView
= rSh
.GetDrawView();
433 bool bPrefSdrPointer
= false;
434 bool bHitHandle
= false;
435 bool bCntAtPos
= false;
436 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly() &&
437 rSh
.IsCursorReadonly();
438 m_aActHitType
= SdrHitKind::NONE
;
439 PointerStyle eStyle
= PointerStyle::Text
;
442 else if ( (bHitHandle
= (pSdrView
->PickHandle(rLPt
) != nullptr)) )
444 m_aActHitType
= SdrHitKind::Object
;
445 bPrefSdrPointer
= true;
449 const bool bNotInSelObj
= !rSh
.IsInsideSelectedObj( rLPt
);
450 if ( m_rView
.GetDrawFuncPtr() && !m_bInsDraw
&& bNotInSelObj
)
452 m_aActHitType
= SdrHitKind::Object
;
453 if (IsObjectSelect())
454 eStyle
= PointerStyle::Arrow
;
456 bPrefSdrPointer
= true;
460 SdrPageView
* pPV
= nullptr;
461 pSdrView
->SetHitTolerancePixel( HIT_PIX
);
462 SdrObject
* pObj
= (bNotInSelObj
&& bExecHyperlinks
) ?
463 pSdrView
->PickObj(rLPt
, pSdrView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMACRO
) :
467 SdrObjMacroHitRec aTmp
;
469 aTmp
.pPageView
= pPV
;
470 SetPointer( pObj
->GetMacroPointer( aTmp
) );
475 // dvo: IsObjSelectable() eventually calls SdrView::PickObj, so
476 // apparently this is used to determine whether this is a
477 // drawling layer object or not.
478 if ( rSh
.IsObjSelectable( rLPt
) )
480 if (pSdrView
->IsTextEdit())
482 m_aActHitType
= SdrHitKind::NONE
;
483 bPrefSdrPointer
= true;
488 SdrHitKind eHit
= pSdrView
->PickAnything(rLPt
, aVEvt
);
490 if (eHit
== SdrHitKind::UrlField
&& bExecHyperlinks
)
492 m_aActHitType
= SdrHitKind::Object
;
493 bPrefSdrPointer
= true;
497 // if we're over a selected object, we show an
498 // ARROW by default. We only show a MOVE if 1) the
499 // object is selected, and 2) it may be moved
500 // (i.e., position is not protected).
503 (rSh
.IsObjSelected() || rSh
.IsFrameSelected()) &&
504 (rSh
.IsSelObjProtected(FlyProtectFlags::Pos
) == FlyProtectFlags::NONE
);
506 SdrObject
* pSelectableObj
= rSh
.GetObjAt(rLPt
);
507 // Don't update pointer if this is a background image only.
508 if (pSelectableObj
->GetLayer() != rSh
.GetDoc()->getIDocumentDrawModelAccess().GetHellId())
509 eStyle
= bMovable
? PointerStyle::Move
: PointerStyle::Arrow
;
510 m_aActHitType
= SdrHitKind::Object
;
516 if ( rSh
.IsFrameSelected() && !bNotInSelObj
)
518 // dvo: this branch appears to be dead and should be
519 // removed in a future version. Reason: The condition
520 // !bNotInSelObj means that this branch will only be
521 // executed in the cursor points inside a selected
522 // object. However, if this is the case, the previous
523 // if( rSh.IsObjSelectable(rLPt) ) must always be true:
524 // rLPt is inside a selected object, then obviously
525 // rLPt is over a selectable object.
526 if (rSh
.IsSelObjProtected(FlyProtectFlags::Size
) != FlyProtectFlags::NONE
)
527 eStyle
= PointerStyle::NotAllowed
;
529 eStyle
= PointerStyle::Move
;
530 m_aActHitType
= SdrHitKind::Object
;
534 if ( m_rView
.GetDrawFuncPtr() )
535 bPrefSdrPointer
= true;
543 if ( bPrefSdrPointer
)
545 if (bIsDocReadOnly
|| (rSh
.IsObjSelected() && rSh
.IsSelObjProtected(FlyProtectFlags::Content
) != FlyProtectFlags::NONE
))
546 SetPointer( PointerStyle::NotAllowed
);
549 if (m_rView
.GetDrawFuncPtr() && m_rView
.GetDrawFuncPtr()->IsInsertForm() && !bHitHandle
)
550 SetPointer( PointerStyle::DrawRect
);
552 SetPointer( pSdrView
->GetPreferredPointer( rLPt
, rSh
.GetOut() ) );
557 if( !rSh
.IsPageAtPos( rLPt
) || m_pAnchorMarker
)
558 eStyle
= PointerStyle::Arrow
;
561 // Even if we already have something, prefer URLs if possible.
562 SwContentAtPos
aUrlPos(IsAttrAtPos::InetAttr
);
563 if (bCntAtPos
|| rSh
.GetContentAtPos(rLPt
, aUrlPos
))
565 SwContentAtPos
aSwContentAtPos(
567 IsAttrAtPos::ClickField
|
568 IsAttrAtPos::InetAttr
|
570 IsAttrAtPos::SmartTag
);
571 if( rSh
.GetContentAtPos( rLPt
, aSwContentAtPos
) )
573 // Is edit inline input field
574 if (IsAttrAtPos::Field
== aSwContentAtPos
.eContentAtPos
575 && aSwContentAtPos
.pFndTextAttr
!= nullptr
576 && aSwContentAtPos
.pFndTextAttr
->Which() == RES_TXTATR_INPUTFIELD
)
578 const SwField
*pCursorField
= rSh
.CursorInsideInputField() ? rSh
.GetCurField( true ) : nullptr;
579 if (!(pCursorField
&& pCursorField
== aSwContentAtPos
.pFndTextAttr
->GetFormatField().GetField()))
580 eStyle
= PointerStyle::RefHand
;
584 const bool bClickToFollow
= IsAttrAtPos::InetAttr
== aSwContentAtPos
.eContentAtPos
||
585 IsAttrAtPos::SmartTag
== aSwContentAtPos
.eContentAtPos
;
586 if( !bClickToFollow
||
587 (IsAttrAtPos::InetAttr
== aSwContentAtPos
.eContentAtPos
&& bExecHyperlinks
) ||
588 (IsAttrAtPos::SmartTag
== aSwContentAtPos
.eContentAtPos
&& bExecSmarttags
) )
589 eStyle
= PointerStyle::RefHand
;
592 else if (GetView().GetWrtShell().GetViewOptions()->IsShowOutlineContentVisibilityButton())
594 aSwContentAtPos
.eContentAtPos
= IsAttrAtPos::Outline
;
595 if (rSh
.GetContentAtPos(rLPt
, aSwContentAtPos
))
597 if (IsAttrAtPos::Outline
== aSwContentAtPos
.eContentAtPos
)
599 if (nModifier
== KEY_MOD1
)
601 eStyle
= PointerStyle::RefHand
;
603 if(aSwContentAtPos
.aFnd
.pNode
&& aSwContentAtPos
.aFnd
.pNode
->IsTextNode())
605 const SwNodes
& rNds
= GetView().GetWrtShell().GetDoc()->GetNodes();
606 SwOutlineNodes::size_type nPos
;
607 rNds
.GetOutLineNds().Seek_Entry(aSwContentAtPos
.aFnd
.pNode
->GetTextNode(), &nPos
);
608 SwOutlineNodes::size_type nOutlineNodesCount
609 = rSh
.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
610 int nLevel
= rSh
.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos
);
611 OUString
sQuickHelp(SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY
));
612 if (!rSh
.GetViewOptions()->IsTreatSubOutlineLevelsAsContent()
613 && nPos
+ 1 < nOutlineNodesCount
614 && rSh
.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos
+ 1) > nLevel
)
615 sQuickHelp
+= " (" + SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT
) + ")";
616 SetQuickHelpText(sQuickHelp
);
625 // which kind of text pointer have we to show - horz / vert - ?
626 if( PointerStyle::Text
== eStyle
&& rSh
.IsInVerticalText( &rLPt
))
627 eStyle
= PointerStyle::TextVertical
;
628 else if (rSh
.GetViewOptions()->CanHideWhitespace() &&
629 rSh
.GetLayout()->IsBetweenPages(rLPt
))
631 if (rSh
.GetViewOptions()->IsHideWhitespaceMode())
632 eStyle
= PointerStyle::ShowWhitespace
;
634 eStyle
= PointerStyle::HideWhitespace
;
637 SetPointer( eStyle
);
642 * Increase timer for selection
644 IMPL_LINK_NOARG(SwEditWin
, TimerHandler
, Timer
*, void)
646 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
647 Point
aModPt( m_aMovePos
);
648 const SwRect
aOldVis( rSh
.VisArea() );
651 if ( !rSh
.VisArea().Contains( aModPt
) )
655 const int nMaxScroll
= 40;
656 m_rView
.Scroll( tools::Rectangle(aModPt
,Size(1,1)), nMaxScroll
, nMaxScroll
);
659 else if ( g_bFrameDrag
)
661 rSh
.Drag(&aModPt
, false);
665 aModPt
= rSh
.GetContentPos( aModPt
,aModPt
.Y() > rSh
.VisArea().Bottom() );
667 if ( !bDone
&& !(g_bFrameDrag
|| m_bInsDraw
) )
669 if ( m_xRowColumnSelectionStart
)
671 Point
aPos( aModPt
);
672 rSh
.SelectTableRowCol( *m_xRowColumnSelectionStart
, &aPos
, m_bIsRowDrag
);
675 rSh
.CallSetCursor( &aModPt
, false );
677 // It can be that a "jump" over a table cannot be accomplished like
678 // that. So we jump over the table by Up/Down here.
679 const SwRect
& rVisArea
= rSh
.VisArea();
680 if( aOldVis
== rVisArea
&& !rSh
.IsStartOfDoc() && !rSh
.IsEndOfDoc() )
682 // take the center point of VisArea to
683 // decide in which direction the user want.
684 if( aModPt
.Y() < ( rVisArea
.Top() + rVisArea
.Height() / 2 ) )
691 m_aMovePos
+= rSh
.VisArea().Pos() - aOldVis
.Pos();
695 void SwEditWin::JustifyAreaTimer()
697 const tools::Rectangle
&rVisArea
= GetView().GetVisArea();
699 const tools::Long coMinLen
= 100;
701 const tools::Long coMinLen
= 50;
703 tools::Long
const nTimeout
= 800,
705 std::max( m_aMovePos
.Y() - rVisArea
.Bottom(), rVisArea
.Top() - m_aMovePos
.Y() ),
706 std::max( m_aMovePos
.X() - rVisArea
.Right(), rVisArea
.Left() - m_aMovePos
.X()));
707 m_aTimer
.SetTimeout( std::max( coMinLen
, nTimeout
- nDiff
*2L) );
710 void SwEditWin::LeaveArea(const Point
&rPos
)
714 if( !m_aTimer
.IsActive() )
716 m_pShadCursor
.reset();
719 inline void SwEditWin::EnterArea()
725 * Insert mode for frames
727 void SwEditWin::InsFrame(sal_uInt16 nCols
)
729 StdDrawMode(SdrObjKind::NewFrame
, false);
731 m_nInsFrameColCount
= nCols
;
734 void SwEditWin::StdDrawMode( SdrObjKind eSdrObjectKind
, bool bObjSelect
)
736 SetSdrDrawMode( eSdrObjectKind
);
739 m_rView
.SetDrawFuncPtr(std::make_unique
<DrawSelection
>( &m_rView
.GetWrtShell(), this, &m_rView
));
741 m_rView
.SetDrawFuncPtr(std::make_unique
<SwDrawBase
>( &m_rView
.GetWrtShell(), this, &m_rView
));
743 m_rView
.SetSelDrawSlot();
744 SetSdrDrawMode( eSdrObjectKind
);
746 m_rView
.GetDrawFuncPtr()->Activate( SID_OBJECT_SELECT
);
748 m_rView
.GetDrawFuncPtr()->Activate( sal::static_int_cast
< sal_uInt16
>(eSdrObjectKind
) );
750 m_nInsFrameColCount
= 1;
753 void SwEditWin::StopInsFrame()
755 if (m_rView
.GetDrawFuncPtr())
757 m_rView
.GetDrawFuncPtr()->Deactivate();
758 m_rView
.SetDrawFuncPtr(nullptr);
760 m_rView
.LeaveDrawCreate(); // leave construction mode
762 m_nInsFrameColCount
= 1;
765 bool SwEditWin::IsInputSequenceCheckingRequired( const OUString
&rText
, const SwPaM
& rCursor
)
767 if ( !SvtCTLOptions::IsCTLFontEnabled() ||
768 !SvtCTLOptions::IsCTLSequenceChecking() )
771 if ( 0 == rCursor
.Start()->GetContentIndex() ) /* first char needs not to be checked */
774 SwBreakIt
*pBreakIter
= SwBreakIt::Get();
775 uno::Reference
< i18n::XBreakIterator
> xBI
= pBreakIter
->GetBreakIter();
777 tools::Long nCTLScriptPos
= -1;
779 if (xBI
->getScriptType( rText
, 0 ) == i18n::ScriptType::COMPLEX
)
782 nCTLScriptPos
= xBI
->nextScript( rText
, 0, i18n::ScriptType::COMPLEX
);
784 return (0 <= nCTLScriptPos
&& nCTLScriptPos
<= rText
.getLength());
787 //return INVALID_HINT if language should not be explicitly overridden, the correct
788 //HintId to use for the eBufferLanguage otherwise
789 static sal_uInt16
lcl_isNonDefaultLanguage(LanguageType eBufferLanguage
, SwView
const & rView
,
790 const OUString
&rInBuffer
)
792 sal_uInt16 nWhich
= INVALID_HINT
;
794 //If the option to IgnoreLanguageChange is set, short-circuit this method
795 //which results in the document/paragraph language remaining the same
796 //despite a change to the keyboard/input language
797 SvtSysLocaleOptions aSysLocaleOptions
;
798 if(aSysLocaleOptions
.IsIgnoreLanguageChange())
804 if(eBufferLanguage
!= LANGUAGE_DONTKNOW
)
806 switch( SvtLanguageOptions::GetI18NScriptTypeOfLanguage( eBufferLanguage
))
808 case i18n::ScriptType::ASIAN
: nWhich
= RES_CHRATR_CJK_LANGUAGE
; break;
809 case i18n::ScriptType::COMPLEX
: nWhich
= RES_CHRATR_CTL_LANGUAGE
; break;
810 case i18n::ScriptType::LATIN
: nWhich
= RES_CHRATR_LANGUAGE
; break;
811 default: bLang
= false;
815 SfxItemSet
aLangSet(rView
.GetPool(), nWhich
, nWhich
);
816 SwWrtShell
& rSh
= rView
.GetWrtShell();
817 rSh
.GetCurAttr(aLangSet
);
818 if(SfxItemState::DEFAULT
<= aLangSet
.GetItemState(nWhich
))
820 LanguageType eLang
= static_cast<const SvxLanguageItem
&>(aLangSet
.Get(nWhich
)).GetLanguage();
821 if ( eLang
== eBufferLanguage
)
823 // current language attribute equal to language reported from system
826 else if ( !g_bInputLanguageSwitched
&& RES_CHRATR_LANGUAGE
== nWhich
)
828 // special case: switching between two "LATIN" languages
829 // In case the current keyboard setting might be suitable
830 // for both languages we can't safely assume that the user
831 // wants to use the language reported from the system,
832 // except if we knew that it was explicitly switched (thus
833 // the check for "bInputLangeSwitched").
835 // The language reported by the system could be just the
836 // system default language that the user is not even aware
837 // of, because no language selection tool is installed at
838 // all. In this case the OOo language should get preference
839 // as it might have been selected by the user explicitly.
841 // Usually this case happens if the OOo language is
842 // different to the system language but the system keyboard
843 // is still suitable for the OOo language (e.g. writing
844 // English texts with a German keyboard).
846 // For non-latin keyboards overwriting the attribute is
847 // still valid. We do this for cyrillic and greek ATM. In
848 // future versions of OOo this should be replaced by a
849 // configuration switch that allows to give the preference
850 // to the OOo setting or the system setting explicitly
851 // and/or a better handling of the script type.
852 i18n::UnicodeScript eType
= !rInBuffer
.isEmpty() ?
853 GetAppCharClass().getScript( rInBuffer
, 0 ) :
854 i18n::UnicodeScript_kScriptCount
;
856 bool bSystemIsNonLatin
= false;
859 case i18n::UnicodeScript_kGreek
:
860 case i18n::UnicodeScript_kCyrillic
:
861 // in case other UnicodeScripts require special
862 // keyboards they can be added here
863 bSystemIsNonLatin
= true;
869 bool bOOoLangIsNonLatin
= MsLangId::isNonLatinWestern( eLang
);
871 bLang
= (bSystemIsNonLatin
!= bOOoLangIsNonLatin
);
876 return bLang
? nWhich
: INVALID_HINT
;
880 * Character buffer is inserted into the document
882 void SwEditWin::FlushInBuffer()
884 if ( m_aKeyInputFlushTimer
.IsActive())
885 m_aKeyInputFlushTimer
.Stop();
887 if ( m_aInBuffer
.isEmpty() )
890 SwWrtShell
& rSh
= m_rView
.GetWrtShell();
892 // generate new sequence input checker if not already done
894 pCheckIt
= new SwCheckIt
;
896 uno::Reference
< i18n::XExtendedInputSequenceChecker
> xISC
= pCheckIt
->xCheck
;
897 if ( xISC
.is() && IsInputSequenceCheckingRequired( m_aInBuffer
, *rSh
.GetCursor() ) )
900 // apply (Thai) input sequence checking/correction
902 rSh
.Push(); // push current cursor to stack
904 // get text from the beginning (i.e left side) of current selection
905 // to the start of the paragraph
906 rSh
.NormalizePam(); // make point be the first (left) one
907 if (!rSh
.GetCursor()->HasMark())
908 rSh
.GetCursor()->SetMark();
909 rSh
.GetCursor()->GetMark()->SetContent(0);
911 const OUString
aOldText( rSh
.GetCursor()->GetText() );
912 const sal_Int32 nOldLen
= aOldText
.getLength();
914 sal_Int32 nExpandSelection
= 0;
917 sal_Int32 nTmpPos
= nOldLen
;
918 sal_Int16 nCheckMode
= SvtCTLOptions::IsCTLSequenceCheckingRestricted() ?
919 i18n::InputSequenceCheckMode::STRICT
: i18n::InputSequenceCheckMode::BASIC
;
921 OUString
aNewText( aOldText
);
922 if (SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace())
924 for( sal_Int32 k
= 0; k
< m_aInBuffer
.getLength(); ++k
)
926 const sal_Unicode cChar
= m_aInBuffer
[k
];
927 const sal_Int32 nPrevPos
=xISC
->correctInputSequence( aNewText
, nTmpPos
- 1, cChar
, nCheckMode
);
929 // valid sequence or sequence could be corrected:
930 if (nPrevPos
!= aNewText
.getLength())
931 nTmpPos
= nPrevPos
+ 1;
934 // find position of first character that has changed
935 sal_Int32 nNewLen
= aNewText
.getLength();
936 const sal_Unicode
*pOldText
= aOldText
.getStr();
937 const sal_Unicode
*pNewText
= aNewText
.getStr();
938 sal_Int32 nChgPos
= 0;
939 while ( nChgPos
< nOldLen
&& nChgPos
< nNewLen
&&
940 pOldText
[nChgPos
] == pNewText
[nChgPos
] )
943 const sal_Int32 nChgLen
= nNewLen
- nChgPos
;
946 m_aInBuffer
= aNewText
.copy( nChgPos
, nChgLen
);
947 nExpandSelection
= nOldLen
- nChgPos
;
954 for( sal_Int32 k
= 0; k
< m_aInBuffer
.getLength(); ++k
)
956 const sal_Unicode cChar
= m_aInBuffer
[k
];
957 if (xISC
->checkInputSequence( aNewText
, nTmpPos
- 1, cChar
, nCheckMode
))
959 // character can be inserted:
960 aNewText
+= OUStringChar( cChar
);
964 m_aInBuffer
= aNewText
.copy( aOldText
.getLength() ); // copy new text to be inserted to buffer
968 // at this point now we will insert the buffer text 'normally' some lines below...
970 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
972 if (m_aInBuffer
.isEmpty())
975 // if text prior to the original selection needs to be changed
976 // as well, we now expand the selection accordingly.
977 SwPaM
&rCursor
= *rSh
.GetCursor();
978 const sal_Int32 nCursorStartPos
= rCursor
.Start()->GetContentIndex();
979 OSL_ENSURE( nCursorStartPos
>= nExpandSelection
, "cannot expand selection as specified!!" );
980 if (nExpandSelection
&& nCursorStartPos
>= nExpandSelection
)
982 if (!rCursor
.HasMark())
984 rCursor
.Start()->AdjustContent( -nExpandSelection
);
988 uno::Reference
< frame::XDispatchRecorder
> xRecorder
=
989 m_rView
.GetViewFrame().GetBindings().GetRecorder();
990 if ( xRecorder
.is() )
993 SfxShell
*pSfxShell
= lcl_GetTextShellFromDispatcher( m_rView
);
994 // generate request and record
997 SfxRequest
aReq(m_rView
.GetViewFrame(), FN_INSERT_STRING
);
998 aReq
.AppendItem( SfxStringItem( FN_INSERT_STRING
, m_aInBuffer
) );
1003 sal_uInt16 nWhich
= lcl_isNonDefaultLanguage(m_eBufferLanguage
, m_rView
, m_aInBuffer
);
1004 if (nWhich
!= INVALID_HINT
)
1006 SvxLanguageItem
aLangItem( m_eBufferLanguage
, nWhich
);
1007 rSh
.SetAttrItem( aLangItem
);
1010 rSh
.Insert( m_aInBuffer
);
1011 m_eBufferLanguage
= LANGUAGE_DONTKNOW
;
1012 m_aInBuffer
.clear();
1015 #define MOVE_LEFT_SMALL 0
1016 #define MOVE_UP_SMALL 1
1017 #define MOVE_RIGHT_BIG 2
1018 #define MOVE_DOWN_BIG 3
1019 #define MOVE_LEFT_BIG 4
1020 #define MOVE_UP_BIG 5
1021 #define MOVE_RIGHT_SMALL 6
1022 #define MOVE_DOWN_SMALL 7
1024 // #i121236# Support for shift key in writer
1025 #define MOVE_LEFT_HUGE 8
1026 #define MOVE_UP_HUGE 9
1027 #define MOVE_RIGHT_HUGE 10
1028 #define MOVE_DOWN_HUGE 11
1030 void SwEditWin::ChangeFly( sal_uInt8 nDir
, bool bWeb
)
1032 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
1033 SwRect aTmp
= rSh
.GetFlyRect();
1034 if( !aTmp
.HasArea() ||
1035 rSh
.IsSelObjProtected( FlyProtectFlags::Pos
) != FlyProtectFlags::NONE
)
1039 RES_FRM_SIZE
, RES_FRM_SIZE
,
1040 RES_PROTECT
, RES_PROTECT
,
1041 RES_VERT_ORIENT
, RES_ANCHOR
,
1043 RES_FOLLOW_TEXT_FLOW
, RES_FOLLOW_TEXT_FLOW
>
1044 aSet( rSh
.GetAttrPool() );
1045 rSh
.GetFlyFrameAttr( aSet
);
1046 RndStdIds eAnchorId
= aSet
.Get(RES_ANCHOR
).GetAnchorId();
1048 bool bHuge(MOVE_LEFT_HUGE
== nDir
||
1049 MOVE_UP_HUGE
== nDir
||
1050 MOVE_RIGHT_HUGE
== nDir
||
1051 MOVE_DOWN_HUGE
== nDir
);
1053 if(MOVE_LEFT_SMALL
== nDir
||
1054 MOVE_UP_SMALL
== nDir
||
1055 MOVE_RIGHT_SMALL
== nDir
||
1056 MOVE_DOWN_SMALL
== nDir
)
1058 aSnap
= PixelToLogic(Size(1,1));
1062 aSnap
= rSh
.GetViewOptions()->GetSnapSize();
1063 short nDiv
= rSh
.GetViewOptions()->GetDivisionX();
1065 aSnap
.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong
>(aSnap
.Width()) / nDiv
) );
1066 nDiv
= rSh
.GetViewOptions()->GetDivisionY();
1068 aSnap
.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong
>(aSnap
.Height()) / nDiv
) );
1073 // #i121236# 567twips == 1cm, but just take three times the normal snap
1074 aSnap
= Size(aSnap
.Width() * 3, aSnap
.Height() * 3);
1079 // adjustment for allowing vertical position
1080 // aligned to page for fly frame anchored to paragraph or to character.
1082 const SwFormatVertOrient
& aVert( aSet
.Get(RES_VERT_ORIENT
) );
1083 const bool bFollowTextFlow
=
1084 aSet
.Get(RES_FOLLOW_TEXT_FLOW
).GetValue();
1085 const SwFormatAnchor
& rFormatAnchor
= aSet
.Get(RES_ANCHOR
);
1086 rSh
.CalcBoundRect( aBoundRect
, eAnchorId
,
1087 text::RelOrientation::FRAME
, aVert
.GetRelationOrient(),
1088 &rFormatAnchor
, bFollowTextFlow
,
1089 false, &aRefPoint
);
1091 tools::Long nLeft
= std::min( aTmp
.Left() - aBoundRect
.Left(), aSnap
.Width() );
1092 tools::Long nRight
= std::min( aBoundRect
.Right() - aTmp
.Right(), aSnap
.Width() );
1093 tools::Long nUp
= std::min( aTmp
.Top() - aBoundRect
.Top(), aSnap
.Height() );
1094 tools::Long nDown
= std::min( aBoundRect
.Bottom() - aTmp
.Bottom(), aSnap
.Height() );
1099 case MOVE_LEFT_HUGE
:
1100 case MOVE_LEFT_SMALL
: aTmp
.Left( aTmp
.Left() - nLeft
);
1105 case MOVE_UP_SMALL
: aTmp
.Top( aTmp
.Top() - nUp
);
1108 case MOVE_RIGHT_SMALL
:
1109 if( aTmp
.Width() < aSnap
.Width() + MINFLY
)
1111 nRight
= aSnap
.Width();
1113 case MOVE_RIGHT_HUGE
:
1114 case MOVE_RIGHT_BIG
: aTmp
.Left( aTmp
.Left() + nRight
);
1117 case MOVE_DOWN_SMALL
:
1118 if( aTmp
.Height() < aSnap
.Height() + MINFLY
)
1120 nDown
= aSnap
.Height();
1122 case MOVE_DOWN_HUGE
:
1123 case MOVE_DOWN_BIG
: aTmp
.Top( aTmp
.Top() + nDown
);
1126 default: OSL_ENSURE(true, "ChangeFly: Unknown direction." );
1129 if ((RndStdIds::FLY_AS_CHAR
== eAnchorId
) && ( nDir
% 2 ))
1131 tools::Long aDiff
= aTmp
.Top() - aRefPoint
.Y();
1134 else if ( aDiff
< -aTmp
.Height() )
1135 aDiff
= -aTmp
.Height();
1136 SwFormatVertOrient
aVert( aSet
.Get(RES_VERT_ORIENT
) );
1140 eNew
= aVert
.GetVertOrient();
1141 bool bDown
= 0 != ( nDir
& 0x02 );
1144 case text::VertOrientation::CHAR_TOP
:
1145 if( bDown
) eNew
= text::VertOrientation::CENTER
;
1147 case text::VertOrientation::CENTER
:
1148 eNew
= bDown
? text::VertOrientation::TOP
: text::VertOrientation::CHAR_TOP
;
1150 case text::VertOrientation::TOP
:
1151 if( !bDown
) eNew
= text::VertOrientation::CENTER
;
1153 case text::VertOrientation::LINE_TOP
:
1154 if( bDown
) eNew
= text::VertOrientation::LINE_CENTER
;
1156 case text::VertOrientation::LINE_CENTER
:
1157 eNew
= bDown
? text::VertOrientation::LINE_BOTTOM
: text::VertOrientation::LINE_TOP
;
1159 case text::VertOrientation::LINE_BOTTOM
:
1160 if( !bDown
) eNew
= text::VertOrientation::LINE_CENTER
;
1162 default:; //prevent warning
1167 aVert
.SetPos( aDiff
);
1168 eNew
= text::VertOrientation::NONE
;
1170 aVert
.SetVertOrient( eNew
);
1174 if (bWeb
&& (RndStdIds::FLY_AT_PARA
== eAnchorId
)
1175 && ( nDir
==MOVE_LEFT_SMALL
|| nDir
==MOVE_RIGHT_BIG
))
1177 SwFormatHoriOrient
aHori( aSet
.Get(RES_HORI_ORIENT
) );
1179 eNew
= aHori
.GetHoriOrient();
1182 case text::HoriOrientation::RIGHT
:
1183 if( nDir
==MOVE_LEFT_SMALL
)
1184 eNew
= text::HoriOrientation::LEFT
;
1186 case text::HoriOrientation::LEFT
:
1187 if( nDir
==MOVE_RIGHT_BIG
)
1188 eNew
= text::HoriOrientation::RIGHT
;
1190 default:; //prevent warning
1192 if( eNew
!= aHori
.GetHoriOrient() )
1194 aHori
.SetHoriOrient( eNew
);
1199 rSh
.StartAllAction();
1201 rSh
.SetFlyFrameAttr( aSet
);
1202 bool bSetPos
= (RndStdIds::FLY_AS_CHAR
!= eAnchorId
);
1205 bSetPos
= RndStdIds::FLY_AT_PAGE
== eAnchorId
;
1208 rSh
.SetFlyPos( aTmp
.Pos() );
1213 void SwEditWin::ChangeDrawing( sal_uInt8 nDir
)
1215 // start undo action in order to get only one
1216 // undo action for this change.
1217 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
1222 const bool bOnePixel(
1223 MOVE_LEFT_SMALL
== nDir
||
1224 MOVE_UP_SMALL
== nDir
||
1225 MOVE_RIGHT_SMALL
== nDir
||
1226 MOVE_DOWN_SMALL
== nDir
);
1228 MOVE_LEFT_HUGE
== nDir
||
1229 MOVE_UP_HUGE
== nDir
||
1230 MOVE_RIGHT_HUGE
== nDir
||
1231 MOVE_DOWN_HUGE
== nDir
);
1232 SwMove nAnchorDir
= SwMove::UP
;
1235 case MOVE_LEFT_SMALL
:
1236 case MOVE_LEFT_HUGE
:
1239 nAnchorDir
= SwMove::LEFT
;
1246 case MOVE_RIGHT_SMALL
:
1247 case MOVE_RIGHT_HUGE
:
1248 case MOVE_RIGHT_BIG
:
1250 nAnchorDir
= SwMove::RIGHT
;
1252 case MOVE_DOWN_SMALL
:
1253 case MOVE_DOWN_HUGE
:
1256 nAnchorDir
= SwMove::DOWN
;
1260 if(0 != nX
|| 0 != nY
)
1262 FlyProtectFlags nProtect
= rSh
.IsSelObjProtected( FlyProtectFlags::Pos
|FlyProtectFlags::Size
);
1263 Size
aSnap( rSh
.GetViewOptions()->GetSnapSize() );
1264 short nDiv
= rSh
.GetViewOptions()->GetDivisionX();
1266 aSnap
.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong
>(aSnap
.Width()) / nDiv
) );
1267 nDiv
= rSh
.GetViewOptions()->GetDivisionY();
1269 aSnap
.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong
>(aSnap
.Height()) / nDiv
) );
1273 aSnap
= PixelToLogic(Size(1,1));
1277 // #i121236# 567twips == 1cm, but just take three times the normal snap
1278 aSnap
= Size(aSnap
.Width() * 3, aSnap
.Height() * 3);
1281 nX
*= aSnap
.Width();
1282 nY
*= aSnap
.Height();
1284 SdrView
*pSdrView
= rSh
.GetDrawView();
1285 const SdrHdlList
& rHdlList
= pSdrView
->GetHdlList();
1286 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
1287 rSh
.StartAllAction();
1290 // now move the selected draw objects
1291 // if the object's position is not protected
1292 if(!(nProtect
&FlyProtectFlags::Pos
))
1294 // Check if object is anchored as character and move direction
1295 bool bDummy1
, bDummy2
;
1296 const bool bVertAnchor
= rSh
.IsFrameVertical( true, bDummy1
, bDummy2
);
1297 bool bHoriMove
= !bVertAnchor
== !( nDir
% 2 );
1299 !bHoriMove
|| (rSh
.GetAnchorId() != RndStdIds::FLY_AS_CHAR
);
1302 pSdrView
->MoveAllMarked(Size(nX
, nY
));
1309 // move handle with index nHandleIndex
1312 if( SdrHdlKind::Anchor
== pHdl
->GetKind() ||
1313 SdrHdlKind::Anchor_TR
== pHdl
->GetKind() )
1315 // anchor move cannot be allowed when position is protected
1316 if(!(nProtect
&FlyProtectFlags::Pos
))
1317 rSh
.MoveAnchor( nAnchorDir
);
1319 //now resize if size is protected
1320 else if(!(nProtect
&FlyProtectFlags::Size
))
1322 // now move the Handle (nX, nY)
1323 Point
aStartPoint(pHdl
->GetPos());
1324 Point
aEndPoint(pHdl
->GetPos() + Point(nX
, nY
));
1325 const SdrDragStat
& rDragStat
= pSdrView
->GetDragStat();
1328 pSdrView
->BegDragObj(aStartPoint
, nullptr, pHdl
, 0);
1330 if(pSdrView
->IsDragObj())
1332 bool bWasNoSnap
= rDragStat
.IsNoSnap();
1333 bool bWasSnapEnabled
= pSdrView
->IsSnapEnabled();
1335 // switch snapping off
1337 const_cast<SdrDragStat
&>(rDragStat
).SetNoSnap();
1339 pSdrView
->SetSnapEnabled(false);
1341 pSdrView
->MovAction(aEndPoint
);
1342 pSdrView
->EndDragObj();
1347 const_cast<SdrDragStat
&>(rDragStat
).SetNoSnap(bWasNoSnap
);
1349 pSdrView
->SetSnapEnabled(bWasSnapEnabled
);
1363 void SwEditWin::KeyInput(const KeyEvent
&rKEvt
)
1365 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
1367 if (comphelper::LibreOfficeKit::isActive() && m_rView
.GetPostItMgr())
1369 if (vcl::Window
* pWindow
= m_rView
.GetPostItMgr()->GetActiveSidebarWin())
1371 pWindow
->KeyInput(rKEvt
);
1376 if( rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
&&
1377 m_pApplyTempl
&& m_pApplyTempl
->m_pFormatClipboard
)
1379 m_pApplyTempl
->m_pFormatClipboard
->Erase();
1380 SetApplyTemplate(SwApplyTemplate());
1381 m_rView
.GetViewFrame().GetBindings().Invalidate(SID_FORMATPAINTBRUSH
);
1383 else if ( rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
&&
1384 rSh
.IsHeaderFooterEdit( ) )
1386 bool bHeader
= bool(FrameTypeFlags::HEADER
& rSh
.GetFrameType(nullptr,false));
1391 rSh
.ToggleHeaderFooterEdit();
1394 SfxObjectShell
*pObjSh
= m_rView
.GetViewFrame().GetObjectShell();
1395 if ( m_bLockInput
|| (pObjSh
&& pObjSh
->GetProgress()) )
1396 // When the progress bar is active or a progress is
1397 // running on a document, no order is being taken
1400 m_pShadCursor
.reset();
1401 // Do not reset the timer here, otherwise when flooded with events it would never time out
1402 // if every key event stopped and started it again.
1403 comphelper::ScopeGuard
keyInputFlushTimerStop([this]() { m_aKeyInputFlushTimer
.Stop(); });
1405 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly() &&
1406 rSh
.IsCursorReadonly();
1408 //if the language changes the buffer must be flushed
1409 LanguageType eNewLanguage
= GetInputLanguage();
1410 if(!bIsDocReadOnly
&& m_eBufferLanguage
!= eNewLanguage
&& !m_aInBuffer
.isEmpty())
1414 m_eBufferLanguage
= eNewLanguage
;
1416 QuickHelpData aTmpQHD
;
1417 if( s_pQuickHlpData
->m_bIsDisplayed
)
1419 aTmpQHD
.Move( *s_pQuickHlpData
);
1420 s_pQuickHlpData
->Stop( rSh
);
1423 // OS:the DrawView also needs a readonly-Flag as well
1424 if ( !bIsDocReadOnly
&& rSh
.GetDrawView() && rSh
.GetDrawView()->KeyInput( rKEvt
, this ) )
1426 rSh
.GetView().GetViewFrame().GetBindings().InvalidateAll( false );
1428 return; // Event evaluated by SdrView
1431 if ( m_rView
.GetDrawFuncPtr() && m_bInsFrame
)
1437 bool bFlushBuffer
= false;
1438 bool bNormalChar
= false;
1439 bool bAppendSpace
= s_pQuickHlpData
->m_bAppendSpace
;
1440 s_pQuickHlpData
->m_bAppendSpace
= false;
1442 if ( getenv("SW_DEBUG") && rKEvt
.GetKeyCode().GetCode() == KEY_F12
)
1444 if( rKEvt
.GetKeyCode().IsShift())
1446 GetView().GetDocShell()->GetDoc()->dumpAsXml();
1451 SwRootFrame
* pLayout
= GetView().GetDocShell()->GetWrtShell()->GetLayout();
1452 pLayout
->dumpAsXml( );
1457 KeyEvent
aKeyEvent( rKEvt
);
1458 // look for vertical mappings
1459 if( !bIsDocReadOnly
&& !rSh
.IsSelFrameMode() && !rSh
.IsObjSelected() )
1461 sal_uInt16 nKey
= rKEvt
.GetKeyCode().GetCode();
1463 if( KEY_UP
== nKey
|| KEY_DOWN
== nKey
||
1464 KEY_LEFT
== nKey
|| KEY_RIGHT
== nKey
)
1466 // In general, we want to map the direction keys if we are inside
1467 // some vertical formatted text.
1468 // 1. Exception: For a table cursor in a horizontal table, the
1469 // directions should never be mapped.
1470 // 2. Exception: For a table cursor in a vertical table, the
1471 // directions should always be mapped.
1472 const bool bVertText
= rSh
.IsInVerticalText();
1473 const bool bTableCursor
= rSh
.GetTableCursor();
1474 const bool bVertTable
= rSh
.IsTableVertical();
1475 if( ( bVertText
&& ( !bTableCursor
|| bVertTable
) ) ||
1476 ( bTableCursor
&& bVertTable
) )
1478 SvxFrameDirection eDirection
= rSh
.GetTextDirection();
1479 if (eDirection
== SvxFrameDirection::Vertical_LR_BT
)
1481 // Map from physical to logical, so rotate clockwise.
1484 else if (KEY_DOWN
== nKey
)
1486 else if (KEY_LEFT
== nKey
)
1488 else /* KEY_RIGHT == nKey */
1493 // Attempt to integrate cursor travelling for mongolian layout does not work.
1494 // Thus, back to previous mapping of cursor keys to direction keys.
1495 if( KEY_UP
== nKey
) nKey
= KEY_LEFT
;
1496 else if( KEY_DOWN
== nKey
) nKey
= KEY_RIGHT
;
1497 else if( KEY_LEFT
== nKey
) nKey
= KEY_DOWN
;
1498 else /* KEY_RIGHT == nKey */ nKey
= KEY_UP
;
1502 if ( rSh
.IsInRightToLeftText() )
1504 if( KEY_LEFT
== nKey
) nKey
= KEY_RIGHT
;
1505 else if( KEY_RIGHT
== nKey
) nKey
= KEY_LEFT
;
1508 aKeyEvent
= KeyEvent( rKEvt
.GetCharCode(),
1509 vcl::KeyCode( nKey
, rKEvt
.GetKeyCode().GetModifier() ),
1510 rKEvt
.GetRepeat() );
1514 const vcl::KeyCode
& rKeyCode
= aKeyEvent
.GetKeyCode();
1515 sal_Unicode aCh
= aKeyEvent
.GetCharCode();
1517 // enable switching to notes anchor with Ctrl - Alt - Page Up/Down
1518 // pressing this inside a note will switch to next/previous note
1519 if ((rKeyCode
.IsMod1() && rKeyCode
.IsMod2()) && ((rKeyCode
.GetCode() == KEY_PAGEUP
) || (rKeyCode
.GetCode() == KEY_PAGEDOWN
)))
1521 const bool bNext
= rKeyCode
.GetCode()==KEY_PAGEDOWN
;
1522 const SwFieldType
* pFieldType
= rSh
.GetFieldType( 0, SwFieldIds::Postit
);
1523 rSh
.MoveFieldType( pFieldType
, bNext
);
1527 if (SwTextContentControl
* pTextContentControl
= rSh
.CursorInsideContentControl())
1529 // Check if this combination of rKeyCode and pTextContentControl should open a popup.
1530 const SwFormatContentControl
& rFormatContentControl
= pTextContentControl
->GetContentControl();
1531 std::shared_ptr
<SwContentControl
> pContentControl
= rFormatContentControl
.GetContentControl();
1532 if (pContentControl
->ShouldOpenPopup(rKeyCode
))
1534 SwShellCursor
* pCursor
= rSh
.GetCursor_();
1537 VclPtr
<SwContentControlButton
> pContentControlButton
= pCursor
->GetContentControlButton();
1538 if (pContentControlButton
)
1540 pContentControlButton
->StartPopup();
1547 const SwFrameFormat
* pFlyFormat
= rSh
.GetFlyFrameFormat();
1551 // See if the fly frame's anchor is in a content control. If so,
1552 // try to interact with it.
1553 const SwFormatAnchor
& rFormatAnchor
= pFlyFormat
->GetAnchor();
1554 SwNode
* pAnchorNode
= rFormatAnchor
.GetAnchorNode();
1557 SwTextNode
* pTextNode
= pAnchorNode
->GetTextNode();
1560 sal_Int32 nContentIdx
= rFormatAnchor
.GetAnchorContentOffset();
1561 SwTextAttr
* pAttr
= pTextNode
->GetTextAttrAt(
1562 nContentIdx
, RES_TXTATR_CONTENTCONTROL
, ::sw::GetTextAttrMode::Parent
);
1565 SwTextContentControl
* pTextContentControl
1566 = static_txtattr_cast
<SwTextContentControl
*>(pAttr
);
1567 const SwFormatContentControl
& rFormatContentControl
1568 = pTextContentControl
->GetContentControl();
1569 std::shared_ptr
<SwContentControl
> pContentControl
1570 = rFormatContentControl
.GetContentControl();
1571 if (pContentControl
->IsInteractingCharacter(aCh
))
1573 rSh
.GotoContentControl(rFormatContentControl
);
1583 SvMacroItemId nEvent
;
1586 0 == (( KEY_MOD1
| KEY_MOD2
) & rKeyCode
.GetModifier() ))
1587 nEvent
= SvMacroItemId::SwFrmKeyInputAlpha
;
1589 nEvent
= SvMacroItemId::SwFrmKeyInputNoAlpha
;
1591 const SvxMacro
* pMacro
= pFlyFormat
->GetMacro().GetMacroTable().Get( nEvent
);
1594 SbxArrayRef xArgs
= new SbxArray
;
1595 SbxVariableRef xVar
= new SbxVariable
;
1596 xVar
->PutString( pFlyFormat
->GetName() );
1597 xArgs
->Put(xVar
.get(), 1);
1599 xVar
= new SbxVariable
;
1600 if( SvMacroItemId::SwFrmKeyInputAlpha
== nEvent
)
1601 xVar
->PutChar( aCh
);
1603 xVar
->PutUShort( rKeyCode
.GetModifier() | rKeyCode
.GetCode() );
1604 xArgs
->Put(xVar
.get(), 2);
1607 rSh
.ExecMacro( *pMacro
, &sRet
, xArgs
.get() );
1608 if( !sRet
.isEmpty() && sRet
.toInt32()!=0 )
1612 SelectionType nLclSelectionType
;
1613 //A is converted to 1
1614 if( rKeyCode
.GetFullCode() == (KEY_A
| KEY_MOD1
|KEY_SHIFT
)
1615 && rSh
.HasDrawView() &&
1616 (bool(nLclSelectionType
= rSh
.GetSelectionType()) &&
1617 ((nLclSelectionType
& (SelectionType::Frame
|SelectionType::Graphic
)) ||
1618 ((nLclSelectionType
& (SelectionType::DrawObject
|SelectionType::DbForm
)) &&
1619 rSh
.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1))))
1621 SdrHdlList
& rHdlList
= const_cast<SdrHdlList
&>(rSh
.GetDrawView()->GetHdlList());
1622 SdrHdl
* pAnchor
= rHdlList
.GetHdl(SdrHdlKind::Anchor
);
1624 pAnchor
= rHdlList
.GetHdl(SdrHdlKind::Anchor_TR
);
1626 rHdlList
.SetFocusHdl(pAnchor
);
1630 SvxAutoCorrCfg
* pACfg
= nullptr;
1631 SvxAutoCorrect
* pACorr
= nullptr;
1633 uno::Reference
< frame::XDispatchRecorder
> xRecorder
=
1634 m_rView
.GetViewFrame().GetBindings().GetRecorder();
1635 if ( !xRecorder
.is() )
1637 pACfg
= &SvxAutoCorrCfg::Get();
1638 pACorr
= pACfg
->GetAutoCorrect();
1641 SwModuleOptions
* pModOpt
= SW_MOD()->GetModuleConfig();
1643 OUString sFormulaEntry
;
1645 enum class SwKeyState
{ CheckKey
, InsChar
, InsTab
,
1646 NoNum
, NumOff
, NumOrNoNum
, NumDown
, NumUp
,
1647 NumIndentInc
, NumIndentDec
,
1650 NextCell
, PrevCell
, OutlineUp
, OutlineDown
,
1651 GlossaryExpand
, NextPrevGlossary
,
1653 NextObject
, PrevObject
,
1655 LaunchOLEObject
, GoIntoFly
, GoIntoDrawing
,
1656 EnterDrawHandleMode
,
1657 CheckDocReadOnlyKeys
,
1658 CheckAutoCorrect
, EditFormula
,
1659 ColLeftBig
, ColRightBig
,
1660 ColLeftSmall
, ColRightSmall
,
1663 CellLeftBig
, CellRightBig
,
1664 CellLeftSmall
, CellRightSmall
,
1665 CellTopBig
, CellBottomBig
,
1666 CellTopSmall
, CellBottomSmall
,
1668 Fly_Change
, Draw_Change
,
1675 SwKeyState eKeyState
= bIsDocReadOnly
? SwKeyState::CheckDocReadOnlyKeys
: SwKeyState::CheckKey
;
1676 SwKeyState eNextKeyState
= SwKeyState::End
;
1679 if (m_nKS_NUMDOWN_Count
> 0)
1680 m_nKS_NUMDOWN_Count
--;
1682 if (m_nKS_NUMINDENTINC_Count
> 0)
1683 m_nKS_NUMINDENTINC_Count
--;
1685 while( SwKeyState::End
!= eKeyState
)
1687 SwKeyState eFlyState
= SwKeyState::KeyToView
;
1691 case SwKeyState::CheckKey
:
1692 eKeyState
= SwKeyState::KeyToView
; // default forward to View
1694 if (!comphelper::LibreOfficeKit::isActive() &&
1695 !rKeyCode
.IsMod2() && '=' == aCh
&&
1696 !rSh
.IsTableMode() && rSh
.GetTableFormat() &&
1698 !rSh
.HasReadonlySel())
1700 // at the beginning of the table's cell a '=' ->
1701 // call EditRow (F2-functionality)
1702 // [Avoid this for LibreOfficeKit, as the separate input window
1703 // steals the focus & things go wrong - the user never gets
1706 if( !rSh
.MoveSection( GoCurrSection
, fnSectionStart
) &&
1707 !rSh
.IsTableBoxTextFormat() )
1709 // is at the beginning of the box
1710 eKeyState
= SwKeyState::EditFormula
;
1715 rSh
.MoveSection( GoCurrSection
, fnSectionEnd
);
1718 sFormulaEntry
= "=";
1721 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
1725 if( pACorr
&& aTmpQHD
.HasContent() && !rSh
.HasSelection() &&
1726 !rSh
.HasReadonlySel() && !aTmpQHD
.m_bIsAutoText
&&
1727 pACorr
->GetSwFlags().nAutoCmpltExpandKey
==
1728 (rKeyCode
.GetModifier() | rKeyCode
.GetCode()) )
1730 eKeyState
= SwKeyState::GlossaryExpand
;
1734 switch( rKeyCode
.GetModifier() | rKeyCode
.GetCode() )
1736 case KEY_RIGHT
| KEY_MOD2
:
1737 eKeyState
= SwKeyState::ColRightBig
;
1738 eFlyState
= SwKeyState::Fly_Change
;
1739 nDir
= MOVE_RIGHT_SMALL
;
1740 goto KEYINPUT_CHECKTABLE
;
1742 case KEY_LEFT
| KEY_MOD2
:
1743 eKeyState
= SwKeyState::ColRightSmall
;
1744 eFlyState
= SwKeyState::Fly_Change
;
1745 nDir
= MOVE_LEFT_SMALL
;
1746 goto KEYINPUT_CHECKTABLE
;
1748 case KEY_RIGHT
| KEY_MOD2
| KEY_SHIFT
:
1749 eKeyState
= SwKeyState::ColLeftSmall
;
1750 goto KEYINPUT_CHECKTABLE
;
1752 case KEY_LEFT
| KEY_MOD2
| KEY_SHIFT
:
1753 eKeyState
= SwKeyState::ColLeftBig
;
1754 goto KEYINPUT_CHECKTABLE
;
1756 case KEY_RIGHT
| KEY_MOD2
| KEY_MOD1
:
1757 eKeyState
= SwKeyState::CellRightBig
;
1758 goto KEYINPUT_CHECKTABLE
;
1760 case KEY_LEFT
| KEY_MOD2
| KEY_MOD1
:
1761 eKeyState
= SwKeyState::CellRightSmall
;
1762 goto KEYINPUT_CHECKTABLE
;
1764 case KEY_RIGHT
| KEY_MOD2
| KEY_SHIFT
| KEY_MOD1
:
1765 eKeyState
= SwKeyState::CellLeftSmall
;
1766 goto KEYINPUT_CHECKTABLE
;
1768 case KEY_LEFT
| KEY_MOD2
| KEY_SHIFT
| KEY_MOD1
:
1769 eKeyState
= SwKeyState::CellLeftBig
;
1770 goto KEYINPUT_CHECKTABLE
;
1772 case KEY_UP
| KEY_MOD2
:
1773 eKeyState
= SwKeyState::ColBottomSmall
;
1774 eFlyState
= SwKeyState::Fly_Change
;
1775 nDir
= MOVE_UP_SMALL
;
1776 goto KEYINPUT_CHECKTABLE
;
1778 case KEY_DOWN
| KEY_MOD2
:
1779 eKeyState
= SwKeyState::ColBottomBig
;
1780 eFlyState
= SwKeyState::Fly_Change
;
1781 nDir
= MOVE_DOWN_SMALL
;
1782 goto KEYINPUT_CHECKTABLE
;
1784 case KEY_UP
| KEY_MOD2
| KEY_MOD1
:
1785 eKeyState
= SwKeyState::CellBottomSmall
;
1786 goto KEYINPUT_CHECKTABLE
;
1788 case KEY_DOWN
| KEY_MOD2
| KEY_MOD1
:
1789 eKeyState
= SwKeyState::CellBottomBig
;
1790 goto KEYINPUT_CHECKTABLE
;
1792 case KEY_UP
| KEY_MOD2
| KEY_SHIFT
| KEY_MOD1
:
1793 eKeyState
= SwKeyState::CellTopBig
;
1794 goto KEYINPUT_CHECKTABLE
;
1796 case KEY_DOWN
| KEY_MOD2
| KEY_SHIFT
| KEY_MOD1
:
1797 eKeyState
= SwKeyState::CellTopSmall
;
1798 goto KEYINPUT_CHECKTABLE
;
1800 KEYINPUT_CHECKTABLE
:
1801 // Resolve bugs 49091, 53190, 93402 and
1802 // https://bz.apache.org/ooo/show_bug.cgi?id=113502
1803 // but provide an option for restoring interactive
1804 // table sizing functionality when needed.
1806 ! (Window::GetIndicatorState() & KeyIndicatorState::CAPSLOCK
)
1807 && m_rView
.KeyInput( aKeyEvent
) // Keystroke is customized
1810 bFlushBuffer
= true;
1811 bNormalChar
= false;
1812 eKeyState
= SwKeyState::End
;
1816 if( rSh
.IsTableMode() || !rSh
.GetTableFormat() )
1818 if(!pFlyFormat
&& SwKeyState::KeyToView
!= eFlyState
&&
1819 (rSh
.GetSelectionType() & (SelectionType::DrawObject
|SelectionType::DbForm
)) &&
1820 rSh
.GetDrawView()->AreObjectsMarked())
1821 eKeyState
= SwKeyState::Draw_Change
;
1824 eKeyState
= eFlyState
;
1825 else if( SwKeyState::Draw_Change
!= eKeyState
)
1826 eKeyState
= SwKeyState::EnterCharCell
;
1831 case KEY_RIGHT
| KEY_SHIFT
:
1832 case KEY_LEFT
| KEY_SHIFT
:
1833 case KEY_UP
| KEY_SHIFT
:
1834 case KEY_DOWN
| KEY_SHIFT
:
1836 const SelectionType nSelectionType
= rSh
.GetSelectionType();
1838 && ( nSelectionType
& (SelectionType::Frame
|SelectionType::Ole
|SelectionType::Graphic
) ) )
1839 || ( ( nSelectionType
& (SelectionType::DrawObject
|SelectionType::DbForm
) )
1840 && rSh
.GetDrawView()->AreObjectsMarked() ) )
1842 eKeyState
= pFlyFormat
? SwKeyState::Fly_Change
: SwKeyState::Draw_Change
;
1843 if (nSelectionType
& SelectionType::DrawObject
)
1845 // tdf#137964: always move the DrawObject if one is selected
1846 eKeyState
= SwKeyState::Draw_Change
;
1848 switch ( rKeyCode
.GetCode() )
1850 case KEY_RIGHT
: nDir
= MOVE_RIGHT_HUGE
; break;
1851 case KEY_LEFT
: nDir
= MOVE_LEFT_HUGE
; break;
1852 case KEY_UP
: nDir
= MOVE_UP_HUGE
; break;
1853 case KEY_DOWN
: nDir
= MOVE_DOWN_HUGE
; break;
1860 case KEY_LEFT
| KEY_MOD1
:
1862 bool bMod1
= 0 != (rKeyCode
.GetModifier() & KEY_MOD1
);
1865 eFlyState
= SwKeyState::Fly_Change
;
1866 nDir
= MOVE_LEFT_BIG
;
1868 goto KEYINPUT_CHECKTABLE_INSDEL
;
1870 case KEY_RIGHT
| KEY_MOD1
:
1872 goto KEYINPUT_CHECKTABLE_INSDEL
;
1875 case KEY_UP
| KEY_MOD1
:
1877 bool bMod1
= 0 != (rKeyCode
.GetModifier() & KEY_MOD1
);
1880 eFlyState
= SwKeyState::Fly_Change
;
1883 goto KEYINPUT_CHECKTABLE_INSDEL
;
1886 case KEY_DOWN
| KEY_MOD1
:
1888 bool bMod1
= 0 != (rKeyCode
.GetModifier() & KEY_MOD1
);
1891 ::sw::mark::IFieldmark
* pMark
= rSh
.GetCurrentFieldmark();
1892 if (auto pDropDown
= dynamic_cast<FieldmarkWithDropDownButton
*>(pMark
))
1894 pDropDown
->LaunchPopup();
1895 eKeyState
= SwKeyState::End
;
1898 eFlyState
= SwKeyState::Fly_Change
;
1899 nDir
= MOVE_DOWN_BIG
;
1901 goto KEYINPUT_CHECKTABLE_INSDEL
;
1904 KEYINPUT_CHECKTABLE_INSDEL
:
1905 if( rSh
.IsTableMode() || !rSh
.GetTableFormat() )
1907 const SelectionType nSelectionType
= rSh
.GetSelectionType();
1909 eKeyState
= SwKeyState::KeyToView
;
1910 if(SwKeyState::KeyToView
!= eFlyState
)
1912 if((nSelectionType
& (SelectionType::DrawObject
|SelectionType::DbForm
)) &&
1913 rSh
.GetDrawView()->AreObjectsMarked())
1914 eKeyState
= SwKeyState::Draw_Change
;
1915 else if(nSelectionType
& (SelectionType::Frame
|SelectionType::Ole
|SelectionType::Graphic
))
1916 eKeyState
= SwKeyState::Fly_Change
;
1923 if ( !rSh
.HasReadonlySel() || rSh
.CursorInsideInputField())
1925 if (rSh
.IsInFrontOfLabel() && rSh
.NumOrNoNum())
1926 eKeyState
= SwKeyState::NumOrNoNum
;
1928 else if (!rSh
.IsCursorInParagraphMetadataField())
1930 rSh
.InfoReadOnlyDialog(false);
1931 eKeyState
= SwKeyState::End
;
1937 if ( !rSh
.HasReadonlySel()
1938 && !rSh
.CursorInsideInputField()
1939 && !rSh
.CursorInsideContentControl() )
1941 const SelectionType nSelectionType
= rSh
.GetSelectionType();
1942 if(nSelectionType
& SelectionType::Ole
)
1943 eKeyState
= SwKeyState::LaunchOLEObject
;
1944 else if(nSelectionType
& SelectionType::Frame
)
1945 eKeyState
= SwKeyState::GoIntoFly
;
1946 else if((nSelectionType
& SelectionType::DrawObject
) &&
1947 !(nSelectionType
& SelectionType::DrawObjectEditMode
) &&
1948 rSh
.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1)
1950 eKeyState
= SwKeyState::GoIntoDrawing
;
1951 if (lcl_goIntoTextBox(*this, rSh
))
1952 eKeyState
= SwKeyState::GoIntoFly
;
1954 else if( aTmpQHD
.HasContent() && !rSh
.HasSelection() &&
1955 aTmpQHD
.m_bIsAutoText
)
1956 eKeyState
= SwKeyState::GlossaryExpand
;
1958 //RETURN and empty paragraph in numbering -> end numbering
1959 else if( m_aInBuffer
.isEmpty() &&
1960 rSh
.GetNumRuleAtCurrCursorPos() &&
1961 !rSh
.GetNumRuleAtCurrCursorPos()->IsOutlineRule() &&
1962 !rSh
.HasSelection() &&
1963 rSh
.IsSttPara() && rSh
.IsEndPara() )
1965 eKeyState
= SwKeyState::NumOff
;
1966 eNextKeyState
= SwKeyState::OutlineLvOff
;
1968 //RETURN for new paragraph with AutoFormatting
1969 else if( pACfg
&& pACfg
->IsAutoFormatByInput() &&
1970 !(nSelectionType
& (SelectionType::Graphic
|
1971 SelectionType::Ole
| SelectionType::Frame
|
1972 SelectionType::TableCell
| SelectionType::DrawObject
|
1973 SelectionType::DrawObjectEditMode
)) )
1975 eKeyState
= SwKeyState::AutoFormatByInput
;
1979 eNextKeyState
= eKeyState
;
1980 eKeyState
= SwKeyState::CheckAutoCorrect
;
1985 case KEY_RETURN
| KEY_MOD2
:
1987 if ( !rSh
.HasReadonlySel()
1989 && rSh
.GetNumRuleAtCurrCursorPos()
1990 && !rSh
.CursorInsideInputField() )
1992 eKeyState
= SwKeyState::NoNum
;
1994 else if( rSh
.CanSpecialInsert() )
1995 eKeyState
= SwKeyState::SpecialInsert
;
1999 case KEY_BACKSPACE
| KEY_SHIFT
:
2000 if ( !rSh
.HasReadonlySel() || rSh
.CursorInsideInputField())
2003 // try to add comment for code snip:
2004 // Remove the paragraph indent, if the cursor is at the
2005 // beginning of a paragraph, there is no selection
2006 // and no numbering rule found at the current paragraph
2007 // Also try to remove indent, if current paragraph
2008 // has numbering rule, but isn't counted and only
2009 // key <backspace> is hit.
2010 const bool bOnlyBackspaceKey( KEY_BACKSPACE
== rKeyCode
.GetFullCode() );
2011 if ( rSh
.IsSttPara()
2012 && !rSh
.HasSelection()
2013 && ( rSh
.GetNumRuleAtCurrCursorPos() == nullptr
2014 || ( rSh
.IsNoNum() && bOnlyBackspaceKey
) ) )
2016 bDone
= rSh
.TryRemoveIndent();
2020 eKeyState
= SwKeyState::End
;
2023 if ( rSh
.IsSttPara() && !rSh
.IsNoNum() )
2025 if (m_nKS_NUMDOWN_Count
> 0 &&
2026 0 < rSh
.GetNumLevel())
2028 eKeyState
= SwKeyState::NumUp
;
2029 m_nKS_NUMDOWN_Count
= 2;
2032 else if (m_nKS_NUMINDENTINC_Count
> 0)
2034 eKeyState
= SwKeyState::NumIndentDec
;
2035 m_nKS_NUMINDENTINC_Count
= 2;
2040 // If the cursor is in an empty paragraph, which has
2041 // a numbering, but not the outline numbering, and
2042 // there is no selection, the numbering has to be
2043 // deleted on key <Backspace>.
2044 // Otherwise method <SwEditShell::NumOrNoNum(..)>
2045 // should only change the <IsCounted()> state of
2046 // the current paragraph depending of the key.
2047 // On <backspace> it is set to <false>,
2048 // on <shift-backspace> it is set to <true>.
2049 // Thus, assure that method <SwEditShell::NumOrNum(..)>
2050 // is only called for the intended purpose.
2051 if ( !bDone
&& rSh
.IsSttPara() )
2053 bool bCallNumOrNoNum( false );
2054 if ( bOnlyBackspaceKey
&& !rSh
.IsNoNum() )
2056 bCallNumOrNoNum
= true;
2058 else if ( !bOnlyBackspaceKey
&& rSh
.IsNoNum() )
2060 bCallNumOrNoNum
= true;
2062 else if ( bOnlyBackspaceKey
2065 && !rSh
.HasSelection() )
2067 const SwNumRule
* pCurrNumRule( rSh
.GetNumRuleAtCurrCursorPos() );
2068 if ( pCurrNumRule
!= nullptr
2069 && pCurrNumRule
!= rSh
.GetOutlineNumRule() )
2071 bCallNumOrNoNum
= true;
2074 if ( bCallNumOrNoNum
2075 && rSh
.NumOrNoNum( !bOnlyBackspaceKey
) )
2077 eKeyState
= SwKeyState::NumOrNoNum
;
2082 else if (!rSh
.IsCursorInParagraphMetadataField())
2084 rSh
.InfoReadOnlyDialog(false);
2085 eKeyState
= SwKeyState::End
;
2091 eFlyState
= SwKeyState::Fly_Change
;
2092 nDir
= MOVE_RIGHT_BIG
;
2093 goto KEYINPUT_CHECKTABLE_INSDEL
;
2097 // Rich text contentControls accept tabs and fieldmarks and other rich text,
2098 // so first act on cases that are not a content control
2099 SwTextContentControl
* pTextContentControl
= rSh
.CursorInsideContentControl();
2100 if ((rSh
.IsFormProtected() && !pTextContentControl
) ||
2101 rSh
.GetCurrentFieldmark() || rSh
.GetChar(false)==CH_TXT_ATR_FORMELEMENT
)
2103 eKeyState
= SwKeyState::GotoNextFieldMark
;
2105 else if ( !rSh
.IsMultiSelection() && rSh
.CursorInsideInputField() )
2107 GetView().GetViewFrame().GetDispatcher()->Execute( FN_GOTO_NEXT_INPUTFLD
);
2108 eKeyState
= SwKeyState::End
;
2110 else if( rSh
.GetNumRuleAtCurrCursorPos()
2111 && rSh
.IsSttOfPara()
2112 && !rSh
.HasReadonlySel() )
2114 if (numfunc::NumDownChangesIndent(rSh
))
2116 eKeyState
= SwKeyState::NumDown
;
2120 eKeyState
= SwKeyState::InsTab
;
2123 else if (rSh
.GetSelectionType() &
2124 (SelectionType::Graphic
|
2125 SelectionType::Frame
|
2126 SelectionType::Ole
|
2127 SelectionType::DrawObject
|
2128 SelectionType::DbForm
))
2130 eKeyState
= SwKeyState::NextObject
;
2132 else if ( rSh
.GetTableFormat() )
2134 if( rSh
.HasSelection() || rSh
.HasReadonlySel() )
2135 eKeyState
= SwKeyState::NextCell
;
2138 eKeyState
= SwKeyState::CheckAutoCorrect
;
2139 eNextKeyState
= SwKeyState::NextCell
;
2142 else if (pTextContentControl
)
2144 auto pCC
= pTextContentControl
->GetContentControl().GetContentControl();
2147 switch (pCC
->GetType())
2149 case SwContentControlType::RICH_TEXT
:
2150 eKeyState
= SwKeyState::InsTab
;
2153 eKeyState
= SwKeyState::GotoNextFieldMark
;
2159 eKeyState
= SwKeyState::InsTab
;
2160 if( rSh
.IsSttOfPara() && !rSh
.HasReadonlySel() )
2162 SwTextFormatColl
* pColl
= rSh
.GetCurTextFormatColl();
2165 pColl
->IsAssignedToListLevelOfOutlineStyle()
2166 && MAXLEVEL
-1 > pColl
->GetAssignedOutlineStyleLevel() )
2167 eKeyState
= SwKeyState::OutlineDown
;
2172 case KEY_TAB
| KEY_SHIFT
:
2174 SwTextContentControl
* pTextContentControl
= rSh
.CursorInsideContentControl();
2175 if ((rSh
.IsFormProtected() && !pTextContentControl
) ||
2176 rSh
.GetCurrentFieldmark()|| rSh
.GetChar(false)==CH_TXT_ATR_FORMELEMENT
)
2178 eKeyState
= SwKeyState::GotoPrevFieldMark
;
2180 else if ( !rSh
.IsMultiSelection() && rSh
.CursorInsideInputField() )
2182 GetView().GetViewFrame().GetDispatcher()->Execute( FN_GOTO_PREV_INPUTFLD
);
2183 eKeyState
= SwKeyState::End
;
2185 else if( rSh
.GetNumRuleAtCurrCursorPos()
2186 && rSh
.IsSttOfPara()
2187 && !rSh
.HasReadonlySel() )
2189 eKeyState
= SwKeyState::NumUp
;
2191 else if (rSh
.GetSelectionType() &
2192 (SelectionType::Graphic
|
2193 SelectionType::Frame
|
2194 SelectionType::Ole
|
2195 SelectionType::DrawObject
|
2196 SelectionType::DbForm
))
2198 eKeyState
= SwKeyState::PrevObject
;
2200 else if ( rSh
.GetTableFormat() )
2202 if( rSh
.HasSelection() || rSh
.HasReadonlySel() )
2203 eKeyState
= SwKeyState::PrevCell
;
2206 eKeyState
= SwKeyState::CheckAutoCorrect
;
2207 eNextKeyState
= SwKeyState::PrevCell
;
2210 else if (pTextContentControl
)
2212 eKeyState
= SwKeyState::GotoPrevFieldMark
;
2216 eKeyState
= SwKeyState::End
;
2217 if( rSh
.IsSttOfPara() && !rSh
.HasReadonlySel() )
2219 SwTextFormatColl
* pColl
= rSh
.GetCurTextFormatColl();
2221 pColl
->IsAssignedToListLevelOfOutlineStyle() &&
2222 0 < pColl
->GetAssignedOutlineStyleLevel())
2223 eKeyState
= SwKeyState::OutlineUp
;
2228 case KEY_TAB
| KEY_MOD1
:
2229 case KEY_TAB
| KEY_MOD2
:
2230 if( !rSh
.HasReadonlySel() )
2232 if( aTmpQHD
.HasContent() && !rSh
.HasSelection() )
2234 // Next auto-complete suggestion
2235 aTmpQHD
.Next( pACorr
&&
2236 pACorr
->GetSwFlags().bAutoCmpltEndless
);
2237 eKeyState
= SwKeyState::NextPrevGlossary
;
2239 else if( rSh
.GetTableFormat() )
2240 eKeyState
= SwKeyState::InsTab
;
2241 else if((rSh
.GetSelectionType() &
2242 (SelectionType::DrawObject
|SelectionType::DbForm
|
2243 SelectionType::Frame
|SelectionType::Ole
|SelectionType::Graphic
)) &&
2244 rSh
.GetDrawView()->AreObjectsMarked())
2245 eKeyState
= SwKeyState::EnterDrawHandleMode
;
2248 if ( !rSh
.IsMultiSelection()
2249 && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
2250 eKeyState
= SwKeyState::NumIndentInc
;
2255 case KEY_TAB
| KEY_MOD1
| KEY_SHIFT
:
2257 if( aTmpQHD
.HasContent() && !rSh
.HasSelection() &&
2258 !rSh
.HasReadonlySel() )
2260 // Previous auto-complete suggestion.
2261 aTmpQHD
.Previous( pACorr
&&
2262 pACorr
->GetSwFlags().bAutoCmpltEndless
);
2263 eKeyState
= SwKeyState::NextPrevGlossary
;
2265 else if((rSh
.GetSelectionType() & (SelectionType::DrawObject
|SelectionType::DbForm
|
2266 SelectionType::Frame
|SelectionType::Ole
|SelectionType::Graphic
)) &&
2267 rSh
.GetDrawView()->AreObjectsMarked())
2269 eKeyState
= SwKeyState::EnterDrawHandleMode
;
2273 if ( !rSh
.IsMultiSelection()
2274 && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
2275 eKeyState
= SwKeyState::NumIndentDec
;
2280 if( !rSh
.HasReadonlySel() )
2282 const SelectionType nSelectionType
= rSh
.GetSelectionType();
2283 if(nSelectionType
& SelectionType::Frame
)
2284 eKeyState
= SwKeyState::GoIntoFly
;
2285 else if(nSelectionType
& SelectionType::DrawObject
)
2287 eKeyState
= SwKeyState::GoIntoDrawing
;
2288 if (lcl_goIntoTextBox(*this, rSh
))
2289 eKeyState
= SwKeyState::GoIntoFly
;
2296 case SwKeyState::CheckDocReadOnlyKeys
:
2298 eKeyState
= SwKeyState::KeyToView
;
2299 switch( rKeyCode
.GetModifier() | rKeyCode
.GetCode() )
2302 case KEY_TAB
| KEY_SHIFT
:
2303 bNormalChar
= false;
2304 eKeyState
= SwKeyState::End
;
2305 if ( rSh
.GetSelectionType() &
2306 (SelectionType::Graphic
|
2307 SelectionType::Frame
|
2308 SelectionType::Ole
|
2309 SelectionType::DrawObject
|
2310 SelectionType::DbForm
))
2313 eKeyState
= (rKeyCode
.GetModifier() & KEY_SHIFT
) ?
2314 SwKeyState::PrevObject
: SwKeyState::NextObject
;
2316 else if ( !rSh
.IsMultiSelection() && rSh
.CursorInsideInputField() )
2318 GetView().GetViewFrame().GetDispatcher()->Execute(
2319 KEY_SHIFT
!= rKeyCode
.GetModifier() ? FN_GOTO_NEXT_INPUTFLD
: FN_GOTO_PREV_INPUTFLD
);
2323 rSh
.SelectNextPrevHyperlink( KEY_SHIFT
!= rKeyCode
.GetModifier() );
2328 const SelectionType nSelectionType
= rSh
.GetSelectionType();
2329 if(nSelectionType
& SelectionType::Frame
)
2330 eKeyState
= SwKeyState::GoIntoFly
;
2333 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(rSh
.GetAttrPool());
2334 rSh
.GetCurAttr(aSet
);
2335 if(SfxItemState::SET
== aSet
.GetItemState(RES_TXTATR_INETFMT
, false))
2337 const SfxPoolItem
& rItem
= aSet
.Get(RES_TXTATR_INETFMT
);
2338 bNormalChar
= false;
2339 eKeyState
= SwKeyState::End
;
2340 rSh
.ClickToINetAttr(static_cast<const SwFormatINetFormat
&>(rItem
));
2349 case SwKeyState::EnterCharCell
:
2351 eKeyState
= SwKeyState::KeyToView
;
2352 switch ( rKeyCode
.GetModifier() | rKeyCode
.GetCode() )
2354 case KEY_RIGHT
| KEY_MOD2
:
2355 rSh
.Right( SwCursorSkipMode::Chars
, false, 1, false );
2356 eKeyState
= SwKeyState::End
;
2359 case KEY_LEFT
| KEY_MOD2
:
2360 rSh
.Left( SwCursorSkipMode::Chars
, false, 1, false );
2361 eKeyState
= SwKeyState::End
;
2368 case SwKeyState::KeyToView
:
2370 eKeyState
= SwKeyState::End
;
2372 !rKeyCode
.IsMod2() &&
2373 rKeyCode
.GetModifier() != KEY_MOD1
&&
2374 rKeyCode
.GetModifier() != (KEY_MOD1
|KEY_SHIFT
) &&
2375 SW_ISPRINTABLE( aCh
);
2377 if( bNormalChar
&& rSh
.IsInFrontOfLabel() )
2382 if( !m_aInBuffer
.isEmpty() && ( !bNormalChar
|| bIsDocReadOnly
))
2385 if (rSh
.HasReadonlySel()
2386 && ( rKeyCode
.GetFunction() == KeyFuncType::PASTE
2387 || rKeyCode
.GetFunction() == KeyFuncType::CUT
))
2389 rSh
.InfoReadOnlyDialog(true);
2390 eKeyState
= SwKeyState::End
;
2392 else if( m_rView
.KeyInput( aKeyEvent
) )
2394 bFlushBuffer
= true;
2395 bNormalChar
= false;
2399 // Because Sfx accelerators are only called when they were
2400 // enabled at the last status update, copy has to called
2401 // 'forcefully' by us if necessary.
2402 if( rKeyCode
.GetFunction() == KeyFuncType::COPY
)
2403 GetView().GetViewFrame().GetBindings().Execute(SID_COPY
);
2405 if( !bIsDocReadOnly
&& bNormalChar
)
2407 const SelectionType nSelectionType
= rSh
.GetSelectionType();
2408 const bool bDrawObject
= (nSelectionType
& SelectionType::DrawObject
) &&
2409 !(nSelectionType
& SelectionType::DrawObjectEditMode
) &&
2410 rSh
.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1;
2412 bool bTextBox
= false;
2413 if (bDrawObject
&& lcl_goIntoTextBox(*this, rSh
))
2414 // A draw shape was selected, but it has a TextBox,
2415 // start editing that instead when the normal
2416 // character is pressed.
2419 if (bDrawObject
&& !bTextBox
)
2421 SdrObject
* pObj
= rSh
.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
2424 EnterDrawTextMode(pObj
->GetLogicRect().Center());
2425 if ( auto pSwDrawTextShell
= dynamic_cast< SwDrawTextShell
*>( m_rView
.GetCurShell() ) )
2426 pSwDrawTextShell
->Init();
2427 rSh
.GetDrawView()->KeyInput( rKEvt
, this );
2430 else if (nSelectionType
& SelectionType::Frame
|| bTextBox
)
2432 rSh
.UnSelectFrame();
2433 rSh
.LeaveSelFrameMode();
2434 m_rView
.AttrChangedNotify(nullptr);
2435 rSh
.MoveSection( GoCurrSection
, fnSectionEnd
);
2437 eKeyState
= SwKeyState::InsChar
;
2441 bNormalChar
= false;
2442 Window::KeyInput( aKeyEvent
);
2447 case SwKeyState::LaunchOLEObject
:
2450 eKeyState
= SwKeyState::End
;
2453 case SwKeyState::GoIntoFly
:
2455 rSh
.UnSelectFrame();
2456 rSh
.LeaveSelFrameMode();
2457 m_rView
.AttrChangedNotify(nullptr);
2458 rSh
.MoveSection( GoCurrSection
, fnSectionEnd
);
2459 eKeyState
= SwKeyState::End
;
2462 case SwKeyState::GoIntoDrawing
:
2464 if (SdrMark
* pMark
= rSh
.GetDrawView()->GetMarkedObjectList().GetMark(0))
2466 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
2469 EnterDrawTextMode(pObj
->GetLogicRect().Center());
2470 if (auto pSwDrawTextShell
= dynamic_cast< SwDrawTextShell
*>( m_rView
.GetCurShell() ) )
2471 pSwDrawTextShell
->Init();
2474 eKeyState
= SwKeyState::End
;
2477 case SwKeyState::EnterDrawHandleMode
:
2479 const SdrHdlList
& rHdlList
= rSh
.GetDrawView()->GetHdlList();
2480 bool bForward(!aKeyEvent
.GetKeyCode().IsShift());
2482 const_cast<SdrHdlList
&>(rHdlList
).TravelFocusHdl(bForward
);
2483 eKeyState
= SwKeyState::End
;
2486 case SwKeyState::InsTab
:
2487 if( dynamic_cast<const SwWebView
*>( &m_rView
) != nullptr) // no Tab for WebView
2489 // then it should be passed along
2490 Window::KeyInput( aKeyEvent
);
2491 eKeyState
= SwKeyState::End
;
2496 case SwKeyState::InsChar
:
2497 if (rSh
.CursorInsideContentControl())
2499 const SwPosition
* pStart
= rSh
.GetCursor()->Start();
2500 SwTextNode
* pTextNode
= pStart
->GetNode().GetTextNode();
2503 sal_Int32 nIndex
= pStart
->GetContentIndex();
2504 SwTextAttr
* pAttr
= pTextNode
->GetTextAttrAt(nIndex
, RES_TXTATR_CONTENTCONTROL
, ::sw::GetTextAttrMode::Parent
);
2507 auto pTextContentControl
= static_txtattr_cast
<SwTextContentControl
*>(pAttr
);
2508 const SwFormatContentControl
& rFormatContentControl
= pTextContentControl
->GetContentControl();
2509 std::shared_ptr
<SwContentControl
> pContentControl
= rFormatContentControl
.GetContentControl();
2510 if (pContentControl
->IsInteractingCharacter(aCh
))
2512 rSh
.GotoContentControl(rFormatContentControl
);
2513 eKeyState
= SwKeyState::End
;
2520 if (rSh
.GetChar(false)==CH_TXT_ATR_FORMELEMENT
)
2522 ::sw::mark::ICheckboxFieldmark
* pFieldmark
=
2523 dynamic_cast< ::sw::mark::ICheckboxFieldmark
* >
2524 (rSh
.GetCurrentFieldmark());
2525 OSL_ENSURE(pFieldmark
,
2526 "Where is my FieldMark??");
2529 pFieldmark
->SetChecked(!pFieldmark
->IsChecked());
2530 OSL_ENSURE(pFieldmark
->IsExpanded(),
2531 "where is the otherpos?");
2532 if (pFieldmark
->IsExpanded())
2537 eKeyState
= SwKeyState::End
;
2539 else if ( !rSh
.HasReadonlySel()
2540 || rSh
.CursorInsideInputField() )
2542 const bool bIsNormalChar
=
2543 GetAppCharClass().isLetterNumeric( OUString( aCh
), 0 );
2544 if( bAppendSpace
&& bIsNormalChar
&&
2545 (!m_aInBuffer
.isEmpty() || !rSh
.IsSttPara() || !rSh
.IsEndPara() ))
2547 // insert a blank ahead of the character. this ends up
2548 // between the expanded text and the new "non-word-separator".
2552 const bool bIsAutoCorrectChar
= SvxAutoCorrect::IsAutoCorrectChar( aCh
);
2553 if( !aKeyEvent
.GetRepeat() && pACorr
&& ( bIsAutoCorrectChar
|| rSh
.IsNbspRunNext() ) &&
2554 pACfg
->IsAutoFormatByInput() &&
2555 (( pACorr
->IsAutoCorrFlag( ACFlags::ChgWeightUnderl
) &&
2556 ( '*' == aCh
|| '_' == aCh
) ) ||
2557 ( pACorr
->IsAutoCorrFlag( ACFlags::ChgQuotes
) && ('\"' == aCh
))||
2558 ( pACorr
->IsAutoCorrFlag( ACFlags::ChgSglQuotes
) && ( '\'' == aCh
))))
2561 rSh
.AutoCorrect( *pACorr
, aCh
);
2562 if( '\"' != aCh
&& '\'' != aCh
) // only call when "*_"!
2565 else if( !aKeyEvent
.GetRepeat() && pACorr
&& ( bIsAutoCorrectChar
|| rSh
.IsNbspRunNext() ) &&
2566 pACfg
->IsAutoFormatByInput() &&
2567 pACorr
->IsAutoCorrFlag( ACFlags::CapitalStartSentence
| ACFlags::CapitalStartWord
|
2568 ACFlags::ChgOrdinalNumber
| ACFlags::AddNonBrkSpace
|
2569 ACFlags::ChgToEnEmDash
| ACFlags::SetINetAttr
|
2570 ACFlags::Autocorrect
| ACFlags::TransliterateRTL
|
2571 ACFlags::SetDOIAttr
) &&
2572 '\"' != aCh
&& '\'' != aCh
&& '*' != aCh
&& '_' != aCh
2576 rSh
.AutoCorrect( *pACorr
, aCh
);
2580 OUStringBuffer
aBuf(m_aInBuffer
);
2581 comphelper::string::padToLength(aBuf
,
2582 m_aInBuffer
.getLength() + aKeyEvent
.GetRepeat() + 1, aCh
);
2583 m_aInBuffer
= aBuf
.makeStringAndClear();
2584 bool delayFlush
= Application::AnyInput( VclInputFlags::KEYBOARD
);
2585 bFlushBuffer
= !delayFlush
;
2588 // Start the timer, make sure to not restart it.
2589 keyInputFlushTimerStop
.dismiss();
2590 if( !m_aKeyInputFlushTimer
.IsActive())
2591 m_aKeyInputFlushTimer
.Start();
2594 eKeyState
= SwKeyState::End
;
2598 rSh
.InfoReadOnlyDialog(true);
2599 eKeyState
= SwKeyState::End
;
2603 case SwKeyState::CheckAutoCorrect
:
2605 if( pACorr
&& pACfg
->IsAutoFormatByInput() &&
2606 pACorr
->IsAutoCorrFlag( ACFlags::CapitalStartSentence
| ACFlags::CapitalStartWord
|
2607 ACFlags::ChgOrdinalNumber
| ACFlags::TransliterateRTL
|
2608 ACFlags::ChgToEnEmDash
| ACFlags::SetINetAttr
|
2609 ACFlags::Autocorrect
| ACFlags::SetDOIAttr
) &&
2610 !rSh
.HasReadonlySel() )
2613 rSh
.AutoCorrect( *pACorr
, u
'\0' );
2615 eKeyState
= eNextKeyState
;
2621 sal_uInt16 nSlotId
= 0;
2625 case SwKeyState::SpecialInsert
:
2626 rSh
.DoSpecialInsert();
2629 case SwKeyState::NoNum
:
2633 case SwKeyState::NumOff
:
2634 // shell change - so record in advance
2637 case SwKeyState::OutlineLvOff
: // delete autofmt outlinelevel later
2640 case SwKeyState::NumDown
:
2642 m_nKS_NUMDOWN_Count
= 2;
2644 case SwKeyState::NumUp
:
2645 rSh
.NumUpDown( false );
2648 case SwKeyState::NumIndentInc
:
2649 rSh
.ChangeIndentOfAllListLevels(360);
2650 m_nKS_NUMINDENTINC_Count
= 2;
2653 case SwKeyState::GotoNextFieldMark
:
2655 rSh
.GotoFormControl(/*bNext=*/true);
2659 case SwKeyState::GotoPrevFieldMark
:
2661 rSh
.GotoFormControl(/*bNext=*/false);
2665 case SwKeyState::NumIndentDec
:
2666 rSh
.ChangeIndentOfAllListLevels(-360);
2669 case SwKeyState::OutlineDown
:
2670 rSh
.OutlineUpDown();
2672 case SwKeyState::OutlineUp
:
2673 rSh
.OutlineUpDown( -1 );
2676 case SwKeyState::NextCell
:
2677 // always 'flush' in tables
2678 rSh
.GoNextCell(!rSh
.HasReadonlySel());
2679 nSlotId
= FN_GOTO_NEXT_CELL
;
2681 case SwKeyState::PrevCell
:
2683 nSlotId
= FN_GOTO_PREV_CELL
;
2685 case SwKeyState::AutoFormatByInput
:
2686 rSh
.SplitNode( true );
2689 case SwKeyState::NextObject
:
2690 case SwKeyState::PrevObject
:
2691 if(rSh
.GotoObj( SwKeyState::NextObject
== eKeyState
, GotoObjFlags::Any
))
2693 if( rSh
.IsFrameSelected() &&
2694 m_rView
.GetDrawFuncPtr() )
2696 m_rView
.GetDrawFuncPtr()->Deactivate();
2697 m_rView
.SetDrawFuncPtr(nullptr);
2698 m_rView
.LeaveDrawCreate();
2699 m_rView
.AttrChangedNotify(nullptr);
2702 rSh
.EnterSelFrameMode();
2705 case SwKeyState::GlossaryExpand
:
2707 // replace the word or abbreviation with the auto text
2708 rSh
.StartUndo( SwUndoId::START
);
2710 OUString
sFnd(aTmpQHD
.CurStr());
2711 if( aTmpQHD
.m_bIsAutoText
)
2713 SwGlossaryList
* pList
= ::GetGlossaryList();
2716 if(pList
->GetShortName( sFnd
, sShrtNm
, sGroup
))
2719 rSh
.ExtendSelection(false, aTmpQHD
.CurLen());
2720 SwGlossaryHdl
* pGlosHdl
= GetView().GetGlosHdl();
2721 pGlosHdl
->SetCurGroup(sGroup
, true);
2722 pGlosHdl
->InsertGlossary( sShrtNm
);
2723 s_pQuickHlpData
->m_bAppendSpace
= true;
2728 sFnd
= sFnd
.copy(aTmpQHD
.CurLen());
2730 s_pQuickHlpData
->m_bAppendSpace
= !pACorr
||
2731 pACorr
->GetSwFlags().bAutoCmpltAppendBlank
;
2733 rSh
.EndUndo( SwUndoId::END
);
2737 case SwKeyState::NextPrevGlossary
:
2738 s_pQuickHlpData
->Move( aTmpQHD
);
2739 s_pQuickHlpData
->Start(rSh
, false);
2742 case SwKeyState::EditFormula
:
2744 const sal_uInt16 nId
= SwInputChild::GetChildWindowId();
2746 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
2747 rVFrame
.ToggleChildWindow( nId
);
2748 SwInputChild
* pChildWin
= static_cast<SwInputChild
*>(rVFrame
.
2749 GetChildWindow( nId
));
2751 pChildWin
->SetFormula( sFormulaEntry
);
2755 case SwKeyState::ColLeftBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableHMove() ); break;
2756 case SwKeyState::ColRightBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::ColRight
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableHMove() ); break;
2757 case SwKeyState::ColLeftSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft
, pModOpt
->GetTableHMove() ); break;
2758 case SwKeyState::ColRightSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::ColRight
, pModOpt
->GetTableHMove() ); break;
2759 case SwKeyState::ColBottomBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableVMove() ); break;
2760 case SwKeyState::ColBottomSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom
, pModOpt
->GetTableVMove() ); break;
2761 case SwKeyState::CellLeftBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableHMove() ); break;
2762 case SwKeyState::CellRightBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellRight
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableHMove() ); break;
2763 case SwKeyState::CellLeftSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft
, pModOpt
->GetTableHMove() ); break;
2764 case SwKeyState::CellRightSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellRight
, pModOpt
->GetTableHMove() ); break;
2765 case SwKeyState::CellTopBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellTop
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableVMove() ); break;
2766 case SwKeyState::CellBottomBig
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom
|TableChgWidthHeightType::BiggerMode
, pModOpt
->GetTableVMove() ); break;
2767 case SwKeyState::CellTopSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellTop
, pModOpt
->GetTableVMove() ); break;
2768 case SwKeyState::CellBottomSmall
: rSh
.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom
, pModOpt
->GetTableVMove() ); break;
2770 case SwKeyState::Fly_Change
:
2772 SdrView
*pSdrView
= rSh
.GetDrawView();
2773 const SdrHdlList
& rHdlList
= pSdrView
->GetHdlList();
2774 if(rHdlList
.GetFocusHdl())
2775 ChangeDrawing( nDir
);
2777 ChangeFly( nDir
, dynamic_cast<const SwWebView
*>( &m_rView
) != nullptr );
2780 case SwKeyState::Draw_Change
:
2781 ChangeDrawing( nDir
);
2786 if( nSlotId
&& m_rView
.GetViewFrame().GetBindings().GetRecorder().is() )
2788 SfxRequest
aReq(m_rView
.GetViewFrame(), nSlotId
);
2791 eKeyState
= SwKeyState::End
;
2796 // update the page number in the statusbar
2797 sal_uInt16 nKey
= rKEvt
.GetKeyCode().GetCode();
2798 if( KEY_UP
== nKey
|| KEY_DOWN
== nKey
|| KEY_PAGEUP
== nKey
|| KEY_PAGEDOWN
== nKey
)
2799 GetView().GetViewFrame().GetBindings().Update( FN_STAT_PAGE
);
2801 // in case the buffered characters are inserted
2802 if( bFlushBuffer
&& !m_aInBuffer
.isEmpty() )
2806 // maybe show Tip-Help
2809 const bool bAutoTextShown
2810 = pACfg
&& pACfg
->IsAutoTextTip() && ShowAutoText(rSh
.GetChunkForAutoText());
2811 if (!bAutoTextShown
&& pACorr
&& pACorr
->GetSwFlags().bAutoCompleteWords
)
2812 ShowAutoCorrectQuickHelp(rSh
.GetPrevAutoCorrWord(*pACorr
), *pACorr
);
2816 // get the word count dialog to update itself
2817 SwWordCountWrapper
*pWrdCnt
= static_cast<SwWordCountWrapper
*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
2819 pWrdCnt
->UpdateCounts();
2826 void SwEditWin::ResetMouseButtonDownFlags()
2828 // Not on all systems a MouseButtonUp is used ahead
2829 // of the modal dialog (like on WINDOWS).
2830 // So reset the statuses here and release the mouse
2832 m_bMBPressed
= false;
2833 g_bNoInterrupt
= false;
2839 * Determines if the current position has a clickable url over a background
2840 * frame. In that case, ctrl-click should select the url, not the frame.
2842 static bool lcl_urlOverBackground(SwWrtShell
& rSh
, const Point
& rDocPos
)
2844 SwContentAtPos
aSwContentAtPos(IsAttrAtPos::InetAttr
);
2845 SdrObject
* pSelectableObj
= rSh
.GetObjAt(rDocPos
);
2847 return rSh
.GetContentAtPos(rDocPos
, aSwContentAtPos
) && pSelectableObj
->GetLayer() == rSh
.GetDoc()->getIDocumentDrawModelAccess().GetHellId();
2850 void SwEditWin::MoveCursor( SwWrtShell
&rSh
, const Point
& rDocPos
,
2851 const bool bOnlyText
, bool bLockView
)
2853 const bool bTmpNoInterrupt
= g_bNoInterrupt
;
2854 g_bNoInterrupt
= false;
2856 int nTmpSetCursor
= 0;
2858 if( !rSh
.IsViewLocked() && bLockView
)
2859 rSh
.LockView( true );
2864 // only temporary generate move context because otherwise
2865 // the query to the content form doesn't work!!!
2866 SwMvContext
aMvContext( &rSh
);
2867 nTmpSetCursor
= rSh
.CallSetCursor(&rDocPos
, bOnlyText
);
2868 g_bValidCursorPos
= !(CRSR_POSCHG
& nTmpSetCursor
);
2871 // notify the edit window that from now on we do not use the input language
2872 if ( !(CRSR_POSOLD
& nTmpSetCursor
) )
2873 SetUseInputLanguage( false );
2876 rSh
.LockView( false );
2878 g_bNoInterrupt
= bTmpNoInterrupt
;
2881 void SwEditWin::MouseButtonDown(const MouseEvent
& _rMEvt
)
2883 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
2884 const SwField
*pCursorField
= rSh
.CursorInsideInputField() ? rSh
.GetCurField( true ) : nullptr;
2886 // We have to check if a context menu is shown and we have an UI
2887 // active inplace client. In that case we have to ignore the mouse
2888 // button down event. Otherwise we would crash (context menu has been
2889 // opened by inplace client and we would deactivate the inplace client,
2890 // the context menu is closed by VCL asynchronously which in the end
2891 // would work on deleted objects or the context menu has no parent anymore)
2892 SfxInPlaceClient
* pIPClient
= rSh
.GetSfxViewShell()->GetIPClient();
2893 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
2895 if (bIsOleActive
&& vcl::IsInPopupMenuExecute())
2898 MouseEvent
aMEvt(_rMEvt
);
2900 if (m_rView
.GetPostItMgr()->IsHit(aMEvt
.GetPosPixel()))
2903 if (comphelper::LibreOfficeKit::isActive())
2905 if (vcl::Window
* pWindow
= m_rView
.GetPostItMgr()->IsHitSidebarWindow(aMEvt
.GetPosPixel()))
2907 pWindow
->MouseButtonDown(aMEvt
);
2912 m_rView
.GetPostItMgr()->SetActiveSidebarWin(nullptr);
2915 rSh
.addCurrentPosition();
2917 //ignore key modifiers for format paintbrush
2919 bool bExecFormatPaintbrush
= m_pApplyTempl
&& m_pApplyTempl
->m_pFormatClipboard
2920 && m_pApplyTempl
->m_pFormatClipboard
->HasContent();
2921 if( bExecFormatPaintbrush
)
2922 aMEvt
= MouseEvent(_rMEvt
.GetPosPixel(), _rMEvt
.GetClicks(), _rMEvt
.GetMode(),
2923 _rMEvt
.GetButtons());
2926 m_bWasShdwCursor
= nullptr != m_pShadCursor
;
2927 m_pShadCursor
.reset();
2929 const Point
aDocPos(PixelToLogic(aMEvt
.GetPosPixel()));
2931 FrameControlType eControl
;
2932 bool bOverFly
= false;
2933 bool bPageAnchored
= false;
2934 bool bOverHeaderFooterFly
= IsOverHeaderFooterFly( aDocPos
, eControl
, bOverFly
, bPageAnchored
);
2936 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly();
2937 if (bOverHeaderFooterFly
&& (!bIsDocReadOnly
&& rSh
.GetCurField()))
2938 // We have a field here, that should have priority over header/footer fly.
2939 bOverHeaderFooterFly
= false;
2941 // Are we clicking on a blank header/footer area?
2942 if ( IsInHeaderFooter( aDocPos
, eControl
) || bOverHeaderFooterFly
)
2944 const SwPageFrame
* pPageFrame
= rSh
.GetLayout()->GetPageAtPos( aDocPos
);
2949 bool bActive
= true;
2950 const SwPageDesc
* pDesc
= pPageFrame
->GetPageDesc();
2952 const SwFrameFormat
* pFormat
= pDesc
->GetLeftFormat();
2953 if ( pPageFrame
->OnRightPage() )
2954 pFormat
= pDesc
->GetRightFormat();
2958 if ( eControl
== FrameControlType::Header
)
2959 bActive
= pFormat
->GetHeader().IsActive();
2961 bActive
= pFormat
->GetFooter().IsActive();
2966 // HeaderFooter menu implies header/footer controls, so only do this with IsUseHeaderFooterMenu enabled.
2967 // But, additionally, when in Hide-Whitespace mode, we don't want those controls.
2968 if (rSh
.GetViewOptions()->IsUseHeaderFooterMenu() && !rSh
.GetViewOptions()->IsHideWhitespaceMode())
2970 SwPaM
aPam(*rSh
.GetCurrentShellCursor().GetPoint());
2971 const bool bWasInHeader
= aPam
.GetPoint()->GetNode().FindHeaderStartNode() != nullptr;
2972 const bool bWasInFooter
= aPam
.GetPoint()->GetNode().FindFooterStartNode() != nullptr;
2974 // Is the cursor in a part like similar to the one we clicked on? For example,
2975 // if the cursor is in a header and we click on an empty header... don't change anything to
2976 // keep consistent behaviour due to header edit mode (and the same for the footer as well).
2978 // Otherwise, we hide the header/footer control if a separator is shown, and vice versa.
2979 if (!(bWasInHeader
&& eControl
== FrameControlType::Header
) &&
2980 !(bWasInFooter
&& eControl
== FrameControlType::Footer
))
2982 const bool bSeparatorWasVisible
= rSh
.IsShowHeaderFooterSeparator(eControl
);
2983 rSh
.SetShowHeaderFooterSeparator(eControl
, !bSeparatorWasVisible
);
2985 // Repaint everything
2988 // tdf#84929. If the footer control had not been showing, do not change the cursor position,
2989 // because the user may have scrolled to turn on the separator control and
2990 // if the cursor cannot be positioned on-screen, then the user would need to scroll back again to use the control.
2991 // This should only be done for the footer. The cursor can always be re-positioned near the header. tdf#134023.
2992 if ( eControl
== FrameControlType::Footer
&& !bSeparatorWasVisible
2993 && !Application::IsHeadlessModeEnabled() )
3000 // Make sure we have the proper Header/Footer separators shown
3001 // as these may be changed if clicking on an empty Header/Footer
3002 rSh
.SetShowHeaderFooterSeparator( FrameControlType::Header
, eControl
== FrameControlType::Header
);
3003 rSh
.SetShowHeaderFooterSeparator( FrameControlType::Footer
, eControl
== FrameControlType::Footer
);
3005 if ( !rSh
.IsHeaderFooterEdit() )
3006 rSh
.ToggleHeaderFooterEdit();
3012 if ( rSh
.IsHeaderFooterEdit( ) )
3013 rSh
.ToggleHeaderFooterEdit( );
3016 // Make sure that the separators are hidden
3017 rSh
.SetShowHeaderFooterSeparator( FrameControlType::Header
, false );
3018 rSh
.SetShowHeaderFooterSeparator( FrameControlType::Footer
, false );
3020 // Repaint everything
3021 // FIXME fdo#67358 for unknown reasons this causes painting
3022 // problems when resizing table columns, so disable it
3023 // rSh.GetWin()->Invalidate();
3026 // Toggle Hide-Whitespace if between pages.
3027 if (rSh
.GetViewOptions()->CanHideWhitespace() &&
3028 rSh
.GetLayout()->IsBetweenPages(aDocPos
))
3030 if (_rMEvt
.GetClicks() >= 2)
3032 SwViewOption
aOpt(*rSh
.GetViewOptions());
3033 aOpt
.SetHideWhitespaceMode(!aOpt
.IsHideWhitespaceMode());
3034 rSh
.ApplyViewOptions(aOpt
);
3041 if ( IsChainMode() )
3043 SetChainMode( false );
3045 SwFlyFrameFormat
*pFormat
= static_cast<SwFlyFrameFormat
*>(rSh
.GetFlyFrameFormat());
3046 if ( rSh
.Chainable( aDummy
, *pFormat
, aDocPos
) == SwChainRet::OK
)
3047 rSh
.Chain( *pFormat
, aDocPos
);
3048 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3052 // After GrabFocus a shell should be pushed. That should actually
3053 // work but in practice ...
3054 m_rView
.SelectShellForDrop();
3056 bool bCallBase
= true;
3058 if( s_pQuickHlpData
->m_bIsDisplayed
)
3059 s_pQuickHlpData
->Stop( rSh
);
3060 s_pQuickHlpData
->m_bAppendSpace
= false;
3062 if( rSh
.FinishOLEObj() )
3063 return; // end InPlace and the click doesn't count anymore
3065 CurrShell
aCurr( &rSh
);
3067 SdrView
*pSdrView
= rSh
.GetDrawView();
3070 if (pSdrView
->MouseButtonDown(aMEvt
, GetOutDev()))
3072 rSh
.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
3073 return; // SdrView's event evaluated
3077 m_bIsInMove
= false;
3078 m_aStartPos
= aMEvt
.GetPosPixel();
3079 m_aRszMvHdlPt
.setX( 0 );
3080 m_aRszMvHdlPt
.setY( 0 );
3082 SwTab nMouseTabCol
= SwTab::COL_NONE
;
3083 const bool bTmp
= !rSh
.IsDrawCreate() && !m_pApplyTempl
&& !rSh
.IsInSelect()
3084 && aMEvt
.GetClicks() == 1 && MOUSE_LEFT
== aMEvt
.GetButtons();
3086 SwTab::COL_NONE
!= (nMouseTabCol
= rSh
.WhichMouseTabCol( aDocPos
) ) &&
3087 !rSh
.IsObjSelectable( aDocPos
) )
3089 // Enhanced table selection
3090 if ( SwTab::SEL_HORI
<= nMouseTabCol
&& SwTab::COLSEL_VERT
>= nMouseTabCol
)
3093 rSh
.SelectTableRowCol( aDocPos
);
3094 if( SwTab::SEL_HORI
!= nMouseTabCol
&& SwTab::SEL_HORI_RTL
!= nMouseTabCol
)
3096 m_xRowColumnSelectionStart
= aDocPos
;
3097 m_bIsRowDrag
= SwTab::ROWSEL_HORI
== nMouseTabCol
||
3098 SwTab::ROWSEL_HORI_RTL
== nMouseTabCol
||
3099 SwTab::COLSEL_VERT
== nMouseTabCol
;
3100 m_bMBPressed
= true;
3106 if ( !rSh
.IsTableMode() )
3108 // comes from table columns out of the document.
3109 if(SwTab::COL_VERT
== nMouseTabCol
|| SwTab::COL_HORI
== nMouseTabCol
)
3110 m_rView
.SetTabColFromDoc( true );
3112 m_rView
.SetTabRowFromDoc( true );
3114 m_rView
.SetTabColFromDocPos( aDocPos
);
3115 m_rView
.InvalidateRulerPos();
3116 SfxBindings
& rBind
= m_rView
.GetViewFrame().GetBindings();
3118 if (RulerColumnDrag(
3119 aMEvt
, (SwTab::COL_VERT
== nMouseTabCol
|| SwTab::ROW_HORI
== nMouseTabCol
)))
3121 m_rView
.SetTabColFromDoc( false );
3122 m_rView
.SetTabRowFromDoc( false );
3123 m_rView
.InvalidateRulerPos();
3134 rSh
.IsNumLabel(aDocPos
))
3136 SwTextNode
* pNodeAtPos
= rSh
.GetNumRuleNodeAtPos( aDocPos
);
3137 m_rView
.SetNumRuleNodeFromDoc( pNodeAtPos
);
3138 m_rView
.InvalidateRulerPos();
3139 SfxBindings
& rBind
= m_rView
.GetViewFrame().GetBindings();
3142 if (RulerMarginDrag(aMEvt
, SwFEShell::IsVerticalModeAtNdAndPos(*pNodeAtPos
, aDocPos
)))
3144 m_rView
.SetNumRuleNodeFromDoc( nullptr );
3145 m_rView
.InvalidateRulerPos();
3151 // Make sure the pointer is set to 0, otherwise it may point to
3152 // nowhere after deleting the corresponding text node.
3153 m_rView
.SetNumRuleNodeFromDoc( nullptr );
3158 if ( rSh
.IsInSelect() )
3161 // query against LEFT because otherwise for example also a right
3162 // click releases the selection.
3163 if (MOUSE_LEFT
== aMEvt
.GetButtons())
3165 bool bOnlyText
= false;
3166 m_bMBPressed
= true;
3167 g_bNoInterrupt
= true;
3168 m_nKS_NUMDOWN_Count
= 0;
3172 // reset cursor position if applicable
3173 rSh
.ResetCursorStack();
3175 switch (aMEvt
.GetModifier() + aMEvt
.GetButtons())
3178 case MOUSE_LEFT
+ KEY_SHIFT
:
3179 case MOUSE_LEFT
+ KEY_MOD2
:
3180 if( rSh
.IsObjSelected() )
3183 if( !bIsDocReadOnly
&&
3186 nullptr != ( pHdl
= pSdrView
->PickHandle(aDocPos
) ) &&
3187 ( pHdl
->GetKind() == SdrHdlKind::Anchor
||
3188 pHdl
->GetKind() == SdrHdlKind::Anchor_TR
) )
3190 // #i121463# Set selected during drag
3191 pHdl
->SetSelected();
3192 m_pAnchorMarker
.reset( new SwAnchorMarker( pHdl
) );
3193 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3197 if (EnterDrawMode(aMEvt
, aDocPos
))
3199 g_bNoInterrupt
= false;
3202 else if ( m_rView
.GetDrawFuncPtr() && m_bInsFrame
)
3208 // Without SHIFT because otherwise Toggle doesn't work at selection
3209 if (aMEvt
.GetClicks() == 1)
3211 if ( rSh
.IsSelFrameMode())
3213 SdrHdl
* pHdl
= rSh
.GetDrawView()->PickHandle(aDocPos
);
3214 bool bHitHandle
= pHdl
&& pHdl
->GetKind() != SdrHdlKind::Anchor
&&
3215 pHdl
->GetKind() != SdrHdlKind::Anchor_TR
;
3217 if ((rSh
.IsInsideSelectedObj(aDocPos
) || bHitHandle
)
3218 && (aMEvt
.GetModifier() != KEY_SHIFT
|| bHitHandle
))
3220 rSh
.EnterSelFrameMode( &aDocPos
);
3221 if ( !m_pApplyTempl
)
3223 // only if no position to size was hit.
3227 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3228 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3230 g_bFrameDrag
= true;
3232 g_bNoInterrupt
= false;
3239 bool bExecHyperlinks
= m_rView
.GetDocShell()->IsReadOnly();
3240 if ( !bExecHyperlinks
)
3242 const bool bSecureOption
= SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink
);
3243 if ((bSecureOption
&& aMEvt
.GetModifier() == KEY_MOD1
)
3244 || (!bSecureOption
&& aMEvt
.GetModifier() != KEY_MOD1
))
3245 bExecHyperlinks
= true;
3248 // Enhanced selection
3249 sal_uInt8 nNumberOfClicks
= static_cast<sal_uInt8
>(aMEvt
.GetClicks() % 4);
3250 if (0 == nNumberOfClicks
&& 0 < aMEvt
.GetClicks())
3251 nNumberOfClicks
= 4;
3253 bool bExecDrawTextLink
= false;
3255 switch (aMEvt
.GetModifier() + aMEvt
.GetButtons())
3258 case MOUSE_LEFT
+ KEY_MOD1
:
3259 case MOUSE_LEFT
+ KEY_MOD2
:
3262 // fdo#79604: first, check if a link has been clicked - do not
3263 // select fly in this case!
3264 if (1 == nNumberOfClicks
)
3266 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3267 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3268 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3270 // hit a URL in DrawText object?
3271 if (bExecHyperlinks
&& pSdrView
)
3274 pSdrView
->PickAnything(aMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
3276 if (aVEvt
.meEvent
== SdrEventKind::ExecuteUrl
)
3277 bExecDrawTextLink
= true;
3281 if (1 == nNumberOfClicks
&& !bExecDrawTextLink
)
3283 // only try to select frame, if pointer already was
3284 // switched accordingly
3285 if ( m_aActHitType
!= SdrHitKind::NONE
&& !rSh
.IsSelFrameMode() &&
3286 !GetView().GetViewFrame().GetDispatcher()->IsLocked())
3288 // Test if there is a draw object at that position and if it should be selected.
3289 bool bShould
= rSh
.ShouldObjectBeSelected(aDocPos
);
3296 bool bUnLockView
= !rSh
.IsViewLocked();
3297 rSh
.LockView( true );
3299 = rSh
.SelectObj(aDocPos
, aMEvt
.IsMod1() ? SW_ENTER_GROUP
: 0);
3301 rSh
.LockView( false );
3305 // if the frame was deselected in the macro
3306 // the cursor just has to be displayed again
3307 if( FrameTypeFlags::NONE
== rSh
.GetSelFrameType() )
3311 if (rSh
.IsFrameSelected() && m_rView
.GetDrawFuncPtr())
3313 m_rView
.GetDrawFuncPtr()->Deactivate();
3314 m_rView
.SetDrawFuncPtr(nullptr);
3315 m_rView
.LeaveDrawCreate();
3316 m_rView
.AttrChangedNotify(nullptr);
3319 rSh
.EnterSelFrameMode( &aDocPos
);
3320 g_bFrameDrag
= true;
3321 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3326 bOnlyText
= rSh
.IsObjSelectable( aDocPos
);
3328 if (!m_rView
.GetDrawFuncPtr())
3332 bOnlyText
= KEY_MOD1
!= aMEvt
.GetModifier();
3334 else if ( rSh
.IsSelFrameMode() &&
3335 (m_aActHitType
== SdrHitKind::NONE
||
3336 !rSh
.IsInsideSelectedObj( aDocPos
)))
3340 if( !bIsDocReadOnly
&& !m_pAnchorMarker
&& nullptr !=
3341 ( pHdl
= pSdrView
->PickHandle(aDocPos
) ) &&
3342 ( pHdl
->GetKind() == SdrHdlKind::Anchor
||
3343 pHdl
->GetKind() == SdrHdlKind::Anchor_TR
) )
3345 m_pAnchorMarker
.reset( new SwAnchorMarker( pHdl
) );
3346 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3351 bool bUnLockView
= !rSh
.IsViewLocked();
3352 rSh
.LockView( true );
3353 sal_uInt8 nFlag
= aMEvt
.IsShift() ? SW_ADD_SELECT
: 0;
3355 nFlag
= nFlag
| SW_ENTER_GROUP
;
3357 if ( rSh
.IsSelFrameMode() )
3359 rSh
.UnSelectFrame();
3360 rSh
.LeaveSelFrameMode();
3361 m_rView
.AttrChangedNotify(nullptr);
3364 bool bSelObj
= rSh
.SelectObj( aDocPos
, nFlag
);
3366 rSh
.LockView( false );
3370 // move cursor here so that it is not drawn in the
3371 // frame first; ShowCursor() happens in LeaveSelFrameMode()
3372 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPos
, false));
3373 rSh
.LeaveSelFrameMode();
3374 m_rView
.AttrChangedNotify(nullptr);
3380 rSh
.EnterSelFrameMode( &aDocPos
);
3381 rSh
.SelFlyGrabCursor();
3382 rSh
.MakeSelVisible();
3383 g_bFrameDrag
= true;
3384 if( rSh
.IsFrameSelected() &&
3385 m_rView
.GetDrawFuncPtr() )
3387 m_rView
.GetDrawFuncPtr()->Deactivate();
3388 m_rView
.SetDrawFuncPtr(nullptr);
3389 m_rView
.LeaveDrawCreate();
3390 m_rView
.AttrChangedNotify(nullptr);
3392 UpdatePointer(aDocPos
, aMEvt
.GetModifier());
3399 switch ( nNumberOfClicks
)
3405 g_bFrameDrag
= false;
3406 if (!bIsDocReadOnly
&& rSh
.IsInsideSelectedObj(aDocPos
)
3407 && (FlyProtectFlags::NONE
3408 == rSh
.IsSelObjProtected(FlyProtectFlags::Content
3409 | FlyProtectFlags::Parent
)
3410 || rSh
.GetSelectionType() == SelectionType::Ole
))
3412 /* This is no good: on the one hand GetSelectionType is used as flag field
3413 * (take a look into the GetSelectionType method) and on the other hand the
3414 * return value is used in a switch without proper masking (very nice), this must lead to trouble
3416 switch ( rSh
.GetSelectionType() & ~SelectionType( SelectionType::FontWork
| SelectionType::ExtrudedCustomShape
) )
3418 case SelectionType::Graphic
:
3419 ResetMouseButtonDownFlags();
3420 if (!comphelper::LibreOfficeKit::isActive())
3422 GetView().GetViewFrame().GetBindings().Execute(
3423 FN_FORMAT_GRAFIC_DLG
, nullptr,
3424 SfxCallMode::RECORD
|SfxCallMode::SLOT
);
3428 // double click on OLE object --> OLE-InPlace
3429 case SelectionType::Ole
:
3430 ResetMouseButtonDownFlags();
3434 case SelectionType::Frame
:
3435 ResetMouseButtonDownFlags();
3436 if (!comphelper::LibreOfficeKit::isActive())
3438 GetView().GetViewFrame().GetBindings().Execute(
3439 FN_FORMAT_FRAME_DLG
, nullptr,
3440 SfxCallMode::RECORD
|SfxCallMode::SLOT
);
3444 case SelectionType::DrawObject
:
3445 ResetMouseButtonDownFlags();
3446 EnterDrawTextMode(aDocPos
);
3447 if ( auto pSwDrawTextShell
= dynamic_cast< SwDrawTextShell
*>( m_rView
.GetCurShell() ) )
3448 pSwDrawTextShell
->Init();
3455 // if the cursor position was corrected or if a Fly
3456 // was selected in ReadOnlyMode, no word selection, except when tiled rendering.
3457 if ((!g_bValidCursorPos
|| rSh
.IsFrameSelected()) && !comphelper::LibreOfficeKit::isActive())
3461 bool bFootnote
= false;
3463 if( !bIsDocReadOnly
&&
3464 (nullptr != (pField
= rSh
.GetCurField(true)) ||
3465 ( bFootnote
= rSh
.GetCurFootnote() ) ) )
3467 ResetMouseButtonDownFlags();
3469 GetView().GetViewFrame().GetBindings().Execute( FN_EDIT_FOOTNOTE
);
3472 SwFieldTypesEnum nTypeId
= pField
->GetTypeId();
3473 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
3476 case SwFieldTypesEnum::Postit
:
3477 case SwFieldTypesEnum::Script
:
3479 // if it's a Readonly region, status has to be enabled
3480 sal_uInt16 nSlot
= SwFieldTypesEnum::Postit
== nTypeId
? FN_POSTIT
: FN_JAVAEDIT
;
3481 SfxBoolItem
aItem(nSlot
, true);
3482 rVFrame
.GetBindings().SetState(aItem
);
3483 rVFrame
.GetBindings().Execute(nSlot
);
3486 case SwFieldTypesEnum::Authority
:
3487 rVFrame
.GetBindings().Execute(FN_EDIT_AUTH_ENTRY_DLG
);
3489 case SwFieldTypesEnum::Input
:
3490 case SwFieldTypesEnum::Dropdown
:
3491 case SwFieldTypesEnum::SetInput
:
3492 rVFrame
.GetBindings().Execute(FN_UPDATE_INPUTFIELDS
);
3495 rVFrame
.GetBindings().Execute(FN_EDIT_FIELD
);
3500 // in extended mode double and triple
3501 // click has no effect.
3502 if ( rSh
.IsExtMode() || rSh
.IsBlockMode() )
3505 // select word, AdditionalMode if applicable
3506 if (KEY_MOD1
== aMEvt
.GetModifier() && !rSh
.IsAddMode())
3509 rSh
.SelWrd( &aDocPos
);
3514 if (!rSh
.SelWrd(&aDocPos
) && comphelper::LibreOfficeKit::isActive())
3515 // Double click did not select any word: try to
3516 // select the current cell in case we are in a
3521 SwContentAtPos
aContentAtPos(IsAttrAtPos::FormControl
);
3522 if( rSh
.GetContentAtPos( aDocPos
, aContentAtPos
) &&
3523 aContentAtPos
.aFnd
.pFieldmark
!= nullptr)
3525 IFieldmark
*pFieldBM
= const_cast< IFieldmark
* > ( aContentAtPos
.aFnd
.pFieldmark
);
3526 if ( pFieldBM
->GetFieldname( ) == ODF_FORMDROPDOWN
|| pFieldBM
->GetFieldname( ) == ODF_FORMDATE
)
3528 ResetMouseButtonDownFlags();
3529 rSh
.getIDocumentMarkAccess()->ClearFieldActivation();
3530 GetView().GetViewFrame().GetBindings().Execute(SID_FM_CTL_PROPERTIES
);
3535 // tdf#143158 - handle alphabetical index entries
3536 SwContentAtPos
aToxContentAtPos(IsAttrAtPos::ToxMark
);
3537 if (rSh
.GetContentAtPos(aDocPos
, aToxContentAtPos
))
3539 const OUString sToxText
= aToxContentAtPos
.sStr
;
3540 if (!sToxText
.isEmpty() && aToxContentAtPos
.pFndTextAttr
)
3542 const SwTOXType
* pTType
3543 = aToxContentAtPos
.pFndTextAttr
->GetTOXMark().GetTOXType();
3544 if (pTType
&& pTType
->GetType() == TOXTypes::TOX_INDEX
)
3546 ResetMouseButtonDownFlags();
3547 GetView().GetViewFrame().GetBindings().Execute(
3548 FN_EDIT_IDX_ENTRY_DLG
);
3554 g_bHoldSelection
= true;
3560 g_bFrameDrag
= false;
3561 // in extended mode double and triple
3562 // click has no effect.
3563 if ( rSh
.IsExtMode() )
3566 // if the cursor position was corrected or if a Fly
3567 // was selected in ReadOnlyMode, no word selection.
3568 if ( !g_bValidCursorPos
|| rSh
.IsFrameSelected() )
3571 // select line, AdditionalMode if applicable
3572 const bool bMod
= KEY_MOD1
== aMEvt
.GetModifier() && !rSh
.IsAddMode();
3577 // Enhanced selection
3578 if ( 3 == nNumberOfClicks
)
3579 rSh
.SelSentence( &aDocPos
);
3581 rSh
.SelPara( &aDocPos
);
3586 g_bHoldSelection
= true;
3596 case MOUSE_LEFT
+ KEY_SHIFT
:
3597 case MOUSE_LEFT
+ KEY_SHIFT
+ KEY_MOD1
:
3599 bool bLockView
= m_bWasShdwCursor
;
3601 switch (aMEvt
.GetModifier())
3603 case KEY_MOD1
+ KEY_SHIFT
:
3605 if ( !m_bInsDraw
&& IsDrawObjSelectable( rSh
, aDocPos
) )
3609 if ( rSh
.IsSelFrameMode() )
3610 rSh
.SelectObj(aDocPos
, SW_ADD_SELECT
| SW_ENTER_GROUP
);
3612 { if ( rSh
.SelectObj( aDocPos
, SW_ADD_SELECT
| SW_ENTER_GROUP
) )
3614 rSh
.EnterSelFrameMode( &aDocPos
);
3615 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3616 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3617 g_bFrameDrag
= true;
3622 else if( rSh
.IsSelFrameMode() &&
3623 rSh
.GetDrawView()->PickHandle( aDocPos
))
3625 g_bFrameDrag
= true;
3626 g_bNoInterrupt
= false;
3632 if ( !bExecDrawTextLink
)
3634 if (rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton())
3636 // ctrl+left-click on outline node frame
3637 SwContentAtPos
aContentAtPos(IsAttrAtPos::Outline
);
3638 if(rSh
.GetContentAtPos(aDocPos
, aContentAtPos
))
3640 SwOutlineNodes::size_type nPos
;
3641 if (rSh
.GetNodes().GetOutLineNds().Seek_Entry(aContentAtPos
.aFnd
.pNode
, &nPos
))
3643 ToggleOutlineContentVisibility(nPos
, false);
3648 if ( !m_bInsDraw
&& IsDrawObjSelectable( rSh
, aDocPos
) && !lcl_urlOverBackground( rSh
, aDocPos
) )
3652 if ( rSh
.IsSelFrameMode() )
3653 rSh
.SelectObj(aDocPos
, SW_ENTER_GROUP
);
3655 { if ( rSh
.SelectObj( aDocPos
, SW_ENTER_GROUP
) )
3657 rSh
.EnterSelFrameMode( &aDocPos
);
3658 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3659 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3660 g_bFrameDrag
= true;
3665 else if( rSh
.IsSelFrameMode() &&
3666 rSh
.GetDrawView()->PickHandle( aDocPos
))
3668 g_bFrameDrag
= true;
3669 g_bNoInterrupt
= false;
3674 if ( !rSh
.IsAddMode() && !rSh
.IsExtMode() && !rSh
.IsBlockMode() )
3677 g_bModePushed
= true;
3679 bool bUnLockView
= !rSh
.IsViewLocked();
3680 rSh
.LockView( true );
3683 rSh
.LockView( false );
3691 if ( !rSh
.IsAddMode() && !rSh
.IsExtMode() && !rSh
.IsBlockMode() )
3694 g_bModePushed
= true;
3695 bool bUnLockView
= !rSh
.IsViewLocked();
3696 rSh
.LockView( true );
3697 rSh
.EnterBlockMode();
3699 rSh
.LockView( false );
3706 if (nNumberOfClicks
== 2)
3708 // Left mouse button, shift, double-click: see if we have a graphic and
3709 // dispatch its dialog in this case.
3710 if (rSh
.GetSelectionType() == SelectionType::Graphic
)
3712 GetView().GetViewFrame().GetBindings().Execute(
3713 FN_FORMAT_GRAFIC_DLG
, nullptr,
3714 SfxCallMode::RECORD
| SfxCallMode::SLOT
);
3719 if ( !m_bInsDraw
&& IsDrawObjSelectable( rSh
, aDocPos
) )
3723 if ( rSh
.IsSelFrameMode() )
3725 rSh
.SelectObj(aDocPos
, SW_ADD_SELECT
);
3727 const SdrMarkList
& rMarkList
= pSdrView
->GetMarkedObjectList();
3728 if (rMarkList
.GetMark(0) == nullptr)
3730 rSh
.LeaveSelFrameMode();
3731 m_rView
.AttrChangedNotify(nullptr);
3732 g_bFrameDrag
= false;
3736 { if ( rSh
.SelectObj( aDocPos
) )
3738 rSh
.EnterSelFrameMode( &aDocPos
);
3739 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3740 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3741 g_bFrameDrag
= true;
3748 bool bShould
= rSh
.ShouldObjectBeSelected(aDocPos
);
3751 // Left mouse button, shift, non-double-click, not a draw object and
3752 // have an object to select: select it.
3754 bool bSelObj
= rSh
.SelectObj(aDocPos
);
3757 rSh
.EnterSelFrameMode(&aDocPos
);
3762 if ( rSh
.IsSelFrameMode() &&
3763 rSh
.IsInsideSelectedObj( aDocPos
) )
3765 rSh
.EnterSelFrameMode( &aDocPos
);
3766 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
3767 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
3768 g_bFrameDrag
= true;
3771 if ( rSh
.IsSelFrameMode() )
3773 rSh
.UnSelectFrame();
3774 rSh
.LeaveSelFrameMode();
3775 m_rView
.AttrChangedNotify(nullptr);
3776 g_bFrameDrag
= false;
3778 if ( !rSh
.IsExtMode() )
3780 // don't start a selection when an
3781 // URL field or a graphic is clicked
3782 bool bSttSelect
= rSh
.HasSelection() ||
3783 PointerStyle::RefHand
!= GetPointer();
3788 if( bExecHyperlinks
)
3790 SwContentAtPos
aContentAtPos(
3792 IsAttrAtPos::InetAttr
);
3794 if( rSh
.GetContentAtPos( aDocPos
, aContentAtPos
) )
3796 if( !rSh
.IsViewLocked() &&
3797 !rSh
.IsReadOnlyAvailable() &&
3798 aContentAtPos
.IsInProtectSect() )
3803 else if( rSh
.IsURLGrfAtPos( aDocPos
))
3816 if( !rSh
.IsViewLocked() )
3818 SwContentAtPos
aContentAtPos( IsAttrAtPos::ClickField
|
3819 IsAttrAtPos::InetAttr
);
3820 if( rSh
.GetContentAtPos( aDocPos
, aContentAtPos
) &&
3821 !rSh
.IsReadOnlyAvailable() &&
3822 aContentAtPos
.IsInProtectSect() )
3827 if ( rSh
.IsGCAttr() )
3833 SwContentAtPos
aFieldAtPos(IsAttrAtPos::Field
);
3834 bool bEditableFieldClicked
= false;
3836 // Are we clicking on a field?
3837 if (rSh
.GetContentAtPos(aDocPos
, aFieldAtPos
))
3839 bool bEditableField
= (aFieldAtPos
.pFndTextAttr
!= nullptr
3840 && aFieldAtPos
.pFndTextAttr
->Which() == RES_TXTATR_INPUTFIELD
);
3842 if (!bEditableField
)
3844 rSh
.CallSetCursor(&aDocPos
, bOnlyText
);
3845 // Unfortunately the cursor may be on field
3846 // position or on position after field depending on which
3847 // half of the field was clicked on.
3848 SwTextAttr
const*const pTextField(aFieldAtPos
.pFndTextAttr
);
3850 rSh
.GetCurrentShellCursor().GetPoint()->GetContentIndex() != pTextField
->GetStart())
3852 assert(rSh
.GetCurrentShellCursor().GetPoint()->GetContentIndex() == (pTextField
->GetStart() + 1));
3853 rSh
.Left( SwCursorSkipMode::Chars
, false, 1, false );
3855 // don't go into the !bOverSelect block below - it moves
3861 bEditableFieldClicked
= true;
3865 bool bOverSelect
= rSh
.TestCurrPam( aDocPos
);
3866 bool bOverURLGrf
= false;
3868 bOverURLGrf
= bOverSelect
= nullptr != rSh
.IsURLGrfAtPos( aDocPos
);
3870 if ( !bOverSelect
|| rSh
.IsInSelect() )
3872 MoveCursor( rSh
, aDocPos
, bOnlyText
, bLockView
);
3875 if (!bOverURLGrf
&& !bExecDrawTextLink
&& !bOnlyText
)
3877 const SelectionType nSelType
= rSh
.GetSelectionType();
3878 // Check in general, if an object is selectable at given position.
3879 // Thus, also text fly frames in background become selectable via Ctrl-Click.
3880 if ( ( nSelType
& SelectionType::Ole
||
3881 nSelType
& SelectionType::Graphic
||
3882 rSh
.IsObjSelectable( aDocPos
) ) && !lcl_urlOverBackground( rSh
, aDocPos
) )
3884 SwMvContext
aMvContext( &rSh
);
3885 rSh
.EnterSelFrameMode();
3889 if ( !bOverSelect
&& bEditableFieldClicked
&& (!pCursorField
||
3890 pCursorField
!= aFieldAtPos
.pFndTextAttr
->GetFormatField().GetField()))
3892 // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
3893 // and CH_TXT_ATR_INPUTFIELDEND
3895 rSh
.SelectTextModel( aFieldAtPos
.pFndTextAttr
->GetStart() + 1,
3896 *(aFieldAtPos
.pFndTextAttr
->End()) - 1 );
3898 // don't reset here any longer so that, in case through MouseMove
3899 // with pressed Ctrl key a multiple-selection should happen,
3900 // the previous selection is not released in Drag.
3905 else if (MOUSE_RIGHT
== aMEvt
.GetButtons())
3907 if (rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton()
3908 && aMEvt
.GetModifier() == KEY_MOD1
)
3910 // ctrl+right-click on outline node frame
3911 SwContentAtPos
aContentAtPos(IsAttrAtPos::Outline
);
3912 if(rSh
.GetContentAtPos(aDocPos
, aContentAtPos
))
3914 SwOutlineNodes::size_type nPos
;
3915 if (rSh
.GetNodes().GetOutLineNds().Seek_Entry(aContentAtPos
.aFnd
.pNode
, &nPos
))
3917 ToggleOutlineContentVisibility(nPos
, !rSh
.GetViewOptions()->IsTreatSubOutlineLevelsAsContent());
3922 else if (!aMEvt
.GetModifier() && static_cast<sal_uInt8
>(aMEvt
.GetClicks() % 4) == 1
3923 && !rSh
.TestCurrPam(aDocPos
))
3925 SwContentAtPos
aFieldAtPos(IsAttrAtPos::Field
);
3927 // Are we clicking on a field?
3928 if (g_bValidCursorPos
3929 && rSh
.GetContentAtPos(aDocPos
, aFieldAtPos
)
3930 && aFieldAtPos
.pFndTextAttr
!= nullptr
3931 && aFieldAtPos
.pFndTextAttr
->Which() == RES_TXTATR_INPUTFIELD
3932 && (!pCursorField
|| pCursorField
!= aFieldAtPos
.pFndTextAttr
->GetFormatField().GetField()))
3935 MoveCursor( rSh
, aDocPos
, rSh
.IsObjSelectable( aDocPos
), m_bWasShdwCursor
);
3938 // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
3939 // and CH_TXT_ATR_INPUTFIELDEND
3941 rSh
.SelectTextModel( aFieldAtPos
.pFndTextAttr
->GetStart() + 1,
3942 *(aFieldAtPos
.pFndTextAttr
->End()) - 1 );
3948 Window::MouseButtonDown(aMEvt
);
3951 bool SwEditWin::changeMousePointer(Point
const & rDocPoint
)
3953 SwWrtShell
& rShell
= m_rView
.GetWrtShell();
3956 if ( SwTab::COL_NONE
!= (nMouseTabCol
= rShell
.WhichMouseTabCol( rDocPoint
) ) &&
3957 !rShell
.IsObjSelectable( rDocPoint
) )
3959 PointerStyle nPointer
= PointerStyle::Null
;
3960 bool bChkTableSel
= false;
3962 switch ( nMouseTabCol
)
3964 case SwTab::COL_VERT
:
3965 case SwTab::ROW_HORI
:
3966 nPointer
= PointerStyle::VSizeBar
;
3967 bChkTableSel
= true;
3969 case SwTab::ROW_VERT
:
3970 case SwTab::COL_HORI
:
3971 nPointer
= PointerStyle::HSizeBar
;
3972 bChkTableSel
= true;
3974 // Enhanced table selection
3975 case SwTab::SEL_HORI
:
3976 nPointer
= PointerStyle::TabSelectSE
;
3978 case SwTab::SEL_HORI_RTL
:
3979 case SwTab::SEL_VERT
:
3980 nPointer
= PointerStyle::TabSelectSW
;
3982 case SwTab::COLSEL_HORI
:
3983 case SwTab::ROWSEL_VERT
:
3984 nPointer
= PointerStyle::TabSelectS
;
3986 case SwTab::ROWSEL_HORI
:
3987 nPointer
= PointerStyle::TabSelectE
;
3989 case SwTab::ROWSEL_HORI_RTL
:
3990 case SwTab::COLSEL_VERT
:
3991 nPointer
= PointerStyle::TabSelectW
;
3993 default: break; // prevent compiler warning
3996 if ( PointerStyle::Null
!= nPointer
&&
3997 // i#35543 - Enhanced table selection is explicitly allowed in table mode
3998 ( !bChkTableSel
|| !rShell
.IsTableMode() ) &&
3999 !comphelper::LibreOfficeKit::isActive() )
4001 SetPointer( nPointer
);
4006 else if (rShell
.IsNumLabel(rDocPoint
, RULER_MOUSE_MARGINWIDTH
))
4008 // i#42921 - consider vertical mode
4009 SwTextNode
* pNodeAtPos
= rShell
.GetNumRuleNodeAtPos( rDocPoint
);
4010 const PointerStyle nPointer
=
4011 SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos
, rDocPoint
)
4012 ? PointerStyle::VSizeBar
4013 : PointerStyle::HSizeBar
;
4014 SetPointer( nPointer
);
4021 void SwEditWin::MouseMove(const MouseEvent
& _rMEvt
)
4023 MouseEvent
rMEvt(_rMEvt
);
4025 if (comphelper::LibreOfficeKit::isActive())
4027 if (vcl::Window
* pWindow
= m_rView
.GetPostItMgr()->IsHitSidebarWindow(rMEvt
.GetPosPixel()))
4029 pWindow
->MouseMove(rMEvt
);
4034 //ignore key modifiers for format paintbrush
4036 bool bExecFormatPaintbrush
= m_pApplyTempl
&& m_pApplyTempl
->m_pFormatClipboard
4037 && m_pApplyTempl
->m_pFormatClipboard
->HasContent();
4038 if( bExecFormatPaintbrush
)
4039 rMEvt
= MouseEvent( _rMEvt
.GetPosPixel(), _rMEvt
.GetClicks(),
4040 _rMEvt
.GetMode(), _rMEvt
.GetButtons() );
4043 // as long as an action is running the MouseMove should be disconnected
4044 // otherwise bug 40102 occurs
4045 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
4046 if( rSh
.ActionPend() )
4049 if (rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton())
4051 // add/remove outline content hide button
4052 const SwNodes
& rNds
= rSh
.GetDoc()->GetNodes();
4053 SwOutlineNodes::size_type nPos
;
4054 SwContentAtPos
aSwContentAtPos(IsAttrAtPos::Outline
);
4055 if (rSh
.GetContentAtPos(PixelToLogic(rMEvt
.GetPosPixel()), aSwContentAtPos
))
4057 // mouse pointer is on an outline paragraph node
4058 if(aSwContentAtPos
.aFnd
.pNode
&& aSwContentAtPos
.aFnd
.pNode
->IsTextNode())
4060 // Get the outline paragraph frame and compare it to the saved outline frame. If they
4061 // are not the same, remove the fold button from the saved outline frame, if not
4062 // already removed, and then add a fold button to the mouse over outline frame if
4063 // the content is not folded.
4064 SwContentFrame
* pContentFrame
=
4065 aSwContentAtPos
.aFnd
.pNode
->GetTextNode()->getLayoutFrame(rSh
.GetLayout());
4066 if (pContentFrame
!= m_pSavedOutlineFrame
)
4068 if (m_pSavedOutlineFrame
)
4070 if (m_pSavedOutlineFrame
->isFrameAreaDefinitionValid())
4072 SwTextNode
* pTextNode
= m_pSavedOutlineFrame
->GetTextNodeFirst();
4073 if (pTextNode
&& rNds
.GetOutLineNds().Seek_Entry(pTextNode
, &nPos
) &&
4074 rSh
.GetAttrOutlineContentVisible(nPos
))
4076 GetFrameControlsManager().RemoveControlsByType(
4077 FrameControlType::Outline
, m_pSavedOutlineFrame
);
4081 m_pSavedOutlineFrame
= static_cast<SwTextFrame
*>(pContentFrame
);
4083 // show fold button if outline content is visible
4084 if (rNds
.GetOutLineNds().Seek_Entry(aSwContentAtPos
.aFnd
.pNode
->GetTextNode(), &nPos
) &&
4085 rSh
.GetAttrOutlineContentVisible(nPos
))
4086 GetFrameControlsManager().SetOutlineContentVisibilityButton(pContentFrame
);
4089 else if (m_pSavedOutlineFrame
)
4091 // The saved frame may not still be in the document, e.g., when an outline paragraph
4092 // is deleted. This causes the call to GetTextNodeFirst to behave badly. Use
4093 // isFrameAreaDefinitionValid to check if the frame is still in the document.
4094 if (m_pSavedOutlineFrame
->isFrameAreaDefinitionValid())
4096 // current pointer pos is not over an outline frame
4097 // previous pointer pos was over an outline frame
4098 // remove outline content visibility button if showing
4099 SwTextNode
* pTextNode
= m_pSavedOutlineFrame
->GetTextNodeFirst();
4100 if (pTextNode
&& rNds
.GetOutLineNds().Seek_Entry(pTextNode
, &nPos
) &&
4101 rSh
.GetAttrOutlineContentVisible(nPos
))
4103 GetFrameControlsManager().RemoveControlsByType(
4104 FrameControlType::Outline
, m_pSavedOutlineFrame
);
4107 m_pSavedOutlineFrame
= nullptr;
4111 if( m_pShadCursor
&& 0 != (rMEvt
.GetModifier() + rMEvt
.GetButtons() ) )
4113 m_pShadCursor
.reset();
4116 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly();
4118 CurrShell
aCurr( &rSh
);
4120 //aPixPt == Point in Pixel, relative to ChildWin
4121 //aDocPt == Point in Twips, document coordinates
4122 const Point
aPixPt( rMEvt
.GetPosPixel() );
4123 const Point
aDocPt( PixelToLogic( aPixPt
) );
4125 if ( IsChainMode() )
4127 UpdatePointer( aDocPt
, rMEvt
.GetModifier() );
4131 SdrView
*pSdrView
= rSh
.GetDrawView();
4133 const SwCallMouseEvent
aLastCallEvent( m_aSaveCallEvent
);
4134 m_aSaveCallEvent
.Clear();
4136 if ( !bIsDocReadOnly
&& pSdrView
&& pSdrView
->MouseMove(rMEvt
,GetOutDev()) )
4138 SetPointer( PointerStyle::Text
);
4139 return; // evaluate SdrView's event
4142 const Point
aOldPt( rSh
.VisArea().Pos() );
4143 const bool bInsWin
= rSh
.VisArea().Contains( aDocPt
) || comphelper::LibreOfficeKit::isActive();
4145 if (rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton())
4147 if (m_pSavedOutlineFrame
&& !bInsWin
)
4149 // the mouse pointer has left the building (edit window)
4150 // remove the outline content visibility button if showing
4151 if (m_pSavedOutlineFrame
->isFrameAreaDefinitionValid())
4153 const SwNodes
& rNds
= rSh
.GetDoc()->GetNodes();
4154 SwOutlineNodes::size_type nPos
;
4155 SwTextNode
* pTextNode
= m_pSavedOutlineFrame
->GetTextNodeFirst();
4156 if (pTextNode
&& rNds
.GetOutLineNds().Seek_Entry(pTextNode
, &nPos
) &&
4157 rSh
.GetAttrOutlineContentVisible(nPos
))
4159 GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline
,
4160 m_pSavedOutlineFrame
);
4163 m_pSavedOutlineFrame
= nullptr;
4167 if( m_pShadCursor
&& !bInsWin
)
4169 m_pShadCursor
.reset();
4172 if( bInsWin
&& m_xRowColumnSelectionStart
)
4175 Point
aPos( aDocPt
);
4176 if( rSh
.SelectTableRowCol( *m_xRowColumnSelectionStart
, &aPos
, m_bIsRowDrag
))
4180 // position is necessary for OS/2 because obviously after a MB-Down
4181 // a MB-Move is called immediately.
4182 if( g_bDDTimerStarted
)
4184 Point
aDD( SwEditWin::s_nDDStartPosX
, SwEditWin::s_nDDStartPosY
);
4185 aDD
= LogicToPixel( aDD
);
4186 tools::Rectangle
aRect( aDD
.X()-3, aDD
.Y()-3, aDD
.X()+3, aDD
.Y()+3 );
4187 if ( !aRect
.Contains( aPixPt
) )
4188 StopDDTimer( &rSh
, aDocPt
);
4191 if(m_rView
.GetDrawFuncPtr())
4195 m_rView
.GetDrawFuncPtr()->MouseMove( rMEvt
);
4198 Point
aTmp( aDocPt
);
4199 aTmp
+= rSh
.VisArea().Pos() - aOldPt
;
4206 else if(!rSh
.IsFrameSelected() && !rSh
.IsObjSelected())
4208 SfxBindings
&rBnd
= rSh
.GetView().GetViewFrame().GetBindings();
4209 Point aRelPos
= rSh
.GetRelativePagePosition(aDocPt
);
4210 if(aRelPos
.X() >= 0)
4212 FieldUnit eMetric
= ::GetDfltMetric(dynamic_cast<SwWebView
*>( &GetView()) != nullptr );
4213 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC
, static_cast< sal_uInt16
>(eMetric
)));
4214 const SfxPointItem
aTmp1( SID_ATTR_POSITION
, aRelPos
);
4215 rBnd
.SetState( aTmp1
);
4219 rBnd
.Invalidate(SID_ATTR_POSITION
);
4221 rBnd
.Invalidate(SID_ATTR_SIZE
);
4222 const SvxStatusItem
aCell( SID_TABLE_CELL
, OUString(), StatusCategory::NONE
);
4223 rBnd
.SetState( aCell
);
4227 // determine if we only change the mouse pointer and return
4228 if (!bIsDocReadOnly
&& bInsWin
&& !m_pApplyTempl
&& !rSh
.IsInSelect() && changeMousePointer(aDocPt
))
4233 bool bDelShadCursor
= true;
4235 switch ( rMEvt
.GetModifier() + rMEvt
.GetButtons() )
4238 if( m_pAnchorMarker
)
4240 // Now we need to refresh the SdrHdl pointer of m_pAnchorMarker.
4241 // This looks a little bit tricky, but it solves the following
4242 // problem: the m_pAnchorMarker contains a pointer to an SdrHdl,
4243 // if the FindAnchorPos-call cause a scrolling of the visible
4244 // area, it's possible that the SdrHdl will be destroyed and a
4245 // new one will initialized at the original position(GetHdlPos).
4246 // So the m_pAnchorMarker has to find the right SdrHdl, if it's
4247 // the old one, it will find it with position aOld, if this one
4248 // is destroyed, it will find a new one at position GetHdlPos().
4250 const Point aOld
= m_pAnchorMarker
->GetPosForHitTest( *(rSh
.GetOut()) );
4251 Point aNew
= rSh
.FindAnchorPos( aDocPt
);
4253 if( pSdrView
&& (nullptr!=( pHdl
= pSdrView
->PickHandle( aOld
) )||
4254 nullptr !=(pHdl
= pSdrView
->PickHandle( m_pAnchorMarker
->GetHdlPos()) ) ) &&
4255 ( pHdl
->GetKind() == SdrHdlKind::Anchor
||
4256 pHdl
->GetKind() == SdrHdlKind::Anchor_TR
) )
4258 m_pAnchorMarker
->ChgHdl( pHdl
);
4259 if( aNew
.X() || aNew
.Y() )
4261 m_pAnchorMarker
->SetPos( aNew
);
4262 m_pAnchorMarker
->SetLastPos( aDocPt
);
4267 m_pAnchorMarker
.reset();
4272 if ( !m_bMBPressed
)
4274 if ( m_bIsInMove
|| IsMinMove( m_aStartPos
, aPixPt
) )
4277 LeaveArea( aDocPt
);
4280 if ( m_rView
.GetDrawFuncPtr() )
4282 pSdrView
->SetOrtho(false);
4283 m_rView
.GetDrawFuncPtr()->MouseMove( rMEvt
);
4291 SwWordCountWrapper
*pWrdCnt
= static_cast<SwWordCountWrapper
*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
4293 pWrdCnt
->UpdateCounts();
4297 case MOUSE_LEFT
+ KEY_SHIFT
:
4298 case MOUSE_LEFT
+ KEY_SHIFT
+ KEY_MOD1
:
4299 if ( !m_bMBPressed
)
4302 case MOUSE_LEFT
+ KEY_MOD1
:
4303 if ( g_bFrameDrag
&& rSh
.IsSelFrameMode() )
4308 if ( m_bIsInMove
|| IsMinMove( m_aStartPos
, aPixPt
) )
4310 // event processing for resizing
4311 if (pSdrView
&& pSdrView
->AreObjectsMarked())
4313 const Point
aSttPt( PixelToLogic( m_aStartPos
) );
4316 if( SdrHdlKind::User
== g_eSdrMoveHdl
)
4318 SdrHdl
* pHdl
= pSdrView
->PickHandle( aSttPt
);
4319 g_eSdrMoveHdl
= pHdl
? pHdl
->GetKind() : SdrHdlKind::Move
;
4322 const SwFrameFormat
*const pFlyFormat(rSh
.GetFlyFrameFormat());
4323 const SvxMacro
* pMacro
= nullptr;
4325 SvMacroItemId nEvent
= SdrHdlKind::Move
== g_eSdrMoveHdl
4326 ? SvMacroItemId::SwFrmMove
4327 : SvMacroItemId::SwFrmResize
;
4329 if (nullptr != pFlyFormat
)
4330 pMacro
= pFlyFormat
->GetMacro().GetMacroTable().Get(nEvent
);
4331 if (nullptr != pMacro
&&
4332 // or notify only e.g. every 20 Twip?
4333 m_aRszMvHdlPt
!= aDocPt
)
4335 m_aRszMvHdlPt
= aDocPt
;
4336 sal_uInt32 nPos
= 0;
4337 SbxArrayRef xArgs
= new SbxArray
;
4338 SbxVariableRef xVar
= new SbxVariable
;
4339 xVar
->PutString( pFlyFormat
->GetName() );
4340 xArgs
->Put(xVar
.get(), ++nPos
);
4342 if( SvMacroItemId::SwFrmResize
== nEvent
)
4344 xVar
= new SbxVariable
;
4345 xVar
->PutUShort( static_cast< sal_uInt16
>(g_eSdrMoveHdl
) );
4346 xArgs
->Put(xVar
.get(), ++nPos
);
4349 xVar
= new SbxVariable
;
4350 xVar
->PutLong( aDocPt
.X() - aSttPt
.X() );
4351 xArgs
->Put(xVar
.get(), ++nPos
);
4352 xVar
= new SbxVariable
;
4353 xVar
->PutLong( aDocPt
.Y() - aSttPt
.Y() );
4354 xArgs
->Put(xVar
.get(), ++nPos
);
4360 rSh
.ExecMacro( *pMacro
, &sRet
, xArgs
.get() );
4364 if( !sRet
.isEmpty() && sRet
.toInt32()!=0 )
4368 // event processing for resizing
4370 if( bIsDocReadOnly
)
4373 bool bResizeKeepRatio
= rSh
.GetSelectionType() & SelectionType::Graphic
||
4374 rSh
.GetSelectionType() & SelectionType::Media
||
4375 rSh
.GetSelectionType() & SelectionType::Ole
;
4376 bool bisResize
= g_eSdrMoveHdl
!= SdrHdlKind::Move
;
4380 // Resize proportionally when media is selected and the user drags on a corner
4381 const Point
aSttPt(PixelToLogic(m_aStartPos
));
4382 SdrHdl
* pHdl
= pSdrView
->PickHandle(aSttPt
);
4384 bResizeKeepRatio
= bResizeKeepRatio
&& pHdl
->IsCornerHdl();
4386 if (pSdrView
->GetDragMode() == SdrDragMode::Crop
)
4388 if (rMEvt
.IsShift())
4390 pSdrView
->SetAngleSnapEnabled(!bResizeKeepRatio
);
4392 pSdrView
->SetOrtho(!bResizeKeepRatio
);
4394 pSdrView
->SetOrtho(true);
4398 pSdrView
->SetAngleSnapEnabled(bResizeKeepRatio
);
4400 pSdrView
->SetOrtho(bResizeKeepRatio
);
4402 pSdrView
->SetOrtho(false);
4406 rSh
.Drag( &aDocPt
, rMEvt
.IsShift() );
4409 else if( bIsDocReadOnly
)
4414 Point
aTmp( aDocPt
);
4415 aTmp
+= rSh
.VisArea().Pos() - aOldPt
;
4418 else if(m_bIsInMove
)
4422 if ( !rSh
.IsSelFrameMode() && !g_bDDINetAttr
&&
4423 (IsMinMove( m_aStartPos
,aPixPt
) || m_bIsInMove
) &&
4424 (rSh
.IsInSelect() || !rSh
.TestCurrPam( aDocPt
)) )
4428 if ( rMEvt
.IsShift() )
4429 pSdrView
->SetOrtho(true);
4431 pSdrView
->SetOrtho(false);
4435 Point
aTmp( aDocPt
);
4436 aTmp
+= rSh
.VisArea().Pos() - aOldPt
;
4441 if( !rMEvt
.IsSynthetic() &&
4442 ( MOUSE_LEFT
!= rMEvt
.GetButtons() ||
4443 KEY_MOD1
!= rMEvt
.GetModifier() ||
4444 !rSh
.Is_FnDragEQBeginDrag() ||
4447 rSh
.Drag( &aDocPt
, false );
4449 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPt
, false));
4454 g_bDDINetAttr
= false;
4458 if ( m_pApplyTempl
)
4460 UpdatePointer(aDocPt
); // maybe a frame has to be marked here
4463 // change ui if mouse is over SwPostItField
4464 // TODO: do the same thing for redlines IsAttrAtPos::Redline
4465 SwContentAtPos
aContentAtPos( IsAttrAtPos::Field
);
4466 if (rSh
.GetContentAtPos(aDocPt
, aContentAtPos
, false))
4468 const SwField
* pField
= aContentAtPos
.aFnd
.pField
;
4469 if (pField
->Which()== SwFieldIds::Postit
)
4471 m_rView
.GetPostItMgr()->SetShadowState(reinterpret_cast<const SwPostItField
*>(pField
),false);
4474 m_rView
.GetPostItMgr()->SetShadowState(nullptr,false);
4477 m_rView
.GetPostItMgr()->SetShadowState(nullptr,false);
4485 bool bTstShdwCursor
= true;
4487 UpdatePointer( aDocPt
, rMEvt
.GetModifier() );
4489 const SwFrameFormat
* pFormat
= nullptr;
4490 const SwFormatINetFormat
* pINet
= nullptr;
4491 SwContentAtPos
aContentAtPos( IsAttrAtPos::InetAttr
);
4492 if( rSh
.GetContentAtPos( aDocPt
, aContentAtPos
) )
4493 pINet
= static_cast<const SwFormatINetFormat
*>(aContentAtPos
.aFnd
.pAttr
);
4495 const void* pTmp
= pINet
;
4498 nullptr != ( pTmp
= pFormat
= rSh
.GetFormatFromAnyObj( aDocPt
)))
4500 bTstShdwCursor
= false;
4502 m_aSaveCallEvent
.Set( pINet
);
4505 IMapObject
* pIMapObj
= pFormat
->GetIMapObject( aDocPt
);
4507 m_aSaveCallEvent
.Set( pFormat
, pIMapObj
);
4509 m_aSaveCallEvent
.Set( EVENT_OBJECT_URLITEM
, pFormat
);
4512 // should be over an InternetField with an
4514 if( m_aSaveCallEvent
!= aLastCallEvent
)
4516 if( aLastCallEvent
.HasEvent() )
4517 rSh
.CallEvent( SvMacroItemId::OnMouseOut
,
4518 aLastCallEvent
, true );
4519 // 0 says that the object doesn't have any table
4520 if( !rSh
.CallEvent( SvMacroItemId::OnMouseOver
,
4522 m_aSaveCallEvent
.Clear();
4525 else if( aLastCallEvent
.HasEvent() )
4527 // cursor was on an object
4528 rSh
.CallEvent( SvMacroItemId::OnMouseOut
,
4529 aLastCallEvent
, true );
4532 if( bTstShdwCursor
&& bInsWin
&& !bIsDocReadOnly
&&
4534 !rSh
.GetViewOptions()->getBrowseMode() &&
4535 rSh
.GetViewOptions()->IsShadowCursor() &&
4536 !(rMEvt
.GetModifier() + rMEvt
.GetButtons()) &&
4537 !rSh
.HasSelection() && !GetOutDev()->GetConnectMetaFile() )
4541 SwFillMode eMode
= rSh
.GetViewOptions()->GetShdwCursorFillMode();
4542 if( rSh
.GetShadowCursorPos( aDocPt
, eMode
, aRect
, eOrient
))
4544 if( !m_pShadCursor
)
4545 m_pShadCursor
.reset( new SwShadowCursor( *this,
4546 rSh
.GetViewOptions()->GetDirectCursorColor() ) );
4547 if( text::HoriOrientation::RIGHT
!= eOrient
&& text::HoriOrientation::CENTER
!= eOrient
)
4548 eOrient
= text::HoriOrientation::LEFT
;
4549 m_pShadCursor
->SetPos( aRect
.Pos(), aRect
.Height(), static_cast< sal_uInt16
>(eOrient
) );
4550 bDelShadCursor
= false;
4555 case MOUSE_LEFT
+ KEY_MOD2
:
4556 if( rSh
.IsBlockMode() && !rMEvt
.IsSynthetic() )
4558 rSh
.Drag( &aDocPt
, false );
4559 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPt
, false));
4565 if( bDelShadCursor
&& m_pShadCursor
)
4567 m_pShadCursor
.reset();
4569 m_bWasShdwCursor
= false;
4575 void SwEditWin::MouseButtonUp(const MouseEvent
& rMEvt
)
4577 if (comphelper::LibreOfficeKit::isActive())
4579 if (vcl::Window
* pWindow
= m_rView
.GetPostItMgr()->IsHitSidebarWindow(rMEvt
.GetPosPixel()))
4581 pWindow
->MouseButtonUp(rMEvt
);
4586 bool bCallBase
= true;
4588 bool bCallShadowCursor
= m_bWasShdwCursor
;
4589 m_bWasShdwCursor
= false;
4592 m_pShadCursor
.reset();
4595 m_xRowColumnSelectionStart
.reset();
4597 SdrHdlKind eOldSdrMoveHdl
= g_eSdrMoveHdl
;
4598 g_eSdrMoveHdl
= SdrHdlKind::User
; // for MoveEvents - reset again
4600 // preventively reset
4601 m_rView
.SetTabColFromDoc( false );
4602 m_rView
.SetNumRuleNodeFromDoc(nullptr);
4604 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
4605 CurrShell
aCurr( &rSh
);
4606 SdrView
*pSdrView
= rSh
.GetDrawView();
4609 // tdf34555: ortho was always reset before being used in EndSdrDrag
4610 // Now, it is reset only if not in Crop mode.
4611 if (pSdrView
->GetDragMode() != SdrDragMode::Crop
&& !rMEvt
.IsShift())
4612 pSdrView
->SetOrtho(false);
4614 if ( pSdrView
->MouseButtonUp( rMEvt
,GetOutDev() ) )
4616 rSh
.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
4617 return; // SdrView's event evaluated
4620 // only process MouseButtonUp when the Down went to that windows as well.
4621 if ( !m_bMBPressed
)
4623 // Undo for the watering can is already in CommandHdl
4624 // that's the way it should be!
4629 Point
aDocPt( PixelToLogic( rMEvt
.GetPosPixel() ) );
4631 if ( g_bDDTimerStarted
)
4633 StopDDTimer( &rSh
, aDocPt
);
4634 m_bMBPressed
= false;
4635 if ( rSh
.IsSelFrameMode() )
4637 rSh
.EndDrag( &aDocPt
, false );
4638 g_bFrameDrag
= false;
4640 g_bNoInterrupt
= false;
4641 const Point
aDocPos( PixelToLogic( rMEvt
.GetPosPixel() ) );
4642 if ((PixelToLogic(m_aStartPos
).Y() == (aDocPos
.Y())) && (PixelToLogic(m_aStartPos
).X() == (aDocPos
.X())))//To make sure it was not moved
4644 SdrPageView
* pPV
= nullptr;
4645 SdrObject
* pObj
= pSdrView
? pSdrView
->PickObj(aDocPos
, pSdrView
->getHitTolLog(), pPV
, SdrSearchOptions::ALSOONMASTER
) : nullptr;
4648 SwFrameFormat
* pFormat
= GetUserCall(pObj
)->GetFormat();
4649 SwFrameFormat
* pShapeFormat
= SwTextBoxHelper::getOtherTextBoxFormat(pFormat
, RES_FLYFRMFMT
);
4652 pSdrView
->UnmarkAllObj();
4653 pSdrView
->MarkObj(pObj
,pPV
);
4657 // If the fly frame is a textbox of a shape, then select the shape instead.
4658 SdrObject
* pShape
= pShapeFormat
->FindSdrObject();
4659 pSdrView
->UnmarkAllObj();
4660 pSdrView
->MarkObj(pShape
, pPV
);
4668 if( m_pAnchorMarker
)
4670 if(m_pAnchorMarker
->GetHdl())
4672 // #i121463# delete selected after drag
4673 m_pAnchorMarker
->GetHdl()->SetSelected(false);
4676 Point
aPnt( m_pAnchorMarker
->GetLastPos() );
4677 m_pAnchorMarker
.reset();
4678 if( aPnt
.X() || aPnt
.Y() )
4679 rSh
.FindAnchorPos( aPnt
, true );
4681 if ( m_bInsDraw
&& m_rView
.GetDrawFuncPtr() )
4683 if ( m_rView
.GetDrawFuncPtr()->MouseButtonUp( rMEvt
) )
4685 if (m_rView
.GetDrawFuncPtr()) // could have been destroyed in MouseButtonUp
4687 m_rView
.GetDrawFuncPtr()->Deactivate();
4689 if (!m_rView
.IsDrawMode())
4691 m_rView
.SetDrawFuncPtr(nullptr);
4692 SfxBindings
& rBind
= m_rView
.GetViewFrame().GetBindings();
4693 rBind
.Invalidate( SID_ATTR_SIZE
);
4694 rBind
.Invalidate( SID_TABLE_CELL
);
4698 if ( rSh
.IsObjSelected() )
4700 rSh
.EnterSelFrameMode();
4701 if (!m_rView
.GetDrawFuncPtr())
4702 StdDrawMode( SdrObjKind::NONE
, true );
4704 else if ( rSh
.IsFrameSelected() )
4706 rSh
.EnterSelFrameMode();
4711 const Point
aDocPos( PixelToLogic( m_aStartPos
) );
4712 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPos
, false));
4716 m_rView
.AttrChangedNotify(nullptr);
4718 else if (rMEvt
.GetButtons() == MOUSE_RIGHT
&& rSh
.IsDrawCreate())
4719 m_rView
.GetDrawFuncPtr()->BreakCreate(); // abort drawing
4721 g_bNoInterrupt
= false;
4722 if (IsMouseCaptured())
4726 bool bPopMode
= false;
4727 switch ( rMEvt
.GetModifier() + rMEvt
.GetButtons() )
4730 if ( m_bInsDraw
&& rSh
.IsDrawCreate() )
4732 if ( m_rView
.GetDrawFuncPtr() && m_rView
.GetDrawFuncPtr()->MouseButtonUp(rMEvt
) )
4734 m_rView
.GetDrawFuncPtr()->Deactivate();
4735 m_rView
.AttrChangedNotify(nullptr);
4736 if ( rSh
.IsObjSelected() )
4737 rSh
.EnterSelFrameMode();
4738 if ( m_rView
.GetDrawFuncPtr() && m_bInsFrame
)
4745 case MOUSE_LEFT
+ KEY_MOD1
:
4746 case MOUSE_LEFT
+ KEY_MOD2
:
4747 case MOUSE_LEFT
+ KEY_SHIFT
+ KEY_MOD1
:
4748 if ( g_bFrameDrag
&& rSh
.IsSelFrameMode() )
4750 if ( rMEvt
.IsMod1() ) // copy and don't move.
4752 // abort drag, use internal Copy instead
4753 tools::Rectangle aRect
;
4754 rSh
.GetDrawView()->TakeActionRect( aRect
);
4755 if (!aRect
.IsEmpty())
4758 Point aEndPt
, aSttPt
;
4759 if ( rSh
.GetSelFrameType() & FrameTypeFlags::FLY_ATCNT
)
4761 aEndPt
= aRect
.TopLeft();
4762 aSttPt
= rSh
.GetDrawView()->GetAllMarkedRect().TopLeft();
4766 aEndPt
= aRect
.Center();
4767 aSttPt
= rSh
.GetDrawView()->GetAllMarkedRect().Center();
4769 if ( aSttPt
!= aEndPt
)
4771 rSh
.StartUndo( SwUndoId::UI_DRAG_AND_COPY
);
4772 rSh
.Copy(rSh
, aSttPt
, aEndPt
);
4773 rSh
.EndUndo( SwUndoId::UI_DRAG_AND_COPY
);
4777 rSh
.EndDrag( &aDocPt
, false );
4783 const SwFrameFormat
*const pFlyFormat(rSh
.GetFlyFrameFormat());
4784 const SvxMacro
* pMacro
= nullptr;
4786 SvMacroItemId nEvent
= SdrHdlKind::Move
== eOldSdrMoveHdl
4787 ? SvMacroItemId::SwFrmMove
4788 : SvMacroItemId::SwFrmResize
;
4790 if (nullptr != pFlyFormat
)
4791 pMacro
= pFlyFormat
->GetMacro().GetMacroTable().Get(nEvent
);
4792 if (nullptr != pMacro
)
4794 const Point
aSttPt( PixelToLogic( m_aStartPos
) );
4795 m_aRszMvHdlPt
= aDocPt
;
4796 sal_uInt32 nPos
= 0;
4797 SbxArrayRef xArgs
= new SbxArray
;
4798 SbxVariableRef xVar
= new SbxVariable
;
4799 xVar
->PutString( pFlyFormat
->GetName() );
4800 xArgs
->Put(xVar
.get(), ++nPos
);
4802 if( SvMacroItemId::SwFrmResize
== nEvent
)
4804 xVar
= new SbxVariable
;
4805 xVar
->PutUShort( static_cast< sal_uInt16
>(eOldSdrMoveHdl
) );
4806 xArgs
->Put(xVar
.get(), ++nPos
);
4809 xVar
= new SbxVariable
;
4810 xVar
->PutLong( aDocPt
.X() - aSttPt
.X() );
4811 xArgs
->Put(xVar
.get(), ++nPos
);
4812 xVar
= new SbxVariable
;
4813 xVar
->PutLong( aDocPt
.Y() - aSttPt
.Y() );
4814 xArgs
->Put(xVar
.get(), ++nPos
);
4816 xVar
= new SbxVariable
;
4817 xVar
->PutUShort( 1 );
4818 xArgs
->Put(xVar
.get(), ++nPos
);
4822 rSh
.ExecMacro( *pMacro
, nullptr, xArgs
.get() );
4829 // See if the fly frame's anchor is in a content control. If so,
4830 // interact with it.
4831 const SwFormatAnchor
& rFormatAnchor
= pFlyFormat
->GetAnchor();
4832 SwNode
* pAnchorNode
= rFormatAnchor
.GetAnchorNode();
4835 SwTextNode
* pTextNode
= pAnchorNode
->GetTextNode();
4838 SwTextAttr
* pAttr
= pTextNode
->GetTextAttrAt(
4839 rFormatAnchor
.GetAnchorContentOffset(), RES_TXTATR_CONTENTCONTROL
,
4840 ::sw::GetTextAttrMode::Parent
);
4843 SwTextContentControl
* pTextContentControl
4844 = static_txtattr_cast
<SwTextContentControl
*>(pAttr
);
4845 const SwFormatContentControl
& rFormatContentControl
4846 = pTextContentControl
->GetContentControl();
4847 rSh
.GotoContentControl(rFormatContentControl
);
4853 rSh
.EndDrag( &aDocPt
, false );
4855 g_bFrameDrag
= false;
4861 case MOUSE_LEFT
+ KEY_SHIFT
:
4862 if (rSh
.IsSelFrameMode())
4865 rSh
.EndDrag( &aDocPt
, false );
4866 g_bFrameDrag
= false;
4871 if( g_bHoldSelection
)
4873 // the EndDrag should be called in any case
4874 g_bHoldSelection
= false;
4875 rSh
.EndDrag( &aDocPt
, false );
4879 SwContentAtPos
aFieldAtPos ( IsAttrAtPos::Field
);
4880 if ( !rSh
.IsInSelect() && rSh
.TestCurrPam( aDocPt
) &&
4881 !rSh
.GetContentAtPos( aDocPt
, aFieldAtPos
) )
4883 const bool bTmpNoInterrupt
= g_bNoInterrupt
;
4884 g_bNoInterrupt
= false;
4885 { // create only temporary move context because otherwise
4886 // the query to the content form doesn't work!!!
4887 SwMvContext
aMvContext( &rSh
);
4888 const Point
aDocPos( PixelToLogic( m_aStartPos
) );
4889 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPos
, false));
4891 g_bNoInterrupt
= bTmpNoInterrupt
;
4896 bool bInSel
= rSh
.IsInSelect();
4897 rSh
.EndDrag( &aDocPt
, false );
4899 // Internetfield? --> call link (load doc!!)
4902 LoadUrlFlags nFilter
= LoadUrlFlags::NONE
;
4903 if( KEY_MOD1
== rMEvt
.GetModifier() )
4904 nFilter
|= LoadUrlFlags::NewView
;
4906 bool bExecHyperlinks
= m_rView
.GetDocShell()->IsReadOnly();
4907 if ( !bExecHyperlinks
)
4909 const bool bSecureOption
= SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink
);
4910 if ( ( bSecureOption
&& rMEvt
.GetModifier() == KEY_MOD1
) ||
4911 ( !bSecureOption
&& rMEvt
.GetModifier() != KEY_MOD1
) )
4912 bExecHyperlinks
= true;
4915 const bool bExecSmarttags
= rMEvt
.GetModifier() == KEY_MOD1
;
4918 bExecHyperlinks
= false;
4920 SwContentAtPos
aContentAtPos( IsAttrAtPos::Field
|
4921 IsAttrAtPos::InetAttr
|
4922 IsAttrAtPos::SmartTag
| IsAttrAtPos::FormControl
|
4923 IsAttrAtPos::ContentControl
);
4925 if( rSh
.GetContentAtPos( aDocPt
, aContentAtPos
) )
4927 // Do it again if we're not on a field/hyperlink to update the cursor accordingly
4928 if ( IsAttrAtPos::Field
!= aContentAtPos
.eContentAtPos
4929 && IsAttrAtPos::InetAttr
!= aContentAtPos
.eContentAtPos
)
4930 rSh
.GetContentAtPos( aDocPt
, aContentAtPos
, true );
4932 bool bViewLocked
= rSh
.IsViewLocked();
4933 if( !bViewLocked
&& !rSh
.IsReadOnlyAvailable() &&
4934 aContentAtPos
.IsInProtectSect() )
4935 rSh
.LockView( true );
4939 if( IsAttrAtPos::Field
== aContentAtPos
.eContentAtPos
)
4941 bool bAddMode(false);
4942 // AdditionalMode if applicable
4943 if (KEY_MOD1
== rMEvt
.GetModifier()
4944 && !rSh
.IsAddMode())
4949 if ( aContentAtPos
.pFndTextAttr
!= nullptr
4950 && aContentAtPos
.pFndTextAttr
->Which() == RES_TXTATR_INPUTFIELD
)
4952 if (!rSh
.IsInSelect())
4954 // create only temporary move context because otherwise
4955 // the query to the content form doesn't work!!!
4956 SwMvContext
aMvContext( &rSh
);
4957 const Point
aDocPos( PixelToLogic( m_aStartPos
) );
4958 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPos
, false));
4962 g_bValidCursorPos
= true;
4967 rSh
.ClickToField(*aContentAtPos
.aFnd
.pField
, bExecHyperlinks
);
4968 // a bit of a mystery what this is good for?
4969 // in this case we assume it's valid since we
4970 // just selected a field
4971 g_bValidCursorPos
= true;
4978 else if (aContentAtPos
.eContentAtPos
== IsAttrAtPos::ContentControl
)
4980 auto pTextContentControl
4981 = static_txtattr_cast
<const SwTextContentControl
*>(
4982 aContentAtPos
.pFndTextAttr
);
4983 const SwFormatContentControl
& rFormatContentControl
4984 = pTextContentControl
->GetContentControl();
4985 rSh
.GotoContentControl(rFormatContentControl
);
4987 else if ( IsAttrAtPos::SmartTag
== aContentAtPos
.eContentAtPos
)
4989 // execute smarttag menu
4990 if ( bExecSmarttags
&& SwSmartTagMgr::Get().IsSmartTagsEnabled() )
4991 m_rView
.ExecSmartTagPopup( aDocPt
);
4993 else if ( IsAttrAtPos::FormControl
== aContentAtPos
.eContentAtPos
)
4995 OSL_ENSURE( aContentAtPos
.aFnd
.pFieldmark
!= nullptr, "where is my field ptr???");
4996 if ( aContentAtPos
.aFnd
.pFieldmark
!= nullptr)
4998 IFieldmark
*fieldBM
= const_cast< IFieldmark
* > ( aContentAtPos
.aFnd
.pFieldmark
);
4999 if ( fieldBM
->GetFieldname( ) == ODF_FORMCHECKBOX
)
5001 ICheckboxFieldmark
& rCheckboxFm
= dynamic_cast<ICheckboxFieldmark
&>(*fieldBM
);
5002 rCheckboxFm
.SetChecked(!rCheckboxFm
.IsChecked());
5003 rCheckboxFm
.Invalidate();
5004 rSh
.InvalidateWindows( SwRect(m_rView
.GetVisArea()) );
5008 else if ( IsAttrAtPos::InetAttr
== aContentAtPos
.eContentAtPos
)
5010 if (comphelper::LibreOfficeKit::isActive())
5012 OUString
val((*static_cast<const SwFormatINetFormat
*>(aContentAtPos
.aFnd
.pAttr
)).GetValue());
5013 if (val
.startsWith("#"))
5014 bExecHyperlinks
= true;
5016 if ( bExecHyperlinks
&& aContentAtPos
.aFnd
.pAttr
)
5017 rSh
.ClickToINetAttr( *static_cast<const SwFormatINetFormat
*>(aContentAtPos
.aFnd
.pAttr
), nFilter
);
5020 rSh
.LockView( bViewLocked
);
5021 bCallShadowCursor
= false;
5025 aContentAtPos
= SwContentAtPos( IsAttrAtPos::Ftn
);
5026 if( !rSh
.GetContentAtPos( aDocPt
, aContentAtPos
, true ) && bExecHyperlinks
)
5031 pSdrView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
5033 if (pSdrView
&& aVEvt
.meEvent
== SdrEventKind::ExecuteUrl
)
5036 const SvxURLField
*pField
= aVEvt
.mpURLField
;
5039 const OUString
& sURL(pField
->GetURL());
5040 const OUString
& sTarget(pField
->GetTargetFrame());
5041 ::LoadURL(rSh
, sURL
, nFilter
, sTarget
);
5043 bCallShadowCursor
= false;
5049 if( rSh
.ClickToINetGrf( aDocPt
, nFilter
))
5050 bCallShadowCursor
= false;
5055 if( bCallShadowCursor
&&
5056 rSh
.GetViewOptions()->IsShadowCursor() &&
5057 MOUSE_LEFT
== (rMEvt
.GetModifier() + rMEvt
.GetButtons()) &&
5058 !rSh
.HasSelection() &&
5059 !GetOutDev()->GetConnectMetaFile() &&
5060 rSh
.VisArea().Contains( aDocPt
))
5062 SwUndoId
nLastUndoId(SwUndoId::EMPTY
);
5063 if (rSh
.GetLastUndoInfo(nullptr, & nLastUndoId
))
5065 if (SwUndoId::INS_FROM_SHADOWCRSR
== nLastUndoId
)
5070 SwFillMode eMode
= rSh
.GetViewOptions()->GetShdwCursorFillMode();
5071 rSh
.SetShadowCursorPos( aDocPt
, eMode
);
5079 // reset pushed mode in Down again if applicable
5080 if ( bPopMode
&& g_bModePushed
)
5083 g_bModePushed
= false;
5095 SelectionType eSelection
= rSh
.GetSelectionType();
5096 SwFormatClipboard
* pFormatClipboard
= m_pApplyTempl
->m_pFormatClipboard
;
5097 if( pFormatClipboard
)//apply format paintbrush
5099 //get some parameters
5100 SwWrtShell
& rWrtShell
= m_rView
.GetWrtShell();
5101 SfxStyleSheetBasePool
* pPool
=nullptr;
5102 bool bNoCharacterFormats
= false;
5103 bool bNoParagraphFormats
= true;
5105 SwDocShell
* pDocSh
= m_rView
.GetDocShell();
5107 pPool
= pDocSh
->GetStyleSheetPool();
5108 if( (rMEvt
.GetModifier()&KEY_MOD1
) && (rMEvt
.GetModifier()&KEY_SHIFT
) )
5110 bNoCharacterFormats
= true;
5111 bNoParagraphFormats
= false;
5113 else if( rMEvt
.GetModifier() & KEY_MOD1
)
5114 bNoParagraphFormats
= false;
5117 pFormatClipboard
->Paste( rWrtShell
, pPool
, bNoCharacterFormats
, bNoParagraphFormats
);
5119 //if the clipboard is empty after paste remove the ApplyTemplate
5120 if(!pFormatClipboard
->HasContent())
5121 SetApplyTemplate(SwApplyTemplate());
5123 //tdf#38101 remove temporary highlighting
5124 m_pUserMarker
.reset();
5126 else if( m_pApplyTempl
->nColor
)
5129 switch( m_pApplyTempl
->nColor
)
5131 case SID_ATTR_CHAR_COLOR_EXT
:
5132 nId
= RES_CHRATR_COLOR
;
5134 case SID_ATTR_CHAR_BACK_COLOR
:
5135 case SID_ATTR_CHAR_COLOR_BACKGROUND
:
5136 nId
= RES_CHRATR_BACKGROUND
;
5139 if( nId
&& (SelectionType::Text
|SelectionType::Table
) & eSelection
)
5141 if( rSh
.IsSelection() && !rSh
.HasReadonlySel() )
5143 m_pApplyTempl
->nUndo
=
5144 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5145 if (nId
== RES_CHRATR_BACKGROUND
)
5146 ApplyCharBackground(m_aWaterCanTextBackColor
, model::ComplexColor(), rSh
);
5148 rSh
.SetAttrItem( SvxColorItem( m_aWaterCanTextColor
, nId
) );
5149 rSh
.UnSetVisibleCursor();
5151 rSh
.SetVisibleCursor(aDocPt
);
5153 m_aTemplateTimer
.Stop();
5155 else if(rMEvt
.GetClicks() == 1)
5157 // no selection -> so turn off watering can
5158 m_aTemplateTimer
.Start();
5164 OUString aStyleName
;
5165 switch ( m_pApplyTempl
->eType
)
5167 case SfxStyleFamily::Para
:
5168 if( (( SelectionType::Text
| SelectionType::Table
)
5169 & eSelection
) && !rSh
.HasReadonlySel() )
5171 rSh
.SetTextFormatColl( m_pApplyTempl
->aColl
.pTextColl
);
5172 m_pApplyTempl
->nUndo
=
5173 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5175 if ( m_pApplyTempl
->aColl
.pTextColl
)
5176 aStyleName
= m_pApplyTempl
->aColl
.pTextColl
->GetName();
5179 case SfxStyleFamily::Char
:
5180 if( (( SelectionType::Text
| SelectionType::Table
)
5181 & eSelection
) && !rSh
.HasReadonlySel() )
5183 rSh
.SetAttrItem( SwFormatCharFormat(m_pApplyTempl
->aColl
.pCharFormat
) );
5184 rSh
.UnSetVisibleCursor();
5186 rSh
.SetVisibleCursor(aDocPt
);
5187 m_pApplyTempl
->nUndo
=
5188 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5190 if ( m_pApplyTempl
->aColl
.pCharFormat
)
5191 aStyleName
= m_pApplyTempl
->aColl
.pCharFormat
->GetName();
5194 case SfxStyleFamily::Frame
:
5196 const SwFrameFormat
* pFormat
= rSh
.GetFormatFromObj( aDocPt
);
5197 if(dynamic_cast<const SwFlyFrameFormat
*>( pFormat
) )
5199 rSh
.SetFrameFormat( m_pApplyTempl
->aColl
.pFrameFormat
, false, &aDocPt
);
5200 m_pApplyTempl
->nUndo
=
5201 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5203 if( m_pApplyTempl
->aColl
.pFrameFormat
)
5204 aStyleName
= m_pApplyTempl
->aColl
.pFrameFormat
->GetName();
5208 case SfxStyleFamily::Page
:
5209 // no Undo with page templates
5210 rSh
.ChgCurPageDesc( *m_pApplyTempl
->aColl
.pPageDesc
);
5211 if ( m_pApplyTempl
->aColl
.pPageDesc
)
5212 aStyleName
= m_pApplyTempl
->aColl
.pPageDesc
->GetName();
5213 m_pApplyTempl
->nUndo
=
5214 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5217 case SfxStyleFamily::Pseudo
:
5218 if( !rSh
.HasReadonlySel() )
5220 rSh
.SetCurNumRule( *m_pApplyTempl
->aColl
.pNumRule
,
5222 m_pApplyTempl
->aColl
.pNumRule
->GetDefaultListId() );
5224 m_pApplyTempl
->nUndo
=
5225 std::min(m_pApplyTempl
->nUndo
, rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5226 if( m_pApplyTempl
->aColl
.pNumRule
)
5227 aStyleName
= m_pApplyTempl
->aColl
.pNumRule
->GetName();
5233 uno::Reference
< frame::XDispatchRecorder
> xRecorder
=
5234 m_rView
.GetViewFrame().GetBindings().GetRecorder();
5235 if ( !aStyleName
.isEmpty() && xRecorder
.is() )
5237 SfxShell
*pSfxShell
= lcl_GetTextShellFromDispatcher( m_rView
);
5240 SfxRequest
aReq(m_rView
.GetViewFrame(), SID_STYLE_APPLY
);
5241 aReq
.AppendItem( SfxStringItem( SID_STYLE_APPLY
, aStyleName
) );
5242 aReq
.AppendItem( SfxUInt16Item( SID_STYLE_FAMILY
, static_cast<sal_uInt16
>(m_pApplyTempl
->eType
) ) );
5250 // Only processed MouseEvents arrive here; only at these this mode can
5252 m_bMBPressed
= false;
5254 // Make this call just to be sure. Selecting has finished surely by now.
5255 // Otherwise the timeout's timer could give problems.
5257 g_bNoInterrupt
= false;
5260 Window::MouseButtonUp(rMEvt
);
5262 if (!(pSdrView
&& rMEvt
.GetClicks() == 1 && comphelper::LibreOfficeKit::isActive()))
5265 // When tiled rendering, single click on a shape text starts editing already.
5266 SdrViewEvent aViewEvent
;
5267 SdrHitKind eHit
= pSdrView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONUP
, aViewEvent
);
5268 const SdrMarkList
& rMarkList
= pSdrView
->GetMarkedObjectList();
5269 if (eHit
== SdrHitKind::TextEditObj
&& rMarkList
.GetMarkCount() == 1)
5271 if (SdrObject
* pObj
= rMarkList
.GetMark(0)->GetMarkedSdrObj())
5273 EnterDrawTextMode(pObj
->GetLogicRect().Center());
5274 if ( auto pSwDrawTextShell
= dynamic_cast< SwDrawTextShell
*>( m_rView
.GetCurShell() ) )
5275 pSwDrawTextShell
->Init();
5283 void SwEditWin::SetApplyTemplate(const SwApplyTemplate
&rTempl
)
5285 static bool bIdle
= false;
5286 m_pApplyTempl
.reset();
5287 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
5289 if(rTempl
.m_pFormatClipboard
)
5291 m_pApplyTempl
.reset(new SwApplyTemplate( rTempl
));
5292 m_pApplyTempl
->nUndo
= rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5293 SetPointer( PointerStyle::Fill
);//@todo #i20119# maybe better a new brush pointer here in future
5294 rSh
.NoEdit( false );
5295 bIdle
= rSh
.GetViewOptions()->IsIdle();
5296 rSh
.GetViewOptions()->SetIdle( false );
5298 else if(rTempl
.nColor
)
5300 m_pApplyTempl
.reset(new SwApplyTemplate( rTempl
));
5301 m_pApplyTempl
->nUndo
= rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5302 SetPointer( PointerStyle::Fill
);
5303 rSh
.NoEdit( false );
5304 bIdle
= rSh
.GetViewOptions()->IsIdle();
5305 rSh
.GetViewOptions()->SetIdle( false );
5307 else if( rTempl
.eType
!= SfxStyleFamily::None
)
5309 m_pApplyTempl
.reset(new SwApplyTemplate( rTempl
));
5310 m_pApplyTempl
->nUndo
= rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5311 SetPointer( PointerStyle::Fill
);
5312 rSh
.NoEdit( false );
5313 bIdle
= rSh
.GetViewOptions()->IsIdle();
5314 rSh
.GetViewOptions()->SetIdle( false );
5318 SetPointer( PointerStyle::Text
);
5319 rSh
.UnSetVisibleCursor();
5321 rSh
.GetViewOptions()->SetIdle( bIdle
);
5322 if ( !rSh
.IsSelFrameMode() )
5326 static sal_uInt16 aInva
[] =
5329 SID_ATTR_CHAR_COLOR_EXT
,
5330 SID_ATTR_CHAR_COLOR_BACKGROUND_EXT
,
5333 m_rView
.GetViewFrame().GetBindings().Invalidate(aInva
);
5339 SwEditWin::SwEditWin(vcl::Window
*pParent
, SwView
&rMyView
):
5340 DocWindow(pParent
, WinBits(WB_CLIPCHILDREN
| WB_DIALOGCONTROL
)),
5341 DropTargetHelper( this ),
5342 DragSourceHelper( this ),
5344 m_aTimer("SwEditWin"),
5345 m_aKeyInputFlushTimer("SwEditWin m_aKeyInputFlushTimer"),
5346 m_eBufferLanguage(LANGUAGE_DONTKNOW
),
5347 m_aTemplateTimer("SwEditWin m_aTemplateTimer"),
5348 m_pUserMarkerObj( nullptr ),
5352 m_aActHitType(SdrHitKind::NONE
),
5353 m_nDropFormat( SotClipboardFormatId::NONE
),
5355 m_nDropDestination( SotExchangeDest::NONE
),
5357 m_eBezierMode(SID_BEZIER_INSERT
),
5358 m_nInsFrameColCount( 1 ),
5359 m_eDrawMode(SdrObjKind::NONE
),
5361 m_bMBPressed(false),
5367 m_bOldIdleSet(false),
5368 m_bChainMode(false),
5369 m_bWasShdwCursor(false),
5370 m_bLockInput(false),
5371 m_bIsRowDrag(false),
5372 m_bUseInputLanguage(false),
5373 m_bObjectSelect(false),
5374 m_nKS_NUMDOWN_Count(0),
5375 m_nKS_NUMINDENTINC_Count(0),
5376 m_pFrameControlsManager(new SwFrameControlsManager(this))
5378 set_id("writer_edit");
5379 SetHelpId(HID_EDIT_WIN
);
5380 EnableChildTransparentMode();
5381 SetDialogControlFlags( DialogControlFlags::Return
| DialogControlFlags::WantFocus
);
5383 m_bMBPressed
= m_bInsDraw
= m_bInsFrame
=
5384 m_bIsInDrag
= m_bOldIdle
= m_bOldIdleSet
= m_bChainMode
= m_bWasShdwCursor
= false;
5385 // initially use the input language
5386 m_bUseInputLanguage
= true;
5388 SetMapMode(MapMode(MapUnit::MapTwip
));
5390 SetPointer( PointerStyle::Text
);
5391 m_aTimer
.SetInvokeHandler(LINK(this, SwEditWin
, TimerHandler
));
5393 m_aKeyInputFlushTimer
.SetTimeout( 20 );
5394 m_aKeyInputFlushTimer
.SetInvokeHandler(LINK(this, SwEditWin
, KeyInputFlushHandler
));
5396 // TemplatePointer for colors should be reset without
5397 // selection after single click, but not after double-click (tdf#122442)
5398 m_aTemplateTimer
.SetTimeout(GetSettings().GetMouseSettings().GetDoubleClickTime());
5399 m_aTemplateTimer
.SetInvokeHandler(LINK(this, SwEditWin
, TemplateTimerHdl
));
5401 // temporary solution!!! Should set the font of the current
5402 // insert position at every cursor movement!
5403 if( !rMyView
.GetDocShell()->IsReadOnly() )
5406 SetInputContext( InputContext( aFont
, InputContextFlags::Text
|
5407 InputContextFlags::ExtText
) );
5411 SwEditWin::~SwEditWin()
5416 void SwEditWin::dispose()
5418 m_pShadCursor
.reset();
5420 if( s_pQuickHlpData
->m_bIsDisplayed
&& m_rView
.GetWrtShellPtr() )
5421 s_pQuickHlpData
->Stop( m_rView
.GetWrtShell() );
5422 g_bExecuteDrag
= false;
5423 m_pApplyTempl
.reset();
5425 m_rView
.SetDrawFuncPtr(nullptr);
5427 m_pUserMarker
.reset();
5429 m_pAnchorMarker
.reset();
5431 m_pFrameControlsManager
->dispose();
5432 m_pFrameControlsManager
.reset();
5434 DragSourceHelper::dispose();
5435 DropTargetHelper::dispose();
5436 vcl::Window::dispose();
5440 * Turn on DrawTextEditMode
5442 void SwEditWin::EnterDrawTextMode( const Point
& aDocPos
)
5444 if ( m_rView
.EnterDrawTextMode(aDocPos
) )
5446 if (m_rView
.GetDrawFuncPtr())
5448 m_rView
.GetDrawFuncPtr()->Deactivate();
5449 m_rView
.SetDrawFuncPtr(nullptr);
5450 m_rView
.LeaveDrawCreate();
5453 m_rView
.AttrChangedNotify(nullptr);
5460 bool SwEditWin::EnterDrawMode(const MouseEvent
& rMEvt
, const Point
& aDocPos
)
5462 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
5463 SdrView
*pSdrView
= rSh
.GetDrawView();
5465 if ( m_rView
.GetDrawFuncPtr() )
5467 if (rSh
.IsDrawCreate())
5470 bool bRet
= m_rView
.GetDrawFuncPtr()->MouseButtonDown( rMEvt
);
5471 m_rView
.AttrChangedNotify(nullptr);
5475 if ( pSdrView
&& pSdrView
->IsTextEdit() )
5477 bool bUnLockView
= !rSh
.IsViewLocked();
5478 rSh
.LockView( true );
5480 rSh
.EndTextEdit(); // clicked aside, end Edit
5481 rSh
.SelectObj( aDocPos
);
5482 if ( !rSh
.IsObjSelected() && !rSh
.IsFrameSelected() )
5483 rSh
.LeaveSelFrameMode();
5486 SwEditWin::s_nDDStartPosY
= aDocPos
.Y();
5487 SwEditWin::s_nDDStartPosX
= aDocPos
.X();
5488 g_bFrameDrag
= true;
5491 rSh
.LockView( false );
5492 m_rView
.AttrChangedNotify(nullptr);
5498 bool SwEditWin::IsDrawSelMode() const
5500 return IsObjectSelect();
5503 void SwEditWin::GetFocus()
5505 if ( m_rView
.GetPostItMgr()->HasActiveSidebarWin() )
5507 m_rView
.GetPostItMgr()->GrabFocusOnActiveSidebarWin();
5513 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
5514 m_rView
.GetWrtShell().InvalidateAccessibleFocus();
5519 void SwEditWin::LoseFocus()
5521 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
5522 if (m_rView
.GetWrtShellPtr())
5523 m_rView
.GetWrtShell().InvalidateAccessibleFocus();
5525 Window::LoseFocus();
5526 if( s_pQuickHlpData
&& s_pQuickHlpData
->m_bIsDisplayed
)
5527 s_pQuickHlpData
->Stop( m_rView
.GetWrtShell() );
5530 void SwEditWin::Command( const CommandEvent
& rCEvt
)
5534 // If ViewFrame dies shortly, no popup anymore!
5535 Window::Command(rCEvt
);
5539 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
5541 // The command event is send to the window after a possible context
5542 // menu from an inplace client has been closed. Now we have the chance
5543 // to deactivate the inplace client without any problem regarding parent
5544 // windows and code on the stack.
5545 SfxInPlaceClient
* pIPClient
= rSh
.GetSfxViewShell()->GetIPClient();
5546 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
5547 if ( bIsOleActive
&& ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
))
5553 bool bCallBase
= true;
5555 switch ( rCEvt
.GetCommand() )
5557 case CommandEventId::ContextMenu
:
5559 const sal_uInt16 nId
= SwInputChild::GetChildWindowId();
5560 SwInputChild
* pChildWin
= static_cast<SwInputChild
*>(GetView().GetViewFrame().
5561 GetChildWindow( nId
));
5563 if (m_rView
.GetPostItMgr()->IsHit(rCEvt
.GetMousePosPixel()))
5566 Point
aDocPos( PixelToLogic( rCEvt
.GetMousePosPixel() ) );
5567 if ( !rCEvt
.IsMouseEvent() )
5568 aDocPos
= rSh
.GetCharRect().Center();
5570 // Don't trigger the command on a frame anchored to header/footer is not editing it
5571 FrameControlType eControl
;
5572 bool bOverFly
= false;
5573 bool bPageAnchored
= false;
5574 bool bOverHeaderFooterFly
= IsOverHeaderFooterFly( aDocPos
, eControl
, bOverFly
, bPageAnchored
);
5575 // !bOverHeaderFooterFly doesn't mean we have a frame to select
5576 if ( !bPageAnchored
&& rCEvt
.IsMouseEvent( ) &&
5577 ( ( rSh
.IsHeaderFooterEdit( ) && !bOverHeaderFooterFly
&& bOverFly
) ||
5578 ( !rSh
.IsHeaderFooterEdit( ) && bOverHeaderFooterFly
) ) )
5583 if((!pChildWin
|| pChildWin
->GetView() != &m_rView
) &&
5584 !rSh
.IsDrawCreate() && !IsDrawAction())
5586 CurrShell
aCurr( &rSh
);
5592 g_bNoInterrupt
= false;
5593 m_bMBPressed
= false;
5595 if ( rCEvt
.IsMouseEvent() )
5597 SelectMenuPosition(rSh
, rCEvt
.GetMousePosPixel());
5598 m_rView
.StopShellTimer();
5600 const Point aPixPos
= LogicToPixel( aDocPos
);
5602 if ( m_rView
.GetDocShell()->IsReadOnly() )
5604 SwReadOnlyPopup
aROPopup(aDocPos
, m_rView
);
5606 ui::ContextMenuExecuteEvent aEvent
;
5607 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( this );
5608 aEvent
.ExecutePosition
.X
= aPixPos
.X();
5609 aEvent
.ExecutePosition
.Y
= aPixPos
.Y();
5610 rtl::Reference
<VCLXPopupMenu
> xMenu
;
5611 rtl::Reference
<VCLXPopupMenu
> xMenuInterface
= aROPopup
.CreateMenuInterface();
5612 if (GetView().TryContextMenuInterception(xMenuInterface
, "private:resource/ReadonlyContextMenu", xMenu
, aEvent
))
5616 css::uno::Reference
<css::awt::XWindowPeer
> xParent(aEvent
.SourceWindow
, css::uno::UNO_QUERY
);
5617 sal_uInt16 nExecId
= xMenu
->execute(xParent
, css::awt::Rectangle(aPixPos
.X(), aPixPos
.Y(), 1, 1),
5618 css::awt::PopupMenuDirection::EXECUTE_DOWN
);
5619 if (!::ExecuteMenuCommand(xMenu
, m_rView
.GetViewFrame(), nExecId
))
5620 aROPopup
.Execute(this, nExecId
);
5623 aROPopup
.Execute(this, aPixPos
);
5626 else if ( !m_rView
.ExecSpellPopup( aDocPos
) )
5627 SfxDispatcher::ExecutePopup(this, &aPixPos
);
5629 else if (m_pApplyTempl
->nUndo
< rSh
.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount())
5631 // Undo until we reach the point when we entered this context.
5632 rSh
.Do(SwWrtShell::UNDO
);
5639 case CommandEventId::Wheel
:
5640 case CommandEventId::StartAutoScroll
:
5641 case CommandEventId::AutoScroll
:
5642 if (m_pSavedOutlineFrame
&& rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton())
5644 GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline
, m_pSavedOutlineFrame
);
5645 m_pSavedOutlineFrame
= nullptr;
5647 m_pShadCursor
.reset();
5648 bCallBase
= !m_rView
.HandleWheelCommands( rCEvt
);
5651 case CommandEventId::GestureZoom
:
5653 if (m_pSavedOutlineFrame
&& rSh
.GetViewOptions()->IsShowOutlineContentVisibilityButton())
5655 GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline
, m_pSavedOutlineFrame
);
5656 m_pSavedOutlineFrame
= nullptr;
5658 m_pShadCursor
.reset();
5659 bCallBase
= !m_rView
.HandleGestureZoomCommand(rCEvt
);
5663 case CommandEventId::GestureLongPress
:
5664 case CommandEventId::GestureSwipe
: //nothing yet
5667 case CommandEventId::StartExtTextInput
:
5669 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly() &&
5670 rSh
.IsCursorReadonly();
5673 if( rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit() )
5676 rSh
.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt
);
5680 if( rSh
.HasSelection() )
5684 LanguageType eInputLanguage
= GetInputLanguage();
5685 rSh
.CreateExtTextInput(eInputLanguage
);
5690 case CommandEventId::EndExtTextInput
:
5692 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly() &&
5693 rSh
.IsCursorReadonly();
5696 if( rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit() )
5699 rSh
.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt
);
5704 OUString sRecord
= rSh
.DeleteExtTextInput();
5705 uno::Reference
< frame::XDispatchRecorder
> xRecorder
=
5706 m_rView
.GetViewFrame().GetBindings().GetRecorder();
5708 if ( !sRecord
.isEmpty() )
5710 // convert quotes in IME text
5711 // works on the last input character, this is especially in Korean text often done
5712 // quotes that are inside of the string are not replaced!
5713 const sal_Unicode aCh
= sRecord
[sRecord
.getLength() - 1];
5714 SvxAutoCorrCfg
& rACfg
= SvxAutoCorrCfg::Get();
5715 SvxAutoCorrect
* pACorr
= rACfg
.GetAutoCorrect();
5717 (( pACorr
->IsAutoCorrFlag( ACFlags::ChgQuotes
) && ('\"' == aCh
))||
5718 ( pACorr
->IsAutoCorrFlag( ACFlags::ChgSglQuotes
) && ( '\'' == aCh
))))
5721 rSh
.AutoCorrect( *pACorr
, aCh
);
5724 if ( xRecorder
.is() )
5727 SfxShell
*pSfxShell
= lcl_GetTextShellFromDispatcher( m_rView
);
5728 // generate request and record
5731 SfxRequest
aReq(m_rView
.GetViewFrame(), FN_INSERT_STRING
);
5732 aReq
.AppendItem( SfxStringItem( FN_INSERT_STRING
, sRecord
) );
5741 case CommandEventId::ExtTextInput
:
5743 bool bIsDocReadOnly
= m_rView
.GetDocShell()->IsReadOnly() &&
5744 rSh
.IsCursorReadonly();
5745 if (!bIsDocReadOnly
&& !rSh
.HasReadonlySel())
5747 if( s_pQuickHlpData
->m_bIsDisplayed
)
5748 s_pQuickHlpData
->Stop( rSh
);
5750 if( rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit() )
5753 rSh
.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt
);
5757 const CommandExtTextInputData
* pData
= rCEvt
.GetExtTextInputData();
5761 rSh
.SetExtTextInputData( *pData
);
5764 uno::Reference
< frame::XDispatchRecorder
> xRecorder
=
5765 m_rView
.GetViewFrame().GetBindings().GetRecorder();
5768 SvxAutoCorrCfg
& rACfg
= SvxAutoCorrCfg::Get();
5769 if (!rACfg
.IsAutoTextTip() || !ShowAutoText(rSh
.GetChunkForAutoText()))
5771 SvxAutoCorrect
* pACorr
= rACfg
.GetAutoCorrect();
5772 if (pACorr
&& pACorr
->GetSwFlags().bAutoCompleteWords
)
5773 ShowAutoCorrectQuickHelp(rSh
.GetPrevAutoCorrWord(*pACorr
), *pACorr
);
5778 if (rSh
.HasReadonlySel())
5780 // Inform the user that the request has been ignored.
5781 rSh
.InfoReadOnlyDialog(true);
5785 case CommandEventId::CursorPos
:
5786 // will be handled by the base class
5789 case CommandEventId::PasteSelection
:
5790 if( !m_rView
.GetDocShell()->IsReadOnly() )
5792 TransferableDataHelper
aDataHelper(
5793 TransferableDataHelper::CreateFromPrimarySelection());
5794 if( !aDataHelper
.GetXTransferable().is() )
5797 SotExchangeDest nDropDestination
= GetDropDestination( rCEvt
.GetMousePosPixel() );
5798 if( nDropDestination
== SotExchangeDest::NONE
)
5800 SotClipboardFormatId nDropFormat
;
5801 sal_uInt8 nEventAction
, nDropAction
;
5802 SotExchangeActionFlags nActionFlags
;
5803 nDropAction
= SotExchange::GetExchangeAction(
5804 aDataHelper
.GetDataFlavorExVector(),
5805 nDropDestination
, EXCHG_IN_ACTION_COPY
,
5806 EXCHG_IN_ACTION_COPY
, nDropFormat
,
5808 SotClipboardFormatId::NONE
, nullptr,
5810 if( EXCHG_INOUT_ACTION_NONE
!= nDropAction
)
5812 const Point
aDocPt( PixelToLogic( rCEvt
.GetMousePosPixel() ) );
5813 SwTransferable::PasteData( aDataHelper
, rSh
, nDropAction
, nActionFlags
,
5814 nDropFormat
, nDropDestination
, false,
5815 false, &aDocPt
, EXCHG_IN_ACTION_COPY
,
5820 case CommandEventId::ModKeyChange
:
5822 const CommandModKeyData
* pCommandData
= rCEvt
.GetModKeyData();
5823 if (!pCommandData
->IsDown() && pCommandData
->IsMod1() && !pCommandData
->IsMod2())
5825 sal_uInt16 nSlot
= 0;
5826 if(pCommandData
->IsLeftShift() && !pCommandData
->IsRightShift())
5827 nSlot
= SID_ATTR_PARA_LEFT_TO_RIGHT
;
5828 else if(!pCommandData
->IsLeftShift() && pCommandData
->IsRightShift())
5829 nSlot
= SID_ATTR_PARA_RIGHT_TO_LEFT
;
5830 if(nSlot
&& SvtCTLOptions::IsCTLFontEnabled())
5831 GetView().GetViewFrame().GetDispatcher()->Execute(nSlot
);
5835 case CommandEventId::InputLanguageChange
:
5836 // i#42732 - update state of fontname if input language changes
5837 g_bInputLanguageSwitched
= true;
5838 SetUseInputLanguage( true );
5840 case CommandEventId::SelectionChange
:
5842 const CommandSelectionChangeData
*pData
= rCEvt
.GetSelectionChangeData();
5843 rSh
.SttCursorMove();
5844 rSh
.GoStartSentence();
5845 rSh
.GetCursor()->GetPoint()->AdjustContent(sal::static_int_cast
<sal_uInt16
, sal_uLong
>(pData
->GetStart()));
5847 rSh
.GetCursor()->GetMark()->AdjustContent(sal::static_int_cast
<sal_uInt16
, sal_uLong
>(pData
->GetEnd() - pData
->GetStart()));
5848 rSh
.EndCursorMove( true );
5851 case CommandEventId::PrepareReconversion
:
5852 if( rSh
.HasSelection() )
5854 SwPaM
*pCursor
= rSh
.GetCursor();
5856 if( rSh
.IsMultiSelection() )
5858 if (pCursor
&& !pCursor
->HasMark() &&
5859 pCursor
->GetPoint() == pCursor
->GetMark())
5862 pCursor
= rSh
.GetCursor();
5865 // Cancel all selections other than the last selected one.
5866 while( rSh
.GetCursor()->GetNext() != rSh
.GetCursor() )
5867 delete rSh
.GetCursor()->GetNext();
5872 SwNodeOffset nPosNodeIdx
= pCursor
->GetPoint()->GetNodeIndex();
5873 const sal_Int32 nPosIdx
= pCursor
->GetPoint()->GetContentIndex();
5874 SwNodeOffset nMarkNodeIdx
= pCursor
->GetMark()->GetNodeIndex();
5875 const sal_Int32 nMarkIdx
= pCursor
->GetMark()->GetContentIndex();
5877 if( !rSh
.GetCursor()->HasMark() )
5878 rSh
.GetCursor()->SetMark();
5880 rSh
.SttCursorMove();
5882 if( nPosNodeIdx
< nMarkNodeIdx
)
5884 rSh
.GetCursor()->GetPoint()->Assign(nPosNodeIdx
, nPosIdx
);
5885 rSh
.GetCursor()->GetMark()->Assign(nPosNodeIdx
,
5886 rSh
.GetCursor()->GetPointContentNode()->Len());
5888 else if( nPosNodeIdx
== nMarkNodeIdx
)
5890 rSh
.GetCursor()->GetPoint()->Assign(nPosNodeIdx
, nPosIdx
);
5891 rSh
.GetCursor()->GetMark()->Assign(nMarkNodeIdx
, nMarkIdx
);
5895 rSh
.GetCursor()->GetMark()->Assign(nMarkNodeIdx
, nMarkIdx
);
5896 rSh
.GetCursor()->GetPoint()->Assign(nMarkNodeIdx
,
5897 rSh
.GetCursor()->GetMarkContentNode()->Len());
5900 rSh
.EndCursorMove( true );
5904 case CommandEventId::QueryCharPosition
:
5906 bool bVertical
= rSh
.IsInVerticalText();
5907 const SwPosition
& rPos
= *rSh
.GetCursor()->GetPoint();
5908 SwDocShell
* pDocSh
= m_rView
.GetDocShell();
5909 SwDoc
*pDoc
= pDocSh
->GetDoc();
5910 SwExtTextInput
* pInput
= pDoc
->GetExtTextInput( rPos
.GetNode(), rPos
.GetContentIndex() );
5913 const SwPosition
& rStart
= *pInput
->Start();
5914 const SwPosition
& rEnd
= *pInput
->End();
5915 sal_Int32 nSize
= rEnd
.GetContentIndex() - rStart
.GetContentIndex();
5916 vcl::Window
& rWin
= rSh
.GetView().GetEditWin();
5919 // When the composition does not exist, use Caret rect instead.
5920 const SwRect
& aCaretRect ( rSh
.GetCharRect() );
5921 tools::Rectangle
aRect( aCaretRect
.Left(), aCaretRect
.Top(), aCaretRect
.Right(), aCaretRect
.Bottom() );
5922 rWin
.SetCompositionCharRect( &aRect
, 1, bVertical
);
5926 std::unique_ptr
<tools::Rectangle
[]> aRects(new tools::Rectangle
[ nSize
]);
5928 for ( sal_Int32 nIndex
= rStart
.GetContentIndex(); nIndex
< rEnd
.GetContentIndex(); ++nIndex
)
5930 const SwPosition
aPos( rStart
.GetNode(), rStart
.GetNode().GetContentNode(), nIndex
);
5931 SwRect
aRect ( rSh
.GetCharRect() );
5932 rSh
.GetCharRectAt( aRect
, &aPos
);
5933 aRects
[ nRectIndex
] = tools::Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Right(), aRect
.Bottom() );
5936 rWin
.SetCompositionCharRect( aRects
.get(), nSize
, bVertical
);
5943 SAL_WARN("sw.ui", "unknown command.");
5947 Window::Command(rCEvt
);
5950 /* i#18686 select the object/cursor at the mouse
5951 position of the context menu request */
5952 void SwEditWin::SelectMenuPosition(SwWrtShell
& rSh
, const Point
& rMousePos
)
5954 const Point
aDocPos( PixelToLogic( rMousePos
) );
5955 const bool bIsInsideSelectedObj( rSh
.IsInsideSelectedObj( aDocPos
) );
5956 //create a synthetic mouse event out of the coordinates
5957 MouseEvent
aMEvt(rMousePos
);
5958 SdrView
*pSdrView
= rSh
.GetDrawView();
5961 // no close of insert_draw and reset of
5962 // draw mode, if context menu position is inside a selected object.
5963 if ( !bIsInsideSelectedObj
&& m_rView
.GetDrawFuncPtr() )
5966 m_rView
.GetDrawFuncPtr()->Deactivate();
5967 m_rView
.SetDrawFuncPtr(nullptr);
5968 m_rView
.LeaveDrawCreate();
5969 SfxBindings
& rBind
= m_rView
.GetViewFrame().GetBindings();
5970 rBind
.Invalidate( SID_ATTR_SIZE
);
5971 rBind
.Invalidate( SID_TABLE_CELL
);
5974 // if draw text is active and there's a text selection
5975 // at the mouse position then do nothing
5976 if(rSh
.GetSelectionType() & SelectionType::DrawObjectEditMode
)
5978 OutlinerView
* pOLV
= pSdrView
->GetTextEditOutlinerView();
5979 ESelection aSelection
= pOLV
->GetSelection();
5980 if(!aSelection
.IsZero())
5982 SdrOutliner
* pOutliner
= pSdrView
->GetTextEditOutliner();
5983 bool bVertical
= pOutliner
->IsVertical();
5984 const EditEngine
& rEditEng
= pOutliner
->GetEditEngine();
5985 Point
aEEPos(aDocPos
);
5986 const tools::Rectangle
& rOutputArea
= pOLV
->GetOutputArea();
5987 // regard vertical mode
5990 aEEPos
-= rOutputArea
.TopRight();
5991 //invert the horizontal direction and exchange X and Y
5992 tools::Long nTemp
= -aEEPos
.X();
5993 aEEPos
.setX( aEEPos
.Y() );
5994 aEEPos
.setY( nTemp
);
5997 aEEPos
-= rOutputArea
.TopLeft();
5999 EPosition aDocPosition
= rEditEng
.FindDocPosition(aEEPos
);
6000 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
6001 // make it a forward selection - otherwise the IsLess/IsGreater do not work :-(
6002 aSelection
.Adjust();
6003 if(!(aCompare
< aSelection
) && !(aCompare
> aSelection
))
6011 if (pSdrView
->MouseButtonDown( aMEvt
, GetOutDev() ) )
6013 pSdrView
->MouseButtonUp( aMEvt
, GetOutDev() );
6014 rSh
.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
6018 rSh
.ResetCursorStack();
6020 if ( EnterDrawMode( aMEvt
, aDocPos
) )
6024 if ( m_rView
.GetDrawFuncPtr() && m_bInsFrame
)
6030 UpdatePointer( aDocPos
);
6032 if( !rSh
.IsSelFrameMode() &&
6033 !GetView().GetViewFrame().GetDispatcher()->IsLocked() )
6035 // Test if there is a draw object at that position and if it should be selected.
6036 bool bShould
= rSh
.ShouldObjectBeSelected(aDocPos
);
6043 bool bUnLockView
= !rSh
.IsViewLocked();
6044 rSh
.LockView( true );
6045 bool bSelObj
= rSh
.SelectObj( aDocPos
);
6047 rSh
.LockView( false );
6051 // in case the frame was deselected in the macro
6052 // just the cursor has to be displayed again.
6053 if( FrameTypeFlags::NONE
== rSh
.GetSelFrameType() )
6057 if (rSh
.IsFrameSelected() && m_rView
.GetDrawFuncPtr())
6059 m_rView
.GetDrawFuncPtr()->Deactivate();
6060 m_rView
.SetDrawFuncPtr(nullptr);
6061 m_rView
.LeaveDrawCreate();
6062 m_rView
.AttrChangedNotify(nullptr);
6065 rSh
.EnterSelFrameMode( &aDocPos
);
6066 g_bFrameDrag
= true;
6067 UpdatePointer( aDocPos
);
6072 if (!m_rView
.GetDrawFuncPtr())
6076 else if ( rSh
.IsSelFrameMode() &&
6077 (m_aActHitType
== SdrHitKind::NONE
||
6078 !bIsInsideSelectedObj
))
6081 bool bUnLockView
= !rSh
.IsViewLocked();
6082 rSh
.LockView( true );
6084 if ( rSh
.IsSelFrameMode() )
6086 rSh
.UnSelectFrame();
6087 rSh
.LeaveSelFrameMode();
6088 m_rView
.AttrChangedNotify(nullptr);
6091 bool bSelObj
= rSh
.SelectObj( aDocPos
, 0/*nFlag*/ );
6093 rSh
.LockView( false );
6097 // move cursor here so that it is not drawn in the
6098 // frame at first; ShowCursor() happens in LeaveSelFrameMode()
6099 g_bValidCursorPos
= !(CRSR_POSCHG
& rSh
.CallSetCursor(&aDocPos
, false));
6100 rSh
.LeaveSelFrameMode();
6101 m_rView
.LeaveDrawCreate();
6102 m_rView
.AttrChangedNotify(nullptr);
6107 rSh
.EnterSelFrameMode( &aDocPos
);
6108 rSh
.SelFlyGrabCursor();
6109 rSh
.MakeSelVisible();
6110 g_bFrameDrag
= true;
6111 if( rSh
.IsFrameSelected() &&
6112 m_rView
.GetDrawFuncPtr() )
6114 m_rView
.GetDrawFuncPtr()->Deactivate();
6115 m_rView
.SetDrawFuncPtr(nullptr);
6116 m_rView
.LeaveDrawCreate();
6117 m_rView
.AttrChangedNotify(nullptr);
6119 UpdatePointer( aDocPos
);
6122 else if ( rSh
.IsSelFrameMode() && bIsInsideSelectedObj
)
6124 // Object at the mouse cursor is already selected - do nothing
6128 if ( rSh
.IsGCAttr() )
6134 bool bOverSelect
= rSh
.TestCurrPam( aDocPos
);
6135 bool bOverURLGrf
= false;
6137 bOverURLGrf
= bOverSelect
= nullptr != rSh
.IsURLGrfAtPos( aDocPos
);
6141 // create only temporary move context because otherwise
6142 // the query against the content form doesn't work!!!
6143 SwMvContext
aMvContext( &rSh
);
6144 rSh
.CallSetCursor(&aDocPos
, false);
6148 const SelectionType nSelType
= rSh
.GetSelectionType();
6149 if( nSelType
== SelectionType::Ole
||
6150 nSelType
== SelectionType::Graphic
)
6152 SwMvContext
aMvContext( &rSh
);
6153 if( !rSh
.IsFrameSelected() )
6155 rSh
.EnterSelFrameMode();
6160 static SfxShell
* lcl_GetTextShellFromDispatcher( SwView
const & rView
)
6164 SfxDispatcher
* pDispatcher
= rView
.GetViewFrame().GetDispatcher();
6165 for(sal_uInt16 i
= 0; true; ++i
)
6167 pShell
= pDispatcher
->GetShell( i
);
6168 if( !pShell
|| dynamic_cast< const SwTextShell
*>( pShell
) != nullptr )
6174 IMPL_LINK_NOARG(SwEditWin
, KeyInputFlushHandler
, Timer
*, void)
6179 void SwEditWin::InitStaticData()
6181 s_pQuickHlpData
= new QuickHelpData();
6184 void SwEditWin::FinitStaticData()
6186 delete s_pQuickHlpData
;
6188 /* i#3370 - remove quick help to prevent saving
6189 * of autocorrection suggestions */
6190 void SwEditWin::StopQuickHelp()
6192 if( HasFocus() && s_pQuickHlpData
&& s_pQuickHlpData
->m_bIsDisplayed
)
6193 s_pQuickHlpData
->Stop( m_rView
.GetWrtShell() );
6196 IMPL_LINK_NOARG(SwEditWin
, TemplateTimerHdl
, Timer
*, void)
6198 SetApplyTemplate(SwApplyTemplate());
6201 void SwEditWin::SetChainMode( bool bOn
)
6203 if ( !m_bChainMode
)
6206 m_pUserMarker
.reset();
6210 static sal_uInt16 aInva
[] =
6212 FN_FRAME_CHAIN
, FN_FRAME_UNCHAIN
, 0
6214 m_rView
.GetViewFrame().GetBindings().Invalidate(aInva
);
6217 uno::Reference
< css::accessibility::XAccessible
> SwEditWin::CreateAccessible()
6219 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
6220 SolarMutexGuard aGuard
; // this should have happened already!!!
6221 SwWrtShell
*pSh
= m_rView
.GetWrtShellPtr();
6222 OSL_ENSURE( pSh
, "no writer shell, no accessible object" );
6224 css::accessibility::XAccessible
> xAcc
;
6226 xAcc
= pSh
->CreateAccessible();
6234 void QuickHelpData::Move( QuickHelpData
& rCpy
)
6236 m_aHelpStrings
.clear();
6237 m_aHelpStrings
.swap( rCpy
.m_aHelpStrings
);
6239 m_bIsDisplayed
= rCpy
.m_bIsDisplayed
;
6240 nCurArrPos
= rCpy
.nCurArrPos
;
6241 m_bAppendSpace
= rCpy
.m_bAppendSpace
;
6242 m_bIsTip
= rCpy
.m_bIsTip
;
6243 m_bIsAutoText
= rCpy
.m_bIsAutoText
;
6246 void QuickHelpData::ClearContent()
6248 nCurArrPos
= nNoPos
;
6249 m_bIsDisplayed
= m_bAppendSpace
= false;
6251 m_aHelpStrings
.clear();
6253 m_bIsAutoText
= true;
6256 void QuickHelpData::Start(SwWrtShell
& rSh
, const bool bRestart
)
6262 m_bIsDisplayed
= true;
6264 vcl::Window
& rWin
= rSh
.GetView().GetEditWin();
6267 Point
aPt( rWin
.OutputToScreenPixel( rWin
.LogicToPixel(
6268 rSh
.GetCharRect().Pos() )));
6270 nTipId
= Help::ShowPopover(&rWin
, tools::Rectangle( aPt
, Size( 1, 1 )),
6272 QuickHelpFlags::Left
| QuickHelpFlags::Bottom
);
6276 OUString
sStr(CurStr());
6277 sStr
= sStr
.copy(CurLen());
6278 sal_uInt16 nL
= sStr
.getLength();
6279 const ExtTextInputAttr nVal
= ExtTextInputAttr::DottedUnderline
|
6280 ExtTextInputAttr::Highlight
;
6281 const std::vector
<ExtTextInputAttr
> aAttrs( nL
, nVal
);
6282 CommandExtTextInputData
aCETID( sStr
, aAttrs
.data(), nL
,
6285 //fdo#33092. If the current input language is the default
6286 //language that text would appear in if typed, then don't
6287 //force a language on for the ExtTextInput.
6288 LanguageType eInputLanguage
= rWin
.GetInputLanguage();
6289 if (lcl_isNonDefaultLanguage(eInputLanguage
,
6290 rSh
.GetView(), sStr
) == INVALID_HINT
)
6292 eInputLanguage
= LANGUAGE_DONTKNOW
;
6295 rSh
.CreateExtTextInput(eInputLanguage
);
6296 rSh
.SetExtTextInputData( aCETID
);
6300 void QuickHelpData::Stop( SwWrtShell
& rSh
)
6303 rSh
.DeleteExtTextInput( false );
6306 vcl::Window
& rWin
= rSh
.GetView().GetEditWin();
6307 Help::HidePopover(&rWin
, nTipId
);
6312 void QuickHelpData::FillStrArr( SwWrtShell
const & rSh
, const OUString
& rWord
)
6314 enum Capitalization
{ CASE_LOWER
, CASE_UPPER
, CASE_SENTENCE
, CASE_OTHER
};
6316 // Determine word capitalization
6317 const CharClass
& rCC
= GetAppCharClass();
6318 const OUString sWordLower
= rCC
.lowercase( rWord
);
6319 Capitalization aWordCase
= CASE_OTHER
;
6320 if ( !rWord
.isEmpty() )
6322 if ( rWord
[0] == sWordLower
[0] )
6324 if ( rWord
== sWordLower
)
6325 aWordCase
= CASE_LOWER
;
6329 // First character is not lower case i.e. assume upper or title case
6330 OUString sWordSentence
= sWordLower
.replaceAt( 0, 1, rtl::OUStringChar(rWord
[0]) );
6331 if ( rWord
== sWordSentence
)
6332 aWordCase
= CASE_SENTENCE
;
6335 if ( rWord
== rCC
.uppercase( rWord
) )
6336 aWordCase
= CASE_UPPER
;
6341 SwCalendarWrapper
& rCalendar
= s_getCalendarWrapper();
6342 rCalendar
.LoadDefaultCalendar( rSh
.GetCurLang() );
6344 // Add matching calendar month and day names
6345 for ( const auto& aNames
: { rCalendar
.getMonths(), rCalendar
.getDays() } )
6347 for ( const auto& rName
: aNames
)
6349 const OUString
& rStr( rName
.FullName
);
6350 // Check string longer than word and case insensitive match
6351 if( rStr
.getLength() > rWord
.getLength() &&
6352 rCC
.lowercase( rStr
, 0, rWord
.getLength() ) == sWordLower
)
6356 //fdo#61251 if it's an exact match, ensure unchanged replacement
6357 //exists as a candidate
6358 if (rStr
.startsWith(rWord
))
6359 m_aHelpStrings
.emplace_back(rStr
, rWord
.getLength());
6361 sStr
= rStr
; // to be added if no case conversion is performed below
6363 if ( aWordCase
== CASE_LOWER
)
6364 sStr
= rCC
.lowercase(rStr
);
6365 else if ( aWordCase
== CASE_SENTENCE
)
6366 sStr
= rCC
.lowercase(rStr
).replaceAt(0, 1, rtl::OUStringChar(rStr
[0]));
6367 else if ( aWordCase
== CASE_UPPER
)
6368 sStr
= rCC
.uppercase(rStr
);
6370 if (!sStr
.isEmpty())
6371 m_aHelpStrings
.emplace_back(sStr
, rWord
.getLength());
6376 // Add matching current date in ISO 8601 format, for example 2016-01-30
6379 // do not suggest for single years, for example for "2016",
6380 // only for "201" or "2016-..." (to avoid unintentional text
6381 // insertion at line ending, for example typing "30 January 2016")
6382 if (!rWord
.isEmpty() && rWord
.getLength() != 4 && rWord
[0] == '2')
6384 rStrToday
= utl::toISO8601(DateTime(Date(Date::SYSTEM
)).GetUNODateTime());
6385 if (rStrToday
.startsWith(rWord
))
6386 m_aHelpStrings
.emplace_back(rStrToday
, rWord
.getLength());
6389 // Add matching words from AutoCompleteWord list
6390 const SwAutoCompleteWord
& rACList
= SwEditShell::GetAutoCompleteWords();
6391 std::vector
<OUString
> strings
;
6393 if ( !rACList
.GetWordsMatching( rWord
, strings
) )
6396 for (const OUString
& aCompletedString
: strings
)
6398 // when we have a matching current date, avoid to suggest
6399 // other words with the same matching starting characters,
6400 // for example 2016-01-3 instead of 2016-01-30
6401 if (!rStrToday
.isEmpty() && aCompletedString
.startsWith(rWord
))
6406 //fdo#61251 if it's an exact match, ensure unchanged replacement
6407 //exists as a candidate
6408 if (aCompletedString
.startsWith(rWord
))
6409 m_aHelpStrings
.emplace_back(aCompletedString
, rWord
.getLength());
6411 sStr
= aCompletedString
; // to be added if no case conversion is performed below
6413 if (aWordCase
== CASE_LOWER
)
6414 sStr
= rCC
.lowercase(aCompletedString
);
6415 else if (aWordCase
== CASE_SENTENCE
)
6416 sStr
= rCC
.lowercase(aCompletedString
)
6417 .replaceAt(0, 1, rtl::OUStringChar(aCompletedString
[0]));
6418 else if (aWordCase
== CASE_UPPER
)
6419 sStr
= rCC
.uppercase(aCompletedString
);
6421 if (!sStr
.isEmpty())
6422 m_aHelpStrings
.emplace_back(aCompletedString
, rWord
.getLength());
6428 class CompareIgnoreCaseAsciiFavorExact
6430 const OUString
&m_rOrigWord
;
6432 explicit CompareIgnoreCaseAsciiFavorExact(const OUString
& rOrigWord
)
6433 : m_rOrigWord(rOrigWord
)
6437 bool operator()(const std::pair
<OUString
, sal_uInt16
>& s1
,
6438 const std::pair
<OUString
, sal_uInt16
>& s2
) const
6440 int nRet
= s1
.first
.compareToIgnoreAsciiCase(s2
.first
);
6443 //fdo#61251 sort stuff that starts with the exact rOrigWord before
6444 //another ignore-case candidate
6445 int n1StartsWithOrig
= s1
.first
.startsWith(m_rOrigWord
) ? 0 : 1;
6446 int n2StartsWithOrig
= s2
.first
.startsWith(m_rOrigWord
) ? 0 : 1;
6447 return n1StartsWithOrig
< n2StartsWithOrig
;
6453 struct EqualIgnoreCaseAscii
6455 bool operator()(const std::pair
<OUString
, sal_uInt16
>& s1
,
6456 const std::pair
<OUString
, sal_uInt16
>& s2
) const
6458 return s1
.first
.equalsIgnoreAsciiCase(s2
.first
);
6462 } // anonymous namespace
6464 // TODO Implement an i18n aware sort
6465 void QuickHelpData::SortAndFilter(const OUString
&rOrigWord
)
6467 std::sort( m_aHelpStrings
.begin(),
6468 m_aHelpStrings
.end(),
6469 CompareIgnoreCaseAsciiFavorExact(rOrigWord
) );
6472 = std::unique(m_aHelpStrings
.begin(), m_aHelpStrings
.end(), EqualIgnoreCaseAscii());
6473 m_aHelpStrings
.erase( it
, m_aHelpStrings
.end() );
6478 // For a given chunk of typed text between 3 and 9 characters long that may start at a word boundary
6479 // or in a whitespace and may include whitespaces, SwEditShell::GetChunkForAutoTextcreates a list of
6480 // possible candidates for long AutoText names. Let's say, we have typed text "lorem ipsum dr f";
6481 // and the cursor is right after the "f". SwEditShell::GetChunkForAutoText would take " dr f",
6482 // since it's the longest chunk to the left of the cursor no longer than 9 characters, not starting
6483 // in the middle of a word. Then it would create this list from it (in this order, longest first):
6487 // It cannot add "r f", because it starts in the middle of the word "dr"; also it cannot give " f",
6488 // because it's only 2 characters long.
6489 // Now the result of SwEditShell::GetChunkForAutoText is passed here to SwEditWin::ShowAutoText, and
6490 // then to SwGlossaryList::HasLongName, where all existing autotext entries' long names are tested
6491 // if they start with one of the list elements. The matches are sorted according the position of the
6492 // candidate that matched first, then alphabetically inside the group of suggestions for a given
6493 // candidate. Say, if we have these AutoText entry long names:
6500 // the resulting list would be:
6501 // " Dr Fuzz" -> matches the first (longest) item in the candidates list
6502 // " dr Faust" -> matches the second candidate item
6503 // "Dr Foo" -> first item of the two matching the third candidate; alphabetically sorted
6504 // "Dr Frodo" -> second item of the two matching the third candidate; alphabetically sorted
6505 // Each of the resulting suggestions knows the length of the candidate it replaces, so accepting the
6506 // first suggestion would replace 6 characters before cursor, while tabbing to and accepting the
6507 // last suggestion would replace only 4 characters to the left of cursor.
6508 bool SwEditWin::ShowAutoText(const std::vector
<OUString
>& rChunkCandidates
)
6510 s_pQuickHlpData
->ClearContent();
6511 if (!rChunkCandidates
.empty())
6513 SwGlossaryList
* pList
= ::GetGlossaryList();
6514 pList
->HasLongName(rChunkCandidates
, s_pQuickHlpData
->m_aHelpStrings
);
6517 if (!s_pQuickHlpData
->m_aHelpStrings
.empty())
6519 s_pQuickHlpData
->Start(m_rView
.GetWrtShell(), true);
6521 return !s_pQuickHlpData
->m_aHelpStrings
.empty();
6524 void SwEditWin::ShowAutoCorrectQuickHelp(
6525 const OUString
& rWord
, SvxAutoCorrect
& rACorr
)
6527 if (rWord
.isEmpty())
6529 SwWrtShell
& rSh
= m_rView
.GetWrtShell();
6530 s_pQuickHlpData
->ClearContent();
6532 if( s_pQuickHlpData
->m_aHelpStrings
.empty() &&
6533 rACorr
.GetSwFlags().bAutoCompleteWords
)
6535 s_pQuickHlpData
->m_bIsAutoText
= false;
6536 s_pQuickHlpData
->m_bIsTip
= rACorr
.GetSwFlags().bAutoCmpltShowAsTip
;
6538 // Get the necessary data to show help text.
6539 s_pQuickHlpData
->FillStrArr( rSh
, rWord
);
6542 if( !s_pQuickHlpData
->m_aHelpStrings
.empty() )
6544 s_pQuickHlpData
->SortAndFilter(rWord
);
6545 s_pQuickHlpData
->Start(rSh
, true);
6549 bool SwEditWin::IsInHeaderFooter( const Point
&rDocPt
, FrameControlType
&rControl
) const
6551 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
6552 const SwPageFrame
* pPageFrame
= rSh
.GetLayout()->GetPageAtPos( rDocPt
);
6554 if ( pPageFrame
&& pPageFrame
->IsOverHeaderFooterArea( rDocPt
, rControl
) )
6557 if ( rSh
.IsShowHeaderFooterSeparator( FrameControlType::Header
) || rSh
.IsShowHeaderFooterSeparator( FrameControlType::Footer
) )
6559 SwFrameControlsManager
&rMgr
= rSh
.GetView().GetEditWin().GetFrameControlsManager();
6560 Point
aPoint( LogicToPixel( rDocPt
) );
6562 if ( rSh
.IsShowHeaderFooterSeparator( FrameControlType::Header
) )
6564 SwFrameControlPtr pControl
= rMgr
.GetControl( FrameControlType::Header
, pPageFrame
);
6565 if ( pControl
&& pControl
->Contains( aPoint
) )
6567 rControl
= FrameControlType::Header
;
6572 if ( rSh
.IsShowHeaderFooterSeparator( FrameControlType::Footer
) )
6574 SwFrameControlPtr pControl
= rMgr
.GetControl( FrameControlType::Footer
, pPageFrame
);
6575 if ( pControl
&& pControl
->Contains( aPoint
) )
6577 rControl
= FrameControlType::Footer
;
6586 bool SwEditWin::IsOverHeaderFooterFly( const Point
& rDocPos
, FrameControlType
& rControl
, bool& bOverFly
, bool& bPageAnchored
) const
6589 Point
aPt( rDocPos
);
6590 SwWrtShell
&rSh
= m_rView
.GetWrtShell();
6591 SwPaM
aPam( *rSh
.GetCurrentShellCursor().GetPoint() );
6592 rSh
.GetLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aPt
, nullptr, true );
6594 const SwStartNode
* pStartFly
= aPam
.GetPoint()->GetNode().FindFlyStartNode();
6598 SwFrameFormat
* pFlyFormat
= pStartFly
->GetFlyFormat( );
6601 const SwNode
* pAnchorNode
= pFlyFormat
->GetAnchor( ).GetAnchorNode( );
6604 bool bInHeader
= pAnchorNode
->FindHeaderStartNode( ) != nullptr;
6605 bool bInFooter
= pAnchorNode
->FindFooterStartNode( ) != nullptr;
6607 bRet
= bInHeader
|| bInFooter
;
6609 rControl
= FrameControlType::Header
;
6610 else if ( bInFooter
)
6611 rControl
= FrameControlType::Footer
;
6614 bPageAnchored
= pFlyFormat
->GetAnchor( ).GetAnchorId( ) == RndStdIds::FLY_AT_PAGE
;
6622 void SwEditWin::SetUseInputLanguage( bool bNew
)
6624 if ( bNew
|| m_bUseInputLanguage
)
6626 SfxBindings
& rBind
= GetView().GetViewFrame().GetBindings();
6627 rBind
.Invalidate( SID_ATTR_CHAR_FONT
);
6628 rBind
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
6630 m_bUseInputLanguage
= bNew
;
6633 OUString
SwEditWin::GetSurroundingText() const
6635 SwWrtShell
& rSh
= m_rView
.GetWrtShell();
6637 if (rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit())
6638 return rSh
.GetDrawView()->GetTextEditOutlinerView()->GetSurroundingText();
6641 if( rSh
.HasSelection() && !rSh
.IsMultiSelection() && rSh
.IsSelOnePara() )
6642 rSh
.GetSelectedText( sReturn
, ParaBreakType::ToOnlyCR
);
6643 else if( !rSh
.HasSelection() )
6645 bool bUnLockView
= !rSh
.IsViewLocked();
6648 // store shell state *before* Push
6649 ::std::optional
<SwCallLink
> aLink(std::in_place
, rSh
);
6652 // disable accessible events for internal-only helper cursor
6653 const bool bSendAccessibleEventOld
= rSh
.IsSendAccessibleCursorEvents();
6654 rSh
.SetSendAccessibleCursorEvents(false);
6656 // get the sentence around the cursor
6658 rSh
.GoStartSentence();
6660 rSh
.GoEndSentence();
6661 rSh
.GetSelectedText( sReturn
, ParaBreakType::ToOnlyCR
);
6663 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
, aLink
);
6664 rSh
.SetSendAccessibleCursorEvents(bSendAccessibleEventOld
);
6668 rSh
.LockView(false);
6674 Selection
SwEditWin::GetSurroundingTextSelection() const
6676 SwWrtShell
& rSh
= m_rView
.GetWrtShell();
6678 if (rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit())
6679 return rSh
.GetDrawView()->GetTextEditOutlinerView()->GetSurroundingTextSelection();
6681 Selection
aSel(0, 0);
6682 if( rSh
.HasSelection() )
6685 rSh
.GetSelectedText( sReturn
, ParaBreakType::ToOnlyCR
);
6686 aSel
= Selection( 0, sReturn
.getLength() );
6688 else if (rSh
.GetCursor()->GetPoint()->GetNode().GetTextNode())
6690 bool bUnLockView
= !rSh
.IsViewLocked();
6693 // Return the position of the visible cursor in the sentence
6694 // around the visible cursor.
6695 TextFrameIndex
const nPos(rSh
.GetCursorPointAsViewIndex());
6697 // store shell state *before* Push
6698 ::std::optional
<SwCallLink
> aLink(std::in_place
, rSh
);
6701 // disable accessible events for internal-only helper cursor
6702 const bool bSendAccessibleEventOld
= rSh
.IsSendAccessibleCursorEvents();
6703 rSh
.SetSendAccessibleCursorEvents(false);
6706 rSh
.GoStartSentence();
6707 TextFrameIndex
const nStartPos(rSh
.GetCursorPointAsViewIndex());
6709 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
, aLink
);
6710 rSh
.SetSendAccessibleCursorEvents(bSendAccessibleEventOld
);
6714 rSh
.LockView(false);
6716 aSel
= Selection(sal_Int32(nPos
- nStartPos
), sal_Int32(nPos
- nStartPos
));
6722 bool SwEditWin::DeleteSurroundingText(const Selection
& rSelection
)
6724 SwWrtShell
& rSh
= m_rView
.GetWrtShell();
6726 if (rSh
.HasDrawView() && rSh
.GetDrawView()->IsTextEdit())
6727 return rSh
.GetDrawView()->GetTextEditOutlinerView()->DeleteSurroundingText(rSelection
);
6729 if (rSh
.HasSelection())
6732 // rSelection is relative to the start of the sentence, so find that and
6733 // adjust the range by it
6736 // disable accessible events for internal-only helper cursor
6737 const bool bSendAccessibleEventOld
= rSh
.IsSendAccessibleCursorEvents();
6738 rSh
.SetSendAccessibleCursorEvents(false);
6741 rSh
.GoStartSentence();
6742 TextFrameIndex
const nStartPos(rSh
.GetCursorPointAsViewIndex());
6744 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
6745 rSh
.SetSendAccessibleCursorEvents(bSendAccessibleEventOld
);
6748 if (rSh
.SelectTextView(nStartPos
+ TextFrameIndex(rSelection
.Min()), nStartPos
+ TextFrameIndex(rSelection
.Max())))
6757 void SwEditWin::LogicInvalidate(const tools::Rectangle
* pRectangle
)
6759 SfxLokHelper::notifyInvalidation(&m_rView
, pRectangle
);
6762 void SwEditWin::SetCursorTwipPosition(const Point
& rPosition
, bool bPoint
, bool bClearMark
)
6764 if (SdrView
* pSdrView
= m_rView
.GetWrtShell().GetDrawView())
6766 // Editing shape text, then route the call to editeng.
6767 if (pSdrView
->GetTextEditObject())
6769 EditView
& rEditView
= pSdrView
->GetTextEditOutlinerView()->GetEditView();
6770 rEditView
.SetCursorLogicPosition(rPosition
, bPoint
, bClearMark
);
6775 if (m_rView
.GetPostItMgr())
6777 if (sw::annotation::SwAnnotationWin
* pWin
= m_rView
.GetPostItMgr()->GetActiveSidebarWin())
6779 // Editing postit text.
6780 pWin
->SetCursorLogicPosition(rPosition
, bPoint
, bClearMark
);
6785 // Not an SwWrtShell, as that would make SwCursorShell::GetCursor() inaccessible.
6786 SwEditShell
& rShell
= m_rView
.GetWrtShell();
6788 bool bCreateSelection
= false;
6790 SwMvContext
aMvContext(&rShell
);
6794 bCreateSelection
= !rShell
.HasMark();
6796 if (bCreateSelection
)
6797 m_rView
.GetWrtShell().SttSelect();
6799 // If the mark is to be updated, then exchange the point and mark before
6800 // and after, as we can't easily set the mark.
6802 rShell
.getShellCursor(/*bBlock=*/false)->Exchange();
6803 rShell
.SetCursor(rPosition
);
6805 rShell
.getShellCursor(/*bBlock=*/false)->Exchange();
6808 if (bCreateSelection
)
6809 m_rView
.GetWrtShell().EndSelect();
6812 void SwEditWin::SetGraphicTwipPosition(bool bStart
, const Point
& rPosition
)
6816 MouseEvent
aClickEvent(rPosition
, 1, MouseEventModifiers::SIMPLECLICK
, MOUSE_LEFT
);
6817 MouseButtonDown(aClickEvent
);
6818 MouseEvent
aMoveEvent(Point(rPosition
.getX() + MIN_MOVE
+ 1, rPosition
.getY()), 0, MouseEventModifiers::SIMPLEMOVE
, MOUSE_LEFT
);
6819 MouseMove(aMoveEvent
);
6823 MouseEvent
aMoveEvent(Point(rPosition
.getX() - MIN_MOVE
- 1, rPosition
.getY()), 0, MouseEventModifiers::SIMPLEMOVE
, MOUSE_LEFT
);
6824 MouseMove(aMoveEvent
);
6825 MouseEvent
aClickEvent(rPosition
, 1, MouseEventModifiers::SIMPLECLICK
, MOUSE_LEFT
);
6826 MouseButtonUp(aClickEvent
);
6830 SwFrameControlsManager
& SwEditWin::GetFrameControlsManager()
6832 return *m_pFrameControlsManager
;
6835 void SwEditWin::ToggleOutlineContentVisibility(const size_t nOutlinePos
, const bool bSubs
)
6837 // bSubs purpose is to set all sub level outline content to the same visibility as
6838 // nOutlinePos outline content visibility is toggled. It is only applicable when not treating
6839 // sub outline levels as content.
6840 SwWrtShell
& rSh
= GetView().GetWrtShell();
6842 if (GetView().GetDrawView()->IsTextEdit())
6844 if (GetView().IsDrawMode())
6845 GetView().LeaveDrawCreate();
6848 if (!bSubs
|| rSh
.GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
6850 SwNode
* pNode
= rSh
.GetNodes().GetOutLineNds()[nOutlinePos
];
6851 bool bVisible
= true;
6852 pNode
->GetTextNode()->GetAttrOutlineContentVisible(bVisible
);
6853 pNode
->GetTextNode()->SetAttrOutlineContentVisible(!bVisible
);
6857 // also toggle sub levels to the same content visibility
6858 SwOutlineNodes::size_type nPos
= nOutlinePos
;
6859 SwOutlineNodes::size_type nOutlineNodesCount
6860 = rSh
.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
6861 int nLevel
= rSh
.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos
);
6862 bool bVisible
= rSh
.IsOutlineContentVisible(nOutlinePos
);
6865 if (rSh
.IsOutlineContentVisible(nPos
) == bVisible
)
6866 rSh
.GetNodes().GetOutLineNds()[nPos
]->GetTextNode()->SetAttrOutlineContentVisible(!bVisible
);
6867 } while (++nPos
< nOutlineNodesCount
6868 && rSh
.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos
) > nLevel
);
6871 rSh
.InvalidateOutlineContentVisibility();
6872 rSh
.GotoOutline(nOutlinePos
);
6874 GetView().GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged
));
6877 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */