Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/docvw/edtwin.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <config_wasm_strip.h>
21
22
#include <swtypes.hxx>
23
#include <hintids.hxx>
24
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/Calendar2.hpp>
29
#include <com/sun/star/i18n/XBreakIterator.hpp>
30
#include <com/sun/star/i18n/ScriptType.hpp>
31
#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
32
#include <com/sun/star/i18n/UnicodeScript.hpp>
33
#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
34
#include <com/sun/star/ui/ContextMenuExecuteEvent.hpp>
35
36
#include <comphelper/scopeguard.hxx>
37
#include <comphelper/string.hxx>
38
#include <comphelper/OAccessible.hxx>
39
40
#include <i18npool/breakiterator.hxx>
41
#include <vcl/dialoghelper.hxx>
42
#include <vcl/inputctx.hxx>
43
#include <vcl/help.hxx>
44
#include <vcl/weld/weld.hxx>
45
#include <vcl/ptrstyle.hxx>
46
#include <svl/macitem.hxx>
47
#include <unotools/securityoptions.hxx>
48
#include <basic/sbxvar.hxx>
49
#include <svl/ctloptions.hxx>
50
#include <basic/sbx.hxx>
51
#include <svl/eitem.hxx>
52
#include <svl/stritem.hxx>
53
#include <sfx2/ipclient.hxx>
54
#include <sfx2/viewfrm.hxx>
55
#include <sfx2/request.hxx>
56
#include <sfx2/bindings.hxx>
57
#include <sfx2/dispatch.hxx>
58
#include <svl/ptitem.hxx>
59
#include <editeng/sizeitem.hxx>
60
#include <editeng/langitem.hxx>
61
#include <svx/statusitem.hxx>
62
#include <svx/svdview.hxx>
63
#include <svx/svdhdl.hxx>
64
#include <svx/svdoutl.hxx>
65
#include <svx/diagram/DiagramHelper_svx.hxx>
66
#include <editeng/editeng.hxx>
67
#include <editeng/editview.hxx>
68
#include <editeng/svxacorr.hxx>
69
#include <editeng/flditem.hxx>
70
#include <editeng/colritem.hxx>
71
#include <unotools/charclass.hxx>
72
#include <unotools/datetime.hxx>
73
74
#include <comphelper/lok.hxx>
75
#include <sfx2/lokhelper.hxx>
76
77
#include <editeng/acorrcfg.hxx>
78
#include <SwSmartTagMgr.hxx>
79
#include <edtdd.hxx>
80
#include <edtwin.hxx>
81
#include <view.hxx>
82
#include <wrtsh.hxx>
83
#include <IDocumentDrawModelAccess.hxx>
84
#include <IDocumentUndoRedo.hxx>
85
#include <textboxhelper.hxx>
86
#include <dcontact.hxx>
87
#include <fldbas.hxx>
88
#include <swmodule.hxx>
89
#include <docsh.hxx>
90
#include <viewopt.hxx>
91
#include <drawbase.hxx>
92
#include <dselect.hxx>
93
#include <textsh.hxx>
94
#include <shdwcrsr.hxx>
95
#include <txatbase.hxx>
96
#include <fmtanchr.hxx>
97
#include <fmtornt.hxx>
98
#include <fmthdft.hxx>
99
#include <frmfmt.hxx>
100
#include <modcfg.hxx>
101
#include <fmtcol.hxx>
102
#include <wview.hxx>
103
#include <gloslst.hxx>
104
#include <inputwin.hxx>
105
#include <gloshdl.hxx>
106
#include <swundo.hxx>
107
#include <drwtxtsh.hxx>
108
#include <fchrfmt.hxx>
109
#include "romenu.hxx"
110
#include <initui.hxx>
111
#include <frmatr.hxx>
112
#include <extinput.hxx>
113
#include <acmplwrd.hxx>
114
#include <swcalwrp.hxx>
115
#include <swdtflvr.hxx>
116
#include <breakit.hxx>
117
#include <checkit.hxx>
118
#include <pagefrm.hxx>
119
#include <usrpref.hxx>
120
121
#include <helpids.h>
122
#include <cmdid.h>
123
#include <uitool.hxx>
124
#include <fmtfollowtextflow.hxx>
125
#include <toolkit/helper/vclunohelper.hxx>
126
#include <charfmt.hxx>
127
#include <numrule.hxx>
128
#include <pagedesc.hxx>
129
#include <svtools/ruler.hxx>
130
#include <formatclipboard.hxx>
131
#include <vcl/svapp.hxx>
132
#include <wordcountdialog.hxx>
133
#include <fmtfld.hxx>
134
135
#include <IMark.hxx>
136
#include <doc.hxx>
137
#include <xmloff/odffields.hxx>
138
139
#include <PostItMgr.hxx>
140
#include <FrameControlsManager.hxx>
141
#include <AnnotationWin.hxx>
142
143
#include <algorithm>
144
#include <vector>
145
146
#include <rootfrm.hxx>
147
148
#include <unotools/syslocaleoptions.hxx>
149
#include <i18nlangtag/mslangid.hxx>
150
#include <salhelper/singletonref.hxx>
151
#include <sfx2/event.hxx>
152
#include <memory>
153
154
#include "../../core/crsr/callnk.hxx"
155
#include <IDocumentOutlineNodes.hxx>
156
#include <ndtxt.hxx>
157
#include <cntfrm.hxx>
158
#include <txtfrm.hxx>
159
#include <strings.hrc>
160
#include <textcontentcontrol.hxx>
161
#include <contentcontrolbutton.hxx>
162
163
using namespace sw::mark;
164
using namespace ::com::sun::star;
165
166
0
#define SCROLL_TIMER_RETARD_LIMIT 5
167
168
/**
169
 * Globals
170
 */
171
static bool g_bInputLanguageSwitched = false;
172
173
// Used to draw the guide line while resizing the comment sidebar width
174
static tools::Rectangle aLastCommentSidebarPos;
175
176
// Usually in MouseButtonUp a selection is revoked when the selection is
177
// not currently being pulled open. Unfortunately in MouseButtonDown there
178
// is being selected at double/triple click. That selection is completely
179
// finished in the Handler and thus can't be distinguished in the Up.
180
// To resolve this g_bHoldSelection is set in Down and evaluated in Up.
181
static bool g_bHoldSelection      = false;
182
183
bool g_bFrameDrag                   = false;
184
static bool g_bValidCursorPos       = false;
185
bool g_bModePushed = false;
186
bool g_bDDTimerStarted            = false;
187
bool g_bDDINetAttr                = false;
188
static SdrHdlKind g_eSdrMoveHdl   = SdrHdlKind::User;
189
190
QuickHelpData* SwEditWin::s_pQuickHlpData = nullptr;
191
192
tools::Long    SwEditWin::s_nDDStartPosY = 0;
193
tools::Long    SwEditWin::s_nDDStartPosX = 0;
194
195
static SfxShell* lcl_GetTextShellFromDispatcher( SwView const & rView );
196
197
/// Check if the selected shape has a TextBox: if so, go into that instead.
198
static bool lcl_goIntoTextBox(SwEditWin& rEditWin, SwWrtShell& rSh)
199
0
{
200
0
    SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0);
201
0
    if (!pMark)
202
0
        return false;
203
204
0
    SdrObject* pSdrObject = pMark->GetMarkedSdrObj();
205
0
    SwFrameFormat* pObjectFormat = ::FindFrameFormat(pSdrObject);
206
0
    if (SwFrameFormat* pTextBoxFormat = SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat, RES_DRAWFRMFMT))
207
0
    {
208
0
        SdrObject* pTextBox = pTextBoxFormat->FindRealSdrObject();
209
0
        SdrView* pSdrView = rSh.GetDrawView();
210
        // Unmark the shape.
211
0
        pSdrView->UnmarkAllObj();
212
        // Mark the textbox.
213
0
        rSh.SelectObj(Point(), SW_ALLOW_TEXTBOX, pTextBox);
214
        // Clear the DrawFuncPtr.
215
0
        rEditWin.StopInsFrame();
216
0
        return true;
217
0
    }
218
0
    return false;
219
0
}
220
221
class SwAnchorMarker
222
{
223
    SdrHdl* m_pHdl;
224
    Point m_aHdlPos;
225
    Point m_aLastPos;
226
    bool m_bTopRightHandle;
227
public:
228
    explicit SwAnchorMarker( SdrHdl* pH )
229
0
        : m_pHdl( pH )
230
0
        , m_aHdlPos( pH->GetPos() )
231
0
        , m_aLastPos( pH->GetPos() )
232
0
        , m_bTopRightHandle( pH->GetKind() == SdrHdlKind::Anchor_TR )
233
0
    {}
234
0
    const Point& GetLastPos() const { return m_aLastPos; }
235
0
    void SetLastPos( const Point& rNew ) { m_aLastPos = rNew; }
236
0
    void SetPos( const Point& rNew ) { m_pHdl->SetPos( rNew ); }
237
0
    const Point& GetHdlPos() const { return m_aHdlPos; }
238
0
    SdrHdl* GetHdl() const { return m_pHdl; }
239
    void ChgHdl( SdrHdl* pNew )
240
0
    {
241
0
        m_pHdl = pNew;
242
0
        if ( m_pHdl )
243
0
        {
244
0
            m_bTopRightHandle = (m_pHdl->GetKind() == SdrHdlKind::Anchor_TR);
245
0
        }
246
0
    }
247
    Point GetPosForHitTest( const OutputDevice& rOut )
248
0
    {
249
0
        Point aHitTestPos( m_pHdl->GetPos() );
250
0
        aHitTestPos = rOut.LogicToPixel( aHitTestPos );
251
0
        if ( m_bTopRightHandle )
252
0
        {
253
0
            aHitTestPos += Point( -1, 1 );
254
0
        }
255
0
        else
256
0
        {
257
0
            aHitTestPos += Point( 1, 1 );
258
0
        }
259
0
        aHitTestPos = rOut.PixelToLogic( aHitTestPos );
260
261
0
        return aHitTestPos;
262
0
    }
263
};
264
265
/// Assists with auto-completion of AutoComplete words and AutoText names.
266
struct QuickHelpData
267
{
268
    /// Strings that at least partially match an input word, and match length.
269
    std::vector<std::pair<OUString, sal_uInt16>> m_aHelpStrings;
270
    /// Index of the current help string.
271
    sal_uInt16 nCurArrPos;
272
    static constexpr sal_uInt16 nNoPos = std::numeric_limits<sal_uInt16>::max();
273
274
    /// Help data stores AutoText names rather than AutoComplete words.
275
    bool m_bIsAutoText;
276
    /// Display help string as a tip rather than inline.
277
    bool m_bIsTip;
278
    /// Tip ID when a help string is displayed as a tip.
279
    void* nTipId;
280
    /// Append a space character to the displayed help string (if appropriate).
281
    bool m_bAppendSpace;
282
283
    /// Help string is currently displayed.
284
    bool m_bIsDisplayed;
285
286
9
    QuickHelpData() { ClearContent(); }
287
288
    void Move( QuickHelpData& rCpy );
289
    void ClearContent();
290
    void Start(SwWrtShell& rSh, bool bRestart);
291
    void Stop( SwWrtShell& rSh );
292
293
0
    bool HasContent() const { return !m_aHelpStrings.empty() && nCurArrPos != nNoPos; }
294
0
    const OUString& CurStr() const { return m_aHelpStrings[nCurArrPos].first; }
295
0
    sal_uInt16 CurLen() const { return m_aHelpStrings[nCurArrPos].second; }
296
297
    /// Next help string.
298
    void Next( bool bEndLess )
299
0
    {
300
0
        if( ++nCurArrPos >= m_aHelpStrings.size() )
301
0
            nCurArrPos = (bEndLess && !m_bIsAutoText ) ? 0 : nCurArrPos-1;
302
0
    }
303
    /// Previous help string.
304
    void Previous( bool bEndLess )
305
0
    {
306
0
        if( 0 == nCurArrPos-- )
307
0
            nCurArrPos = (bEndLess && !m_bIsAutoText ) ? m_aHelpStrings.size()-1 : 0;
308
0
    }
309
310
    // Fills internal structures with hopefully helpful information.
311
    void FillStrArr( SwWrtShell const & rSh, const OUString& rWord );
312
    void SortAndFilter(const OUString &rOrigWord);
313
};
314
315
316
// Minimise jitter
317
318
constexpr auto HIT_PIX = 2;  // Hit tolerance in pixels
319
constexpr auto MIN_MOVE = 4;
320
321
static bool IsMinMove(const Point &rStartPos, const Point &rLPt)
322
0
{
323
0
    return std::abs(rStartPos.X() - rLPt.X()) > MIN_MOVE ||
324
0
           std::abs(rStartPos.Y() - rLPt.Y()) > MIN_MOVE;
325
0
}
326
327
/**
328
 * For MouseButtonDown - determine whether a DrawObject
329
 * a NO SwgFrame was hit! Shift/Ctrl should only result
330
 * in selecting, with DrawObjects; at SwgFlys to trigger
331
 * hyperlinks if applicable (Download/NewWindow!)
332
 */
333
static bool IsDrawObjSelectable( const SwWrtShell& rSh, const Point& rPt )
334
0
{
335
0
    bool bRet = true;
336
0
    SdrObject* pObj;
337
0
    switch( rSh.GetObjCntType( rPt, pObj ))
338
0
    {
339
0
    case OBJCNT_NONE:
340
0
    case OBJCNT_FLY:
341
0
    case OBJCNT_GRF:
342
0
    case OBJCNT_OLE:
343
0
        bRet = false;
344
0
        break;
345
0
    default:; //prevent warning
346
0
    }
347
0
    return bRet;
348
0
}
349
350
/*
351
 * Switch pointer
352
 */
353
void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 nModifier )
354
4.08k
{
355
4.08k
    SetQuickHelpText(OUString());
356
4.08k
    SwWrtShell &rSh = m_rView.GetWrtShell();
357
4.08k
    if( m_pApplyTempl )
358
0
    {
359
0
        PointerStyle eStyle = PointerStyle::Fill;
360
0
        if ( rSh.IsOverReadOnlyPos( rLPt ) )
361
0
        {
362
0
            m_pUserMarker.reset();
363
364
0
            eStyle = PointerStyle::NotAllowed;
365
0
        }
366
0
        else
367
0
        {
368
0
            SwRect aRect;
369
0
            SwRect* pRect = &aRect;
370
0
            const SwFrameFormat* pFormat = nullptr;
371
372
0
            bool bFrameIsValidTarget = false;
373
0
            if( m_pApplyTempl->m_pFormatClipboard )
374
0
                bFrameIsValidTarget = m_pApplyTempl->m_pFormatClipboard->HasContentForThisType( SelectionType::Frame );
375
0
            else if( !m_pApplyTempl->nColor )
376
0
                bFrameIsValidTarget = ( m_pApplyTempl->eType == SfxStyleFamily::Frame );
377
378
0
            if( bFrameIsValidTarget &&
379
0
                        nullptr !=(pFormat = rSh.GetFormatFromObj( rLPt, &pRect )) &&
380
0
                        dynamic_cast<const SwFlyFrameFormat*>( pFormat) )
381
0
            {
382
                //turn on highlight for frame
383
0
                tools::Rectangle aTmp( pRect->SVRect() );
384
385
0
                if ( !m_pUserMarker )
386
0
                {
387
0
                    m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp ));
388
0
                }
389
0
            }
390
0
            else
391
0
            {
392
0
                m_pUserMarker.reset();
393
0
            }
394
395
0
            rSh.SwCursorShell::SetVisibleCursor( rLPt );
396
0
        }
397
0
        SetPointer( eStyle );
398
0
        return;
399
0
    }
400
401
4.08k
    if( !rSh.VisArea().Width() )
402
4.08k
        return;
403
404
0
    CurrShell aCurr(&rSh);
405
406
0
    if ( IsChainMode() )
407
0
    {
408
0
        SwRect aRect;
409
0
        SwChainRet nChainable = rSh.Chainable( aRect, *rSh.GetFlyFrameFormat(), rLPt );
410
0
        PointerStyle eStyle = nChainable != SwChainRet::OK
411
0
                ? PointerStyle::ChainNotAllowed : PointerStyle::Chain;
412
0
        if ( nChainable == SwChainRet::OK )
413
0
        {
414
0
            tools::Rectangle aTmp( aRect.SVRect() );
415
416
0
            if ( !m_pUserMarker )
417
0
            {
418
0
                m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp ));
419
0
            }
420
0
        }
421
0
        else
422
0
        {
423
0
            m_pUserMarker.reset();
424
0
        }
425
426
0
        SetPointer( eStyle );
427
0
        return;
428
0
    }
429
430
0
    bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
431
0
    if ( !bExecHyperlinks )
432
0
    {
433
0
        const bool bSecureOption = SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
434
0
        if ( (  bSecureOption && nModifier == KEY_MOD1 ) ||
435
0
             ( !bSecureOption && nModifier != KEY_MOD1 ) )
436
0
            bExecHyperlinks = true;
437
0
    }
438
439
0
    const bool bExecSmarttags  = nModifier == KEY_MOD1;
440
441
0
    SdrView *pSdrView = rSh.GetDrawView();
442
0
    bool bPrefSdrPointer = false;
443
0
    bool bHitHandle = false;
444
0
    bool bCntAtPos = false;
445
0
    bool bIsViewReadOnly = IsViewReadonly();
446
447
0
    m_aActHitType = SdrHitKind::NONE;
448
0
    PointerStyle eStyle = PointerStyle::Text;
449
0
    if ( !pSdrView )
450
0
        bCntAtPos = true;
451
0
    else if ( (bHitHandle = (pSdrView->PickHandle(rLPt) != nullptr)) )
452
0
    {
453
0
        m_aActHitType = SdrHitKind::Object;
454
0
        bPrefSdrPointer = true;
455
0
    }
456
0
    else
457
0
    {
458
0
        const bool bNotInSelObj = !rSh.IsInsideSelectedObj( rLPt );
459
0
        if ( m_rView.GetDrawFuncPtr() && !m_bInsDraw && bNotInSelObj )
460
0
        {
461
0
            m_aActHitType = SdrHitKind::Object;
462
0
            if (IsObjectSelect())
463
0
                eStyle = PointerStyle::Arrow;
464
0
            else
465
0
                bPrefSdrPointer = true;
466
0
        }
467
0
        else
468
0
        {
469
0
            SdrPageView* pPV = nullptr;
470
0
            pSdrView->SetHitTolerancePixel( HIT_PIX );
471
0
            SdrObject* pObj  = (bNotInSelObj && bExecHyperlinks) ?
472
0
                 pSdrView->PickObj(rLPt, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) :
473
0
                 nullptr;
474
0
            if (pObj)
475
0
            {
476
0
                SdrObjMacroHitRec aTmp;
477
0
                aTmp.aPos = rLPt;
478
0
                aTmp.pPageView = pPV;
479
0
                SetPointer( pObj->GetMacroPointer( aTmp ) );
480
0
                return;
481
0
            }
482
0
            else
483
0
            {
484
                // dvo: IsObjSelectable() eventually calls SdrView::PickObj, so
485
                // apparently this is used to determine whether this is a
486
                // drawling layer object or not.
487
0
                if ( rSh.IsObjSelectable( rLPt ) )
488
0
                {
489
0
                    if (pSdrView->IsTextEdit())
490
0
                    {
491
0
                        m_aActHitType = SdrHitKind::NONE;
492
0
                        bPrefSdrPointer = true;
493
0
                    }
494
0
                    else
495
0
                    {
496
0
                        SdrViewEvent aVEvt;
497
0
                        SdrHitKind eHit = pSdrView->PickAnything(rLPt, aVEvt);
498
499
0
                        if (eHit == SdrHitKind::UrlField && bExecHyperlinks)
500
0
                        {
501
0
                            m_aActHitType = SdrHitKind::Object;
502
0
                            bPrefSdrPointer = true;
503
0
                        }
504
0
                        else
505
0
                        {
506
                            // if we're over a selected object, we show an
507
                            // ARROW by default. We only show a MOVE if 1) the
508
                            // object is selected, and 2) it may be moved
509
                            // (i.e., position is not protected).
510
0
                            bool bMovable =
511
0
                                (!bNotInSelObj) &&
512
0
                                (rSh.GetSelectedObjCount() || rSh.IsFrameSelected()) &&
513
0
                                (rSh.IsSelObjProtected(FlyProtectFlags::Pos) == FlyProtectFlags::NONE);
514
515
0
                            SdrObject* pSelectableObj = rSh.GetObjAt(rLPt);
516
                            // Don't update pointer if this is a background image only.
517
0
                            if (pSelectableObj->GetLayer() != rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId())
518
0
                                eStyle = bMovable ? PointerStyle::Move : PointerStyle::Arrow;
519
0
                            m_aActHitType = SdrHitKind::Object;
520
0
                        }
521
0
                    }
522
0
                }
523
0
                else
524
0
                {
525
0
                    if ( rSh.IsFrameSelected() && !bNotInSelObj )
526
0
                    {
527
                        // dvo: this branch appears to be dead and should be
528
                        // removed in a future version. Reason: The condition
529
                        // !bNotInSelObj means that this branch will only be
530
                        // executed in the cursor points inside a selected
531
                        // object. However, if this is the case, the previous
532
                        // if( rSh.IsObjSelectable(rLPt) ) must always be true:
533
                        // rLPt is inside a selected object, then obviously
534
                        // rLPt is over a selectable object.
535
0
                        if (rSh.IsSelObjProtected(FlyProtectFlags::Size) != FlyProtectFlags::NONE)
536
0
                            eStyle = PointerStyle::NotAllowed;
537
0
                        else
538
0
                            eStyle = PointerStyle::Move;
539
0
                        m_aActHitType = SdrHitKind::Object;
540
0
                    }
541
0
                    else
542
0
                    {
543
0
                        if ( m_rView.GetDrawFuncPtr() )
544
0
                            bPrefSdrPointer = true;
545
0
                        else
546
0
                            bCntAtPos = true;
547
0
                    }
548
0
                }
549
0
            }
550
0
        }
551
0
    }
552
0
    if ( bPrefSdrPointer )
553
0
    {
554
0
        if (bIsViewReadOnly || (rSh.GetSelectedObjCount() && rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE))
555
0
            SetPointer( PointerStyle::NotAllowed );
556
0
        else
557
0
        {
558
0
            if (m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->IsInsertForm() && !bHitHandle)
559
0
                SetPointer( PointerStyle::DrawRect );
560
0
            else
561
0
                SetPointer( pSdrView->GetPreferredPointer( rLPt, rSh.GetOut() ) );
562
0
        }
563
0
    }
564
0
    else
565
0
    {
566
0
        if( !rSh.IsPageAtPos( rLPt ) || m_pAnchorMarker )
567
0
            eStyle = PointerStyle::Arrow;
568
0
        else
569
0
        {
570
            // Even if we already have something, prefer URLs if possible.
571
0
            SwContentAtPos aUrlPos(IsAttrAtPos::InetAttr);
572
0
            if (bCntAtPos || rSh.GetContentAtPos(rLPt, aUrlPos))
573
0
            {
574
0
                SwContentAtPos aSwContentAtPos(
575
0
                    IsAttrAtPos::Field |
576
0
                    IsAttrAtPos::ClickField |
577
0
                    IsAttrAtPos::InetAttr |
578
0
                    IsAttrAtPos::Footnote |
579
0
                    IsAttrAtPos::SmartTag);
580
0
                if( rSh.GetContentAtPos( rLPt, aSwContentAtPos) )
581
0
                {
582
                    // Is edit inline input field
583
0
                    if (IsAttrAtPos::Field == aSwContentAtPos.eContentAtPos
584
0
                             && aSwContentAtPos.pFndTextAttr != nullptr
585
0
                             && aSwContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD)
586
0
                    {
587
0
                        const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr;
588
0
                        if (!(pCursorField && pCursorField == aSwContentAtPos.pFndTextAttr->GetFormatField().GetField()))
589
0
                            eStyle = PointerStyle::RefHand;
590
0
                    }
591
0
                    else
592
0
                    {
593
0
                        const bool bClickToFollow = IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos ||
594
0
                                                    IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos;
595
0
                        if( !bClickToFollow ||
596
0
                            (IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos && bExecHyperlinks) ||
597
0
                            (IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos && bExecSmarttags) )
598
0
                            eStyle = PointerStyle::RefHand;
599
0
                    }
600
0
                }
601
0
                else if (GetView().GetWrtShell().GetViewOptions()->IsShowOutlineContentVisibilityButton())
602
0
                {
603
0
                    aSwContentAtPos.eContentAtPos = IsAttrAtPos::Outline;
604
0
                    if (rSh.GetContentAtPos(rLPt, aSwContentAtPos))
605
0
                    {
606
0
                        if (IsAttrAtPos::Outline == aSwContentAtPos.eContentAtPos)
607
0
                        {
608
0
                            if (nModifier == KEY_MOD1)
609
0
                            {
610
0
                                eStyle = PointerStyle::RefHand;
611
                                // set quick help
612
0
                                if(aSwContentAtPos.aFnd.pNode && aSwContentAtPos.aFnd.pNode->IsTextNode())
613
0
                                {
614
0
                                    const SwNodes& rNds = GetView().GetWrtShell().GetDoc()->GetNodes();
615
0
                                    SwOutlineNodes::size_type nPos;
616
0
                                    rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), &nPos);
617
0
                                    SwOutlineNodes::size_type nOutlineNodesCount
618
0
                                            = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
619
0
                                    int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos);
620
0
                                    OUString sQuickHelp(SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY));
621
0
                                    if (!rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent()
622
0
                                            && nPos + 1 < nOutlineNodesCount
623
0
                                            && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos + 1) > nLevel)
624
0
                                        sQuickHelp += " (" + SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")";
625
0
                                    SetQuickHelpText(sQuickHelp);
626
0
                                }
627
0
                            }
628
0
                        }
629
0
                    }
630
0
                }
631
0
            }
632
0
        }
633
634
        // which kind of text pointer have we to show - horz / vert - ?
635
0
        if( PointerStyle::Text == eStyle && rSh.IsInVerticalText( &rLPt ))
636
0
            eStyle = PointerStyle::TextVertical;
637
0
        else if (rSh.GetViewOptions()->CanHideWhitespace() &&
638
0
                 rSh.GetLayout()->IsBetweenPages(rLPt))
639
0
        {
640
0
            if (rSh.GetViewOptions()->IsHideWhitespaceMode())
641
0
                eStyle = PointerStyle::ShowWhitespace;
642
0
            else
643
0
                eStyle = PointerStyle::HideWhitespace;
644
0
        }
645
646
0
        if( m_pShadCursor )
647
0
        {
648
0
            if( text::HoriOrientation::LEFT == m_eOrient )    // Arrow to the right
649
0
                eStyle = PointerStyle::AutoScrollE;
650
0
            else    // Arrow to the left
651
0
                eStyle = PointerStyle::AutoScrollW;
652
0
        }
653
654
0
        SetPointer( eStyle );
655
0
    }
656
0
}
657
658
/**
659
 * Increase timer for selection
660
 */
661
IMPL_LINK_NOARG(SwEditWin, TimerHandler, Timer *, void)
662
0
{
663
0
    ++m_nTimerCalls;
664
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
665
0
    Point aModPt( m_aMovePos );
666
0
    const SwRect aOldVis( rSh.VisArea() );
667
0
    bool bDone = false;
668
669
0
    if ( !rSh.VisArea().Contains( aModPt ) )
670
0
    {
671
0
        if ( m_bInsDraw )
672
0
        {
673
0
            const int nMaxScroll = 40;
674
0
            m_rView.Scroll( tools::Rectangle(aModPt,Size(1,1)), nMaxScroll, nMaxScroll);
675
0
            bDone = true;
676
0
        }
677
0
        else if ( g_bFrameDrag )
678
0
        {
679
0
            rSh.Drag(&aModPt, false);
680
0
            bDone = true;
681
0
        }
682
0
        if (!bDone)
683
0
        {
684
0
            bool bForward = aModPt.Y() > rSh.VisArea().Bottom();
685
0
            if (m_xRowColumnSelectionStart)
686
0
                aModPt = rSh.GetContentPos( aModPt, bForward );
687
0
            else
688
0
            {
689
0
                sal_Int32 nMove = (aOldVis.Bottom() - aOldVis.Top()) / 20;
690
0
                if (bForward)
691
0
                    aModPt.setY(aOldVis.Bottom() + nMove);
692
0
                else
693
0
                    aModPt.setY(aOldVis.Top() - nMove);
694
0
            }
695
0
        }
696
0
    }
697
0
    if ( !bDone && !(g_bFrameDrag || m_bInsDraw) )
698
0
    {
699
0
        if ( m_xRowColumnSelectionStart )
700
0
        {
701
0
            Point aPos( aModPt );
702
0
            rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag );
703
0
        }
704
0
        else
705
0
            rSh.CallSetCursor( &aModPt, true, m_eScrollSizeMode );
706
707
        // It can be that a "jump" over a table cannot be accomplished like
708
        // that. So we jump over the table by Up/Down here.
709
0
        const SwRect& rVisArea = rSh.VisArea();
710
0
        if( aOldVis == rVisArea && !rSh.IsStartOfDoc() && !rSh.IsEndOfDoc() )
711
0
        {
712
            // take the center point of VisArea to
713
            // decide in which direction the user want.
714
0
            if( aModPt.Y() < ( rVisArea.Top() + rVisArea.Height() / 2 ) )
715
0
                rSh.Up( true );
716
0
            else
717
0
                rSh.Down( true );
718
0
        }
719
0
    }
720
721
0
    m_aMovePos += rSh.VisArea().Pos() - aOldVis.Pos();
722
0
    JustifyAreaTimer();
723
0
}
724
725
void SwEditWin::JustifyAreaTimer(bool bStart)
726
0
{
727
0
    if (bStart)
728
0
        m_nTimerCalls = 0;
729
0
    const tools::Rectangle &rVisArea = GetView().GetVisArea();
730
0
#ifdef UNX
731
0
    const tools::Long coMinLen = 40;
732
#else
733
    const tools::Long coMinLen = 20;
734
#endif
735
0
    tools::Long const nTimeout = 800,
736
0
         nDiff = std::max(
737
0
         std::max( m_aMovePos.Y() - rVisArea.Bottom(), rVisArea.Top() - m_aMovePos.Y() ),
738
0
         std::max( m_aMovePos.X() - rVisArea.Right(),  rVisArea.Left() - m_aMovePos.X()));
739
0
    if (m_nTimerCalls < SCROLL_TIMER_RETARD_LIMIT)
740
0
    {
741
0
        m_aTimer.SetTimeout(nTimeout);
742
0
        m_eScrollSizeMode = ScrollSizeMode::ScrollSizeMouseSelection;
743
0
    }
744
0
    else
745
0
    {
746
0
        m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff) );
747
0
        m_eScrollSizeMode = m_aTimer.GetTimeout() < 100 ?
748
0
            ScrollSizeMode::ScrollSizeTimer2 :
749
0
            m_aTimer.GetTimeout() < 400 ?
750
0
                ScrollSizeMode::ScrollSizeTimer :
751
0
                ScrollSizeMode::ScrollSizeMouseSelection;
752
0
    }
753
0
}
754
755
void SwEditWin::LeaveArea(const Point &rPos)
756
0
{
757
0
    m_aMovePos = rPos;
758
0
    JustifyAreaTimer(true);
759
0
    if( !m_aTimer.IsActive() )
760
0
        m_aTimer.Start();
761
0
    m_pShadCursor.reset();
762
0
}
763
764
inline void SwEditWin::EnterArea()
765
0
{
766
0
    m_aTimer.Stop();
767
0
}
768
769
/**
770
 * Insert mode for frames
771
 */
772
void SwEditWin::InsFrame(sal_uInt16 nCols)
773
0
{
774
0
    StdDrawMode(SdrObjKind::NewFrame, false);
775
0
    m_bInsFrame = true;
776
0
    m_nInsFrameColCount = nCols;
777
0
}
778
779
void SwEditWin::StdDrawMode( SdrObjKind eSdrObjectKind, bool bObjSelect )
780
0
{
781
0
    SetSdrDrawMode( eSdrObjectKind );
782
783
0
    if (bObjSelect)
784
0
        m_rView.SetDrawFuncPtr(std::make_unique<DrawSelection>( &m_rView.GetWrtShell(), this, m_rView ));
785
0
    else
786
0
        m_rView.SetDrawFuncPtr(std::make_unique<SwDrawBase>( &m_rView.GetWrtShell(), this, m_rView ));
787
788
0
    m_rView.SetSelDrawSlot();
789
0
    SetSdrDrawMode( eSdrObjectKind );
790
0
    if (bObjSelect)
791
0
        m_rView.GetDrawFuncPtr()->Activate( SID_OBJECT_SELECT );
792
0
    else
793
0
        m_rView.GetDrawFuncPtr()->Activate( sal::static_int_cast< sal_uInt16 >(eSdrObjectKind) );
794
0
    m_bInsFrame = false;
795
0
    m_nInsFrameColCount = 1;
796
0
}
797
798
void SwEditWin::StopInsFrame()
799
0
{
800
0
    if (m_rView.GetDrawFuncPtr())
801
0
    {
802
0
        m_rView.GetDrawFuncPtr()->Deactivate();
803
0
        m_rView.SetDrawFuncPtr(nullptr);
804
0
    }
805
0
    m_rView.LeaveDrawCreate();    // leave construction mode
806
0
    m_bInsFrame = false;
807
0
    m_nInsFrameColCount = 1;
808
0
}
809
810
bool SwEditWin::IsInputSequenceCheckingRequired( const OUString &rText, const SwPaM& rCursor )
811
0
{
812
0
    if ( !SvtCTLOptions::IsCTLFontEnabled() ||
813
0
         !SvtCTLOptions::IsCTLSequenceChecking() )
814
0
         return false;
815
816
0
    if ( 0 == rCursor.Start()->GetContentIndex() ) /* first char needs not to be checked */
817
0
        return false;
818
819
0
    SwBreakIt *pBreakIter = SwBreakIt::Get();
820
0
    rtl::Reference < i18npool::BreakIterator > xBI = pBreakIter->GetBreakIter();
821
0
    assert(xBI.is());
822
0
    tools::Long nCTLScriptPos = -1;
823
824
0
    if (xBI->getScriptType( rText, 0 ) == i18n::ScriptType::COMPLEX)
825
0
        nCTLScriptPos = 0;
826
0
    else
827
0
        nCTLScriptPos = xBI->nextScript( rText, 0, i18n::ScriptType::COMPLEX );
828
829
0
    return (0 <= nCTLScriptPos && nCTLScriptPos <= rText.getLength());
830
0
}
831
832
//return INVALID_HINT if language should not be explicitly overridden, the correct
833
//HintId to use for the eBufferLanguage otherwise
834
static sal_uInt16 lcl_isNonDefaultLanguage(LanguageType eBufferLanguage, SwView const & rView,
835
    const OUString &rInBuffer)
836
0
{
837
0
    sal_uInt16 nWhich = INVALID_HINT;
838
839
    //If the option to IgnoreLanguageChange is set, short-circuit this method
840
    //which results in the document/paragraph language remaining the same
841
    //despite a change to the keyboard/input language
842
0
    SvtSysLocaleOptions aSysLocaleOptions;
843
0
    if(aSysLocaleOptions.IsIgnoreLanguageChange())
844
0
    {
845
0
        return INVALID_HINT;
846
0
    }
847
848
0
    bool bLang = true;
849
0
    if(eBufferLanguage != LANGUAGE_DONTKNOW)
850
0
    {
851
0
        switch( SvtLanguageOptions::GetI18NScriptTypeOfLanguage( eBufferLanguage ))
852
0
        {
853
0
            case  i18n::ScriptType::ASIAN:     nWhich = RES_CHRATR_CJK_LANGUAGE; break;
854
0
            case  i18n::ScriptType::COMPLEX:   nWhich = RES_CHRATR_CTL_LANGUAGE; break;
855
0
            case  i18n::ScriptType::LATIN:     nWhich = RES_CHRATR_LANGUAGE; break;
856
0
            default: bLang = false;
857
0
        }
858
0
        if(bLang)
859
0
        {
860
0
            SfxItemSet aLangSet(rView.GetPool(), nWhich, nWhich);
861
0
            SwWrtShell& rSh = rView.GetWrtShell();
862
0
            rSh.GetCurAttr(aLangSet);
863
0
            if(SfxItemState::DEFAULT <= aLangSet.GetItemState(nWhich))
864
0
            {
865
0
                LanguageType eLang = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage();
866
0
                if ( eLang == eBufferLanguage )
867
0
                {
868
                    // current language attribute equal to language reported from system
869
0
                    bLang = false;
870
0
                }
871
0
                else if ( !g_bInputLanguageSwitched && RES_CHRATR_LANGUAGE == nWhich )
872
0
                {
873
                    // special case: switching between two "LATIN" languages
874
                    // In case the current keyboard setting might be suitable
875
                    // for both languages we can't safely assume that the user
876
                    // wants to use the language reported from the system,
877
                    // except if we knew that it was explicitly switched (thus
878
                    // the check for "bInputLangeSwitched").
879
880
                    // The language reported by the system could be just the
881
                    // system default language that the user is not even aware
882
                    // of, because no language selection tool is installed at
883
                    // all. In this case the OOo language should get preference
884
                    // as it might have been selected by the user explicitly.
885
886
                    // Usually this case happens if the OOo language is
887
                    // different to the system language but the system keyboard
888
                    // is still suitable for the OOo language (e.g. writing
889
                    // English texts with a German keyboard).
890
891
                    // For non-latin keyboards overwriting the attribute is
892
                    // still valid. We do this for cyrillic and greek ATM.  In
893
                    // future versions of OOo this should be replaced by a
894
                    // configuration switch that allows to give the preference
895
                    // to the OOo setting or the system setting explicitly
896
                    // and/or a better handling of the script type.
897
0
                    i18n::UnicodeScript eType = !rInBuffer.isEmpty() ?
898
0
                        GetAppCharClass().getScript( rInBuffer, 0 ) :
899
0
                        i18n::UnicodeScript_kScriptCount;
900
901
0
                    bool bSystemIsNonLatin = false;
902
0
                    switch ( eType )
903
0
                    {
904
0
                        case i18n::UnicodeScript_kGreek:
905
0
                        case i18n::UnicodeScript_kCyrillic:
906
                            // in case other UnicodeScripts require special
907
                            // keyboards they can be added here
908
0
                            bSystemIsNonLatin = true;
909
0
                            break;
910
0
                        default:
911
0
                            break;
912
0
                    }
913
914
0
                    bool bOOoLangIsNonLatin = MsLangId::isNonLatinWestern( eLang);
915
916
0
                    bLang = (bSystemIsNonLatin != bOOoLangIsNonLatin);
917
0
                }
918
0
            }
919
0
        }
920
0
    }
921
0
    return bLang ? nWhich : INVALID_HINT;
922
0
}
923
924
/**
925
 * Character buffer is inserted into the document
926
 */
927
void SwEditWin::FlushInBuffer()
928
4.08k
{
929
4.08k
    if ( m_aKeyInputFlushTimer.IsActive())
930
0
        m_aKeyInputFlushTimer.Stop();
931
932
4.08k
    if ( m_aInBuffer.isEmpty() )
933
4.08k
        return;
934
935
0
    SwWrtShell& rSh = m_rView.GetWrtShell();
936
0
    uno::Reference<frame::XDispatchRecorder> xRecorder
937
0
        = m_rView.GetViewFrame().GetBindings().GetRecorder();
938
939
0
    comphelper::ScopeGuard showTooltipGuard(
940
0
        [this, &rSh]
941
0
        {
942
0
            SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
943
0
            const bool bAutoTextShown
944
0
                = rACfg.IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText());
945
0
            if (!bAutoTextShown)
946
0
            {
947
0
                SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
948
0
                if (pACorr && pACorr->GetSwFlags().bAutoCompleteWords)
949
0
                    ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr);
950
0
            }
951
0
        });
952
0
    if (!m_bMaybeShowTooltipAfterBufferFlush || xRecorder)
953
0
        showTooltipGuard.dismiss();
954
0
    m_bMaybeShowTooltipAfterBufferFlush = false;
955
956
    // generate new sequence input checker if not already done
957
0
    if ( !pCheckIt )
958
0
        pCheckIt = new SwCheckIt;
959
960
0
    uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = pCheckIt->xCheck;
961
0
    if ( xISC.is() && IsInputSequenceCheckingRequired( m_aInBuffer, *rSh.GetCursor() ) )
962
0
    {
963
964
        // apply (Thai) input sequence checking/correction
965
966
0
        rSh.Push(); // push current cursor to stack
967
968
        // get text from the beginning (i.e left side) of current selection
969
        // to the start of the paragraph
970
0
        rSh.NormalizePam();     // make point be the first (left) one
971
0
        if (!rSh.GetCursor()->HasMark())
972
0
            rSh.GetCursor()->SetMark();
973
0
        rSh.GetCursor()->GetMark()->SetContent(0);
974
975
0
        const OUString aOldText( rSh.GetCursor()->GetText() );
976
0
        const sal_Int32 nOldLen = aOldText.getLength();
977
978
0
        sal_Int32 nExpandSelection = 0;
979
0
        if (nOldLen > 0)
980
0
        {
981
0
            sal_Int32 nTmpPos = nOldLen;
982
0
            sal_Int16 nCheckMode = SvtCTLOptions::IsCTLSequenceCheckingRestricted() ?
983
0
                    i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
984
985
0
            OUString aNewText( aOldText );
986
0
            if (SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace())
987
0
            {
988
0
                for( sal_Int32 k = 0;  k < m_aInBuffer.getLength();  ++k)
989
0
                {
990
0
                    const sal_Unicode cChar = m_aInBuffer[k];
991
0
                    const sal_Int32 nPrevPos =xISC->correctInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode );
992
993
                    // valid sequence or sequence could be corrected:
994
0
                    if (nPrevPos != aNewText.getLength())
995
0
                        nTmpPos = nPrevPos + 1;
996
0
                }
997
998
                // find position of first character that has changed
999
0
                sal_Int32 nNewLen = aNewText.getLength();
1000
0
                const sal_Unicode *pOldText = aOldText.getStr();
1001
0
                const sal_Unicode *pNewText = aNewText.getStr();
1002
0
                sal_Int32 nChgPos = 0;
1003
0
                while ( nChgPos < nOldLen && nChgPos < nNewLen &&
1004
0
                        pOldText[nChgPos] == pNewText[nChgPos] )
1005
0
                    ++nChgPos;
1006
1007
0
                const sal_Int32 nChgLen = nNewLen - nChgPos;
1008
0
                if (nChgLen)
1009
0
                {
1010
0
                    m_aInBuffer = aNewText.copy( nChgPos, nChgLen );
1011
0
                    nExpandSelection = nOldLen - nChgPos;
1012
0
                }
1013
0
                else
1014
0
                    m_aInBuffer.clear();
1015
0
            }
1016
0
            else
1017
0
            {
1018
0
                for( sal_Int32 k = 0;  k < m_aInBuffer.getLength(); ++k )
1019
0
                {
1020
0
                    const sal_Unicode cChar = m_aInBuffer[k];
1021
0
                    if (xISC->checkInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode ))
1022
0
                    {
1023
                        // character can be inserted:
1024
0
                        aNewText += OUStringChar( cChar );
1025
0
                        ++nTmpPos;
1026
0
                    }
1027
0
                }
1028
0
                m_aInBuffer = aNewText.copy( aOldText.getLength() );  // copy new text to be inserted to buffer
1029
0
            }
1030
0
        }
1031
1032
        // at this point now we will insert the buffer text 'normally' some lines below...
1033
1034
0
        rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
1035
1036
0
        if (m_aInBuffer.isEmpty())
1037
0
            return;
1038
1039
        // if text prior to the original selection needs to be changed
1040
        // as well, we now expand the selection accordingly.
1041
0
        SwPaM &rCursor = *rSh.GetCursor();
1042
0
        const sal_Int32 nCursorStartPos = rCursor.Start()->GetContentIndex();
1043
0
        OSL_ENSURE( nCursorStartPos >= nExpandSelection, "cannot expand selection as specified!!" );
1044
0
        if (nExpandSelection && nCursorStartPos >= nExpandSelection)
1045
0
        {
1046
0
            if (!rCursor.HasMark())
1047
0
                rCursor.SetMark();
1048
0
            rCursor.Start()->AdjustContent( -nExpandSelection );
1049
0
        }
1050
0
    }
1051
1052
0
    if ( xRecorder.is() )
1053
0
    {
1054
        // determine shell
1055
0
        SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView );
1056
        // generate request and record
1057
0
        if (pSfxShell)
1058
0
        {
1059
0
            SfxRequest aReq(m_rView.GetViewFrame(), FN_INSERT_STRING);
1060
0
            aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, m_aInBuffer ) );
1061
0
            aReq.Done();
1062
0
        }
1063
0
    }
1064
1065
0
    sal_uInt16 nWhich = lcl_isNonDefaultLanguage(m_eBufferLanguage, m_rView, m_aInBuffer);
1066
0
    if (nWhich != INVALID_HINT )
1067
0
    {
1068
0
        SvxLanguageItem aLangItem( m_eBufferLanguage, nWhich );
1069
0
        rSh.SetAttrItem( aLangItem );
1070
0
    }
1071
1072
0
    rSh.Insert( m_aInBuffer );
1073
0
    m_eBufferLanguage = LANGUAGE_DONTKNOW;
1074
0
    m_aInBuffer.clear();
1075
0
}
1076
1077
void SwEditWin::ChangeFly( Move::Direction eDir, Move::Size eDirSize, bool bWeb )
1078
0
{
1079
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
1080
0
    SwRect aTmp = rSh.GetFlyRect();
1081
0
    if( !aTmp.HasArea() ||
1082
0
        rSh.IsSelObjProtected( FlyProtectFlags::Pos ) != FlyProtectFlags::NONE )
1083
0
        return;
1084
1085
0
    SfxItemSetFixed<
1086
0
            RES_FRM_SIZE, RES_FRM_SIZE,
1087
0
            RES_PROTECT, RES_PROTECT,
1088
0
            RES_VERT_ORIENT, RES_ANCHOR,
1089
0
            RES_COL, RES_COL,
1090
0
            RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW>
1091
0
        aSet( rSh.GetAttrPool() );
1092
0
    rSh.GetFlyFrameAttr( aSet );
1093
0
    RndStdIds eAnchorId = aSet.Get(RES_ANCHOR).GetAnchorId();
1094
0
    Size aSnap;
1095
1096
0
    if(eDirSize == Move::Size::Small)
1097
0
    {
1098
0
        aSnap = PixelToLogic(Size(1,1));
1099
0
    }
1100
0
    else
1101
0
    {
1102
0
        aSnap = rSh.GetViewOptions()->GetSnapSize();
1103
0
        short nDiv = rSh.GetViewOptions()->GetDivisionX();
1104
0
        if ( nDiv > 0 )
1105
0
            aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) );
1106
0
        nDiv = rSh.GetViewOptions()->GetDivisionY();
1107
0
        if ( nDiv > 0 )
1108
0
            aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) );
1109
0
    }
1110
1111
0
    if(eDirSize == Move::Size::Huge)
1112
0
    {
1113
        // #i121236# 567twips == 1cm, but just take three times the normal snap
1114
0
        aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
1115
0
    }
1116
1117
0
    SwRect aBoundRect;
1118
0
    Point aRefPoint;
1119
    // adjustment for allowing vertical position
1120
    // aligned to page for fly frame anchored to paragraph or to character.
1121
0
    {
1122
0
        const SwFormatVertOrient& aVert( aSet.Get(RES_VERT_ORIENT) );
1123
0
        const bool bFollowTextFlow =
1124
0
                aSet.Get(RES_FOLLOW_TEXT_FLOW).GetValue();
1125
0
        const SwFormatAnchor& rFormatAnchor = aSet.Get(RES_ANCHOR);
1126
0
        rSh.CalcBoundRect( aBoundRect, eAnchorId,
1127
0
                           text::RelOrientation::FRAME, aVert.GetRelationOrient(),
1128
0
                           &rFormatAnchor, bFollowTextFlow,
1129
0
                           false, &aRefPoint );
1130
0
    }
1131
0
    tools::Long nLeft = std::min( aTmp.Left() - aBoundRect.Left(), aSnap.Width() );
1132
0
    tools::Long nRight = std::min( aBoundRect.Right() - aTmp.Right(), aSnap.Width() );
1133
0
    tools::Long nUp = std::min( aTmp.Top() - aBoundRect.Top(), aSnap.Height() );
1134
0
    tools::Long nDown = std::min( aBoundRect.Bottom() - aTmp.Bottom(), aSnap.Height() );
1135
1136
0
    switch (eDir)
1137
0
    {
1138
0
        case Move::Direction::Left: aTmp.Left(aTmp.Left() - nLeft);
1139
0
            break;
1140
1141
0
        case Move::Direction::Up: aTmp.Top(aTmp.Top() - nUp);
1142
0
            break;
1143
1144
0
        case Move::Direction::Right:
1145
0
            switch (eDirSize) {
1146
0
                case Move::Size::Small:
1147
0
                    if (aTmp.Width() < aSnap.Width() + MINFLY)
1148
0
                        break;
1149
0
                    nRight = aSnap.Width();
1150
0
                    [[fallthrough]];
1151
1152
0
                case Move::Size::Huge:
1153
0
                case Move::Size::Big: aTmp.Left(aTmp.Left() + nRight);
1154
1155
0
            }
1156
0
            break;
1157
1158
0
        case Move::Direction::Down:
1159
0
            switch (eDirSize) {
1160
0
                case Move::Size::Small:
1161
0
                    if (aTmp.Height() < aSnap.Height() + MINFLY)
1162
0
                        break;
1163
0
                    nDown = aSnap.Height();
1164
0
                    [[fallthrough]];
1165
1166
0
                case Move::Size::Huge:
1167
0
                case Move::Size::Big: aTmp.Top(aTmp.Top() + nDown);
1168
1169
0
            }
1170
0
            break;
1171
1172
0
        default: OSL_ENSURE(true, "ChangeFly: Unknown direction." );
1173
0
    }
1174
0
    bool bSet = false;
1175
0
    if ((RndStdIds::FLY_AS_CHAR == eAnchorId) && (eDir == Move::Direction::Down || eDir == Move::Direction::Up))
1176
0
    {
1177
0
        tools::Long aDiff = aTmp.Top() - aRefPoint.Y();
1178
0
        if( aDiff > 0 )
1179
0
            aDiff = 0;
1180
0
        else if ( aDiff < -aTmp.Height() )
1181
0
            aDiff = -aTmp.Height();
1182
0
        SwFormatVertOrient aVert( aSet.Get(RES_VERT_ORIENT) );
1183
0
        sal_Int16 eNew;
1184
0
        if( bWeb )
1185
0
        {
1186
0
            eNew = aVert.GetVertOrient();
1187
0
            bool bDown = eDir == Move::Direction::Down;
1188
0
            switch( eNew )
1189
0
            {
1190
0
                case text::VertOrientation::CHAR_TOP:
1191
0
                    if( bDown ) eNew = text::VertOrientation::CENTER;
1192
0
                break;
1193
0
                case text::VertOrientation::CENTER:
1194
0
                    eNew = bDown ? text::VertOrientation::TOP : text::VertOrientation::CHAR_TOP;
1195
0
                break;
1196
0
                case text::VertOrientation::TOP:
1197
0
                    if( !bDown ) eNew = text::VertOrientation::CENTER;
1198
0
                break;
1199
0
                case text::VertOrientation::LINE_TOP:
1200
0
                    if( bDown ) eNew = text::VertOrientation::LINE_CENTER;
1201
0
                break;
1202
0
                case text::VertOrientation::LINE_CENTER:
1203
0
                    eNew = bDown ? text::VertOrientation::LINE_BOTTOM : text::VertOrientation::LINE_TOP;
1204
0
                break;
1205
0
                case text::VertOrientation::LINE_BOTTOM:
1206
0
                    if( !bDown ) eNew = text::VertOrientation::LINE_CENTER;
1207
0
                break;
1208
0
                default:; //prevent warning
1209
0
            }
1210
0
        }
1211
0
        else
1212
0
        {
1213
0
            aVert.SetPos( aDiff );
1214
0
            eNew = text::VertOrientation::NONE;
1215
0
        }
1216
0
        aVert.SetVertOrient( eNew );
1217
0
        aSet.Put( aVert );
1218
0
        bSet = true;
1219
0
    }
1220
0
    if (bWeb && (RndStdIds::FLY_AT_PARA == eAnchorId)
1221
0
        && ( (eDir == Move::Direction::Left && eDirSize == Move::Size::Small)
1222
0
            || (eDir == Move::Direction::Right && eDirSize == Move::Size::Big) ))
1223
0
    {
1224
0
        SwFormatHoriOrient aHori( aSet.Get(RES_HORI_ORIENT) );
1225
0
        sal_Int16 eNew;
1226
0
        eNew = aHori.GetHoriOrient();
1227
0
        switch( eNew )
1228
0
        {
1229
0
            case text::HoriOrientation::RIGHT:
1230
0
                if(eDir == Move::Direction::Left && eDirSize == Move::Size::Small)
1231
0
                    eNew = text::HoriOrientation::LEFT;
1232
0
            break;
1233
0
            case text::HoriOrientation::LEFT:
1234
0
                if(eDir == Move::Direction::Right && eDirSize == Move::Size::Big)
1235
0
                    eNew = text::HoriOrientation::RIGHT;
1236
0
            break;
1237
0
            default:; //prevent warning
1238
0
        }
1239
0
        if( eNew != aHori.GetHoriOrient() )
1240
0
        {
1241
0
            aHori.SetHoriOrient( eNew );
1242
0
            aSet.Put( aHori );
1243
0
            bSet = true;
1244
0
        }
1245
0
    }
1246
0
    rSh.StartAllAction();
1247
0
    if( bSet )
1248
0
        rSh.SetFlyFrameAttr( aSet );
1249
0
    bool bSetPos = (RndStdIds::FLY_AS_CHAR != eAnchorId);
1250
0
    if(bSetPos && bWeb)
1251
0
    {
1252
0
        bSetPos = RndStdIds::FLY_AT_PAGE == eAnchorId;
1253
0
    }
1254
0
    if( bSetPos )
1255
0
        rSh.SetFlyPos( aTmp.Pos() );
1256
0
    rSh.EndAllAction();
1257
1258
0
}
1259
1260
void SwEditWin::ChangeDrawing(Move::Direction eDir, Move::Size eDirSize)
1261
0
{
1262
    // start undo action in order to get only one
1263
    // undo action for this change.
1264
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
1265
0
    rSh.StartUndo();
1266
1267
0
    tools::Long nX = 0;
1268
0
    tools::Long nY = 0;
1269
1270
0
    SwMove nAnchorDir = SwMove::UP;
1271
0
    switch(eDir)
1272
0
    {
1273
0
        case Move::Direction::Left:
1274
0
            nX = -1;
1275
0
            nAnchorDir = SwMove::LEFT;
1276
0
        break;
1277
0
        case Move::Direction::Up:
1278
0
            nY = -1;
1279
0
        break;
1280
0
        case Move::Direction::Right:
1281
0
            nX = +1;
1282
0
            nAnchorDir = SwMove::RIGHT;
1283
0
        break;
1284
0
        case Move::Direction::Down:
1285
0
            nY = +1;
1286
0
            nAnchorDir = SwMove::DOWN;
1287
0
        break;
1288
0
    }
1289
1290
0
    if(0 != nX || 0 != nY)
1291
0
    {
1292
0
        FlyProtectFlags nProtect = rSh.IsSelObjProtected( FlyProtectFlags::Pos|FlyProtectFlags::Size );
1293
0
        Size aSnap( rSh.GetViewOptions()->GetSnapSize() );
1294
0
        short nDiv = rSh.GetViewOptions()->GetDivisionX();
1295
0
        if ( nDiv > 0 )
1296
0
            aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) );
1297
0
        nDiv = rSh.GetViewOptions()->GetDivisionY();
1298
0
        if ( nDiv > 0 )
1299
0
            aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) );
1300
1301
0
        if(eDirSize == Move::Size::Small)
1302
0
        {
1303
0
            aSnap = PixelToLogic(Size(1,1));
1304
0
        }
1305
0
        else if(eDirSize == Move::Size::Huge)
1306
0
        {
1307
            // #i121236# 567twips == 1cm, but just take three times the normal snap
1308
0
            aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
1309
0
        }
1310
1311
0
        nX *= aSnap.Width();
1312
0
        nY *= aSnap.Height();
1313
1314
0
        SdrView *pSdrView = rSh.GetDrawView();
1315
0
        const SdrHdlList& rHdlList = pSdrView->GetHdlList();
1316
0
        SdrHdl* pHdl = rHdlList.GetFocusHdl();
1317
0
        rSh.StartAllAction();
1318
0
        if(nullptr == pHdl)
1319
0
        {
1320
            // now move the selected draw objects
1321
            // if the object's position is not protected
1322
0
            if(!(nProtect&FlyProtectFlags::Pos))
1323
0
            {
1324
                // Check if object is anchored as character and move direction
1325
0
                bool bDummy1, bDummy2;
1326
0
                const bool bVertAnchor = rSh.IsFrameVertical( true, bDummy1, bDummy2 );
1327
0
                const bool bIsHorizontalDirection = eDir == Move::Direction::Left || eDir == Move::Direction::Right;
1328
0
                const bool bHoriMove = bVertAnchor != bIsHorizontalDirection;
1329
0
                const bool bMoveAllowed = !bHoriMove || (rSh.GetAnchorId() != RndStdIds::FLY_AS_CHAR);
1330
0
                if ( bMoveAllowed )
1331
0
                {
1332
0
                    pSdrView->MoveAllMarked(Size(nX, nY));
1333
0
                    rSh.SetModified();
1334
0
                }
1335
0
            }
1336
0
        }
1337
0
        else
1338
0
        {
1339
            // move handle with index nHandleIndex
1340
0
            if (nX || nY)
1341
0
            {
1342
0
                if( SdrHdlKind::Anchor == pHdl->GetKind() ||
1343
0
                    SdrHdlKind::Anchor_TR == pHdl->GetKind() )
1344
0
                {
1345
                    // anchor move cannot be allowed when position is protected
1346
0
                    if(!(nProtect&FlyProtectFlags::Pos))
1347
0
                        rSh.MoveAnchor( nAnchorDir );
1348
0
                }
1349
                //now resize if size is protected
1350
0
                else if(!(nProtect&FlyProtectFlags::Size))
1351
0
                {
1352
                    // now move the Handle (nX, nY)
1353
0
                    Point aStartPoint(pHdl->GetPos());
1354
0
                    Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
1355
0
                    const SdrDragStat& rDragStat = pSdrView->GetDragStat();
1356
1357
                    // start dragging
1358
0
                    pSdrView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
1359
1360
0
                    if(pSdrView->IsDragObj())
1361
0
                    {
1362
0
                        bool bWasNoSnap = rDragStat.IsNoSnap();
1363
0
                        bool bWasSnapEnabled = pSdrView->IsSnapEnabled();
1364
1365
                        // switch snapping off
1366
0
                        if(!bWasNoSnap)
1367
0
                            const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
1368
0
                        if(bWasSnapEnabled)
1369
0
                            pSdrView->SetSnapEnabled(false);
1370
1371
0
                        pSdrView->MovAction(aEndPoint);
1372
0
                        pSdrView->EndDragObj();
1373
0
                        rSh.SetModified();
1374
1375
                        // restore snap
1376
0
                        if(!bWasNoSnap)
1377
0
                            const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
1378
0
                        if(bWasSnapEnabled)
1379
0
                            pSdrView->SetSnapEnabled(bWasSnapEnabled);
1380
0
                    }
1381
0
                }
1382
0
            }
1383
0
        }
1384
0
        rSh.EndAllAction();
1385
0
    }
1386
1387
0
    rSh.EndUndo();
1388
0
}
1389
1390
/**
1391
 * KeyEvents
1392
 */
1393
void SwEditWin::KeyInput(const KeyEvent &rKEvt)
1394
0
{
1395
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
1396
1397
0
    if (comphelper::LibreOfficeKit::isActive() && m_rView.GetPostItMgr())
1398
0
    {
1399
0
        if (vcl::Window* pWindow = m_rView.GetPostItMgr()->GetActiveSidebarWin())
1400
0
        {
1401
0
            pWindow->KeyInput(rKEvt);
1402
0
            return;
1403
0
        }
1404
0
    }
1405
1406
    // Do not show autotext / word completion tooltips in intermediate flushes
1407
0
    m_bMaybeShowTooltipAfterBufferFlush = false;
1408
1409
0
    sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
1410
1411
0
    if (nKey == KEY_ESCAPE)
1412
0
    {
1413
0
        if (m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard)
1414
0
        {
1415
0
            m_pApplyTempl->m_pFormatClipboard->Erase();
1416
0
            SetApplyTemplate(SwApplyTemplate());
1417
0
            m_rView.GetViewFrame().GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
1418
0
        }
1419
0
        else if (rSh.IsHeaderFooterEdit())
1420
0
        {
1421
0
            bool bHeader = bool(FrameTypeFlags::HEADER & rSh.GetFrameType(nullptr, false));
1422
0
            if (bHeader)
1423
0
                rSh.SttPg();
1424
0
            else
1425
0
                rSh.EndPg();
1426
0
            rSh.ToggleHeaderFooterEdit();
1427
0
        }
1428
0
    }
1429
1430
0
    SfxObjectShell *pObjSh = m_rView.GetViewFrame().GetObjectShell();
1431
0
    if ( m_bLockInput || (pObjSh && pObjSh->GetProgress()) )
1432
        // When the progress bar is active or a progress is
1433
        // running on a document, no order is being taken
1434
0
        return;
1435
1436
0
    m_pShadCursor.reset();
1437
    // Do not reset the timer here, otherwise when flooded with events it would never time out
1438
    // if every key event stopped and started it again.
1439
0
    comphelper::ScopeGuard keyInputFlushTimerStop([this]() { m_aKeyInputFlushTimer.Stop(); });
1440
1441
0
    bool bIsViewReadOnly = IsViewReadonly();
1442
1443
    //if the language changes the buffer must be flushed
1444
0
    LanguageType eNewLanguage = GetInputLanguage();
1445
0
    if(!bIsViewReadOnly && m_eBufferLanguage != eNewLanguage && !m_aInBuffer.isEmpty())
1446
0
    {
1447
0
        FlushInBuffer();
1448
0
    }
1449
0
    m_eBufferLanguage = eNewLanguage;
1450
1451
0
    QuickHelpData aTmpQHD;
1452
0
    if( s_pQuickHlpData->m_bIsDisplayed )
1453
0
    {
1454
0
        aTmpQHD.Move( *s_pQuickHlpData );
1455
0
        s_pQuickHlpData->Stop( rSh );
1456
0
    }
1457
1458
    // OS:the DrawView also needs a readonly-Flag as well
1459
0
    if ( !bIsViewReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( rKEvt, this ) )
1460
0
    {
1461
0
        rSh.GetView().GetViewFrame().GetBindings().InvalidateAll( false );
1462
0
        rSh.SetModified();
1463
0
        return; // Event evaluated by SdrView
1464
0
    }
1465
1466
0
    if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
1467
0
    {
1468
0
        StopInsFrame();
1469
0
        rSh.Edit();
1470
0
    }
1471
1472
0
    bool bFlushBuffer = false;
1473
0
    bool bNormalChar = false;
1474
0
    bool bAppendSpace = s_pQuickHlpData->m_bAppendSpace;
1475
0
    s_pQuickHlpData->m_bAppendSpace = false;
1476
1477
0
    if (nKey == KEY_F12 && getenv("SW_DEBUG"))
1478
0
    {
1479
0
        if( rKEvt.GetKeyCode().IsShift())
1480
0
        {
1481
0
            GetView().GetDocShell()->GetDoc()->dumpAsXml();
1482
0
        }
1483
0
        else
1484
0
        {
1485
0
            SwRootFrame* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout();
1486
0
            pLayout->dumpAsXml( );
1487
0
        }
1488
0
        return;
1489
0
    }
1490
1491
0
    KeyEvent aKeyEvent( rKEvt );
1492
    // look for vertical mappings
1493
0
    if( !bIsViewReadOnly && !rSh.IsSelFrameMode() && !rSh.GetSelectedObjCount() )
1494
0
    {
1495
0
        if( KEY_UP == nKey || KEY_DOWN == nKey ||
1496
0
            KEY_LEFT == nKey || KEY_RIGHT == nKey )
1497
0
        {
1498
            // In general, we want to map the direction keys if we are inside
1499
            // some vertical formatted text.
1500
            // 1. Exception: For a table cursor in a horizontal table, the
1501
            //               directions should never be mapped.
1502
            // 2. Exception: For a table cursor in a vertical table, the
1503
            //               directions should always be mapped.
1504
0
            const bool bVertText = rSh.IsInVerticalText();
1505
0
            const bool bTableCursor = rSh.GetTableCursor();
1506
0
            const bool bVertTable = rSh.IsTableVertical();
1507
0
            if( ( bVertText && ( !bTableCursor || bVertTable ) ) ||
1508
0
                ( bTableCursor && bVertTable ) )
1509
0
            {
1510
0
                SvxFrameDirection eDirection = rSh.GetTextDirection();
1511
0
                if (eDirection == SvxFrameDirection::Vertical_LR_BT)
1512
0
                {
1513
                    // Map from physical to logical, so rotate clockwise.
1514
0
                    if (KEY_UP == nKey)
1515
0
                        nKey = KEY_RIGHT;
1516
0
                    else if (KEY_DOWN == nKey)
1517
0
                        nKey = KEY_LEFT;
1518
0
                    else if (KEY_LEFT == nKey)
1519
0
                        nKey = KEY_UP;
1520
0
                    else /* KEY_RIGHT == nKey */
1521
0
                        nKey = KEY_DOWN;
1522
0
                }
1523
0
                else
1524
0
                {
1525
                    // Attempt to integrate cursor travelling for mongolian layout does not work.
1526
                    // Thus, back to previous mapping of cursor keys to direction keys.
1527
0
                    if( KEY_UP == nKey ) nKey = KEY_LEFT;
1528
0
                    else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT;
1529
0
                    else if( KEY_LEFT == nKey ) nKey = KEY_DOWN;
1530
0
                    else /* KEY_RIGHT == nKey */ nKey = KEY_UP;
1531
0
                }
1532
0
            }
1533
1534
0
            if ( rSh.IsInRightToLeftText() )
1535
0
            {
1536
0
                if( KEY_LEFT == nKey ) nKey = KEY_RIGHT;
1537
0
                else if( KEY_RIGHT == nKey ) nKey = KEY_LEFT;
1538
0
            }
1539
1540
0
            aKeyEvent = KeyEvent( rKEvt.GetCharCode(),
1541
0
                                  vcl::KeyCode( nKey, rKEvt.GetKeyCode().GetModifier() ),
1542
0
                                  rKEvt.GetRepeat() );
1543
0
        }
1544
0
    }
1545
1546
0
    const vcl::KeyCode& rKeyCode = aKeyEvent.GetKeyCode();
1547
0
    sal_Unicode aCh = aKeyEvent.GetCharCode();
1548
1549
    // enable switching to notes anchor with Ctrl - Alt - Page Up/Down
1550
    // pressing this inside a note will switch to next/previous note
1551
0
    if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((rKeyCode.GetCode() == KEY_PAGEUP) || (rKeyCode.GetCode() == KEY_PAGEDOWN)))
1552
0
    {
1553
0
        const bool bNext = rKeyCode.GetCode()==KEY_PAGEDOWN;
1554
0
        const SwFieldType* pFieldType = rSh.GetFieldType( 0, SwFieldIds::Postit );
1555
0
        rSh.MoveFieldType( pFieldType, bNext );
1556
0
        return;
1557
0
    }
1558
1559
0
    if (SwTextContentControl* pTextContentControl = rSh.CursorInsideContentControl())
1560
0
    {
1561
        // Check if this combination of rKeyCode and pTextContentControl should open a popup.
1562
0
        const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
1563
0
        std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
1564
0
        if (pContentControl->ShouldOpenPopup(rKeyCode))
1565
0
        {
1566
0
            SwShellCursor* pCursor = rSh.GetCursor_();
1567
0
            if (pCursor)
1568
0
            {
1569
0
                VclPtr<SwContentControlButton> pContentControlButton = pCursor->GetContentControlButton();
1570
0
                if (pContentControlButton)
1571
0
                {
1572
0
                    pContentControlButton->StartPopup();
1573
0
                    return;
1574
0
                }
1575
0
            }
1576
0
        }
1577
0
    }
1578
1579
0
    const SwFrameFormat* pFlyFormat = rSh.GetFlyFrameFormat();
1580
1581
0
    if (pFlyFormat)
1582
0
    {
1583
        // See if the fly frame's anchor is in a content control. If so,
1584
        // try to interact with it.
1585
0
        const SwFormatAnchor& rFormatAnchor = pFlyFormat->GetAnchor();
1586
0
        SwNode* pAnchorNode = rFormatAnchor.GetAnchorNode();
1587
0
        if (pAnchorNode)
1588
0
        {
1589
0
            SwTextNode* pTextNode = pAnchorNode->GetTextNode();
1590
0
            if (pTextNode)
1591
0
            {
1592
0
                sal_Int32 nContentIdx = rFormatAnchor.GetAnchorContentOffset();
1593
0
                SwTextAttr* pAttr = pTextNode->GetTextAttrAt(
1594
0
                    nContentIdx, RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
1595
0
                if (pAttr)
1596
0
                {
1597
0
                    SwTextContentControl* pTextContentControl
1598
0
                        = static_txtattr_cast<SwTextContentControl*>(pAttr);
1599
0
                    const SwFormatContentControl& rFormatContentControl
1600
0
                        = pTextContentControl->GetContentControl();
1601
0
                    std::shared_ptr<SwContentControl> pContentControl
1602
0
                        = rFormatContentControl.GetContentControl();
1603
0
                    if (pContentControl->IsInteractingCharacter(aCh))
1604
0
                    {
1605
0
                        rSh.GotoContentControl(rFormatContentControl);
1606
0
                        return;
1607
0
                    }
1608
0
                }
1609
0
            }
1610
0
        }
1611
0
    }
1612
1613
0
    if( pFlyFormat )
1614
0
    {
1615
0
        SvMacroItemId nEvent;
1616
1617
0
        if( 32 <= aCh &&
1618
0
            0 == (( KEY_MOD1 | KEY_MOD2 ) & rKeyCode.GetModifier() ))
1619
0
            nEvent = SvMacroItemId::SwFrmKeyInputAlpha;
1620
0
        else
1621
0
            nEvent = SvMacroItemId::SwFrmKeyInputNoAlpha;
1622
1623
0
        const SvxMacro* pMacro = pFlyFormat->GetMacro().GetMacroTable().Get( nEvent );
1624
0
        if( pMacro )
1625
0
        {
1626
0
            SbxArrayRef xArgs = new SbxArray;
1627
0
            SbxVariableRef xVar = new SbxVariable;
1628
0
            xVar->PutString( pFlyFormat->GetName().toString() );
1629
0
            xArgs->Put(xVar.get(), 1);
1630
1631
0
            xVar = new SbxVariable;
1632
0
            if( SvMacroItemId::SwFrmKeyInputAlpha == nEvent )
1633
0
                xVar->PutChar( aCh );
1634
0
            else
1635
0
                xVar->PutUShort( rKeyCode.GetModifier() | rKeyCode.GetCode() );
1636
0
            xArgs->Put(xVar.get(), 2);
1637
1638
0
            OUString sRet;
1639
0
            rSh.ExecMacro( *pMacro, &sRet, xArgs.get() );
1640
0
            if( !sRet.isEmpty() && sRet.toInt32()!=0 )
1641
0
                return ;
1642
0
        }
1643
0
    }
1644
0
    SelectionType nLclSelectionType;
1645
    //A is converted to 1
1646
0
    if( rKeyCode.GetFullCode() == (KEY_A | KEY_MOD1 |KEY_SHIFT)
1647
0
        && rSh.HasDrawView() &&
1648
0
        (bool(nLclSelectionType = rSh.GetSelectionType()) &&
1649
0
        ((nLclSelectionType & (SelectionType::Frame|SelectionType::Graphic)) ||
1650
0
        ((nLclSelectionType & (SelectionType::DrawObject|SelectionType::DbForm)) &&
1651
0
                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1))))
1652
0
    {
1653
0
        SdrHdlList& rHdlList = const_cast<SdrHdlList&>(rSh.GetDrawView()->GetHdlList());
1654
0
        SdrHdl* pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor);
1655
0
        if ( ! pAnchor )
1656
0
            pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor_TR);
1657
0
        if(pAnchor)
1658
0
            rHdlList.SetFocusHdl(pAnchor);
1659
0
        return;
1660
0
    }
1661
1662
0
    SvxAutoCorrCfg* pACfg = nullptr;
1663
0
    SvxAutoCorrect* pACorr = nullptr;
1664
1665
0
    uno::Reference< frame::XDispatchRecorder > xRecorder =
1666
0
            m_rView.GetViewFrame().GetBindings().GetRecorder();
1667
0
    if ( !xRecorder.is() )
1668
0
    {
1669
0
        pACfg = &SvxAutoCorrCfg::Get();
1670
0
        pACorr = pACfg->GetAutoCorrect();
1671
0
    }
1672
1673
0
    SwModuleOptions* pModOpt = SwModule::get()->GetModuleConfig();
1674
1675
0
    OUString sFormulaEntry;
1676
1677
0
    enum class SwKeyState { CheckKey, InsChar, InsTab,
1678
0
                       NoNum, NumOff, NumOrNoNum, NumDown, NumUp,
1679
0
                       NumIndentInc, NumIndentDec,
1680
1681
0
                       OutlineLvOff,
1682
0
                       NextCell, PrevCell, OutlineUp, OutlineDown,
1683
0
                       GlossaryExpand, NextPrevGlossary,
1684
0
                       AutoFormatByInput,
1685
0
                       NextObject, PrevObject,
1686
0
                       KeyToView,
1687
0
                       LaunchOLEObject, GoIntoFly, GoIntoDrawing,
1688
0
                       EnterDrawHandleMode,
1689
0
                       CheckDocReadOnlyKeys,
1690
0
                       CheckAutoCorrect, EditFormula,
1691
0
                       ColLeftBig, ColRightBig,
1692
0
                       ColLeftSmall, ColRightSmall,
1693
0
                       ColBottomBig,
1694
0
                       ColBottomSmall,
1695
0
                       CellLeftBig, CellRightBig,
1696
0
                       CellLeftSmall, CellRightSmall,
1697
0
                       CellTopBig, CellBottomBig,
1698
0
                       CellTopSmall, CellBottomSmall,
1699
1700
0
                       Fly_Change, Draw_Change,
1701
0
                       SpecialInsert,
1702
0
                       EnterCharCell,
1703
0
                       GotoNextFieldMark,
1704
0
                       GotoPrevFieldMark,
1705
0
                       End };
1706
1707
0
    SwKeyState eKeyState = bIsViewReadOnly ? SwKeyState::CheckDocReadOnlyKeys : SwKeyState::CheckKey;
1708
1709
    // tdf#112932 Pressing enter in read-only Table of Content doesn't jump to heading
1710
0
    if (!bIsViewReadOnly
1711
0
        && ((rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN
1712
0
            || (rKeyCode.GetModifier() | rKeyCode.GetCode()) == (KEY_MOD1 | KEY_RETURN)))
1713
0
    {
1714
0
        const SwTOXBase* pTOXBase = rSh.GetCurTOX();
1715
0
        if (pTOXBase && SwEditShell::IsTOXBaseReadonly(*pTOXBase))
1716
0
            eKeyState = SwKeyState::CheckDocReadOnlyKeys;
1717
0
    }
1718
1719
0
    SwKeyState eNextKeyState = SwKeyState::End;
1720
0
    Move::Direction eDir = Move::Direction::Left;
1721
0
    Move::Size eDirSize = Move::Size::Small;
1722
1723
0
    if (m_nKS_NUMDOWN_Count > 0)
1724
0
        m_nKS_NUMDOWN_Count--;
1725
1726
0
    if (m_nKS_NUMINDENTINC_Count > 0)
1727
0
        m_nKS_NUMINDENTINC_Count--;
1728
1729
0
    while( SwKeyState::End != eKeyState )
1730
0
    {
1731
0
        SwKeyState eFlyState = SwKeyState::KeyToView;
1732
1733
0
        switch( eKeyState )
1734
0
        {
1735
0
        case SwKeyState::CheckKey:
1736
0
            eKeyState = SwKeyState::KeyToView;       // default forward to View
1737
1738
0
            if (!comphelper::LibreOfficeKit::isActive() &&
1739
0
                !rKeyCode.IsMod2() && '=' == aCh &&
1740
0
                !rSh.IsTableMode() && rSh.GetTableFormat() &&
1741
0
                rSh.IsSttPara() &&
1742
0
                !rSh.HasReadonlySel())
1743
0
            {
1744
                // at the beginning of the table's cell a '=' ->
1745
                // call EditRow (F2-functionality)
1746
                // [Avoid this for LibreOfficeKit, as the separate input window
1747
                // steals the focus & things go wrong - the user never gets
1748
                // the focus back.]
1749
0
                rSh.Push();
1750
0
                if( !rSh.MoveSection( GoCurrSection, fnSectionStart) &&
1751
0
                    !rSh.IsTableBoxTextFormat() )
1752
0
                {
1753
                    // is at the beginning of the box
1754
0
                    eKeyState = SwKeyState::EditFormula;
1755
0
                    if( rSh.HasMark() )
1756
0
                        rSh.SwapPam();
1757
0
                    else
1758
0
                        rSh.SttSelect();
1759
0
                    rSh.MoveSection( GoCurrSection, fnSectionEnd );
1760
0
                    rSh.Pop();
1761
0
                    rSh.EndSelect();
1762
0
                    sFormulaEntry = "=";
1763
0
                }
1764
0
                else
1765
0
                    rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
1766
0
            }
1767
0
            else
1768
0
            {
1769
0
                if( pACorr && aTmpQHD.HasContent() && !rSh.HasSelection() &&
1770
0
                    !rSh.HasReadonlySel() && !aTmpQHD.m_bIsAutoText &&
1771
0
                    pACorr->GetSwFlags().nAutoCmpltExpandKey ==
1772
0
                    (rKeyCode.GetModifier() | rKeyCode.GetCode()) )
1773
0
                {
1774
0
                    eKeyState = SwKeyState::GlossaryExpand;
1775
0
                    break;
1776
0
                }
1777
1778
0
                switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
1779
0
                {
1780
0
                case KEY_RIGHT | KEY_MOD2:
1781
0
                    eKeyState = SwKeyState::ColRightBig;
1782
0
                    eFlyState = SwKeyState::Fly_Change;
1783
0
                    eDir = Move::Direction::Right;
1784
0
                    eDirSize = Move::Size::Small;
1785
0
                    goto KEYINPUT_CHECKTABLE;
1786
1787
0
                case KEY_LEFT | KEY_MOD2:
1788
0
                    eKeyState = SwKeyState::ColRightSmall;
1789
0
                    eFlyState = SwKeyState::Fly_Change;
1790
0
                    eDir = Move::Direction::Left;
1791
0
                    eDirSize = Move::Size::Small;
1792
0
                    goto KEYINPUT_CHECKTABLE;
1793
1794
0
                case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT:
1795
0
                    eKeyState = SwKeyState::ColLeftSmall;
1796
0
                    goto KEYINPUT_CHECKTABLE;
1797
1798
0
                case KEY_LEFT | KEY_MOD2 | KEY_SHIFT:
1799
0
                    eKeyState = SwKeyState::ColLeftBig;
1800
0
                    goto KEYINPUT_CHECKTABLE;
1801
1802
0
                case KEY_RIGHT | KEY_MOD2 | KEY_MOD1:
1803
0
                    eKeyState = SwKeyState::CellRightBig;
1804
0
                    goto KEYINPUT_CHECKTABLE;
1805
1806
0
                case KEY_LEFT | KEY_MOD2 | KEY_MOD1:
1807
0
                    eKeyState = SwKeyState::CellRightSmall;
1808
0
                    goto KEYINPUT_CHECKTABLE;
1809
1810
0
                case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1811
0
                    eKeyState = SwKeyState::CellLeftSmall;
1812
0
                    goto KEYINPUT_CHECKTABLE;
1813
1814
0
                case KEY_LEFT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1815
0
                    eKeyState = SwKeyState::CellLeftBig;
1816
0
                    goto KEYINPUT_CHECKTABLE;
1817
1818
0
                case KEY_UP | KEY_MOD2:
1819
0
                    eKeyState = SwKeyState::ColBottomSmall;
1820
0
                    eFlyState = SwKeyState::Fly_Change;
1821
0
                    eDir = Move::Direction::Up;
1822
0
                    eDirSize = Move::Size::Small;
1823
0
                    goto KEYINPUT_CHECKTABLE;
1824
1825
0
                case KEY_DOWN | KEY_MOD2:
1826
0
                    eKeyState = SwKeyState::ColBottomBig;
1827
0
                    eFlyState = SwKeyState::Fly_Change;
1828
0
                    eDir = Move::Direction::Down;
1829
0
                    eDirSize = Move::Size::Small;
1830
0
                    goto KEYINPUT_CHECKTABLE;
1831
1832
0
                case KEY_UP | KEY_MOD2 | KEY_MOD1:
1833
0
                    eKeyState = SwKeyState::CellBottomSmall;
1834
0
                    goto KEYINPUT_CHECKTABLE;
1835
1836
0
                case KEY_DOWN | KEY_MOD2 | KEY_MOD1:
1837
0
                    eKeyState = SwKeyState::CellBottomBig;
1838
0
                    goto KEYINPUT_CHECKTABLE;
1839
1840
0
                case KEY_UP | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1841
0
                    eKeyState = SwKeyState::CellTopBig;
1842
0
                    goto KEYINPUT_CHECKTABLE;
1843
1844
0
                case KEY_DOWN | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
1845
0
                    eKeyState = SwKeyState::CellTopSmall;
1846
0
                    goto KEYINPUT_CHECKTABLE;
1847
1848
0
KEYINPUT_CHECKTABLE:
1849
                    // Resolve bugs 49091, 53190, 93402 and
1850
                    // https://bz.apache.org/ooo/show_bug.cgi?id=113502
1851
                    // but provide an option for restoring interactive
1852
                    // table sizing functionality when needed.
1853
0
                    if (
1854
0
                      ! (Window::GetIndicatorState() & KeyIndicatorState::CAPSLOCK)
1855
0
                      && m_rView.KeyInput( aKeyEvent ) // Keystroke is customized
1856
0
                    )
1857
0
                    {
1858
0
                        bFlushBuffer = true;
1859
0
                        bNormalChar = false;
1860
0
                        eKeyState = SwKeyState::End;
1861
0
                        break ;
1862
0
                    }
1863
1864
0
                    if( rSh.IsTableMode() || !rSh.GetTableFormat() )
1865
0
                    {
1866
0
                        if(!pFlyFormat && SwKeyState::KeyToView != eFlyState &&
1867
0
                            (rSh.GetSelectionType() & (SelectionType::DrawObject|SelectionType::DbForm))  &&
1868
0
                                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0)
1869
0
                            eKeyState = SwKeyState::Draw_Change;
1870
1871
0
                        if( pFlyFormat )
1872
0
                            eKeyState = eFlyState;
1873
0
                        else if( SwKeyState::Draw_Change != eKeyState)
1874
0
                            eKeyState = SwKeyState::EnterCharCell;
1875
0
                    }
1876
0
                    break;
1877
1878
                // huge object move
1879
0
                case KEY_RIGHT | KEY_SHIFT:
1880
0
                case KEY_LEFT | KEY_SHIFT:
1881
0
                case KEY_UP | KEY_SHIFT:
1882
0
                case KEY_DOWN | KEY_SHIFT:
1883
0
                {
1884
0
                    const SelectionType nSelectionType = rSh.GetSelectionType();
1885
0
                    if ( ( pFlyFormat
1886
0
                           && ( nSelectionType & (SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic) ) )
1887
0
                         || ( ( nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm) )
1888
0
                              && rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0 ) )
1889
0
                    {
1890
0
                        eKeyState = pFlyFormat ? SwKeyState::Fly_Change : SwKeyState::Draw_Change;
1891
0
                        if (nSelectionType & SelectionType::DrawObject)
1892
0
                        {
1893
                            // tdf#137964: always move the DrawObject if one is selected
1894
0
                            eKeyState = SwKeyState::Draw_Change;
1895
0
                        }
1896
0
                        switch ( rKeyCode.GetCode() )
1897
0
                        {
1898
0
                            case KEY_RIGHT: eDir = Move::Direction::Right; eDirSize = Move::Size::Huge; break;
1899
0
                            case KEY_LEFT: eDir = Move::Direction::Left; eDirSize = Move::Size::Huge; break;
1900
0
                            case KEY_UP: eDir = Move::Direction::Up; eDirSize = Move::Size::Huge; break;
1901
0
                            case KEY_DOWN: eDir = Move::Direction::Down; eDirSize = Move::Size::Huge; break;
1902
0
                        }
1903
0
                    }
1904
0
                    break;
1905
0
                }
1906
1907
0
                case KEY_LEFT:
1908
0
                case KEY_LEFT | KEY_MOD1:
1909
0
                {
1910
0
                    bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1911
0
                    if(!bMod1)
1912
0
                    {
1913
0
                        eFlyState = SwKeyState::Fly_Change;
1914
0
                        eDir = Move::Direction::Left;
1915
0
                        eDirSize = Move::Size::Big;
1916
0
                    }
1917
0
                    goto KEYINPUT_CHECKTABLE_INSDEL;
1918
0
                }
1919
0
                case KEY_RIGHT | KEY_MOD1:
1920
0
                {
1921
0
                    goto KEYINPUT_CHECKTABLE_INSDEL;
1922
0
                }
1923
0
                case KEY_UP:
1924
0
                case KEY_UP | KEY_MOD1:
1925
0
                {
1926
0
                    bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1927
0
                    if(!bMod1)
1928
0
                    {
1929
0
                        eFlyState = SwKeyState::Fly_Change;
1930
0
                        eDir = Move::Direction::Up;
1931
0
                        eDirSize = Move::Size::Big;
1932
0
                    }
1933
0
                    goto KEYINPUT_CHECKTABLE_INSDEL;
1934
0
                }
1935
0
                case KEY_DOWN:
1936
0
                case KEY_DOWN | KEY_MOD1:
1937
0
                {
1938
0
                    bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
1939
0
                    if(!bMod1)
1940
0
                    {
1941
0
                        ::sw::mark::Fieldmark* pMark = rSh.GetCurrentFieldmark();
1942
0
                        if (auto pDropDown = dynamic_cast<FieldmarkWithDropDownButton*>(pMark))
1943
0
                        {
1944
0
                            pDropDown->LaunchPopup();
1945
0
                            eKeyState = SwKeyState::End;
1946
0
                            break;
1947
0
                        }
1948
0
                        eFlyState = SwKeyState::Fly_Change;
1949
0
                        eDir = Move::Direction::Down;
1950
0
                        eDirSize = Move::Size::Big;
1951
0
                    }
1952
0
                    goto KEYINPUT_CHECKTABLE_INSDEL;
1953
0
                }
1954
1955
0
KEYINPUT_CHECKTABLE_INSDEL:
1956
0
                if( rSh.IsTableMode() || !rSh.GetTableFormat() )
1957
0
                {
1958
0
                    const SelectionType nSelectionType = rSh.GetSelectionType();
1959
1960
0
                    eKeyState = SwKeyState::KeyToView;
1961
0
                    if(SwKeyState::KeyToView != eFlyState)
1962
0
                    {
1963
0
                        if((nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm))  &&
1964
0
                                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0)
1965
0
                            eKeyState = SwKeyState::Draw_Change;
1966
0
                        else if(nSelectionType & (SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic))
1967
0
                            eKeyState = SwKeyState::Fly_Change;
1968
0
                    }
1969
0
                }
1970
0
                break;
1971
1972
1973
0
                case KEY_DELETE:
1974
0
                    if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField())
1975
0
                    {
1976
0
                        if (rSh.IsInFrontOfLabel() && rSh.NumOrNoNum())
1977
0
                            eKeyState = SwKeyState::NumOrNoNum;
1978
0
                    }
1979
0
                    else if (!rSh.IsCursorInParagraphMetadataField())
1980
0
                    {
1981
0
                        rSh.InfoReadOnlyDialog(/*bAsync=*/true);
1982
0
                        eKeyState = SwKeyState::End;
1983
0
                    }
1984
0
                    break;
1985
1986
0
                case KEY_RETURN:
1987
0
                {
1988
0
                    if ( !rSh.HasReadonlySel()
1989
0
                         && !rSh.CursorInsideInputField()
1990
0
                         && !rSh.CursorInsideContentControl() )
1991
0
                    {
1992
0
                        const SelectionType nSelectionType = rSh.GetSelectionType();
1993
0
                        if(nSelectionType & SelectionType::Ole)
1994
0
                            eKeyState = SwKeyState::LaunchOLEObject;
1995
0
                        else if(nSelectionType & SelectionType::Frame)
1996
0
                            eKeyState = SwKeyState::GoIntoFly;
1997
0
                        else if((nSelectionType & SelectionType::DrawObject) &&
1998
0
                                !(nSelectionType & SelectionType::DrawObjectEditMode) &&
1999
0
                                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1)
2000
0
                        {
2001
0
                            eKeyState = SwKeyState::GoIntoDrawing;
2002
0
                            if (lcl_goIntoTextBox(*this, rSh))
2003
0
                                eKeyState = SwKeyState::GoIntoFly;
2004
0
                        }
2005
0
                        else if( aTmpQHD.HasContent() && !rSh.HasSelection() &&
2006
0
                            aTmpQHD.m_bIsAutoText )
2007
0
                            eKeyState = SwKeyState::GlossaryExpand;
2008
2009
                        //RETURN and empty paragraph in numbering -> end numbering
2010
0
                        else if( m_aInBuffer.isEmpty() &&
2011
0
                                 rSh.GetNumRuleAtCurrCursorPos() &&
2012
0
                                 !rSh.GetNumRuleAtCurrCursorPos()->IsOutlineRule() &&
2013
0
                                 !rSh.HasSelection() &&
2014
0
                                rSh.IsSttPara() && rSh.IsEndPara() )
2015
0
                        {
2016
0
                            eKeyState = SwKeyState::NumOff;
2017
0
                            eNextKeyState = SwKeyState::OutlineLvOff;
2018
0
                        }
2019
                        //RETURN for new paragraph with AutoFormatting
2020
0
                        else if( pACfg && pACfg->IsAutoFormatByInput() &&
2021
0
                                !(nSelectionType & (SelectionType::Graphic |
2022
0
                                    SelectionType::Ole | SelectionType::Frame |
2023
0
                                    SelectionType::TableCell | SelectionType::DrawObject |
2024
0
                                    SelectionType::DrawObjectEditMode)) )
2025
0
                        {
2026
0
                            eKeyState = SwKeyState::AutoFormatByInput;
2027
0
                        }
2028
0
                        else
2029
0
                        {
2030
0
                            eNextKeyState = eKeyState;
2031
0
                            eKeyState = SwKeyState::CheckAutoCorrect;
2032
0
                        }
2033
0
                    }
2034
0
                }
2035
0
                break;
2036
0
                case KEY_RETURN | KEY_MOD2:
2037
0
                {
2038
0
                    if ( !rSh.HasReadonlySel()
2039
0
                         && !rSh.IsSttPara()
2040
0
                         && rSh.GetNumRuleAtCurrCursorPos()
2041
0
                         && !rSh.CursorInsideInputField() )
2042
0
                    {
2043
0
                        eKeyState = SwKeyState::NoNum;
2044
0
                    }
2045
0
                    else if( rSh.CanSpecialInsert() )
2046
0
                        eKeyState = SwKeyState::SpecialInsert;
2047
0
                }
2048
0
                break;
2049
0
                case KEY_BACKSPACE:
2050
0
                case KEY_BACKSPACE | KEY_SHIFT:
2051
0
                    if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField())
2052
0
                    {
2053
0
                        bool bDone = false;
2054
                        // try to add comment for code snip:
2055
                        // Remove the paragraph indent, if the cursor is at the
2056
                        // beginning of a paragraph, there is no selection
2057
                        // and no numbering rule found at the current paragraph
2058
                        // Also try to remove indent, if current paragraph
2059
                        // has numbering rule, but isn't counted and only
2060
                        // key <backspace> is hit.
2061
0
                        const bool bOnlyBackspaceKey( KEY_BACKSPACE == rKeyCode.GetFullCode() );
2062
0
                        if ( rSh.IsSttPara()
2063
0
                             && !rSh.HasSelection()
2064
0
                             && ( rSh.GetNumRuleAtCurrCursorPos() == nullptr
2065
0
                                  || ( rSh.IsNoNum() && bOnlyBackspaceKey ) ) )
2066
0
                        {
2067
0
                            bDone = rSh.TryRemoveIndent();
2068
0
                        }
2069
2070
0
                        if (bDone)
2071
0
                            eKeyState = SwKeyState::End;
2072
0
                        else
2073
0
                        {
2074
0
                            if ( rSh.IsSttPara() && !rSh.IsNoNum() )
2075
0
                            {
2076
0
                                if (m_nKS_NUMDOWN_Count > 0 &&
2077
0
                                    0 < rSh.GetNumLevel())
2078
0
                                {
2079
0
                                    eKeyState = SwKeyState::NumUp;
2080
0
                                    m_nKS_NUMDOWN_Count = 2;
2081
0
                                    bDone = true;
2082
0
                                }
2083
0
                                else if (m_nKS_NUMINDENTINC_Count > 0)
2084
0
                                {
2085
0
                                    eKeyState = SwKeyState::NumIndentDec;
2086
0
                                    m_nKS_NUMINDENTINC_Count = 2;
2087
0
                                    bDone = true;
2088
0
                                }
2089
0
                            }
2090
2091
                            // If the cursor is in an empty paragraph, which has
2092
                            // a numbering, but not the outline numbering, and
2093
                            // there is no selection, the numbering has to be
2094
                            // deleted on key <Backspace>.
2095
                            // Otherwise method <SwEditShell::NumOrNoNum(..)>
2096
                            // should only change the <IsCounted()> state of
2097
                            // the current paragraph depending of the key.
2098
                            // On <backspace> it is set to <false>,
2099
                            // on <shift-backspace> it is set to <true>.
2100
                            // Thus, assure that method <SwEditShell::NumOrNum(..)>
2101
                            // is only called for the intended purpose.
2102
0
                            if ( !bDone && rSh.IsSttPara() )
2103
0
                            {
2104
0
                                bool bCallNumOrNoNum( false );
2105
0
                                if ( bOnlyBackspaceKey && !rSh.IsNoNum() )
2106
0
                                {
2107
0
                                    bCallNumOrNoNum = true;
2108
0
                                }
2109
0
                                else if ( !bOnlyBackspaceKey && rSh.IsNoNum() )
2110
0
                                {
2111
0
                                    bCallNumOrNoNum = true;
2112
0
                                }
2113
0
                                else if ( bOnlyBackspaceKey
2114
0
                                          && rSh.IsSttPara()
2115
0
                                          && rSh.IsEndPara()
2116
0
                                          && !rSh.HasSelection() )
2117
0
                                {
2118
0
                                    const SwNumRule* pCurrNumRule( rSh.GetNumRuleAtCurrCursorPos() );
2119
0
                                    if ( pCurrNumRule != nullptr
2120
0
                                         && pCurrNumRule != rSh.GetOutlineNumRule() )
2121
0
                                    {
2122
0
                                        bCallNumOrNoNum = true;
2123
0
                                    }
2124
0
                                }
2125
0
                                if ( bCallNumOrNoNum
2126
0
                                     && rSh.NumOrNoNum( !bOnlyBackspaceKey ) )
2127
0
                                {
2128
0
                                    eKeyState = SwKeyState::NumOrNoNum;
2129
0
                                }
2130
0
                            }
2131
0
                        }
2132
0
                    }
2133
0
                    else if (!rSh.IsCursorInParagraphMetadataField())
2134
0
                    {
2135
0
                        rSh.InfoReadOnlyDialog(true);
2136
0
                        eKeyState = SwKeyState::End;
2137
0
                    }
2138
0
                    break;
2139
2140
0
                case KEY_RIGHT:
2141
0
                    {
2142
0
                        eFlyState = SwKeyState::Fly_Change;
2143
0
                        eDir = Move::Direction::Right;
2144
0
                        eDirSize = Move::Size::Big;
2145
0
                        goto KEYINPUT_CHECKTABLE_INSDEL;
2146
0
                    }
2147
0
                case KEY_TAB:
2148
0
                {
2149
                    // Rich text contentControls accept tabs and fieldmarks and other rich text,
2150
                    // so first act on cases that are not a content control
2151
0
                    SwTextContentControl* pTextContentControl = rSh.CursorInsideContentControl();
2152
0
                    if ((rSh.IsFormProtected() && !pTextContentControl) ||
2153
0
                        rSh.GetCurrentFieldmark() || rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2154
0
                    {
2155
0
                        eKeyState = SwKeyState::GotoNextFieldMark;
2156
0
                    }
2157
0
                    else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2158
0
                    {
2159
0
                        GetView().GetViewFrame().GetDispatcher()->Execute( FN_GOTO_NEXT_INPUTFLD );
2160
0
                        eKeyState = SwKeyState::End;
2161
0
                    }
2162
0
                    else if( rSh.GetNumRuleAtCurrCursorPos()
2163
0
                             && rSh.IsSttOfPara()
2164
0
                             && !rSh.HasReadonlySel() )
2165
0
                    {
2166
0
                        if (numfunc::NumDownChangesIndent(rSh))
2167
0
                        {
2168
0
                            eKeyState = SwKeyState::NumDown;
2169
0
                        }
2170
0
                        else
2171
0
                        {
2172
0
                            eKeyState = SwKeyState::InsTab;
2173
0
                        }
2174
0
                    }
2175
0
                    else if (rSh.GetSelectionType() &
2176
0
                             (SelectionType::Graphic |
2177
0
                              SelectionType::Frame |
2178
0
                              SelectionType::Ole |
2179
0
                              SelectionType::DrawObject |
2180
0
                              SelectionType::DbForm))
2181
0
                    {
2182
0
                        eKeyState = SwKeyState::NextObject;
2183
0
                    }
2184
0
                    else if ( rSh.GetTableFormat() )
2185
0
                    {
2186
0
                        if( rSh.HasSelection() || rSh.HasReadonlySel() )
2187
0
                            eKeyState = SwKeyState::NextCell;
2188
0
                        else
2189
0
                        {
2190
0
                            eKeyState = SwKeyState::CheckAutoCorrect;
2191
0
                            eNextKeyState = SwKeyState::NextCell;
2192
0
                        }
2193
0
                    }
2194
0
                    else if (pTextContentControl)
2195
0
                    {
2196
0
                        auto pCC = pTextContentControl->GetContentControl().GetContentControl();
2197
0
                        if (pCC)
2198
0
                        {
2199
0
                            switch (pCC->GetType())
2200
0
                            {
2201
0
                                case SwContentControlType::RICH_TEXT:
2202
0
                                    eKeyState = SwKeyState::InsTab;
2203
0
                                    break;
2204
0
                                default:
2205
0
                                    eKeyState = SwKeyState::GotoNextFieldMark;
2206
0
                            }
2207
0
                        }
2208
0
                    }
2209
0
                    else
2210
0
                    {
2211
0
                        eKeyState = SwKeyState::InsTab;
2212
0
                        if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
2213
0
                        {
2214
0
                            SwTextFormatColl* pColl = rSh.GetCurTextFormatColl();
2215
0
                            if( pColl &&
2216
2217
0
                                pColl->IsAssignedToListLevelOfOutlineStyle()
2218
0
                                && MAXLEVEL-1 > pColl->GetAssignedOutlineStyleLevel() )
2219
0
                                eKeyState = SwKeyState::OutlineDown;
2220
0
                        }
2221
0
                    }
2222
0
                }
2223
0
                break;
2224
0
                case KEY_TAB | KEY_SHIFT:
2225
0
                {
2226
0
                    SwTextContentControl* pTextContentControl = rSh.CursorInsideContentControl();
2227
0
                    if ((rSh.IsFormProtected() && !pTextContentControl) ||
2228
0
                        rSh.GetCurrentFieldmark()|| rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2229
0
                    {
2230
0
                        eKeyState = SwKeyState::GotoPrevFieldMark;
2231
0
                    }
2232
0
                    else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2233
0
                    {
2234
0
                        GetView().GetViewFrame().GetDispatcher()->Execute( FN_GOTO_PREV_INPUTFLD );
2235
0
                        eKeyState = SwKeyState::End;
2236
0
                    }
2237
0
                    else if( rSh.GetNumRuleAtCurrCursorPos()
2238
0
                             && rSh.IsSttOfPara()
2239
0
                             && !rSh.HasReadonlySel() )
2240
0
                    {
2241
0
                        eKeyState = SwKeyState::NumUp;
2242
0
                    }
2243
0
                    else if (rSh.GetSelectionType() &
2244
0
                             (SelectionType::Graphic |
2245
0
                              SelectionType::Frame |
2246
0
                              SelectionType::Ole |
2247
0
                              SelectionType::DrawObject |
2248
0
                              SelectionType::DbForm))
2249
0
                    {
2250
0
                        eKeyState = SwKeyState::PrevObject;
2251
0
                    }
2252
0
                    else if ( rSh.GetTableFormat() )
2253
0
                    {
2254
0
                        if( rSh.HasSelection() || rSh.HasReadonlySel() )
2255
0
                            eKeyState = SwKeyState::PrevCell;
2256
0
                        else
2257
0
                        {
2258
0
                            eKeyState = SwKeyState::CheckAutoCorrect;
2259
0
                            eNextKeyState = SwKeyState::PrevCell;
2260
0
                        }
2261
0
                    }
2262
0
                    else if (pTextContentControl)
2263
0
                    {
2264
0
                        eKeyState = SwKeyState::GotoPrevFieldMark;
2265
0
                    }
2266
0
                    else
2267
0
                    {
2268
0
                        eKeyState = SwKeyState::End;
2269
0
                        if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
2270
0
                        {
2271
0
                            SwTextFormatColl* pColl = rSh.GetCurTextFormatColl();
2272
0
                            if( pColl &&
2273
0
                                pColl->IsAssignedToListLevelOfOutlineStyle() &&
2274
0
                                0 < pColl->GetAssignedOutlineStyleLevel())
2275
0
                                eKeyState = SwKeyState::OutlineUp;
2276
0
                        }
2277
0
                    }
2278
0
                }
2279
0
                break;
2280
0
                case KEY_TAB | KEY_MOD1:
2281
0
                case KEY_TAB | KEY_MOD2:
2282
0
                    if( !rSh.HasReadonlySel() )
2283
0
                    {
2284
0
                        if( aTmpQHD.HasContent() && !rSh.HasSelection() )
2285
0
                        {
2286
                            // Next auto-complete suggestion
2287
0
                            aTmpQHD.Next( pACorr &&
2288
0
                                          pACorr->GetSwFlags().bAutoCmpltEndless );
2289
0
                            eKeyState = SwKeyState::NextPrevGlossary;
2290
0
                        }
2291
0
                        else if( rSh.GetTableFormat() )
2292
0
                            eKeyState = SwKeyState::InsTab;
2293
0
                        else if((rSh.GetSelectionType() &
2294
0
                                    (SelectionType::DrawObject|SelectionType::DbForm|
2295
0
                                        SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic))  &&
2296
0
                                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0)
2297
0
                            eKeyState = SwKeyState::EnterDrawHandleMode;
2298
0
                        else
2299
0
                        {
2300
0
                            if ( !rSh.IsMultiSelection()
2301
0
                                && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
2302
0
                                eKeyState = SwKeyState::NumIndentInc;
2303
0
                        }
2304
0
                    }
2305
0
                    break;
2306
2307
0
                    case KEY_TAB | KEY_MOD1 | KEY_SHIFT:
2308
0
                    {
2309
0
                        if( aTmpQHD.HasContent() && !rSh.HasSelection() &&
2310
0
                            !rSh.HasReadonlySel() )
2311
0
                        {
2312
                            // Previous auto-complete suggestion.
2313
0
                            aTmpQHD.Previous( pACorr &&
2314
0
                                              pACorr->GetSwFlags().bAutoCmpltEndless );
2315
0
                            eKeyState = SwKeyState::NextPrevGlossary;
2316
0
                        }
2317
0
                        else if((rSh.GetSelectionType() & (SelectionType::DrawObject|SelectionType::DbForm|
2318
0
                                        SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic)) &&
2319
0
                                rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0)
2320
0
                        {
2321
0
                            eKeyState = SwKeyState::EnterDrawHandleMode;
2322
0
                        }
2323
0
                        else
2324
0
                        {
2325
0
                            if ( !rSh.IsMultiSelection()
2326
0
                                && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
2327
0
                                eKeyState = SwKeyState::NumIndentDec;
2328
0
                        }
2329
0
                    }
2330
0
                    break;
2331
0
                    case KEY_F2 :
2332
0
                    if( !rSh.HasReadonlySel() )
2333
0
                    {
2334
0
                        const SelectionType nSelectionType = rSh.GetSelectionType();
2335
0
                        if(nSelectionType & SelectionType::Frame)
2336
0
                            eKeyState = SwKeyState::GoIntoFly;
2337
0
                        else if(nSelectionType & SelectionType::DrawObject)
2338
0
                        {
2339
0
                            eKeyState = SwKeyState::GoIntoDrawing;
2340
0
                            if (lcl_goIntoTextBox(*this, rSh))
2341
0
                                eKeyState = SwKeyState::GoIntoFly;
2342
0
                        }
2343
0
                    }
2344
0
                    break;
2345
0
                }
2346
0
            }
2347
0
            break;
2348
0
        case SwKeyState::CheckDocReadOnlyKeys:
2349
0
            {
2350
0
                eKeyState = SwKeyState::KeyToView;
2351
0
                switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
2352
0
                {
2353
0
                    case KEY_TAB:
2354
0
                    case KEY_TAB | KEY_SHIFT:
2355
0
                        bNormalChar = false;
2356
0
                        eKeyState = SwKeyState::End;
2357
0
                        if ( rSh.GetSelectionType() &
2358
0
                                (SelectionType::Graphic |
2359
0
                                    SelectionType::Frame |
2360
0
                                    SelectionType::Ole |
2361
0
                                    SelectionType::DrawObject |
2362
0
                                    SelectionType::DbForm))
2363
2364
0
                        {
2365
0
                            eKeyState = (rKeyCode.GetModifier() & KEY_SHIFT) ?
2366
0
                                                SwKeyState::PrevObject : SwKeyState::NextObject;
2367
0
                        }
2368
0
                        else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() )
2369
0
                        {
2370
0
                            GetView().GetViewFrame().GetDispatcher()->Execute(
2371
0
                                KEY_SHIFT != rKeyCode.GetModifier() ? FN_GOTO_NEXT_INPUTFLD : FN_GOTO_PREV_INPUTFLD );
2372
0
                        }
2373
0
                        else
2374
0
                        {
2375
0
                            rSh.SelectNextPrevHyperlink( KEY_SHIFT != rKeyCode.GetModifier() );
2376
0
                        }
2377
0
                    break;
2378
0
                    case KEY_RETURN:
2379
0
                    case KEY_RETURN | KEY_MOD1:
2380
0
                    {
2381
0
                        const SelectionType nSelectionType = rSh.GetSelectionType();
2382
0
                        if(nSelectionType & SelectionType::Frame)
2383
0
                            eKeyState = SwKeyState::GoIntoFly;
2384
0
                        else
2385
0
                        {
2386
0
                            SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(rSh.GetAttrPool());
2387
0
                            rSh.GetCurAttr(aSet);
2388
0
                            if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false))
2389
0
                            {
2390
0
                                const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT);
2391
0
                                bNormalChar = false;
2392
0
                                eKeyState = SwKeyState::End;
2393
0
                                rSh.ClickToINetAttr(static_cast<const SwFormatINetFormat&>(rItem));
2394
0
                            }
2395
0
                        }
2396
0
                    }
2397
0
                    break;
2398
0
                }
2399
0
            }
2400
0
            break;
2401
2402
0
        case SwKeyState::EnterCharCell:
2403
0
            {
2404
0
                eKeyState = SwKeyState::KeyToView;
2405
0
                switch ( rKeyCode.GetModifier() | rKeyCode.GetCode() )
2406
0
                {
2407
0
                    case KEY_RIGHT | KEY_MOD2:
2408
0
                        rSh.Right( SwCursorSkipMode::Chars, false, 1, false );
2409
0
                        eKeyState = SwKeyState::End;
2410
0
                        FlushInBuffer();
2411
0
                        break;
2412
0
                    case KEY_LEFT | KEY_MOD2:
2413
0
                        rSh.Left( SwCursorSkipMode::Chars, false, 1, false );
2414
0
                        eKeyState = SwKeyState::End;
2415
0
                        FlushInBuffer();
2416
0
                        break;
2417
0
                }
2418
0
            }
2419
0
            break;
2420
2421
0
        case SwKeyState::KeyToView:
2422
0
            {
2423
0
                eKeyState = SwKeyState::End;
2424
0
                bNormalChar =
2425
0
                    !rKeyCode.IsMod2() &&
2426
0
                    rKeyCode.GetModifier() != KEY_MOD1 &&
2427
0
                    rKeyCode.GetModifier() != (KEY_MOD1|KEY_SHIFT) &&
2428
0
                    SW_ISPRINTABLE( aCh );
2429
2430
0
                if( bNormalChar && rSh.IsInFrontOfLabel() )
2431
0
                {
2432
0
                    rSh.NumOrNoNum();
2433
0
                }
2434
2435
0
                if( !m_aInBuffer.isEmpty() && ( !bNormalChar || bIsViewReadOnly ))
2436
0
                    FlushInBuffer();
2437
2438
0
                if (rSh.HasReadonlySel()
2439
0
                    && (   rKeyCode.GetFunction() == KeyFuncType::PASTE
2440
0
                        || rKeyCode.GetFunction() == KeyFuncType::CUT))
2441
0
                {
2442
0
                    rSh.InfoReadOnlyDialog(true);
2443
0
                    eKeyState = SwKeyState::End;
2444
0
                }
2445
0
                else if( m_rView.KeyInput( aKeyEvent ) )
2446
0
                {
2447
0
                    bFlushBuffer = true;
2448
0
                    bNormalChar = false;
2449
0
                }
2450
0
                else
2451
0
                {
2452
                    // Because Sfx accelerators are only called when they were
2453
                    // enabled at the last status update, copy has to called
2454
                    // 'forcefully' by us if necessary.
2455
0
                    if( rKeyCode.GetFunction() == KeyFuncType::COPY )
2456
0
                        GetView().GetViewFrame().GetBindings().Execute(SID_COPY);
2457
2458
0
                    if( !bIsViewReadOnly && bNormalChar )
2459
0
                    {
2460
0
                        const SelectionType nSelectionType = rSh.GetSelectionType();
2461
0
                        const bool bDrawObject = (nSelectionType & SelectionType::DrawObject) &&
2462
0
                            !(nSelectionType & SelectionType::DrawObjectEditMode) &&
2463
0
                            rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1;
2464
2465
0
                        bool bTextBox = false;
2466
0
                        if (bDrawObject && lcl_goIntoTextBox(*this, rSh))
2467
                            // A draw shape was selected, but it has a TextBox,
2468
                            // start editing that instead when the normal
2469
                            // character is pressed.
2470
0
                            bTextBox = true;
2471
2472
0
                        if (bDrawObject && !bTextBox)
2473
0
                        {
2474
0
                            SdrObject* pObj = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
2475
2476
0
                            if (nullptr != pObj && pObj->isDiagram())
2477
0
                            {
2478
0
                                SdrObject* pSubSelection(pObj->getDiagramSubSelection());
2479
0
                                if (nullptr != pSubSelection && pSubSelection->isDiagramTextNode())
2480
0
                                    pObj = pSubSelection;
2481
0
                                else
2482
0
                                    pObj = nullptr;
2483
0
                            }
2484
2485
0
                            if(pObj)
2486
0
                            {
2487
0
                                EnterDrawTextMode(pObj->GetLogicRect().Center());
2488
0
                                if ( auto pSwDrawTextShell = dynamic_cast< SwDrawTextShell *>(  m_rView.GetCurShell() )  )
2489
0
                                    pSwDrawTextShell->Init();
2490
0
                                rSh.GetDrawView()->KeyInput( rKEvt, this );
2491
0
                            }
2492
0
                        }
2493
0
                        else if (nSelectionType & SelectionType::Frame || bTextBox)
2494
0
                        {
2495
0
                            rSh.UnSelectFrame();
2496
0
                            rSh.LeaveSelFrameMode();
2497
0
                            m_rView.AttrChangedNotify(nullptr);
2498
0
                            rSh.MoveSection( GoCurrSection, fnSectionEnd );
2499
0
                        }
2500
0
                        eKeyState = SwKeyState::InsChar;
2501
0
                    }
2502
0
                    else
2503
0
                    {
2504
0
                        bNormalChar = false;
2505
0
                        Window::KeyInput( aKeyEvent );
2506
0
                    }
2507
0
                }
2508
0
            }
2509
0
            break;
2510
0
        case SwKeyState::LaunchOLEObject:
2511
0
        {
2512
0
            rSh.LaunchOLEObj();
2513
0
            eKeyState = SwKeyState::End;
2514
0
        }
2515
0
        break;
2516
0
        case SwKeyState::GoIntoFly:
2517
0
        {
2518
0
            rSh.UnSelectFrame();
2519
0
            rSh.LeaveSelFrameMode();
2520
0
            m_rView.AttrChangedNotify(nullptr);
2521
0
            rSh.MoveSection( GoCurrSection, fnSectionEnd );
2522
0
            eKeyState = SwKeyState::End;
2523
0
        }
2524
0
        break;
2525
0
        case SwKeyState::GoIntoDrawing:
2526
0
        {
2527
0
            if (SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0))
2528
0
            {
2529
0
                SdrObject* pObj = pMark->GetMarkedSdrObj();
2530
0
                if(pObj)
2531
0
                {
2532
0
                    EnterDrawTextMode(pObj->GetLogicRect().Center());
2533
0
                    if (auto pSwDrawTextShell = dynamic_cast< SwDrawTextShell *>(  m_rView.GetCurShell() )  )
2534
0
                        pSwDrawTextShell->Init();
2535
0
                }
2536
0
            }
2537
0
            eKeyState = SwKeyState::End;
2538
0
        }
2539
0
        break;
2540
0
        case SwKeyState::EnterDrawHandleMode:
2541
0
        {
2542
0
            const SdrHdlList& rHdlList = rSh.GetDrawView()->GetHdlList();
2543
0
            bool bForward(!aKeyEvent.GetKeyCode().IsShift());
2544
2545
0
            const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
2546
0
            eKeyState = SwKeyState::End;
2547
0
        }
2548
0
        break;
2549
0
        case SwKeyState::InsTab:
2550
0
            if( dynamic_cast<const SwWebView*>( &m_rView) !=  nullptr)     // no Tab for WebView
2551
0
            {
2552
                // then it should be passed along
2553
0
                Window::KeyInput( aKeyEvent );
2554
0
                eKeyState = SwKeyState::End;
2555
0
                break;
2556
0
            }
2557
0
            aCh = '\t';
2558
0
            [[fallthrough]];
2559
0
        case SwKeyState::InsChar:
2560
0
        {
2561
0
            if (rSh.CursorInsideContentControl())
2562
0
            {
2563
0
                const SwPosition* pStart = rSh.GetCursor()->Start();
2564
0
                SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
2565
0
                if (pTextNode)
2566
0
                {
2567
0
                    sal_Int32 nIndex = pStart->GetContentIndex();
2568
0
                    SwTextAttr* pAttr = pTextNode->GetTextAttrAt(nIndex, RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
2569
0
                    if (pAttr)
2570
0
                    {
2571
0
                        auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
2572
0
                        const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
2573
0
                        std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
2574
0
                        if (pContentControl->IsInteractingCharacter(aCh))
2575
0
                        {
2576
0
                            rSh.GotoContentControl(rFormatContentControl);
2577
0
                            eKeyState = SwKeyState::End;
2578
0
                            break;
2579
0
                        }
2580
0
                    }
2581
0
                }
2582
0
            }
2583
2584
0
            if (rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
2585
0
            {
2586
0
                ::sw::mark::CheckboxFieldmark* pFieldmark =
2587
0
                    dynamic_cast< ::sw::mark::CheckboxFieldmark* >
2588
0
                        (rSh.GetCurrentFieldmark());
2589
0
                OSL_ENSURE(pFieldmark,
2590
0
                    "Where is my FieldMark??");
2591
0
                if(pFieldmark)
2592
0
                {
2593
0
                    pFieldmark->SetChecked(!pFieldmark->IsChecked());
2594
0
                    OSL_ENSURE(pFieldmark->IsExpanded(),
2595
0
                        "where is the otherpos?");
2596
0
                    if (pFieldmark->IsExpanded())
2597
0
                    {
2598
0
                        rSh.CalcLayout();
2599
0
                    }
2600
0
                }
2601
0
                eKeyState = SwKeyState::End;
2602
0
            }
2603
0
            else if ( !rSh.HasReadonlySel()
2604
0
                      || rSh.CursorInsideInputField() )
2605
0
            {
2606
0
                const bool bIsNormalChar =
2607
0
                    GetAppCharClass().isLetterNumeric( OUString( aCh ), 0 );
2608
0
                if( bAppendSpace && bIsNormalChar &&
2609
0
                    (!m_aInBuffer.isEmpty() || !rSh.IsSttPara() || !rSh.IsEndPara() ))
2610
0
                {
2611
                    // insert a blank ahead of the character. this ends up
2612
                    // between the expanded text and the new "non-word-separator".
2613
0
                    m_aInBuffer += " ";
2614
0
                }
2615
2616
0
                const SwViewOption& rVwOpt = SwViewOption::GetCurrentViewOptions();
2617
0
                const bool bIsAutoCorrectChar = SvxAutoCorrect::IsAutoCorrectChar(aCh);
2618
0
                if (!aKeyEvent.GetRepeat() && rSh.HasSelection()
2619
0
                    && rVwOpt.IsEncloseWithCharactersOn()
2620
0
                    && SwViewOption::IsEncloseWithCharactersTrigger(aCh))
2621
0
                {
2622
0
                    FlushInBuffer();
2623
0
                    switch (aCh)
2624
0
                    {
2625
0
                        case '(':
2626
0
                            rSh.InsertEnclosingChars(u"("_ustr, u")"_ustr);
2627
0
                            break;
2628
0
                        case '[':
2629
0
                            rSh.InsertEnclosingChars(u"["_ustr, u"]"_ustr);
2630
0
                            break;
2631
0
                        case '{':
2632
0
                            rSh.InsertEnclosingChars(u"{"_ustr, u"}"_ustr);
2633
0
                            break;
2634
0
                        case '\"':
2635
0
                        {
2636
0
                            LanguageType eLang
2637
0
                                = Application::GetSettings().GetLanguageTag().getLanguageType();
2638
0
                            OUString sStartQuote{ pACorr->GetQuote('\"', true, eLang) };
2639
0
                            OUString sEndQuote{ pACorr->GetQuote('\"', false, eLang) };
2640
0
                            rSh.InsertEnclosingChars(sStartQuote, sEndQuote);
2641
0
                            break;
2642
0
                        }
2643
0
                        case '\'':
2644
0
                        {
2645
0
                            LanguageType eLang
2646
0
                                = Application::GetSettings().GetLanguageTag().getLanguageType();
2647
0
                            OUString sStartQuote{ pACorr->GetQuote('\'', true, eLang) };
2648
0
                            OUString sEndQuote{ pACorr->GetQuote('\'', false, eLang) };
2649
0
                            rSh.InsertEnclosingChars(sStartQuote, sEndQuote);
2650
0
                            break;
2651
0
                        }
2652
0
                    }
2653
0
                }
2654
0
                else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) &&
2655
0
                        pACfg->IsAutoFormatByInput() &&
2656
0
                    (( pACorr->IsAutoCorrFlag( ACFlags::ChgWeightUnderl ) &&
2657
0
                        ( '*' == aCh || '_' == aCh ) ) ||
2658
0
                     ( pACorr->IsAutoCorrFlag( ACFlags::ChgQuotes ) && ('\"' == aCh ))||
2659
0
                     ( pACorr->IsAutoCorrFlag( ACFlags::ChgSglQuotes ) && ( '\'' == aCh))))
2660
0
                {
2661
0
                    FlushInBuffer();
2662
0
                    rSh.AutoCorrect( *pACorr, aCh );
2663
0
                    if( '\"' != aCh && '\'' != aCh )        // only call when "*_"!
2664
0
                        rSh.UpdateAttr();
2665
0
                }
2666
0
                else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) &&
2667
0
                        pACfg->IsAutoFormatByInput() &&
2668
0
                    pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2669
0
                                            ACFlags::ChgOrdinalNumber | ACFlags::AddNonBrkSpace |
2670
0
                                            ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr |
2671
0
                                            ACFlags::Autocorrect | ACFlags::TransliterateRTL |
2672
0
                                            ACFlags::SetDOIAttr ) &&
2673
0
                    '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh
2674
0
                    )
2675
0
                {
2676
0
                    FlushInBuffer();
2677
0
                    rSh.AutoCorrect( *pACorr, aCh );
2678
0
                }
2679
0
                else
2680
0
                {
2681
0
                    m_aInBuffer += OUString::Concat(RepeatedUChar(aCh, aKeyEvent.GetRepeat() + 1));
2682
0
                    bool delayFlush = Application::AnyInput( VclInputFlags::KEYBOARD );
2683
0
                    bFlushBuffer = !delayFlush;
2684
0
                    if( delayFlush )
2685
0
                    {
2686
                        // Start the timer, make sure to not restart it.
2687
0
                        keyInputFlushTimerStop.dismiss();
2688
0
                        if( !m_aKeyInputFlushTimer.IsActive())
2689
0
                            m_aKeyInputFlushTimer.Start();
2690
0
                    }
2691
0
                }
2692
0
                eKeyState = SwKeyState::End;
2693
0
            }
2694
0
            else
2695
0
            {
2696
0
                rSh.InfoReadOnlyDialog(true);
2697
0
                eKeyState = SwKeyState::End;
2698
0
            }
2699
2700
0
            bool bIsSpace = (aCh == ' ');
2701
0
            if (bIsSpace && pACorr && pACfg)
2702
0
            {
2703
                // do the formatting only for few starting characters (for "* " or "- " conversion)
2704
0
                SwPosition aPos(*rSh.GetCursor()->GetPoint());
2705
0
                if (aPos.nContent < 3)
2706
0
                {
2707
0
                    SvxSwAutoFormatFlags& rFlags = pACorr->GetSwFlags();
2708
0
                    if(pACfg->IsAutoFormatByInput() && rFlags.bSetNumRule && rFlags.bSetNumRuleAfterSpace)
2709
0
                        rSh.AutoFormat(&rFlags, true);
2710
0
                }
2711
0
            }
2712
0
        }
2713
0
        break;
2714
2715
0
        case SwKeyState::CheckAutoCorrect:
2716
0
        {
2717
0
            if( pACorr && pACfg->IsAutoFormatByInput() &&
2718
0
                pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2719
0
                                        ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL |
2720
0
                                        ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr |
2721
0
                                        ACFlags::Autocorrect | ACFlags::SetDOIAttr ) &&
2722
0
                !rSh.HasReadonlySel() )
2723
0
            {
2724
0
                FlushInBuffer();
2725
0
                rSh.AutoCorrect( *pACorr, u'\0' );
2726
0
            }
2727
0
            eKeyState = eNextKeyState;
2728
0
        }
2729
0
        break;
2730
2731
0
        default:
2732
0
        {
2733
0
            sal_uInt16 nSlotId = 0;
2734
0
            FlushInBuffer();
2735
0
            switch( eKeyState )
2736
0
            {
2737
0
            case SwKeyState::SpecialInsert:
2738
0
                rSh.DoSpecialInsert();
2739
0
                break;
2740
2741
0
            case SwKeyState::NoNum:
2742
0
                rSh.NoNum();
2743
0
                break;
2744
2745
0
            case SwKeyState::NumOff:
2746
                // shell change - so record in advance
2747
0
                rSh.DelNumRules();
2748
0
                break;
2749
0
            case SwKeyState::OutlineLvOff: // delete autofmt outlinelevel later
2750
0
                break;
2751
2752
0
            case SwKeyState::NumDown:
2753
0
                rSh.NumUpDown();
2754
0
                m_nKS_NUMDOWN_Count = 2;
2755
0
                break;
2756
0
            case SwKeyState::NumUp:
2757
0
                rSh.NumUpDown( false );
2758
0
                break;
2759
2760
0
            case SwKeyState::NumIndentInc:
2761
0
                rSh.ChangeIndentOfAllListLevels(360);
2762
0
                m_nKS_NUMINDENTINC_Count = 2;
2763
0
                break;
2764
2765
0
            case SwKeyState::GotoNextFieldMark:
2766
0
                {
2767
0
                    rSh.GotoFormControl(/*bNext=*/true);
2768
0
                }
2769
0
                break;
2770
2771
0
            case SwKeyState::GotoPrevFieldMark:
2772
0
                {
2773
0
                    rSh.GotoFormControl(/*bNext=*/false);
2774
0
                }
2775
0
                break;
2776
2777
0
            case SwKeyState::NumIndentDec:
2778
0
                rSh.ChangeIndentOfAllListLevels(-360);
2779
0
                break;
2780
2781
0
            case SwKeyState::OutlineDown:
2782
0
                rSh.OutlineUpDown();
2783
0
                break;
2784
0
            case SwKeyState::OutlineUp:
2785
0
                rSh.OutlineUpDown( -1 );
2786
0
                break;
2787
2788
0
            case SwKeyState::NextCell:
2789
                // always 'flush' in tables
2790
0
                rSh.GoNextCell(!rSh.HasReadonlySel());
2791
0
                nSlotId = FN_GOTO_NEXT_CELL;
2792
0
                break;
2793
0
            case SwKeyState::PrevCell:
2794
0
                rSh.GoPrevCell();
2795
0
                nSlotId = FN_GOTO_PREV_CELL;
2796
0
                break;
2797
0
            case SwKeyState::AutoFormatByInput:
2798
0
                rSh.SplitNode( true );
2799
0
                break;
2800
2801
0
            case SwKeyState::NextObject:
2802
0
            case SwKeyState::PrevObject:
2803
0
                if(rSh.GotoObj( SwKeyState::NextObject == eKeyState, GotoObjFlags::Any))
2804
0
                {
2805
0
                    if( rSh.IsFrameSelected() &&
2806
0
                        m_rView.GetDrawFuncPtr() )
2807
0
                    {
2808
0
                        m_rView.GetDrawFuncPtr()->Deactivate();
2809
0
                        m_rView.SetDrawFuncPtr(nullptr);
2810
0
                        m_rView.LeaveDrawCreate();
2811
0
                        m_rView.AttrChangedNotify(nullptr);
2812
0
                    }
2813
0
                    rSh.HideCursor();
2814
0
                    rSh.EnterSelFrameMode();
2815
0
                }
2816
0
            break;
2817
0
            case SwKeyState::GlossaryExpand:
2818
0
            {
2819
                // replace the word or abbreviation with the auto text
2820
0
                rSh.StartUndo( SwUndoId::START );
2821
2822
0
                OUString sFnd(aTmpQHD.CurStr());
2823
0
                if( aTmpQHD.m_bIsAutoText )
2824
0
                {
2825
0
                    SwGlossaryList* pList = ::GetGlossaryList();
2826
0
                    OUString sShrtNm;
2827
0
                    OUString sGroup;
2828
0
                    if(pList->GetShortName( sFnd, sShrtNm, sGroup))
2829
0
                    {
2830
0
                        rSh.SttSelect();
2831
0
                        rSh.ExtendSelection(false, aTmpQHD.CurLen());
2832
0
                        SwGlossaryHdl* pGlosHdl = GetView().GetGlosHdl();
2833
0
                        pGlosHdl->SetCurGroup(sGroup, true);
2834
0
                        pGlosHdl->InsertGlossary( sShrtNm);
2835
0
                        s_pQuickHlpData->m_bAppendSpace = true;
2836
0
                    }
2837
0
                }
2838
0
                else
2839
0
                {
2840
0
                    sFnd = sFnd.copy(aTmpQHD.CurLen());
2841
0
                    rSh.Insert( sFnd );
2842
0
                    s_pQuickHlpData->m_bAppendSpace = !pACorr ||
2843
0
                            pACorr->GetSwFlags().bAutoCmpltAppendBlank;
2844
0
                }
2845
0
                rSh.EndUndo( SwUndoId::END );
2846
0
            }
2847
0
            break;
2848
2849
0
            case SwKeyState::NextPrevGlossary:
2850
0
                s_pQuickHlpData->Move( aTmpQHD );
2851
0
                s_pQuickHlpData->Start(rSh, false);
2852
0
                break;
2853
2854
0
            case SwKeyState::EditFormula:
2855
0
            {
2856
0
                const sal_uInt16 nId = SwInputChild::GetChildWindowId();
2857
2858
0
                SfxViewFrame& rVFrame = GetView().GetViewFrame();
2859
0
                rVFrame.ToggleChildWindow( nId );
2860
0
                SwInputChild* pChildWin = static_cast<SwInputChild*>(rVFrame.
2861
0
                                                    GetChildWindow( nId ));
2862
0
                if( pChildWin )
2863
0
                    pChildWin->SetFormula( sFormulaEntry );
2864
0
            }
2865
0
            break;
2866
2867
0
            case SwKeyState::ColLeftBig:         rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() );   break;
2868
0
            case SwKeyState::ColRightBig:        rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() );  break;
2869
0
            case SwKeyState::ColLeftSmall:       rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft, pModOpt->GetTableHMove() );   break;
2870
0
            case SwKeyState::ColRightSmall:      rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight, pModOpt->GetTableHMove() );  break;
2871
0
            case SwKeyState::ColBottomBig:       rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break;
2872
0
            case SwKeyState::ColBottomSmall:     rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom, pModOpt->GetTableVMove() ); break;
2873
0
            case SwKeyState::CellLeftBig:        rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() );  break;
2874
0
            case SwKeyState::CellRightBig:       rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break;
2875
0
            case SwKeyState::CellLeftSmall:      rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft, pModOpt->GetTableHMove() );  break;
2876
0
            case SwKeyState::CellRightSmall:     rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight, pModOpt->GetTableHMove() ); break;
2877
0
            case SwKeyState::CellTopBig:         rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() );   break;
2878
0
            case SwKeyState::CellBottomBig:      rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() );    break;
2879
0
            case SwKeyState::CellTopSmall:       rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop, pModOpt->GetTableVMove() );   break;
2880
0
            case SwKeyState::CellBottomSmall:    rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom, pModOpt->GetTableVMove() );    break;
2881
2882
0
            case SwKeyState::Fly_Change:
2883
0
            {
2884
0
                SdrView *pSdrView = rSh.GetDrawView();
2885
0
                const SdrHdlList& rHdlList = pSdrView->GetHdlList();
2886
0
                if(rHdlList.GetFocusHdl())
2887
0
                    ChangeDrawing(eDir, eDirSize);
2888
0
                else
2889
0
                    ChangeFly(eDir, eDirSize, dynamic_cast<const SwWebView*>( &m_rView) !=  nullptr);
2890
0
            }
2891
0
            break;
2892
0
            case SwKeyState::Draw_Change :
2893
0
                ChangeDrawing(eDir, eDirSize);
2894
0
                break;
2895
0
            default:
2896
0
                break;
2897
0
            }
2898
0
            if( nSlotId && m_rView.GetViewFrame().GetBindings().GetRecorder().is() )
2899
0
            {
2900
0
                SfxRequest aReq(m_rView.GetViewFrame(), nSlotId);
2901
0
                aReq.Done();
2902
0
            }
2903
0
            eKeyState = SwKeyState::End;
2904
0
        }
2905
0
        }
2906
0
    }
2907
2908
    // update the page number in the statusbar
2909
0
    nKey = rKEvt.GetKeyCode().GetCode();
2910
0
    if( KEY_UP == nKey || KEY_DOWN == nKey || KEY_PAGEUP == nKey || KEY_PAGEDOWN == nKey )
2911
0
        GetView().GetViewFrame().GetBindings().Update( FN_STAT_PAGE );
2912
2913
0
    m_bMaybeShowTooltipAfterBufferFlush = bNormalChar;
2914
2915
    // in case the buffered characters are inserted
2916
0
    if( bFlushBuffer && !m_aInBuffer.isEmpty() )
2917
0
    {
2918
0
        FlushInBuffer();
2919
0
    }
2920
2921
    // get the word count dialog to update itself
2922
0
    SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
2923
0
    if( pWrdCnt )
2924
0
        pWrdCnt->UpdateCounts();
2925
2926
0
}
2927
2928
/**
2929
 * MouseEvents
2930
 */
2931
void SwEditWin::ResetMouseButtonDownFlags()
2932
0
{
2933
    // Not on all systems a MouseButtonUp is used ahead
2934
    // of the modal dialog (like on WINDOWS).
2935
    // So reset the statuses here and release the mouse
2936
    // for the dialog.
2937
0
    m_bMBPressed = false;
2938
0
    g_bNoInterrupt = false;
2939
0
    EnterArea();
2940
0
    ReleaseMouse();
2941
0
}
2942
2943
/**
2944
 * Determines if the current position has a clickable url over a background
2945
 * frame. In that case, ctrl-click should select the url, not the frame.
2946
 */
2947
static bool lcl_urlOverBackground(SwWrtShell& rSh, const Point& rDocPos)
2948
0
{
2949
0
    SwContentAtPos aSwContentAtPos(IsAttrAtPos::InetAttr);
2950
0
    SdrObject* pSelectableObj = rSh.GetObjAt(rDocPos);
2951
2952
0
    return rSh.GetContentAtPos(rDocPos, aSwContentAtPos) && pSelectableObj->GetLayer() == rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId();
2953
0
}
2954
2955
void SwEditWin::MoveCursor( SwWrtShell &rSh, const Point& rDocPos,
2956
                            const bool bOnlyText, bool bLockView )
2957
0
{
2958
0
    const bool bTmpNoInterrupt = g_bNoInterrupt;
2959
0
    g_bNoInterrupt = false;
2960
2961
0
    int nTmpSetCursor = 0;
2962
2963
0
    if( !rSh.IsViewLocked() && bLockView )
2964
0
        rSh.LockView( true );
2965
0
    else
2966
0
        bLockView = false;
2967
2968
0
    {
2969
        // only temporary generate move context because otherwise
2970
        // the query to the content form doesn't work!!!
2971
0
        SwMvContext aMvContext( &rSh );
2972
0
        nTmpSetCursor = rSh.CallSetCursor(&rDocPos, bOnlyText);
2973
0
        g_bValidCursorPos = !(CRSR_POSCHG & nTmpSetCursor);
2974
0
    }
2975
2976
    // notify the edit window that from now on we do not use the input language
2977
0
    if ( !(CRSR_POSOLD & nTmpSetCursor) )
2978
0
        SetUseInputLanguage( false );
2979
2980
0
    if( bLockView )
2981
0
        rSh.LockView( false );
2982
2983
0
    g_bNoInterrupt = bTmpNoInterrupt;
2984
0
}
2985
2986
void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
2987
0
{
2988
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
2989
0
    const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr;
2990
2991
    // We have to check if a context menu is shown and we have an UI
2992
    // active inplace client. In that case we have to ignore the mouse
2993
    // button down event. Otherwise we would crash (context menu has been
2994
    // opened by inplace client and we would deactivate the inplace client,
2995
    // the context menu is closed by VCL asynchronously which in the end
2996
    // would work on deleted objects or the context menu has no parent anymore)
2997
0
    SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient();
2998
0
    bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() );
2999
3000
0
    if (bIsOleActive && vcl::IsInPopupMenuExecute())
3001
0
        return;
3002
3003
0
    MouseEvent aMEvt(_rMEvt);
3004
3005
0
    if (m_rView.GetPostItMgr()->IsHit(aMEvt.GetPosPixel()))
3006
0
        return;
3007
3008
0
    if (comphelper::LibreOfficeKit::isActive())
3009
0
    {
3010
0
        if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(aMEvt.GetPosPixel()))
3011
0
        {
3012
0
            pWindow->MouseButtonDown(aMEvt);
3013
0
            return;
3014
0
        }
3015
0
    }
3016
3017
0
    if (aMEvt.GetButtons() == MOUSE_LEFT && m_rView.GetPostItMgr()->IsHitSidebarDragArea(aMEvt.GetPosPixel()))
3018
0
    {
3019
0
        mbIsDragSidebar = true;
3020
        // Capture mouse to keep tracking even if the mouse leaves the document window
3021
0
        CaptureMouse();
3022
0
        return;
3023
0
    }
3024
3025
0
    m_rView.GetPostItMgr()->SetActiveSidebarWin(nullptr);
3026
3027
0
    GrabFocus();
3028
0
    rSh.addCurrentPosition();
3029
3030
    //ignore key modifiers for format paintbrush
3031
0
    {
3032
0
        bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
3033
0
                                &&  m_pApplyTempl->m_pFormatClipboard->HasContent();
3034
0
        if( bExecFormatPaintbrush )
3035
0
            aMEvt = MouseEvent(_rMEvt.GetPosPixel(), _rMEvt.GetClicks(), _rMEvt.GetMode(),
3036
0
                               _rMEvt.GetButtons());
3037
0
    }
3038
3039
0
    m_bWasShdwCursor = nullptr != m_pShadCursor;
3040
0
    m_pShadCursor.reset();
3041
3042
0
    const Point aDocPos(PixelToLogic(aMEvt.GetPosPixel()));
3043
3044
0
    FrameControlType eControl;
3045
0
    bool bOverFly = false;
3046
0
    bool bPageAnchored = false;
3047
0
    bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored );
3048
3049
0
    bool bIsViewReadOnly = m_rView.GetDocShell()->IsReadOnly() || (rSh.GetSfxViewShell() && rSh.GetSfxViewShell()->IsLokReadOnlyView());
3050
0
    if (bOverHeaderFooterFly && (!bIsViewReadOnly && rSh.GetCurField()))
3051
        // We have a field here, that should have priority over header/footer fly.
3052
0
        bOverHeaderFooterFly = false;
3053
3054
    // Are we clicking on a blank header/footer area?
3055
0
    if ( IsInHeaderFooter( aDocPos, eControl ) || bOverHeaderFooterFly )
3056
0
    {
3057
0
        const SwPageFrame* pPageFrame = rSh.GetLayout()->GetPageAtPos( aDocPos );
3058
3059
0
        if ( pPageFrame )
3060
0
        {
3061
            // Is it active?
3062
0
            bool bActive = true;
3063
0
            const SwPageDesc* pDesc = pPageFrame->GetPageDesc();
3064
3065
0
            const SwFrameFormat* pFormat = pDesc->GetLeftFormat();
3066
0
            if ( pPageFrame->OnRightPage() )
3067
0
                 pFormat = pDesc->GetRightFormat();
3068
3069
0
            if ( pFormat )
3070
0
            {
3071
0
                if ( eControl == FrameControlType::Header )
3072
0
                    bActive = pFormat->GetHeader().IsActive();
3073
0
                else
3074
0
                    bActive = pFormat->GetFooter().IsActive();
3075
0
            }
3076
3077
0
            if ( !bActive )
3078
0
            {
3079
                // HeaderFooter menu implies header/footer controls, so only do this with IsUseHeaderFooterMenu enabled.
3080
                // But, additionally, when in Hide-Whitespace mode, we don't want those controls.
3081
0
                if (rSh.GetViewOptions()->IsUseHeaderFooterMenu() && !rSh.GetViewOptions()->IsHideWhitespaceMode())
3082
0
                {
3083
0
                    SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint());
3084
0
                    const bool bWasInHeader = aPam.GetPoint()->GetNode().FindHeaderStartNode() != nullptr;
3085
0
                    const bool bWasInFooter = aPam.GetPoint()->GetNode().FindFooterStartNode() != nullptr;
3086
3087
                    // Is the cursor in a part like similar to the one we clicked on? For example,
3088
                    // if the cursor is in a header and we click on an empty header... don't change anything to
3089
                    // keep consistent behaviour due to header edit mode (and the same for the footer as well).
3090
3091
                    // Otherwise, we hide the header/footer control if a separator is shown, and vice versa.
3092
0
                    if (!(bWasInHeader && eControl == FrameControlType::Header) &&
3093
0
                        !(bWasInFooter && eControl == FrameControlType::Footer))
3094
0
                    {
3095
0
                        const bool bSeparatorWasVisible = rSh.IsShowHeaderFooterSeparator(eControl);
3096
0
                        rSh.SetShowHeaderFooterSeparator(eControl, !bSeparatorWasVisible);
3097
3098
                        // Repaint everything
3099
0
                        Invalidate();
3100
3101
                        // tdf#84929. If the footer control had not been showing, do not change the cursor position,
3102
                        // because the user may have scrolled to turn on the separator control and
3103
                        // if the cursor cannot be positioned on-screen, then the user would need to scroll back again to use the control.
3104
                        // This should only be done for the footer. The cursor can always be re-positioned near the header. tdf#134023.
3105
0
                        if ( eControl == FrameControlType::Footer && !bSeparatorWasVisible
3106
0
                             && !Application::IsHeadlessModeEnabled() )
3107
0
                            return;
3108
0
                    }
3109
0
                }
3110
0
            }
3111
0
            else
3112
0
            {
3113
                // Make sure we have the proper Header/Footer separators shown
3114
                // as these may be changed if clicking on an empty Header/Footer
3115
0
                rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, eControl == FrameControlType::Header );
3116
0
                rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, eControl == FrameControlType::Footer );
3117
3118
0
                if ( !rSh.IsHeaderFooterEdit() )
3119
0
                    rSh.ToggleHeaderFooterEdit();
3120
0
            }
3121
0
        }
3122
0
    }
3123
0
    else
3124
0
    {
3125
0
        if ( rSh.IsHeaderFooterEdit( ) )
3126
0
            rSh.ToggleHeaderFooterEdit( );
3127
0
        else
3128
0
        {
3129
            // Make sure that the separators are hidden
3130
0
            rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, false );
3131
0
            rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
3132
0
        }
3133
3134
        // Toggle Hide-Whitespace if between pages.
3135
0
        if (rSh.GetViewOptions()->CanHideWhitespace() &&
3136
0
            rSh.GetLayout()->IsBetweenPages(aDocPos))
3137
0
        {
3138
0
            if (_rMEvt.GetClicks() >= 2)
3139
0
            {
3140
0
                SwViewOption aOpt(*rSh.GetViewOptions());
3141
0
                aOpt.SetHideWhitespaceMode(!aOpt.IsHideWhitespaceMode());
3142
0
                rSh.ApplyViewOptions(aOpt);
3143
0
            }
3144
3145
0
            return;
3146
0
        }
3147
0
    }
3148
3149
0
    if ( IsChainMode() )
3150
0
    {
3151
0
        SetChainMode( false );
3152
0
        SwRect aDummy;
3153
0
        SwFlyFrameFormat *pFormat = static_cast<SwFlyFrameFormat*>(rSh.GetFlyFrameFormat());
3154
0
        if ( rSh.Chainable( aDummy, *pFormat, aDocPos ) == SwChainRet::OK )
3155
0
            rSh.Chain( *pFormat, aDocPos );
3156
0
        UpdatePointer(aDocPos, aMEvt.GetModifier());
3157
0
        return;
3158
0
    }
3159
3160
    // After GrabFocus a shell should be pushed. That should actually
3161
    // work but in practice ...
3162
0
    m_rView.SelectShellForDrop();
3163
3164
0
    bool bCallBase = true;
3165
3166
0
    if( s_pQuickHlpData->m_bIsDisplayed )
3167
0
        s_pQuickHlpData->Stop( rSh );
3168
0
    s_pQuickHlpData->m_bAppendSpace = false;
3169
3170
0
    if( rSh.FinishOLEObj() )
3171
0
        return; // end InPlace and the click doesn't count anymore
3172
3173
0
    CurrShell aCurr( &rSh );
3174
3175
0
    SdrView *pSdrView = rSh.GetDrawView();
3176
0
    if ( pSdrView )
3177
0
    {
3178
0
        if (pSdrView->MouseButtonDown(aMEvt, GetOutDev()))
3179
0
        {
3180
0
            rSh.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
3181
0
            return; // SdrView's event evaluated
3182
0
        }
3183
0
    }
3184
3185
0
    m_bIsInMove = false;
3186
0
    m_aStartPos = aMEvt.GetPosPixel();
3187
0
    m_aRszMvHdlPt.setX( 0 );
3188
0
    m_aRszMvHdlPt.setY( 0 );
3189
3190
0
    SwTab nMouseTabCol = SwTab::COL_NONE;
3191
0
    const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && !rSh.IsInSelect()
3192
0
                      && aMEvt.GetClicks() == 1 && MOUSE_LEFT == aMEvt.GetButtons();
3193
3194
0
    if (  bTmp &&
3195
0
         SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) &&
3196
0
         ( !rSh.IsObjSelectable( aDocPos ) ||
3197
             // allow resizing row height, if the image is anchored as character in the cell
3198
0
             !( SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol ) ) )
3199
0
    {
3200
        // Enhanced table selection
3201
0
        if ( SwTab::SEL_HORI <= nMouseTabCol && SwTab::COLSEL_VERT >= nMouseTabCol )
3202
0
        {
3203
0
            rSh.EnterStdMode();
3204
0
            rSh.SelectTableRowCol( aDocPos );
3205
0
            if( SwTab::SEL_HORI  != nMouseTabCol && SwTab::SEL_HORI_RTL  != nMouseTabCol)
3206
0
            {
3207
0
                m_xRowColumnSelectionStart = aDocPos;
3208
0
                m_bIsRowDrag = SwTab::ROWSEL_HORI == nMouseTabCol||
3209
0
                            SwTab::ROWSEL_HORI_RTL == nMouseTabCol ||
3210
0
                            SwTab::COLSEL_VERT == nMouseTabCol;
3211
0
                m_bMBPressed = true;
3212
0
                CaptureMouse();
3213
0
            }
3214
0
            return;
3215
0
        }
3216
3217
0
        if ( !rSh.IsTableMode() )
3218
0
        {
3219
            // comes from table columns out of the document.
3220
0
            if(SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol)
3221
0
                m_rView.SetTabColFromDoc( true );
3222
0
            else
3223
0
                m_rView.SetTabRowFromDoc( true );
3224
3225
0
            m_rView.SetTabColFromDocPos( aDocPos );
3226
0
            m_rView.InvalidateRulerPos();
3227
0
            SfxBindings& rBind = m_rView.GetViewFrame().GetBindings();
3228
0
            rBind.Update();
3229
0
            if (RulerColumnDrag(
3230
0
                    aMEvt, (SwTab::COL_VERT == nMouseTabCol || SwTab::ROW_HORI == nMouseTabCol)))
3231
0
            {
3232
0
                m_rView.SetTabColFromDoc( false );
3233
0
                m_rView.SetTabRowFromDoc( false );
3234
0
                m_rView.InvalidateRulerPos();
3235
0
                rBind.Update();
3236
0
                bCallBase = false;
3237
0
            }
3238
0
            else
3239
0
            {
3240
0
                return;
3241
0
            }
3242
0
        }
3243
0
    }
3244
0
    else if (bTmp &&
3245
0
             rSh.IsNumLabel(aDocPos))
3246
0
    {
3247
0
        SwTextNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPos );
3248
0
        m_rView.SetNumRuleNodeFromDoc( pNodeAtPos );
3249
0
        m_rView.InvalidateRulerPos();
3250
0
        SfxBindings& rBind = m_rView.GetViewFrame().GetBindings();
3251
0
        rBind.Update();
3252
3253
0
        if (RulerMarginDrag(aMEvt, SwFEShell::IsVerticalModeAtNdAndPos(*pNodeAtPos, aDocPos)))
3254
0
        {
3255
0
            m_rView.SetNumRuleNodeFromDoc( nullptr );
3256
0
            m_rView.InvalidateRulerPos();
3257
0
            rBind.Update();
3258
0
            bCallBase = false;
3259
0
        }
3260
0
        else
3261
0
        {
3262
            // Make sure the pointer is set to 0, otherwise it may point to
3263
            // nowhere after deleting the corresponding text node.
3264
0
            m_rView.SetNumRuleNodeFromDoc( nullptr );
3265
0
            return;
3266
0
        }
3267
0
    }
3268
3269
0
    if ( rSh.IsInSelect() )
3270
0
        rSh.EndSelect();
3271
3272
    // query against LEFT because otherwise for example also a right
3273
    // click releases the selection.
3274
0
    if (MOUSE_LEFT == aMEvt.GetButtons())
3275
0
    {
3276
0
        bool bOnlyText = false;
3277
0
        m_bMBPressed = true;
3278
0
        g_bNoInterrupt = true;
3279
0
        m_nKS_NUMDOWN_Count = 0;
3280
3281
0
        CaptureMouse();
3282
3283
        // reset cursor position if applicable
3284
0
        rSh.ResetCursorStack();
3285
3286
0
        switch (aMEvt.GetModifier() + aMEvt.GetButtons())
3287
0
        {
3288
0
            case MOUSE_LEFT:
3289
0
            case MOUSE_LEFT + KEY_SHIFT:
3290
0
            case MOUSE_LEFT + KEY_MOD2:
3291
0
                if( rSh.GetSelectedObjCount() )
3292
0
                {
3293
0
                    SdrHdl* pHdl;
3294
0
                    if( !bIsViewReadOnly &&
3295
0
                        !m_pAnchorMarker &&
3296
0
                        pSdrView &&
3297
0
                        nullptr != ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
3298
0
                            ( pHdl->GetKind() == SdrHdlKind::Anchor ||
3299
0
                              pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
3300
0
                    {
3301
                        // #i121463# Set selected during drag
3302
0
                        pHdl->SetSelected();
3303
0
                        m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) );
3304
0
                        UpdatePointer(aDocPos, aMEvt.GetModifier());
3305
0
                        return;
3306
0
                    }
3307
0
                }
3308
0
                if (EnterDrawMode(aMEvt, aDocPos))
3309
0
                {
3310
0
                    g_bNoInterrupt = false;
3311
0
                    return;
3312
0
                }
3313
0
                else  if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
3314
0
                {
3315
0
                    StopInsFrame();
3316
0
                    rSh.Edit();
3317
0
                }
3318
3319
                // Without SHIFT because otherwise Toggle doesn't work at selection
3320
0
                if (aMEvt.GetClicks() == 1)
3321
0
                {
3322
0
                    if ( rSh.IsSelFrameMode())
3323
0
                    {
3324
0
                        SdrHdl* pHdl = rSh.GetDrawView()->PickHandle(aDocPos);
3325
0
                        bool bHitHandle = pHdl && pHdl->GetKind() != SdrHdlKind::Anchor &&
3326
0
                                                  pHdl->GetKind() != SdrHdlKind::Anchor_TR;
3327
3328
0
                        if ((rSh.IsInsideSelectedObj(aDocPos) || bHitHandle)
3329
0
                            && (aMEvt.GetModifier() != KEY_SHIFT || bHitHandle))
3330
0
                        {
3331
0
                            rSh.EnterSelFrameMode( &aDocPos );
3332
0
                            if ( !m_pApplyTempl )
3333
0
                            {
3334
                                // only if no position to size was hit.
3335
0
                                if (!bHitHandle)
3336
0
                                {
3337
0
                                    StartDDTimer();
3338
0
                                    SwEditWin::s_nDDStartPosY = aDocPos.Y();
3339
0
                                    SwEditWin::s_nDDStartPosX = aDocPos.X();
3340
0
                                }
3341
0
                                g_bFrameDrag = true;
3342
0
                            }
3343
0
                            g_bNoInterrupt = false;
3344
0
                            return;
3345
0
                        }
3346
0
                    }
3347
0
                }
3348
0
        }
3349
3350
0
        bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
3351
0
        if ( !bExecHyperlinks )
3352
0
        {
3353
0
            const bool bSecureOption = SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
3354
0
            if ((bSecureOption && aMEvt.GetModifier() == KEY_MOD1)
3355
0
                || (!bSecureOption && aMEvt.GetModifier() != KEY_MOD1))
3356
0
                bExecHyperlinks = true;
3357
0
        }
3358
3359
        // Enhanced selection
3360
0
        sal_uInt8 nNumberOfClicks = static_cast<sal_uInt8>(aMEvt.GetClicks() % 4);
3361
0
        if (0 == nNumberOfClicks && 0 < aMEvt.GetClicks())
3362
0
            nNumberOfClicks = 4;
3363
3364
0
        bool bExecDrawTextLink = false;
3365
3366
0
        switch (aMEvt.GetModifier() + aMEvt.GetButtons())
3367
0
        {
3368
0
            case MOUSE_LEFT:
3369
0
            case MOUSE_LEFT + KEY_MOD1:
3370
0
            case MOUSE_LEFT + KEY_MOD2:
3371
0
            {
3372
3373
                // fdo#79604: first, check if a link has been clicked - do not
3374
                // select fly in this case!
3375
0
                if (1 == nNumberOfClicks)
3376
0
                {
3377
0
                    UpdatePointer(aDocPos, aMEvt.GetModifier());
3378
0
                    SwEditWin::s_nDDStartPosY = aDocPos.Y();
3379
0
                    SwEditWin::s_nDDStartPosX = aDocPos.X();
3380
3381
                    // hit a URL in DrawText object?
3382
0
                    if (bExecHyperlinks && pSdrView)
3383
0
                    {
3384
0
                        SdrViewEvent aVEvt;
3385
0
                        pSdrView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
3386
3387
0
                        if (aVEvt.meEvent == SdrEventKind::ExecuteUrl)
3388
0
                            bExecDrawTextLink = true;
3389
0
                    }
3390
0
                }
3391
3392
0
                if (1 == nNumberOfClicks && !bExecDrawTextLink)
3393
0
                {
3394
                    // only try to select frame, if pointer already was
3395
                    // switched accordingly
3396
0
                    if ( m_aActHitType != SdrHitKind::NONE && !rSh.IsSelFrameMode() &&
3397
0
                        !GetView().GetViewFrame().GetDispatcher()->IsLocked())
3398
0
                    {
3399
                        // Test if there is a draw object at that position and if it should be selected.
3400
0
                        bool bSelectFrameInsteadOfCroppedImage = false;
3401
0
                        bool bShould = rSh.ShouldObjectBeSelected(aDocPos, &bSelectFrameInsteadOfCroppedImage);
3402
3403
0
                        if(bShould)
3404
0
                        {
3405
0
                            m_rView.NoRotate();
3406
0
                            rSh.HideCursor();
3407
3408
0
                            bool bUnLockView = !rSh.IsViewLocked();
3409
0
                            rSh.LockView( true );
3410
0
                            bool bSelObj
3411
0
                                = rSh.SelectObj(aDocPos, aMEvt.IsMod1() ? SW_ENTER_GROUP : 0);
3412
0
                            if ( bSelObj && bSelectFrameInsteadOfCroppedImage && pSdrView )
3413
0
                            {
3414
0
                                bool bWrapped(false);
3415
0
                                const SdrObject* pFly = rSh.GetBestObject(false, GotoObjFlags::FlyAny, true, nullptr, &bWrapped);
3416
0
                                pSdrView->UnmarkAllObj();
3417
0
                                bSelObj =
3418
0
                                    rSh.SelectObj(aDocPos, aMEvt.IsMod1() ? SW_ENTER_GROUP : 0, const_cast<SdrObject*>(pFly));
3419
0
                            }
3420
0
                            if( bUnLockView )
3421
0
                                rSh.LockView( false );
3422
3423
0
                            if( bSelObj )
3424
0
                            {
3425
                                // if the frame was deselected in the macro
3426
                                // the cursor just has to be displayed again
3427
0
                                if( FrameTypeFlags::NONE == rSh.GetSelFrameType() )
3428
0
                                    rSh.ShowCursor();
3429
0
                                else
3430
0
                                {
3431
0
                                    if (rSh.IsFrameSelected() && m_rView.GetDrawFuncPtr())
3432
0
                                    {
3433
0
                                        m_rView.GetDrawFuncPtr()->Deactivate();
3434
0
                                        m_rView.SetDrawFuncPtr(nullptr);
3435
0
                                        m_rView.LeaveDrawCreate();
3436
0
                                        m_rView.AttrChangedNotify(nullptr);
3437
0
                                    }
3438
3439
0
                                    rSh.EnterSelFrameMode( &aDocPos );
3440
0
                                    g_bFrameDrag = true;
3441
0
                                    UpdatePointer(aDocPos, aMEvt.GetModifier());
3442
0
                                }
3443
0
                                return;
3444
0
                            }
3445
0
                            else
3446
0
                                bOnlyText = rSh.IsObjSelectable( aDocPos );
3447
3448
0
                            if (!m_rView.GetDrawFuncPtr())
3449
0
                                rSh.ShowCursor();
3450
0
                        }
3451
0
                        else
3452
0
                            bOnlyText = KEY_MOD1 != aMEvt.GetModifier();
3453
0
                    }
3454
0
                    else if ( rSh.IsSelFrameMode() &&
3455
0
                              (m_aActHitType == SdrHitKind::NONE ||
3456
0
                               !rSh.IsInsideSelectedObj( aDocPos )))
3457
0
                    {
3458
0
                        m_rView.NoRotate();
3459
0
                        SdrHdl *pHdl;
3460
0
                        if( !bIsViewReadOnly && !m_pAnchorMarker && nullptr !=
3461
0
                            ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
3462
0
                                ( pHdl->GetKind() == SdrHdlKind::Anchor ||
3463
0
                                  pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
3464
0
                        {
3465
0
                            m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) );
3466
0
                            UpdatePointer(aDocPos, aMEvt.GetModifier());
3467
0
                            return;
3468
0
                        }
3469
0
                        else
3470
0
                        {
3471
0
                            bool bUnLockView = !rSh.IsViewLocked();
3472
0
                            rSh.LockView( true );
3473
0
                            sal_uInt8 nFlag = aMEvt.IsShift() ? SW_ADD_SELECT : 0;
3474
0
                            if (aMEvt.IsMod1())
3475
0
                                nFlag = nFlag | SW_ENTER_GROUP;
3476
3477
0
                            if ( rSh.IsSelFrameMode() )
3478
0
                            {
3479
0
                                rSh.UnSelectFrame();
3480
0
                                rSh.LeaveSelFrameMode();
3481
0
                                m_rView.AttrChangedNotify(nullptr);
3482
0
                            }
3483
3484
0
                            bool bSelObj = rSh.SelectObj( aDocPos, nFlag );
3485
0
                            if( bUnLockView )
3486
0
                                rSh.LockView( false );
3487
3488
0
                            if( !bSelObj )
3489
0
                            {
3490
                                // move cursor here so that it is not drawn in the
3491
                                // frame first; ShowCursor() happens in LeaveSelFrameMode()
3492
0
                                g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
3493
0
                                rSh.LeaveSelFrameMode();
3494
0
                                m_rView.AttrChangedNotify(nullptr);
3495
0
                                bCallBase = false;
3496
0
                            }
3497
0
                            else
3498
0
                            {
3499
0
                                rSh.HideCursor();
3500
0
                                rSh.EnterSelFrameMode( &aDocPos );
3501
0
                                rSh.SelFlyGrabCursor();
3502
0
                                rSh.MakeSelVisible();
3503
0
                                g_bFrameDrag = true;
3504
0
                                if( rSh.IsFrameSelected() &&
3505
0
                                    m_rView.GetDrawFuncPtr() )
3506
0
                                {
3507
0
                                    m_rView.GetDrawFuncPtr()->Deactivate();
3508
0
                                    m_rView.SetDrawFuncPtr(nullptr);
3509
0
                                    m_rView.LeaveDrawCreate();
3510
0
                                    m_rView.AttrChangedNotify(nullptr);
3511
0
                                }
3512
0
                                UpdatePointer(aDocPos, aMEvt.GetModifier());
3513
0
                                return;
3514
0
                            }
3515
0
                        }
3516
0
                    }
3517
0
                }
3518
3519
0
                switch ( nNumberOfClicks )
3520
0
                {
3521
0
                    case 1:
3522
0
                        break;
3523
0
                    case 2:
3524
0
                    {
3525
0
                        g_bFrameDrag = false;
3526
0
                        if (!bIsViewReadOnly && rSh.IsInsideSelectedObj(aDocPos)
3527
0
                            && (FlyProtectFlags::NONE
3528
0
                                    == rSh.IsSelObjProtected(FlyProtectFlags::Content
3529
0
                                                             | FlyProtectFlags::Parent)
3530
0
                                || rSh.GetSelectionType() == SelectionType::Ole))
3531
0
                        {
3532
                        /* This is no good: on the one hand GetSelectionType is used as flag field
3533
                         * (take a look into the GetSelectionType method) and on the other hand the
3534
                         * return value is used in a switch without proper masking (very nice), this must lead to trouble
3535
                         */
3536
0
                            switch ( rSh.GetSelectionType() & ~SelectionType( SelectionType::FontWork | SelectionType::ExtrudedCustomShape ) )
3537
0
                            {
3538
0
                            case SelectionType::Graphic:
3539
0
                                ResetMouseButtonDownFlags();
3540
0
                                if (!comphelper::LibreOfficeKit::isActive())
3541
0
                                {
3542
0
                                    GetView().GetViewFrame().GetBindings().Execute(
3543
0
                                        FN_FORMAT_GRAFIC_DLG, nullptr,
3544
0
                                        SfxCallMode::RECORD|SfxCallMode::SLOT);
3545
0
                                }
3546
0
                                return;
3547
3548
                            // double click on OLE object --> OLE-InPlace
3549
0
                            case SelectionType::Ole:
3550
0
                                ResetMouseButtonDownFlags();
3551
0
                                rSh.LaunchOLEObj();
3552
0
                                return;
3553
3554
0
                            case SelectionType::Frame:
3555
0
                                ResetMouseButtonDownFlags();
3556
0
                                if (!comphelper::LibreOfficeKit::isActive())
3557
0
                                {
3558
0
                                    GetView().GetViewFrame().GetBindings().Execute(
3559
0
                                        FN_FORMAT_FRAME_DLG, nullptr,
3560
0
                                        SfxCallMode::RECORD|SfxCallMode::SLOT);
3561
0
                                }
3562
0
                                return;
3563
3564
0
                            case SelectionType::DrawObject:
3565
0
                                ResetMouseButtonDownFlags();
3566
0
                                EnterDrawTextMode(aDocPos);
3567
0
                                if ( auto pSwDrawTextShell = dynamic_cast< SwDrawTextShell *>(  m_rView.GetCurShell() )  )
3568
0
                                    pSwDrawTextShell->Init();
3569
0
                                return;
3570
3571
0
                            default: break;
3572
0
                            }
3573
0
                        }
3574
3575
                        // if the cursor position was corrected or if a Fly
3576
                        // was selected in ReadOnlyMode, no word selection, except when tiled rendering.
3577
0
                        if ((!g_bValidCursorPos || rSh.IsFrameSelected()) && !comphelper::LibreOfficeKit::isActive())
3578
0
                            return;
3579
3580
0
                        SwField *pField = rSh.GetCurField(true);
3581
0
                        bool bFootnote = false;
3582
3583
0
                        if( nullptr != pField ||
3584
0
                              ( bFootnote = rSh.GetCurFootnote() ))
3585
0
                        {
3586
0
                            if (!bIsViewReadOnly)
3587
0
                            {
3588
0
                                ResetMouseButtonDownFlags();
3589
0
                                if( bFootnote )
3590
0
                                    GetView().GetViewFrame().GetBindings().Execute( FN_EDIT_FOOTNOTE );
3591
0
                                else
3592
0
                                {
3593
0
                                    SwFieldTypesEnum nTypeId = pField->GetTypeId();
3594
0
                                    SfxViewFrame& rVFrame = GetView().GetViewFrame();
3595
0
                                    switch( nTypeId )
3596
0
                                    {
3597
0
                                    case SwFieldTypesEnum::Postit:
3598
0
                                    case SwFieldTypesEnum::Script:
3599
0
                                    {
3600
                                        // if it's a Readonly region, status has to be enabled
3601
0
                                        sal_uInt16 nSlot = SwFieldTypesEnum::Postit == nTypeId ? FN_POSTIT : FN_JAVAEDIT;
3602
0
                                        SfxBoolItem aItem(nSlot, true);
3603
0
                                        rVFrame.GetBindings().SetState(aItem);
3604
0
                                        rVFrame.GetBindings().Execute(nSlot);
3605
0
                                        break;
3606
0
                                    }
3607
0
                                    case SwFieldTypesEnum::Authority :
3608
0
                                        rVFrame.GetBindings().Execute(FN_EDIT_AUTH_ENTRY_DLG);
3609
0
                                    break;
3610
0
                                    case SwFieldTypesEnum::Input:
3611
0
                                    case SwFieldTypesEnum::Dropdown:
3612
0
                                    case SwFieldTypesEnum::SetInput:
3613
0
                                        rVFrame.GetBindings().Execute(FN_UPDATE_INPUTFIELDS);
3614
0
                                        break;
3615
0
                                    default:
3616
0
                                        rVFrame.GetBindings().Execute(FN_EDIT_FIELD);
3617
0
                                    }
3618
0
                                }
3619
0
                                return;
3620
0
                            }
3621
0
                            else if (pField && pField->ExpandField(true, nullptr).getLength())
3622
0
                            {
3623
0
                                ResetMouseButtonDownFlags();
3624
0
                                GetView().GetViewFrame().GetBindings().Execute(FN_COPY_FIELD);
3625
0
                            }
3626
0
                        }
3627
                        // in extended mode double and triple
3628
                        // click has no effect.
3629
0
                        if ( rSh.IsExtMode() || rSh.IsBlockMode() )
3630
0
                            return;
3631
3632
                        // select word, AdditionalMode if applicable
3633
0
                        if (KEY_MOD1 == aMEvt.GetModifier() && !rSh.IsAddMode())
3634
0
                        {
3635
0
                            rSh.EnterAddMode();
3636
0
                            rSh.SelWrd( &aDocPos );
3637
0
                            rSh.LeaveAddMode();
3638
0
                        }
3639
0
                        else
3640
0
                        {
3641
0
                            if (!rSh.SelWrd(&aDocPos) && comphelper::LibreOfficeKit::isActive())
3642
                                // Double click did not select any word: try to
3643
                                // select the current cell in case we are in a
3644
                                // table.
3645
0
                                rSh.SelTableBox();
3646
0
                        }
3647
3648
0
                        SwContentAtPos aContentAtPos(IsAttrAtPos::FormControl);
3649
0
                        if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) &&
3650
0
                                aContentAtPos.aFnd.pFieldmark != nullptr)
3651
0
                        {
3652
0
                            Fieldmark *pFieldBM = const_cast< Fieldmark* > ( aContentAtPos.aFnd.pFieldmark );
3653
0
                            if ( pFieldBM->GetFieldname( ) == ODF_FORMDROPDOWN || pFieldBM->GetFieldname( ) == ODF_FORMDATE )
3654
0
                            {
3655
0
                                ResetMouseButtonDownFlags();
3656
0
                                rSh.getIDocumentMarkAccess()->ClearFieldActivation();
3657
0
                                GetView().GetViewFrame().GetBindings().Execute(SID_FM_CTL_PROPERTIES);
3658
0
                                return;
3659
0
                            }
3660
0
                        }
3661
3662
                        // tdf#143158 - handle alphabetical index entries
3663
0
                        SwContentAtPos aToxContentAtPos(IsAttrAtPos::ToxMark);
3664
0
                        if (rSh.GetContentAtPos(aDocPos, aToxContentAtPos))
3665
0
                        {
3666
0
                            const OUString sToxText = aToxContentAtPos.sStr;
3667
0
                            if (!sToxText.isEmpty() && aToxContentAtPos.pFndTextAttr)
3668
0
                            {
3669
0
                                const SwTOXType* pTType
3670
0
                                    = aToxContentAtPos.pFndTextAttr->GetTOXMark().GetTOXType();
3671
0
                                if (pTType && pTType->GetType() == TOXTypes::TOX_INDEX)
3672
0
                                {
3673
0
                                    ResetMouseButtonDownFlags();
3674
0
                                    GetView().GetViewFrame().GetBindings().Execute(
3675
0
                                        FN_EDIT_IDX_ENTRY_DLG);
3676
0
                                    return;
3677
0
                                }
3678
0
                            }
3679
0
                        }
3680
3681
0
                        g_bHoldSelection = true;
3682
0
                        return;
3683
0
                    }
3684
0
                    case 3:
3685
0
                    case 4:
3686
0
                    {
3687
0
                        g_bFrameDrag = false;
3688
                        // in extended mode double and triple
3689
                        // click has no effect.
3690
0
                        if ( rSh.IsExtMode() )
3691
0
                            return;
3692
3693
                        // if the cursor position was corrected or if a Fly
3694
                        // was selected in ReadOnlyMode, no word selection.
3695
0
                        if ( !g_bValidCursorPos || rSh.IsFrameSelected() )
3696
0
                            return;
3697
3698
                        // select line, AdditionalMode if applicable
3699
0
                        const bool bMod = KEY_MOD1 == aMEvt.GetModifier() && !rSh.IsAddMode();
3700
3701
0
                        if ( bMod )
3702
0
                            rSh.EnterAddMode();
3703
3704
                        // Enhanced selection
3705
0
                        if ( 3 == nNumberOfClicks )
3706
0
                            rSh.SelSentence( &aDocPos );
3707
0
                        else
3708
0
                            rSh.SelPara( &aDocPos );
3709
3710
0
                        if ( bMod )
3711
0
                            rSh.LeaveAddMode();
3712
3713
0
                        g_bHoldSelection = true;
3714
0
                        return;
3715
0
                    }
3716
3717
0
                    default:
3718
0
                        return;
3719
0
                }
3720
3721
0
                [[fallthrough]];
3722
0
            }
3723
0
            case MOUSE_LEFT + KEY_SHIFT:
3724
0
            case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
3725
0
            {
3726
0
                bool bLockView = m_bWasShdwCursor;
3727
3728
0
                switch (aMEvt.GetModifier())
3729
0
                {
3730
0
                    case KEY_MOD1 + KEY_SHIFT:
3731
0
                    {
3732
0
                        if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
3733
0
                        {
3734
0
                            m_rView.NoRotate();
3735
0
                            rSh.HideCursor();
3736
0
                            if ( rSh.IsSelFrameMode() )
3737
0
                                rSh.SelectObj(aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP);
3738
0
                            else
3739
0
                            {   if ( rSh.SelectObj( aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP ) )
3740
0
                                {
3741
0
                                    rSh.EnterSelFrameMode( &aDocPos );
3742
0
                                    SwEditWin::s_nDDStartPosY = aDocPos.Y();
3743
0
                                    SwEditWin::s_nDDStartPosX = aDocPos.X();
3744
0
                                    g_bFrameDrag = true;
3745
0
                                    return;
3746
0
                                }
3747
0
                            }
3748
0
                        }
3749
0
                        else if( rSh.IsSelFrameMode() &&
3750
0
                                 rSh.GetDrawView()->PickHandle( aDocPos ))
3751
0
                        {
3752
0
                            g_bFrameDrag = true;
3753
0
                            g_bNoInterrupt = false;
3754
0
                            return;
3755
0
                        }
3756
0
                    }
3757
0
                    break;
3758
0
                    case KEY_MOD1:
3759
0
                    if ( !bExecDrawTextLink )
3760
0
                    {
3761
0
                        if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
3762
0
                        {
3763
                            // ctrl+left-click on outline node frame
3764
0
                            SwContentAtPos aContentAtPos(IsAttrAtPos::Outline);
3765
0
                            if(rSh.GetContentAtPos(aDocPos, aContentAtPos))
3766
0
                            {
3767
0
                                SwOutlineNodes::size_type nPos;
3768
0
                                if (rSh.GetNodes().GetOutLineNds().Seek_Entry(aContentAtPos.aFnd.pNode, &nPos))
3769
0
                                {
3770
0
                                    ToggleOutlineContentVisibility(nPos, false);
3771
0
                                    return;
3772
0
                                }
3773
0
                            }
3774
0
                        }
3775
0
                        if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) && !lcl_urlOverBackground( rSh, aDocPos ) )
3776
0
                        {
3777
0
                            m_rView.NoRotate();
3778
0
                            rSh.HideCursor();
3779
0
                            if ( rSh.IsSelFrameMode() )
3780
0
                                rSh.SelectObj(aDocPos, SW_ENTER_GROUP);
3781
0
                            else
3782
0
                            {   if ( rSh.SelectObj( aDocPos, SW_ENTER_GROUP ) )
3783
0
                                {
3784
0
                                    rSh.EnterSelFrameMode( &aDocPos );
3785
0
                                    SwEditWin::s_nDDStartPosY = aDocPos.Y();
3786
0
                                    SwEditWin::s_nDDStartPosX = aDocPos.X();
3787
0
                                    g_bFrameDrag = true;
3788
0
                                    return;
3789
0
                                }
3790
0
                            }
3791
0
                        }
3792
0
                        else if( rSh.IsSelFrameMode() &&
3793
0
                                 rSh.GetDrawView()->PickHandle( aDocPos ))
3794
0
                        {
3795
0
                            g_bFrameDrag = true;
3796
0
                            g_bNoInterrupt = false;
3797
0
                            return;
3798
0
                        }
3799
0
                        else
3800
0
                        {
3801
0
                            if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
3802
0
                            {
3803
0
                                rSh.PushMode();
3804
0
                                g_bModePushed = true;
3805
3806
0
                                bool bUnLockView = !rSh.IsViewLocked();
3807
0
                                rSh.LockView( true );
3808
0
                                rSh.EnterAddMode();
3809
0
                                if( bUnLockView )
3810
0
                                    rSh.LockView( false );
3811
0
                            }
3812
0
                            bCallBase = false;
3813
0
                        }
3814
0
                    }
3815
0
                    break;
3816
0
                    case KEY_MOD2:
3817
0
                    {
3818
0
                        if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
3819
0
                        {
3820
0
                            rSh.PushMode();
3821
0
                            g_bModePushed = true;
3822
0
                            bool bUnLockView = !rSh.IsViewLocked();
3823
0
                            rSh.LockView( true );
3824
0
                            rSh.EnterBlockMode();
3825
0
                            if( bUnLockView )
3826
0
                                rSh.LockView( false );
3827
0
                        }
3828
0
                        bCallBase = false;
3829
0
                    }
3830
0
                    break;
3831
0
                    case KEY_SHIFT:
3832
0
                    {
3833
0
                        if (nNumberOfClicks == 2)
3834
0
                        {
3835
                            // Left mouse button, shift, double-click: see if we have a graphic and
3836
                            // dispatch its dialog in this case.
3837
0
                            if (rSh.GetSelectionType() == SelectionType::Graphic)
3838
0
                            {
3839
0
                                GetView().GetViewFrame().GetBindings().Execute(
3840
0
                                    FN_FORMAT_GRAFIC_DLG, nullptr,
3841
0
                                    SfxCallMode::RECORD | SfxCallMode::SLOT);
3842
0
                                return;
3843
0
                            }
3844
0
                        }
3845
3846
0
                        if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
3847
0
                        {
3848
0
                            m_rView.NoRotate();
3849
0
                            rSh.HideCursor();
3850
0
                            if ( rSh.IsSelFrameMode() )
3851
0
                            {
3852
0
                                rSh.SelectObj(aDocPos, SW_ADD_SELECT);
3853
3854
0
                                const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
3855
0
                                if (rMarkList.GetMark(0) == nullptr)
3856
0
                                {
3857
0
                                    rSh.LeaveSelFrameMode();
3858
0
                                    m_rView.AttrChangedNotify(nullptr);
3859
0
                                    g_bFrameDrag = false;
3860
0
                                }
3861
0
                            }
3862
0
                            else
3863
0
                            {   if ( rSh.SelectObj( aDocPos ) )
3864
0
                                {
3865
0
                                    rSh.EnterSelFrameMode( &aDocPos );
3866
0
                                    SwEditWin::s_nDDStartPosY = aDocPos.Y();
3867
0
                                    SwEditWin::s_nDDStartPosX = aDocPos.X();
3868
0
                                    g_bFrameDrag = true;
3869
0
                                    return;
3870
0
                                }
3871
0
                            }
3872
0
                        }
3873
0
                        else
3874
0
                        {
3875
0
                            bool bShould = rSh.ShouldObjectBeSelected(aDocPos);
3876
0
                            if (bShould)
3877
0
                            {
3878
                                // Left mouse button, shift, non-double-click, not a draw object and
3879
                                // have an object to select: select it.
3880
0
                                rSh.HideCursor();
3881
0
                                bool bSelObj = rSh.SelectObj(aDocPos);
3882
0
                                if (bSelObj)
3883
0
                                {
3884
0
                                    rSh.EnterSelFrameMode(&aDocPos);
3885
0
                                }
3886
0
                                return;
3887
0
                            }
3888
3889
0
                            if ( rSh.IsSelFrameMode() &&
3890
0
                                 rSh.IsInsideSelectedObj( aDocPos ) )
3891
0
                            {
3892
0
                                rSh.EnterSelFrameMode( &aDocPos );
3893
0
                                SwEditWin::s_nDDStartPosY = aDocPos.Y();
3894
0
                                SwEditWin::s_nDDStartPosX = aDocPos.X();
3895
0
                                g_bFrameDrag = true;
3896
0
                                return;
3897
0
                            }
3898
0
                            if ( rSh.IsSelFrameMode() )
3899
0
                            {
3900
0
                                rSh.UnSelectFrame();
3901
0
                                rSh.LeaveSelFrameMode();
3902
0
                                m_rView.AttrChangedNotify(nullptr);
3903
0
                                g_bFrameDrag = false;
3904
0
                            }
3905
0
                            if ( !rSh.IsExtMode() )
3906
0
                            {
3907
                                // don't start a selection when an
3908
                                // URL field or a graphic is clicked
3909
0
                                bool bSttSelect = rSh.HasSelection() ||
3910
0
                                                PointerStyle::RefHand != GetPointer();
3911
3912
0
                                if( !bSttSelect )
3913
0
                                {
3914
0
                                    bSttSelect = true;
3915
0
                                    if( bExecHyperlinks )
3916
0
                                    {
3917
0
                                        SwContentAtPos aContentAtPos(
3918
0
                                            IsAttrAtPos::Footnote |
3919
0
                                            IsAttrAtPos::InetAttr );
3920
3921
0
                                        if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) )
3922
0
                                        {
3923
0
                                            if( !rSh.IsViewLocked() &&
3924
0
                                                !rSh.IsReadOnlyAvailable() &&
3925
0
                                                aContentAtPos.IsInProtectSect() )
3926
0
                                                    bLockView = true;
3927
3928
0
                                            bSttSelect = false;
3929
0
                                        }
3930
0
                                        else if( rSh.IsURLGrfAtPos( aDocPos ))
3931
0
                                            bSttSelect = false;
3932
0
                                    }
3933
0
                                }
3934
3935
0
                                if( bSttSelect )
3936
0
                                    rSh.SttSelect();
3937
0
                            }
3938
0
                        }
3939
0
                        bCallBase = false;
3940
0
                        break;
3941
0
                    }
3942
0
                    default:
3943
0
                        if( !rSh.IsViewLocked() )
3944
0
                        {
3945
0
                            SwContentAtPos aContentAtPos( IsAttrAtPos::ClickField |
3946
0
                                                        IsAttrAtPos::InetAttr );
3947
0
                            if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) &&
3948
0
                                !rSh.IsReadOnlyAvailable() &&
3949
0
                                aContentAtPos.IsInProtectSect() )
3950
0
                                bLockView = true;
3951
0
                        }
3952
0
                }
3953
3954
0
                if ( rSh.IsGCAttr() )
3955
0
                {
3956
0
                    rSh.GCAttr();
3957
0
                    rSh.ClearGCAttr();
3958
0
                }
3959
3960
0
                SwContentAtPos aFieldAtPos(IsAttrAtPos::Field);
3961
0
                bool bEditableFieldClicked = false;
3962
3963
                // Are we clicking on a field?
3964
0
                if (rSh.GetContentAtPos(aDocPos, aFieldAtPos))
3965
0
                {
3966
0
                    bool bEditableField = (aFieldAtPos.pFndTextAttr != nullptr
3967
0
                        && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD);
3968
3969
0
                    if (!bEditableField)
3970
0
                    {
3971
0
                        rSh.CallSetCursor(&aDocPos, bOnlyText);
3972
                        // Unfortunately the cursor may be on field
3973
                        // position or on position after field depending on which
3974
                        // half of the field was clicked on.
3975
0
                        SwTextAttr const*const pTextField(aFieldAtPos.pFndTextAttr);
3976
0
                        if (pTextField &&
3977
0
                            rSh.GetCurrentShellCursor().GetPoint()->GetContentIndex() != pTextField->GetStart())
3978
0
                        {
3979
0
                            assert(rSh.GetCurrentShellCursor().GetPoint()->GetContentIndex() == (pTextField->GetStart() + 1));
3980
0
                            rSh.Left( SwCursorSkipMode::Chars, false, 1, false );
3981
0
                        }
3982
                        // don't go into the !bOverSelect block below - it moves
3983
                        // the cursor
3984
0
                        break;
3985
0
                    }
3986
0
                    else
3987
0
                    {
3988
0
                        bEditableFieldClicked = true;
3989
0
                    }
3990
0
                }
3991
3992
0
                bool bOverSelect = rSh.TestCurrPam( aDocPos );
3993
0
                bool bOverURLGrf = false;
3994
0
                if( !bOverSelect )
3995
0
                    bOverURLGrf = bOverSelect = nullptr != rSh.IsURLGrfAtPos( aDocPos );
3996
3997
0
                if ( !bOverSelect || rSh.IsInSelect() )
3998
0
                {
3999
0
                    MoveCursor( rSh, aDocPos, bOnlyText, bLockView);
4000
0
                    bCallBase = false;
4001
0
                }
4002
0
                if (!bOverURLGrf && !bExecDrawTextLink && !bOnlyText)
4003
0
                {
4004
0
                    const SelectionType nSelType = rSh.GetSelectionType();
4005
                    // Check in general, if an object is selectable at given position.
4006
                    // Thus, also text fly frames in background become selectable via Ctrl-Click.
4007
0
                    if ( ( nSelType & SelectionType::Ole ||
4008
0
                         nSelType & SelectionType::Graphic ||
4009
0
                         rSh.IsObjSelectable( aDocPos ) ) && !lcl_urlOverBackground( rSh, aDocPos ) )
4010
0
                    {
4011
0
                        SwMvContext aMvContext( &rSh );
4012
0
                        rSh.EnterSelFrameMode();
4013
0
                        bCallBase = false;
4014
0
                    }
4015
0
                }
4016
0
                if ( !bOverSelect && bEditableFieldClicked && (!pCursorField ||
4017
0
                     pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField()))
4018
0
                {
4019
                    // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
4020
                    // and CH_TXT_ATR_INPUTFIELDEND
4021
0
                    rSh.SttSelect();
4022
0
                    rSh.SelectTextModel( aFieldAtPos.pFndTextAttr->GetStart() + 1,
4023
0
                                 *(aFieldAtPos.pFndTextAttr->End()) - 1 );
4024
0
                }
4025
                // don't reset here any longer so that, in case through MouseMove
4026
                // with pressed Ctrl key a multiple-selection should happen,
4027
                // the previous selection is not released in Drag.
4028
0
                break;
4029
0
            }
4030
0
        }
4031
0
    }
4032
0
    else if (MOUSE_RIGHT == aMEvt.GetButtons())
4033
0
    {
4034
        // If right-click while dragging to resize the comment width, stop resizing
4035
0
        if (mbIsDragSidebar)
4036
0
        {
4037
0
            ReleaseCommentGuideLine();
4038
0
            ReleaseMouse();
4039
0
            return;
4040
0
        }
4041
4042
0
        if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()
4043
0
            && aMEvt.GetModifier() == KEY_MOD1)
4044
0
        {
4045
            // ctrl+right-click on outline node frame
4046
0
            SwContentAtPos aContentAtPos(IsAttrAtPos::Outline);
4047
0
            if(rSh.GetContentAtPos(aDocPos, aContentAtPos))
4048
0
            {
4049
0
                SwOutlineNodes::size_type nPos;
4050
0
                if (rSh.GetNodes().GetOutLineNds().Seek_Entry(aContentAtPos.aFnd.pNode, &nPos))
4051
0
                {
4052
0
                    ToggleOutlineContentVisibility(nPos, !rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent());
4053
0
                    return;
4054
0
                }
4055
0
            }
4056
0
        }
4057
0
        else if (!aMEvt.GetModifier() && static_cast<sal_uInt8>(aMEvt.GetClicks() % 4) == 1
4058
0
                 && !rSh.TestCurrPam(aDocPos))
4059
0
        {
4060
0
            SwContentAtPos aFieldAtPos(IsAttrAtPos::Field);
4061
4062
            // Are we clicking on a field?
4063
0
            if (g_bValidCursorPos
4064
0
                    && rSh.GetContentAtPos(aDocPos, aFieldAtPos)
4065
0
                    && aFieldAtPos.pFndTextAttr != nullptr
4066
0
                    && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD
4067
0
                    && (!pCursorField || pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField()))
4068
0
            {
4069
                // Move the cursor
4070
0
                MoveCursor( rSh, aDocPos, rSh.IsObjSelectable( aDocPos ), m_bWasShdwCursor );
4071
0
                bCallBase = false;
4072
4073
                // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
4074
                // and CH_TXT_ATR_INPUTFIELDEND
4075
0
                rSh.SttSelect();
4076
0
                rSh.SelectTextModel( aFieldAtPos.pFndTextAttr->GetStart() + 1,
4077
0
                                *(aFieldAtPos.pFndTextAttr->End()) - 1 );
4078
0
            }
4079
0
        }
4080
0
    }
4081
4082
0
    if (bCallBase)
4083
0
        Window::MouseButtonDown(aMEvt);
4084
0
}
4085
4086
bool SwEditWin::changeMousePointer(Point const & rDocPoint)
4087
0
{
4088
0
    SwWrtShell & rShell = m_rView.GetWrtShell();
4089
4090
0
    SwTab nMouseTabCol;
4091
4092
0
    if ( SwTab::COL_NONE != (nMouseTabCol = rShell.WhichMouseTabCol( rDocPoint ) ) &&
4093
0
         ( !rShell.IsObjSelectable( rDocPoint ) ||
4094
             // allow resizing row height, if the image is anchored as character in the cell
4095
0
             !( SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol ) ) )
4096
0
    {
4097
0
        PointerStyle nPointer = PointerStyle::Null;
4098
0
        bool bChkTableSel = false;
4099
4100
0
        switch ( nMouseTabCol )
4101
0
        {
4102
0
            case SwTab::COL_VERT :
4103
0
            case SwTab::ROW_HORI :
4104
0
                nPointer = PointerStyle::VSizeBar;
4105
0
                bChkTableSel = true;
4106
0
                break;
4107
0
            case SwTab::ROW_VERT :
4108
0
            case SwTab::COL_HORI :
4109
0
                nPointer = PointerStyle::HSizeBar;
4110
0
                bChkTableSel = true;
4111
0
                break;
4112
            // Enhanced table selection
4113
0
            case SwTab::SEL_HORI :
4114
0
                nPointer = PointerStyle::TabSelectSE;
4115
0
                break;
4116
0
            case SwTab::SEL_HORI_RTL :
4117
0
            case SwTab::SEL_VERT :
4118
0
                nPointer = PointerStyle::TabSelectSW;
4119
0
                break;
4120
0
            case SwTab::COLSEL_HORI :
4121
0
            case SwTab::ROWSEL_VERT :
4122
0
                nPointer = PointerStyle::TabSelectS;
4123
0
                break;
4124
0
            case SwTab::ROWSEL_HORI :
4125
0
                nPointer = PointerStyle::TabSelectE;
4126
0
                break;
4127
0
            case SwTab::ROWSEL_HORI_RTL :
4128
0
            case SwTab::COLSEL_VERT :
4129
0
                nPointer = PointerStyle::TabSelectW;
4130
0
                break;
4131
0
            default: break; // prevent compiler warning
4132
0
        }
4133
4134
0
        if ( PointerStyle::Null != nPointer &&
4135
            // i#35543 - Enhanced table selection is explicitly allowed in table mode
4136
0
            ( !bChkTableSel || !rShell.IsTableMode() ) &&
4137
0
            !comphelper::LibreOfficeKit::isActive() )
4138
0
        {
4139
0
            SetPointer( nPointer );
4140
0
        }
4141
4142
0
        return true;
4143
0
    }
4144
0
    else if (rShell.IsNumLabel(rDocPoint, RULER_MOUSE_MARGINWIDTH))
4145
0
    {
4146
        // i#42921 - consider vertical mode
4147
0
        SwTextNode* pNodeAtPos = rShell.GetNumRuleNodeAtPos( rDocPoint );
4148
0
        const PointerStyle nPointer =
4149
0
                SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos, rDocPoint )
4150
0
                ? PointerStyle::VSizeBar
4151
0
                : PointerStyle::HSizeBar;
4152
0
        SetPointer( nPointer );
4153
4154
0
        return true;
4155
0
    }
4156
0
    return false;
4157
0
}
4158
4159
void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
4160
0
{
4161
0
    MouseEvent rMEvt(_rMEvt);
4162
4163
0
    if (comphelper::LibreOfficeKit::isActive())
4164
0
    {
4165
0
        if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel()))
4166
0
        {
4167
0
            pWindow->MouseMove(rMEvt);
4168
0
            return;
4169
0
        }
4170
0
    }
4171
4172
0
    if (m_rView.GetPostItMgr()->IsHitSidebarDragArea(rMEvt.GetPosPixel()))
4173
0
    {
4174
0
        SetPointer(PointerStyle::HSizeBar);
4175
0
        return;
4176
0
    }
4177
4178
0
    if (mbIsDragSidebar)
4179
0
    {
4180
0
        DrawCommentGuideLine(rMEvt.GetPosPixel());
4181
0
        return;
4182
0
    }
4183
4184
    //ignore key modifiers for format paintbrush
4185
0
    {
4186
0
        bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
4187
0
                                &&  m_pApplyTempl->m_pFormatClipboard->HasContent();
4188
0
        if( bExecFormatPaintbrush )
4189
0
            rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(),
4190
0
                                    _rMEvt.GetMode(), _rMEvt.GetButtons() );
4191
0
    }
4192
4193
    // as long as an action is running the MouseMove should be disconnected
4194
    // otherwise bug 40102 occurs
4195
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
4196
0
    if( rSh.ActionPend() )
4197
0
        return ;
4198
4199
0
    if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
4200
0
    {
4201
        // add/remove outline content hide button
4202
0
        const SwNodes& rNds = rSh.GetDoc()->GetNodes();
4203
0
        SwOutlineNodes::size_type nPos;
4204
0
        SwContentAtPos aSwContentAtPos(IsAttrAtPos::Outline);
4205
0
        if (rSh.GetContentAtPos(PixelToLogic(rMEvt.GetPosPixel()), aSwContentAtPos))
4206
0
        {
4207
            // mouse pointer is on an outline paragraph node
4208
0
            if(aSwContentAtPos.aFnd.pNode && aSwContentAtPos.aFnd.pNode->IsTextNode())
4209
0
            {
4210
                // Get the outline paragraph frame and compare it to the saved outline frame. If they
4211
                // are not the same, remove the fold button from the saved outline frame, if not
4212
                // already removed, and then add a fold button to the mouse over outline frame if
4213
                // the content is not folded.
4214
0
                SwContentFrame* pContentFrame =
4215
0
                        aSwContentAtPos.aFnd.pNode->GetTextNode()->getLayoutFrame(rSh.GetLayout());
4216
0
                if (pContentFrame != m_pSavedOutlineFrame)
4217
0
                {
4218
0
                    if (m_pSavedOutlineFrame)
4219
0
                    {
4220
0
                        if (m_pSavedOutlineFrame->isFrameAreaDefinitionValid())
4221
0
                        {
4222
0
                            SwTextNode* pTextNode = m_pSavedOutlineFrame->GetTextNodeFirst();
4223
0
                            if (pTextNode && rNds.GetOutLineNds().Seek_Entry(pTextNode, &nPos) &&
4224
0
                                    rSh.GetAttrOutlineContentVisible(nPos))
4225
0
                            {
4226
0
                                GetFrameControlsManager().RemoveControlsByType(
4227
0
                                            FrameControlType::Outline, m_pSavedOutlineFrame);
4228
0
                            }
4229
0
                        }
4230
0
                    }
4231
0
                    m_pSavedOutlineFrame = static_cast<SwTextFrame*>(pContentFrame);
4232
0
                }
4233
                // show fold button if outline content is visible
4234
0
                if (rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), &nPos) &&
4235
0
                        rSh.GetAttrOutlineContentVisible(nPos))
4236
0
                    GetFrameControlsManager().SetOutlineContentVisibilityButton(pContentFrame);
4237
0
            }
4238
0
        }
4239
0
        else if (m_pSavedOutlineFrame)
4240
0
        {
4241
            // The saved frame may not still be in the document, e.g., when an outline paragraph
4242
            // is deleted. This causes the call to GetTextNodeFirst to behave badly. Use
4243
            // isFrameAreaDefinitionValid to check if the frame is still in the document.
4244
0
            if (m_pSavedOutlineFrame->isFrameAreaDefinitionValid())
4245
0
            {
4246
                // current pointer pos is not over an outline frame
4247
                // previous pointer pos was over an outline frame
4248
                // remove outline content visibility button if showing
4249
0
                SwTextNode* pTextNode = m_pSavedOutlineFrame->GetTextNodeFirst();
4250
0
                if (pTextNode && rNds.GetOutLineNds().Seek_Entry(pTextNode, &nPos) &&
4251
0
                        rSh.GetAttrOutlineContentVisible(nPos))
4252
0
                {
4253
0
                    GetFrameControlsManager().RemoveControlsByType(
4254
0
                                FrameControlType::Outline, m_pSavedOutlineFrame);
4255
0
                }
4256
0
            }
4257
0
            m_pSavedOutlineFrame = nullptr;
4258
0
        }
4259
0
    }
4260
4261
0
    if( m_pShadCursor && 0 != (rMEvt.GetModifier() + rMEvt.GetButtons() ) )
4262
0
    {
4263
0
        m_pShadCursor.reset();
4264
0
    }
4265
4266
0
    bool bIsViewReadOnly = m_rView.GetDocShell()->IsReadOnly() || (rSh.GetSfxViewShell() && rSh.GetSfxViewShell()->IsLokReadOnlyView());
4267
4268
0
    CurrShell aCurr( &rSh );
4269
4270
    //aPixPt == Point in Pixel, relative to ChildWin
4271
    //aDocPt == Point in Twips, document coordinates
4272
0
    const Point aPixPt( rMEvt.GetPosPixel() );
4273
0
    const Point aDocPt( PixelToLogic( aPixPt ) );
4274
4275
0
    if ( IsChainMode() )
4276
0
    {
4277
0
        UpdatePointer( aDocPt, rMEvt.GetModifier() );
4278
0
        return;
4279
0
    }
4280
4281
0
    SdrView *pSdrView = rSh.GetDrawView();
4282
4283
0
    const SwCallMouseEvent aLastCallEvent( m_aSaveCallEvent );
4284
0
    m_aSaveCallEvent.Clear();
4285
4286
0
    if ( !bIsViewReadOnly && pSdrView && pSdrView->MouseMove(rMEvt,GetOutDev()) )
4287
0
    {
4288
0
        SetPointer( PointerStyle::Text );
4289
0
        return; // evaluate SdrView's event
4290
0
    }
4291
4292
0
    const Point aOldPt( rSh.VisArea().Pos() );
4293
0
    const bool bInsWin = rSh.VisArea().Contains( aDocPt ) || comphelper::LibreOfficeKit::isActive();
4294
4295
0
    if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
4296
0
    {
4297
0
        if (m_pSavedOutlineFrame && !bInsWin)
4298
0
        {
4299
            // the mouse pointer has left the building (edit window)
4300
            // remove the outline content visibility button if showing
4301
0
            if (m_pSavedOutlineFrame->isFrameAreaDefinitionValid())
4302
0
            {
4303
0
                const SwNodes& rNds = rSh.GetDoc()->GetNodes();
4304
0
                SwOutlineNodes::size_type nPos;
4305
0
                SwTextNode* pTextNode = m_pSavedOutlineFrame->GetTextNodeFirst();
4306
0
                if (pTextNode && rNds.GetOutLineNds().Seek_Entry(pTextNode, &nPos) &&
4307
0
                        rSh.GetAttrOutlineContentVisible(nPos))
4308
0
                {
4309
0
                    GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline,
4310
0
                                                                   m_pSavedOutlineFrame);
4311
0
                }
4312
0
            }
4313
0
            m_pSavedOutlineFrame = nullptr;
4314
0
        }
4315
0
    }
4316
4317
0
    if( m_pShadCursor && !bInsWin )
4318
0
    {
4319
0
        m_pShadCursor.reset();
4320
0
    }
4321
4322
0
    if( bInsWin && m_xRowColumnSelectionStart )
4323
0
    {
4324
0
        EnterArea();
4325
0
        Point aPos( aDocPt );
4326
0
        if( rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag ))
4327
0
            return;
4328
0
    }
4329
4330
    // position is necessary for OS/2 because obviously after a MB-Down
4331
    // a MB-Move is called immediately.
4332
0
    if( g_bDDTimerStarted )
4333
0
    {
4334
0
        Point aDD( SwEditWin::s_nDDStartPosX, SwEditWin::s_nDDStartPosY );
4335
0
        aDD = LogicToPixel( aDD );
4336
0
        tools::Rectangle aRect( aDD.X()-3, aDD.Y()-3, aDD.X()+3, aDD.Y()+3 );
4337
0
        if ( !aRect.Contains( aPixPt ) )
4338
0
            StopDDTimer( &rSh, aDocPt );
4339
0
    }
4340
4341
0
    if(m_rView.GetDrawFuncPtr())
4342
0
    {
4343
0
        if( m_bInsDraw  )
4344
0
        {
4345
0
            m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
4346
0
            if ( !bInsWin )
4347
0
            {
4348
0
                Point aTmp( aDocPt );
4349
0
                aTmp += rSh.VisArea().Pos() - aOldPt;
4350
0
                LeaveArea( aTmp );
4351
0
            }
4352
0
            else
4353
0
                EnterArea();
4354
0
            return;
4355
0
        }
4356
0
        else if(!rSh.IsFrameSelected() && !rSh.GetSelectedObjCount())
4357
0
        {
4358
0
            SfxBindings &rBnd = rSh.GetView().GetViewFrame().GetBindings();
4359
0
            Point aRelPos = rSh.GetRelativePagePosition(aDocPt);
4360
0
            if(aRelPos.X() >= 0)
4361
0
            {
4362
0
                FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &GetView())  != nullptr );
4363
0
                SwModule::get()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
4364
0
                const SfxPointItem aTmp1( SID_ATTR_POSITION, aRelPos );
4365
0
                rBnd.SetState( aTmp1 );
4366
0
            }
4367
0
            else
4368
0
            {
4369
0
                rBnd.Invalidate(SID_ATTR_POSITION);
4370
0
            }
4371
0
            rBnd.Invalidate(SID_ATTR_SIZE);
4372
0
            const SvxStatusItem aCell( SID_TABLE_CELL, OUString(), StatusCategory::NONE );
4373
0
            rBnd.SetState( aCell );
4374
0
        }
4375
0
    }
4376
4377
    // determine if we only change the mouse pointer and return
4378
0
    if (!bIsViewReadOnly && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() && changeMousePointer(aDocPt))
4379
0
    {
4380
0
        return;
4381
0
    }
4382
4383
0
    bool bDelShadCursor = true;
4384
4385
0
    switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
4386
0
    {
4387
0
        case MOUSE_LEFT:
4388
0
            if( m_pAnchorMarker )
4389
0
            {
4390
                // Now we need to refresh the SdrHdl pointer of m_pAnchorMarker.
4391
                // This looks a little bit tricky, but it solves the following
4392
                // problem: the m_pAnchorMarker contains a pointer to an SdrHdl,
4393
                // if the FindAnchorPos-call cause a scrolling of the visible
4394
                // area, it's possible that the SdrHdl will be destroyed and a
4395
                // new one will initialized at the original position(GetHdlPos).
4396
                // So the m_pAnchorMarker has to find the right SdrHdl, if it's
4397
                // the old one, it will find it with position aOld, if this one
4398
                // is destroyed, it will find a new one at position GetHdlPos().
4399
4400
0
                const Point aOld = m_pAnchorMarker->GetPosForHitTest( *(rSh.GetOut()) );
4401
0
                Point aNew = rSh.FindAnchorPos( aDocPt );
4402
0
                SdrHdl* pHdl;
4403
0
                if( pSdrView && (nullptr!=( pHdl = pSdrView->PickHandle( aOld ) )||
4404
0
                    nullptr !=(pHdl = pSdrView->PickHandle( m_pAnchorMarker->GetHdlPos()) ) ) &&
4405
0
                        ( pHdl->GetKind() == SdrHdlKind::Anchor ||
4406
0
                          pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
4407
0
                {
4408
0
                    m_pAnchorMarker->ChgHdl( pHdl );
4409
0
                    if( aNew.X() || aNew.Y() )
4410
0
                    {
4411
0
                        m_pAnchorMarker->SetPos( aNew );
4412
0
                        m_pAnchorMarker->SetLastPos( aDocPt );
4413
0
                    }
4414
0
                }
4415
0
                else
4416
0
                {
4417
0
                    m_pAnchorMarker.reset();
4418
0
                }
4419
0
            }
4420
0
            if ( m_bInsDraw )
4421
0
            {
4422
0
                if ( !m_bMBPressed )
4423
0
                    break;
4424
0
                if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
4425
0
                {
4426
0
                    if ( !bInsWin )
4427
0
                        LeaveArea( aDocPt );
4428
0
                    else
4429
0
                        EnterArea();
4430
0
                    if ( m_rView.GetDrawFuncPtr() )
4431
0
                    {
4432
0
                        pSdrView->SetOrtho(false);
4433
0
                        m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
4434
0
                    }
4435
0
                    m_bIsInMove = true;
4436
0
                }
4437
0
                return;
4438
0
            }
4439
4440
0
            {
4441
0
            SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
4442
0
            if (pWrdCnt)
4443
0
                pWrdCnt->UpdateCounts();
4444
0
            }
4445
0
            [[fallthrough]];
4446
4447
0
        case MOUSE_LEFT + KEY_SHIFT:
4448
0
        case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
4449
0
            if ( !m_bMBPressed )
4450
0
                break;
4451
0
            [[fallthrough]];
4452
0
        case MOUSE_LEFT + KEY_MOD1:
4453
0
            if ( g_bFrameDrag && rSh.IsSelFrameMode() )
4454
0
            {
4455
0
                if( !m_bMBPressed )
4456
0
                    break;
4457
4458
0
                if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
4459
0
                {
4460
                    // event processing for resizing
4461
0
                    if (pSdrView && pSdrView->GetMarkedObjectList().GetMarkCount() != 0)
4462
0
                    {
4463
0
                        const Point aSttPt( PixelToLogic( m_aStartPos ) );
4464
4465
                        // can we start?
4466
0
                        if( SdrHdlKind::User == g_eSdrMoveHdl )
4467
0
                        {
4468
0
                            SdrHdl* pHdl = pSdrView->PickHandle( aSttPt );
4469
0
                            g_eSdrMoveHdl = pHdl ? pHdl->GetKind() : SdrHdlKind::Move;
4470
0
                        }
4471
4472
0
                        const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat());
4473
0
                        const SvxMacro* pMacro = nullptr;
4474
4475
0
                        SvMacroItemId nEvent = SdrHdlKind::Move == g_eSdrMoveHdl
4476
0
                                            ? SvMacroItemId::SwFrmMove
4477
0
                                            : SvMacroItemId::SwFrmResize;
4478
4479
0
                        if (nullptr != pFlyFormat)
4480
0
                            pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent);
4481
0
                        if (nullptr != pMacro &&
4482
                        // or notify only e.g. every 20 Twip?
4483
0
                            m_aRszMvHdlPt != aDocPt )
4484
0
                        {
4485
0
                            m_aRszMvHdlPt = aDocPt;
4486
0
                            sal_uInt32 nPos = 0;
4487
0
                            SbxArrayRef xArgs = new SbxArray;
4488
0
                            SbxVariableRef xVar = new SbxVariable;
4489
0
                            xVar->PutString( pFlyFormat->GetName().toString() );
4490
0
                            xArgs->Put(xVar.get(), ++nPos);
4491
4492
0
                            if( SvMacroItemId::SwFrmResize == nEvent )
4493
0
                            {
4494
0
                                xVar = new SbxVariable;
4495
0
                                xVar->PutUShort( static_cast< sal_uInt16 >(g_eSdrMoveHdl) );
4496
0
                                xArgs->Put(xVar.get(), ++nPos);
4497
0
                            }
4498
4499
0
                            xVar = new SbxVariable;
4500
0
                            xVar->PutLong( aDocPt.X() - aSttPt.X() );
4501
0
                            xArgs->Put(xVar.get(), ++nPos);
4502
0
                            xVar = new SbxVariable;
4503
0
                            xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
4504
0
                            xArgs->Put(xVar.get(), ++nPos);
4505
4506
0
                            OUString sRet;
4507
4508
0
                            ReleaseMouse();
4509
4510
0
                            rSh.ExecMacro( *pMacro, &sRet, xArgs.get() );
4511
4512
0
                            CaptureMouse();
4513
4514
0
                            if( !sRet.isEmpty() && sRet.toInt32()!=0 )
4515
0
                                return ;
4516
0
                        }
4517
0
                    }
4518
                    // event processing for resizing
4519
4520
0
                    if( bIsViewReadOnly )
4521
0
                        break;
4522
4523
0
                    bool bResizeKeepRatio = rSh.GetSelectionType() & SelectionType::Graphic ||
4524
0
                                            rSh.GetSelectionType() & SelectionType::Media ||
4525
0
                                            rSh.GetSelectionType() & SelectionType::Ole;
4526
0
                    bool bisResize = g_eSdrMoveHdl != SdrHdlKind::Move;
4527
4528
0
                    if (pSdrView)
4529
0
                    {
4530
                        // Resize proportionally when media is selected and the user drags on a corner
4531
0
                        const Point aSttPt(PixelToLogic(m_aStartPos));
4532
0
                        SdrHdl* pHdl = pSdrView->PickHandle(aSttPt);
4533
0
                        if (pHdl)
4534
0
                            bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl();
4535
4536
0
                        if (pSdrView->GetDragMode() == SdrDragMode::Crop)
4537
0
                            bisResize = false;
4538
0
                        if (rMEvt.IsShift())
4539
0
                        {
4540
0
                            pSdrView->SetAngleSnapEnabled(!bResizeKeepRatio);
4541
0
                            if (bisResize)
4542
0
                                pSdrView->SetOrtho(!bResizeKeepRatio);
4543
0
                            else
4544
0
                                pSdrView->SetOrtho(true);
4545
0
                        }
4546
0
                        else
4547
0
                        {
4548
0
                            pSdrView->SetAngleSnapEnabled(bResizeKeepRatio);
4549
0
                            if (bisResize)
4550
0
                                pSdrView->SetOrtho(bResizeKeepRatio);
4551
0
                            else
4552
0
                                pSdrView->SetOrtho(false);
4553
0
                        }
4554
0
                    }
4555
4556
0
                    rSh.Drag( &aDocPt, rMEvt.IsShift() );
4557
0
                    m_bIsInMove = true;
4558
0
                }
4559
0
                else if( bIsViewReadOnly )
4560
0
                    break;
4561
4562
0
                if ( !bInsWin )
4563
0
                {
4564
0
                    Point aTmp( aDocPt );
4565
0
                    aTmp += rSh.VisArea().Pos() - aOldPt;
4566
0
                    LeaveArea( aTmp );
4567
0
                }
4568
0
                else if(m_bIsInMove)
4569
0
                    EnterArea();
4570
0
                return;
4571
0
            }
4572
0
            if ( !rSh.IsSelFrameMode() && !g_bDDINetAttr &&
4573
0
                (IsMinMove( m_aStartPos,aPixPt ) || m_bIsInMove) &&
4574
0
                (rSh.IsInSelect() || !rSh.TestCurrPam( aDocPt )) )
4575
0
            {
4576
0
                if ( pSdrView )
4577
0
                {
4578
0
                    if ( rMEvt.IsShift() )
4579
0
                        pSdrView->SetOrtho(true);
4580
0
                    else
4581
0
                        pSdrView->SetOrtho(false);
4582
0
                }
4583
0
                if ( !bInsWin )
4584
0
                {
4585
0
                    Point aTmp( aDocPt );
4586
0
                    aTmp += rSh.VisArea().Pos() - aOldPt;
4587
0
                    LeaveArea( aTmp );
4588
0
                }
4589
0
                else
4590
0
                {
4591
0
                    if( !rMEvt.IsSynthetic() &&
4592
0
                        ( MOUSE_LEFT != rMEvt.GetButtons() ||
4593
0
                          KEY_MOD1 != rMEvt.GetModifier() ||
4594
0
                          !rSh.Is_FnDragEQBeginDrag() ||
4595
0
                          rSh.IsAddMode() ) )
4596
0
                    {
4597
0
                        rSh.Drag( &aDocPt, false );
4598
0
                        g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false,
4599
0
                            ScrollSizeMode::ScrollSizeMouseSelection));
4600
0
                        EnterArea();
4601
0
                    }
4602
0
                }
4603
0
            }
4604
0
            g_bDDINetAttr = false;
4605
0
            break;
4606
0
        case 0:
4607
0
        {
4608
0
            if ( m_pApplyTempl )
4609
0
            {
4610
0
                UpdatePointer(aDocPt); // maybe a frame has to be marked here
4611
0
                break;
4612
0
            }
4613
            // change ui if mouse is over SwPostItField
4614
            // TODO: do the same thing for redlines IsAttrAtPos::Redline
4615
0
            SwContentAtPos aContentAtPos( IsAttrAtPos::Field);
4616
0
            if (rSh.GetContentAtPos(aDocPt, aContentAtPos, false))
4617
0
            {
4618
0
                const SwField* pField = aContentAtPos.aFnd.pField;
4619
0
                if (pField->Which()== SwFieldIds::Postit)
4620
0
                {
4621
0
                    m_rView.GetPostItMgr()->SetShadowState(reinterpret_cast<const SwPostItField*>(pField),false);
4622
0
                }
4623
0
                else
4624
0
                    m_rView.GetPostItMgr()->SetShadowState(nullptr,false);
4625
0
            }
4626
0
            else
4627
0
                m_rView.GetPostItMgr()->SetShadowState(nullptr,false);
4628
0
            [[fallthrough]];
4629
0
        }
4630
0
        case KEY_SHIFT:
4631
0
        case KEY_MOD2:
4632
0
        case KEY_MOD1:
4633
0
            if ( !m_bInsDraw )
4634
0
            {
4635
0
                bool bTstShdwCursor = true;
4636
4637
0
                UpdatePointer( aDocPt, rMEvt.GetModifier() );
4638
4639
0
                const SwFrameFormat* pFormat = nullptr;
4640
0
                const SwFormatINetFormat* pINet = nullptr;
4641
0
                SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
4642
0
                if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) )
4643
0
                    pINet = static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr);
4644
4645
0
                const void* pTmp = pINet;
4646
4647
0
                if( pINet ||
4648
0
                    nullptr != ( pTmp = pFormat = rSh.GetFormatFromAnyObj( aDocPt )))
4649
0
                {
4650
0
                    bTstShdwCursor = false;
4651
0
                    if( pTmp == pINet )
4652
0
                        m_aSaveCallEvent.Set( pINet );
4653
0
                    else
4654
0
                    {
4655
0
                        IMapObject* pIMapObj = pFormat->GetIMapObject( aDocPt );
4656
0
                        if( pIMapObj )
4657
0
                            m_aSaveCallEvent.Set( pFormat, pIMapObj );
4658
0
                        else
4659
0
                            m_aSaveCallEvent.Set( EVENT_OBJECT_URLITEM, pFormat );
4660
0
                    }
4661
4662
                    // should be over an InternetField with an
4663
                    // embedded macro?
4664
0
                    if( m_aSaveCallEvent != aLastCallEvent )
4665
0
                    {
4666
0
                        if( aLastCallEvent.HasEvent() )
4667
0
                            rSh.CallEvent( SvMacroItemId::OnMouseOut,
4668
0
                                            aLastCallEvent, true );
4669
                        // 0 says that the object doesn't have any table
4670
0
                        if( !rSh.CallEvent( SvMacroItemId::OnMouseOver,
4671
0
                                        m_aSaveCallEvent ))
4672
0
                            m_aSaveCallEvent.Clear();
4673
0
                    }
4674
0
                }
4675
0
                else if( aLastCallEvent.HasEvent() )
4676
0
                {
4677
                    // cursor was on an object
4678
0
                    rSh.CallEvent( SvMacroItemId::OnMouseOut,
4679
0
                                    aLastCallEvent, true );
4680
0
                }
4681
4682
0
                if( bTstShdwCursor && bInsWin && !bIsViewReadOnly &&
4683
0
                    !m_bInsFrame &&
4684
0
                    !rSh.GetViewOptions()->getBrowseMode() &&
4685
0
                    rSh.GetViewOptions()->IsShadowCursor() &&
4686
0
                    !(rMEvt.GetModifier() + rMEvt.GetButtons()) &&
4687
0
                    !rSh.HasSelection() && !GetOutDev()->GetConnectMetaFile() )
4688
0
                {
4689
0
                    SwRect aRect;
4690
4691
0
                    SwFillMode eMode = rSh.GetViewOptions()->GetShdwCursorFillMode();
4692
0
                    if( rSh.GetShadowCursorPos( aDocPt, eMode, aRect, m_eOrient ))
4693
0
                    {
4694
0
                        if( !m_pShadCursor )
4695
0
                            m_pShadCursor.reset( new SwShadowCursor( *this ) );
4696
0
                        if( text::HoriOrientation::RIGHT != m_eOrient && text::HoriOrientation::CENTER != m_eOrient )
4697
0
                            m_eOrient = text::HoriOrientation::LEFT;
4698
0
                        m_pShadCursor->SetPos( aRect.Pos(), aRect.Height(), static_cast< sal_uInt16 >(m_eOrient) );
4699
0
                        bDelShadCursor = false;
4700
0
                    }
4701
0
                }
4702
0
            }
4703
0
            break;
4704
0
        case MOUSE_LEFT + KEY_MOD2:
4705
0
            if( rSh.IsBlockMode() && !rMEvt.IsSynthetic() )
4706
0
            {
4707
0
                rSh.Drag( &aDocPt, false );
4708
0
                g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false));
4709
0
                EnterArea();
4710
0
            }
4711
0
        break;
4712
0
    }
4713
4714
0
    if( bDelShadCursor && m_pShadCursor )
4715
0
    {
4716
0
        m_pShadCursor.reset();
4717
0
    }
4718
0
    m_bWasShdwCursor = false;
4719
0
}
4720
4721
/**
4722
 * Button Up
4723
 */
4724
void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
4725
0
{
4726
0
    if (comphelper::LibreOfficeKit::isActive())
4727
0
    {
4728
0
        if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel()))
4729
0
        {
4730
0
            pWindow->MouseButtonUp(rMEvt);
4731
0
            return;
4732
0
        }
4733
0
    }
4734
4735
0
    if (mbIsDragSidebar)
4736
0
    {
4737
0
        SetSidebarWidth(rMEvt.GetPosPixel());
4738
        // While dragging the mouse is captured, so we need to release it here
4739
0
        ReleaseMouse();
4740
0
        ReleaseCommentGuideLine();
4741
0
        return;
4742
0
    }
4743
4744
0
    bool bCallBase = true;
4745
4746
0
    bool bCallShadowCursor = m_bWasShdwCursor;
4747
0
    m_bWasShdwCursor = false;
4748
0
    if( m_pShadCursor )
4749
0
    {
4750
0
        m_pShadCursor.reset();
4751
0
    }
4752
4753
0
    m_xRowColumnSelectionStart.reset();
4754
4755
0
    SdrHdlKind eOldSdrMoveHdl = g_eSdrMoveHdl;
4756
0
    g_eSdrMoveHdl = SdrHdlKind::User;     // for MoveEvents - reset again
4757
4758
    // preventively reset
4759
0
    m_rView.SetTabColFromDoc( false );
4760
0
    m_rView.SetNumRuleNodeFromDoc(nullptr);
4761
4762
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
4763
0
    CurrShell aCurr( &rSh );
4764
0
    SdrView *pSdrView = rSh.GetDrawView();
4765
0
    if ( pSdrView )
4766
0
    {
4767
        // tdf34555: ortho was always reset before being used in EndSdrDrag
4768
        // Now, it is reset only if not in Crop mode.
4769
0
        if (pSdrView->GetDragMode() != SdrDragMode::Crop && !rMEvt.IsShift())
4770
0
            pSdrView->SetOrtho(false);
4771
4772
0
        if ( pSdrView->MouseButtonUp( rMEvt,GetOutDev() ) )
4773
0
        {
4774
0
            rSh.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
4775
0
            return; // SdrView's event evaluated
4776
0
        }
4777
4778
0
        const Point aDocPos(PixelToLogic(rMEvt.GetPosPixel()));
4779
0
        SdrHdl* pHdl(pSdrView->PickHandle(aDocPos));
4780
4781
0
        if (nullptr != pHdl)
4782
0
        {
4783
0
            SdrObject* pSingleObj(nullptr);
4784
0
            const SdrMarkList& rMarkList(pSdrView->GetMarkedObjectList());
4785
4786
0
            if (1 == rMarkList.GetMarkCount())
4787
0
                pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
4788
4789
0
            if (nullptr != pSingleObj)
4790
0
            {
4791
                // Check for click on svx::diagram::DiagramFrameHdl
4792
                // - if we hit a SdrHdl
4793
                // - if single object is selected
4794
                //   - and it is a Diagram
4795
0
                if(pHdl && nullptr != pSingleObj && pSingleObj->isDiagram())
4796
0
                {
4797
0
                    svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl));
4798
0
                    if(nullptr != pDiagramFrameHdl)
4799
0
                    {
4800
                        // let the DiagramFrameHdl decide what to do
4801
0
                        svx::diagram::DiagramFrameHdl::clicked(aDocPos);
4802
0
                    }
4803
0
                }
4804
0
            }
4805
0
        }
4806
4807
4808
0
    }
4809
    // only process MouseButtonUp when the Down went to that windows as well.
4810
0
    if ( !m_bMBPressed )
4811
0
    {
4812
    // Undo for the watering can is already in CommandHdl
4813
    // that's the way it should be!
4814
4815
0
        return;
4816
0
    }
4817
4818
0
    Point aDocPt( PixelToLogic( rMEvt.GetPosPixel() ) );
4819
4820
0
    if ( g_bDDTimerStarted )
4821
0
    {
4822
0
        StopDDTimer( &rSh, aDocPt );
4823
0
        m_bMBPressed = false;
4824
0
        if ( rSh.IsSelFrameMode() )
4825
0
        {
4826
0
            rSh.EndDrag( &aDocPt, false );
4827
0
            g_bFrameDrag = false;
4828
0
        }
4829
0
        g_bNoInterrupt = false;
4830
0
        const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) );
4831
0
        if ((PixelToLogic(m_aStartPos).Y() == (aDocPos.Y())) && (PixelToLogic(m_aStartPos).X() == (aDocPos.X())))//To make sure it was not moved
4832
0
        {
4833
0
            SdrPageView* pPV = nullptr;
4834
0
            SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr;
4835
0
            if (pObj)
4836
0
            {
4837
0
                if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
4838
0
                {
4839
0
                    SwFrameFormat* pFormat = pContact->GetFormat();
4840
0
                    SwFrameFormat* pShapeFormat
4841
0
                        = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT);
4842
0
                    if (!pShapeFormat)
4843
0
                    {
4844
0
                        pSdrView->UnmarkAllObj();
4845
0
                        rSh.SelectObj(aDocPos, SW_FROM_CLICK, pObj);
4846
0
                        if (rMEvt.IsLeft() && rMEvt.GetClicks() == 1 &&
4847
0
                            SwModule::get()->GetUsrPref(
4848
0
                                dynamic_cast<const SwWebView*>(&m_rView) != nullptr)->
4849
0
                            IsClickChangeRotation())
4850
0
                            m_rView.ToggleRotate();
4851
0
                    }
4852
0
                    else
4853
0
                    {
4854
                        // If the fly frame is a textbox of a shape, then select the shape instead.
4855
0
                        SdrObject* pShape = pShapeFormat->FindSdrObject();
4856
0
                        pSdrView->UnmarkAllObj();
4857
0
                        rSh.SelectObj(aDocPos, SW_ALLOW_TEXTBOX, pShape);
4858
0
                    }
4859
0
                }
4860
0
            }
4861
0
        }
4862
0
        ReleaseMouse();
4863
0
        return;
4864
0
    }
4865
4866
0
    if( m_pAnchorMarker )
4867
0
    {
4868
0
        if(m_pAnchorMarker->GetHdl())
4869
0
        {
4870
            // #i121463# delete selected after drag
4871
0
            m_pAnchorMarker->GetHdl()->SetSelected(false);
4872
0
        }
4873
4874
0
        Point aPnt( m_pAnchorMarker->GetLastPos() );
4875
0
        m_pAnchorMarker.reset();
4876
0
        if( aPnt.X() || aPnt.Y() )
4877
0
            rSh.FindAnchorPos( aPnt, true );
4878
0
    }
4879
0
    if ( m_bInsDraw && m_rView.GetDrawFuncPtr() )
4880
0
    {
4881
0
        if ( m_rView.GetDrawFuncPtr()->MouseButtonUp( rMEvt ) )
4882
0
        {
4883
0
            if (m_rView.GetDrawFuncPtr()) // could have been destroyed in MouseButtonUp
4884
0
            {
4885
0
                m_rView.GetDrawFuncPtr()->Deactivate();
4886
4887
0
                if (!m_rView.IsDrawMode())
4888
0
                {
4889
0
                    m_rView.SetDrawFuncPtr(nullptr);
4890
0
                    SfxBindings& rBind = m_rView.GetViewFrame().GetBindings();
4891
0
                    rBind.Invalidate( SID_ATTR_SIZE );
4892
0
                    rBind.Invalidate( SID_TABLE_CELL );
4893
0
                }
4894
0
            }
4895
4896
0
            if ( rSh.GetSelectedObjCount() )
4897
0
            {
4898
0
                rSh.EnterSelFrameMode();
4899
0
                if (!m_rView.GetDrawFuncPtr())
4900
0
                    StdDrawMode( SdrObjKind::NONE, true );
4901
0
            }
4902
0
            else if ( rSh.IsFrameSelected() )
4903
0
            {
4904
0
                rSh.EnterSelFrameMode();
4905
0
                StopInsFrame();
4906
0
            }
4907
0
            else
4908
0
            {
4909
0
                const Point aDocPos( PixelToLogic( m_aStartPos ) );
4910
0
                g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
4911
0
                rSh.Edit();
4912
0
            }
4913
4914
0
            m_rView.AttrChangedNotify(nullptr);
4915
0
        }
4916
0
        else if (rMEvt.GetButtons() == MOUSE_RIGHT && rSh.IsDrawCreate())
4917
0
            m_rView.GetDrawFuncPtr()->BreakCreate();   // abort drawing
4918
4919
0
        g_bNoInterrupt = false;
4920
0
        if (IsMouseCaptured())
4921
0
            ReleaseMouse();
4922
0
        return;
4923
0
    }
4924
0
    bool bPopMode = false;
4925
0
    switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
4926
0
    {
4927
0
        case MOUSE_LEFT:
4928
0
            if ( m_bInsDraw && rSh.IsDrawCreate() )
4929
0
            {
4930
0
                if ( m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->MouseButtonUp(rMEvt) )
4931
0
                {
4932
0
                    m_rView.GetDrawFuncPtr()->Deactivate();
4933
0
                    m_rView.AttrChangedNotify(nullptr);
4934
0
                    if ( rSh.GetSelectedObjCount() )
4935
0
                        rSh.EnterSelFrameMode();
4936
0
                    if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
4937
0
                        StopInsFrame();
4938
0
                }
4939
0
                bCallBase = false;
4940
0
                break;
4941
0
            }
4942
0
            [[fallthrough]];
4943
0
        case MOUSE_LEFT + KEY_MOD1:
4944
0
        case MOUSE_LEFT + KEY_MOD2:
4945
0
        case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
4946
0
            if ( g_bFrameDrag && rSh.IsSelFrameMode() )
4947
0
            {
4948
0
                if ( rMEvt.IsMod1() ) // copy and don't move.
4949
0
                {
4950
                    // abort drag, use internal Copy instead
4951
0
                    tools::Rectangle aRect;
4952
0
                    rSh.GetDrawView()->TakeActionRect( aRect );
4953
0
                    if (!aRect.IsEmpty())
4954
0
                    {
4955
0
                        rSh.BreakDrag();
4956
0
                        Point aEndPt, aSttPt;
4957
0
                        if ( rSh.GetSelFrameType() & FrameTypeFlags::FLY_ATCNT )
4958
0
                        {
4959
0
                            aEndPt = aRect.TopLeft();
4960
0
                            aSttPt = rSh.GetDrawView()->GetAllMarkedRect().TopLeft();
4961
0
                        }
4962
0
                        else
4963
0
                        {
4964
0
                            aEndPt = aRect.Center();
4965
0
                            aSttPt = rSh.GetDrawView()->GetAllMarkedRect().Center();
4966
0
                        }
4967
0
                        if ( aSttPt != aEndPt )
4968
0
                        {
4969
0
                            rSh.StartUndo( SwUndoId::UI_DRAG_AND_COPY );
4970
0
                            rSh.Copy(rSh, aSttPt, aEndPt);
4971
0
                            rSh.EndUndo( SwUndoId::UI_DRAG_AND_COPY );
4972
0
                        }
4973
0
                    }
4974
0
                    else {
4975
0
                        rSh.EndDrag( &aDocPt, false );
4976
0
                    }
4977
0
                }
4978
0
                else
4979
0
                {
4980
0
                    {
4981
0
                        const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat());
4982
0
                        const SvxMacro* pMacro = nullptr;
4983
4984
0
                        SvMacroItemId nEvent = SdrHdlKind::Move == eOldSdrMoveHdl
4985
0
                                            ? SvMacroItemId::SwFrmMove
4986
0
                                            : SvMacroItemId::SwFrmResize;
4987
4988
0
                        if (nullptr != pFlyFormat)
4989
0
                            pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent);
4990
0
                        if (nullptr != pMacro)
4991
0
                        {
4992
0
                            const Point aSttPt( PixelToLogic( m_aStartPos ) );
4993
0
                            m_aRszMvHdlPt = aDocPt;
4994
0
                            sal_uInt32 nPos = 0;
4995
0
                            SbxArrayRef xArgs = new SbxArray;
4996
0
                            SbxVariableRef xVar = new SbxVariable;
4997
0
                            xVar->PutString( pFlyFormat->GetName().toString() );
4998
0
                            xArgs->Put(xVar.get(), ++nPos);
4999
5000
0
                            if( SvMacroItemId::SwFrmResize == nEvent )
5001
0
                            {
5002
0
                                xVar = new SbxVariable;
5003
0
                                xVar->PutUShort( static_cast< sal_uInt16 >(eOldSdrMoveHdl) );
5004
0
                                xArgs->Put(xVar.get(), ++nPos);
5005
0
                            }
5006
5007
0
                            xVar = new SbxVariable;
5008
0
                            xVar->PutLong( aDocPt.X() - aSttPt.X() );
5009
0
                            xArgs->Put(xVar.get(), ++nPos);
5010
0
                            xVar = new SbxVariable;
5011
0
                            xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
5012
0
                            xArgs->Put(xVar.get(), ++nPos);
5013
5014
0
                            xVar = new SbxVariable;
5015
0
                            xVar->PutUShort( 1 );
5016
0
                            xArgs->Put(xVar.get(), ++nPos);
5017
5018
0
                            ReleaseMouse();
5019
5020
0
                            rSh.ExecMacro( *pMacro, nullptr, xArgs.get() );
5021
5022
0
                            CaptureMouse();
5023
0
                        }
5024
5025
0
                        if (pFlyFormat)
5026
0
                        {
5027
                            // See if the fly frame's anchor is in a content control. If so,
5028
                            // interact with it.
5029
0
                            const SwFormatAnchor& rFormatAnchor = pFlyFormat->GetAnchor();
5030
0
                            SwNode* pAnchorNode = rFormatAnchor.GetAnchorNode();
5031
0
                            if (pAnchorNode)
5032
0
                            {
5033
0
                                SwTextNode* pTextNode = pAnchorNode->GetTextNode();
5034
0
                                if (pTextNode)
5035
0
                                {
5036
0
                                    SwTextAttr* pAttr = pTextNode->GetTextAttrAt(
5037
0
                                        rFormatAnchor.GetAnchorContentOffset(), RES_TXTATR_CONTENTCONTROL,
5038
0
                                        ::sw::GetTextAttrMode::Parent);
5039
0
                                    if (pAttr)
5040
0
                                    {
5041
0
                                        SwTextContentControl* pTextContentControl
5042
0
                                            = static_txtattr_cast<SwTextContentControl*>(pAttr);
5043
0
                                        const SwFormatContentControl& rFormatContentControl
5044
0
                                            = pTextContentControl->GetContentControl();
5045
0
                                        rSh.GotoContentControl(rFormatContentControl);
5046
0
                                    }
5047
0
                                }
5048
0
                            }
5049
0
                        }
5050
0
                    }
5051
0
                    rSh.EndDrag( &aDocPt, false );
5052
0
                }
5053
0
                g_bFrameDrag = false;
5054
0
                bCallBase = false;
5055
0
                break;
5056
0
            }
5057
0
            bPopMode = true;
5058
0
            [[fallthrough]];
5059
0
        case MOUSE_LEFT + KEY_SHIFT:
5060
0
            if (rSh.IsSelFrameMode())
5061
0
            {
5062
5063
0
                rSh.EndDrag( &aDocPt, false );
5064
0
                g_bFrameDrag = false;
5065
0
                bCallBase = false;
5066
0
                break;
5067
0
            }
5068
5069
0
            if( g_bHoldSelection )
5070
0
            {
5071
                // the EndDrag should be called in any case
5072
0
                g_bHoldSelection = false;
5073
0
                rSh.EndDrag( &aDocPt, false );
5074
0
            }
5075
0
            else
5076
0
            {
5077
0
                SwContentAtPos aFieldAtPos (IsAttrAtPos::Field);
5078
0
                if ( !rSh.IsInSelect() && rSh.TestCurrPam( aDocPt ) &&
5079
0
                     !rSh.GetContentAtPos( aDocPt, aFieldAtPos ) )
5080
0
                {
5081
0
                    const bool bTmpNoInterrupt = g_bNoInterrupt;
5082
0
                    g_bNoInterrupt = false;
5083
0
                    {   // create only temporary move context because otherwise
5084
                        // the query to the content form doesn't work!!!
5085
0
                        SwMvContext aMvContext( &rSh );
5086
0
                        const Point aDocPos( PixelToLogic( m_aStartPos ) );
5087
0
                        g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
5088
0
                    }
5089
0
                    g_bNoInterrupt = bTmpNoInterrupt;
5090
5091
0
                }
5092
0
                else
5093
0
                {
5094
0
                    bool bInSel = rSh.IsInSelect();
5095
0
                    rSh.EndDrag( &aDocPt, false );
5096
5097
                    // Internetfield? --> call link (load doc!!)
5098
0
                    if( !bInSel )
5099
0
                    {
5100
0
                        LoadUrlFlags nFilter = LoadUrlFlags::NONE;
5101
0
                        if( KEY_MOD1 == rMEvt.GetModifier() )
5102
0
                            nFilter |= LoadUrlFlags::NewView;
5103
5104
0
                        bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
5105
0
                        if ( !bExecHyperlinks )
5106
0
                        {
5107
0
                            const bool bSecureOption = SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink );
5108
0
                            if ( (  bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) ||
5109
0
                                 ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) )
5110
0
                                bExecHyperlinks = true;
5111
0
                        }
5112
5113
0
                        const bool bExecSmarttags = rMEvt.GetModifier() == KEY_MOD1;
5114
5115
0
                        if(m_pApplyTempl)
5116
0
                            bExecHyperlinks = false;
5117
5118
0
                        SwContentAtPos aContentAtPos( IsAttrAtPos::Field |
5119
0
                                                    IsAttrAtPos::InetAttr |
5120
0
                                                    IsAttrAtPos::SmartTag  | IsAttrAtPos::FormControl |
5121
0
                                                    IsAttrAtPos::ContentControl);
5122
5123
0
                        if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) )
5124
0
                        {
5125
                            // Do it again if we're not on a field/hyperlink to update the cursor accordingly
5126
0
                            if ( IsAttrAtPos::Field != aContentAtPos.eContentAtPos
5127
0
                                 && IsAttrAtPos::InetAttr != aContentAtPos.eContentAtPos )
5128
0
                                rSh.GetContentAtPos( aDocPt, aContentAtPos, true );
5129
5130
0
                            bool bViewLocked = rSh.IsViewLocked();
5131
0
                            if( !bViewLocked && !rSh.IsReadOnlyAvailable() &&
5132
0
                                aContentAtPos.IsInProtectSect() )
5133
0
                                rSh.LockView( true );
5134
5135
0
                            ReleaseMouse();
5136
5137
0
                            if( IsAttrAtPos::Field == aContentAtPos.eContentAtPos )
5138
0
                            {
5139
0
                                bool bAddMode(false);
5140
                                // AdditionalMode if applicable
5141
0
                                if (KEY_MOD1 == rMEvt.GetModifier()
5142
0
                                    && !rSh.IsAddMode())
5143
0
                                {
5144
0
                                    bAddMode = true;
5145
0
                                    rSh.EnterAddMode();
5146
0
                                }
5147
0
                                if ( aContentAtPos.pFndTextAttr != nullptr
5148
0
                                     && aContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD )
5149
0
                                {
5150
0
                                    if (!rSh.IsInSelect())
5151
0
                                    {
5152
                                        // create only temporary move context because otherwise
5153
                                        // the query to the content form doesn't work!!!
5154
0
                                        SwMvContext aMvContext( &rSh );
5155
0
                                        const Point aDocPos( PixelToLogic( m_aStartPos ) );
5156
0
                                        g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
5157
0
                                    }
5158
0
                                    else
5159
0
                                    {
5160
0
                                        g_bValidCursorPos = true;
5161
0
                                    }
5162
0
                                }
5163
0
                                else
5164
0
                                {
5165
0
                                    rSh.ClickToField(*aContentAtPos.aFnd.pField, bExecHyperlinks);
5166
                                    // a bit of a mystery what this is good for?
5167
                                    // in this case we assume it's valid since we
5168
                                    // just selected a field
5169
0
                                    g_bValidCursorPos = true;
5170
0
                                }
5171
0
                                if (bAddMode)
5172
0
                                {
5173
0
                                    rSh.LeaveAddMode();
5174
0
                                }
5175
0
                            }
5176
0
                            else if (aContentAtPos.eContentAtPos == IsAttrAtPos::ContentControl)
5177
0
                            {
5178
0
                                auto pTextContentControl
5179
0
                                    = static_txtattr_cast<const SwTextContentControl*>(
5180
0
                                        aContentAtPos.pFndTextAttr);
5181
0
                                const SwFormatContentControl& rFormatContentControl
5182
0
                                    = pTextContentControl->GetContentControl();
5183
0
                                rSh.GotoContentControl(rFormatContentControl);
5184
0
                            }
5185
0
                            else if ( IsAttrAtPos::SmartTag == aContentAtPos.eContentAtPos )
5186
0
                            {
5187
                                    // execute smarttag menu
5188
0
                                    if ( bExecSmarttags && SwSmartTagMgr::Get().IsSmartTagsEnabled() )
5189
0
                                        m_rView.ExecSmartTagPopup( aDocPt );
5190
0
                            }
5191
0
                            else if ( IsAttrAtPos::FormControl == aContentAtPos.eContentAtPos )
5192
0
                            {
5193
0
                                OSL_ENSURE( aContentAtPos.aFnd.pFieldmark != nullptr, "where is my field ptr???");
5194
0
                                if ( aContentAtPos.aFnd.pFieldmark != nullptr)
5195
0
                                {
5196
0
                                    Fieldmark *fieldBM = const_cast< Fieldmark* > ( aContentAtPos.aFnd.pFieldmark );
5197
0
                                    if ( fieldBM->GetFieldname( ) == ODF_FORMCHECKBOX )
5198
0
                                    {
5199
0
                                        CheckboxFieldmark& rCheckboxFm = dynamic_cast<CheckboxFieldmark&>(*fieldBM);
5200
0
                                        rCheckboxFm.SetChecked(!rCheckboxFm.IsChecked());
5201
0
                                        rCheckboxFm.Invalidate();
5202
0
                                        rSh.InvalidateWindows( SwRect(m_rView.GetVisArea()) );
5203
0
                                    }
5204
0
                                    else if ( fieldBM->GetFieldname( ) == ODF_FORMTEXT &&
5205
0
                                        static_cast< const TextFieldmark* > ( aContentAtPos.aFnd.pFieldmark )->HasDefaultContent() )
5206
0
                                    {
5207
0
                                        rSh.GotoFieldmark( aContentAtPos.aFnd.pFieldmark );
5208
0
                                    }
5209
5210
0
                                }
5211
0
                            }
5212
0
                            else if ( IsAttrAtPos::InetAttr == aContentAtPos.eContentAtPos )
5213
0
                            {
5214
0
                                if (comphelper::LibreOfficeKit::isActive())
5215
0
                                {
5216
0
                                    OUString val((*static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr)).GetValue());
5217
0
                                    if (val.startsWith("#"))
5218
0
                                        bExecHyperlinks = true;
5219
0
                                }
5220
0
                                if ( bExecHyperlinks && aContentAtPos.aFnd.pAttr )
5221
0
                                    rSh.ClickToINetAttr( *static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr), nFilter );
5222
0
                            }
5223
5224
0
                            rSh.LockView( bViewLocked );
5225
0
                            bCallShadowCursor = false;
5226
0
                        }
5227
0
                        else
5228
0
                        {
5229
0
                            aContentAtPos = SwContentAtPos( IsAttrAtPos::Footnote );
5230
0
                            if( !rSh.GetContentAtPos( aDocPt, aContentAtPos, true ) && bExecHyperlinks )
5231
0
                            {
5232
0
                                SdrViewEvent aVEvt;
5233
5234
0
                                if (pSdrView)
5235
0
                                    pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
5236
5237
0
                                if (pSdrView && aVEvt.meEvent == SdrEventKind::ExecuteUrl)
5238
0
                                {
5239
                                    // hit URL field
5240
0
                                    const SvxURLField *pField = aVEvt.mpURLField;
5241
0
                                    if (pField)
5242
0
                                    {
5243
0
                                        const OUString& sURL(pField->GetURL());
5244
0
                                        const OUString& sTarget(pField->GetTargetFrame());
5245
0
                                        ::LoadURL(rSh, sURL, nFilter, sTarget);
5246
0
                                    }
5247
0
                                    bCallShadowCursor = false;
5248
0
                                }
5249
0
                                else
5250
0
                                {
5251
                                    // hit graphic
5252
0
                                    ReleaseMouse();
5253
0
                                    if( rSh.ClickToINetGrf( aDocPt, nFilter ))
5254
0
                                        bCallShadowCursor = false;
5255
0
                                }
5256
0
                            }
5257
0
                        }
5258
5259
0
                        if( bCallShadowCursor &&
5260
0
                            rSh.GetViewOptions()->IsShadowCursor() &&
5261
0
                            MOUSE_LEFT == (rMEvt.GetModifier() + rMEvt.GetButtons()) &&
5262
0
                            !rSh.HasSelection() &&
5263
0
                            !GetOutDev()->GetConnectMetaFile() &&
5264
0
                            rSh.VisArea().Contains( aDocPt ))
5265
0
                        {
5266
0
                            SwUndoId nLastUndoId(SwUndoId::EMPTY);
5267
0
                            if (rSh.GetLastUndoInfo(nullptr, & nLastUndoId))
5268
0
                            {
5269
0
                                if (SwUndoId::INS_FROM_SHADOWCRSR == nLastUndoId)
5270
0
                                {
5271
0
                                    rSh.Undo();
5272
0
                                }
5273
0
                            }
5274
0
                            SwFillMode eMode = rSh.GetViewOptions()->GetShdwCursorFillMode();
5275
0
                            rSh.SetShadowCursorPos( aDocPt, eMode );
5276
0
                        }
5277
0
                    }
5278
0
                }
5279
0
                bCallBase = false;
5280
5281
0
            }
5282
5283
            // reset pushed mode in Down again if applicable
5284
0
            if ( bPopMode && g_bModePushed )
5285
0
            {
5286
0
                rSh.PopMode();
5287
0
                g_bModePushed = false;
5288
0
                bCallBase = false;
5289
0
            }
5290
0
            break;
5291
5292
0
        default:
5293
0
            ReleaseMouse();
5294
0
            return;
5295
0
    }
5296
5297
0
    if( m_pApplyTempl )
5298
0
    {
5299
0
        SelectionType eSelection = rSh.GetSelectionType();
5300
0
        SwFormatClipboard* pFormatClipboard = m_pApplyTempl->m_pFormatClipboard;
5301
0
        if( pFormatClipboard )//apply format paintbrush
5302
0
        {
5303
            //get some parameters
5304
0
            SwWrtShell& rWrtShell = m_rView.GetWrtShell();
5305
0
            SfxStyleSheetBasePool* pPool=nullptr;
5306
0
            bool bNoCharacterFormats = false;
5307
            // Paste paragraph properties if the selection contains a whole paragraph or
5308
            // there was no selection at all (i.e. just a left click)
5309
0
            bool bNoParagraphFormats = rSh.HasSelection() && rSh.IsSelOnePara() && !rSh.IsSelFullPara();
5310
5311
0
            {
5312
0
                SwDocShell* pDocSh = m_rView.GetDocShell();
5313
0
                if(pDocSh)
5314
0
                    pPool = pDocSh->GetStyleSheetPool();
5315
0
                if( (rMEvt.GetModifier()&KEY_MOD1) && (rMEvt.GetModifier()&KEY_SHIFT) )
5316
0
                {
5317
0
                    bNoCharacterFormats = true;
5318
0
                    bNoParagraphFormats = false;
5319
0
                }
5320
0
                else if( rMEvt.GetModifier() & KEY_MOD1 )
5321
0
                    bNoParagraphFormats = true;
5322
0
            }
5323
            //execute paste
5324
0
            pFormatClipboard->Paste( rWrtShell, pPool, bNoCharacterFormats, bNoParagraphFormats );
5325
5326
            //if the clipboard is empty after paste remove the ApplyTemplate
5327
0
            if(!pFormatClipboard->HasContent())
5328
0
                SetApplyTemplate(SwApplyTemplate());
5329
5330
            //tdf#38101 remove temporary highlighting
5331
0
            m_pUserMarker.reset();
5332
0
        }
5333
0
        else if( m_pApplyTempl->nColor )
5334
0
        {
5335
0
            sal_uInt16 nId = 0;
5336
0
            switch( m_pApplyTempl->nColor )
5337
0
            {
5338
0
                case SID_ATTR_CHAR_COLOR_EXT:
5339
0
                    nId = RES_CHRATR_COLOR;
5340
0
                    break;
5341
0
                case SID_ATTR_CHAR_BACK_COLOR:
5342
0
                case SID_ATTR_CHAR_COLOR_BACKGROUND:
5343
0
                    nId = RES_CHRATR_BACKGROUND;
5344
0
                    break;
5345
0
            }
5346
0
            if( nId && (SelectionType::Text|SelectionType::Table) & eSelection)
5347
0
            {
5348
0
                if( rSh.IsSelection() && !rSh.HasReadonlySel() )
5349
0
                {
5350
0
                    m_pApplyTempl->nUndo =
5351
0
                        std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5352
0
                    if (nId == RES_CHRATR_BACKGROUND)
5353
0
                        ApplyCharBackground(m_aWaterCanTextBackColor, model::ComplexColor(), rSh);
5354
0
                    else
5355
0
                        rSh.SetAttrItem( SvxColorItem( m_aWaterCanTextColor, nId ) );
5356
0
                    rSh.UnSetVisibleCursor();
5357
0
                    rSh.EnterStdMode();
5358
0
                    rSh.SetVisibleCursor(aDocPt);
5359
0
                    bCallBase = false;
5360
0
                    m_aTemplateTimer.Stop();
5361
0
                }
5362
0
                else if(rMEvt.GetClicks() == 1)
5363
0
                {
5364
                    // no selection -> so turn off watering can
5365
0
                    m_aTemplateTimer.Start();
5366
0
                }
5367
0
            }
5368
0
        }
5369
0
        else
5370
0
        {
5371
0
            UIName aStyleName;
5372
0
            switch ( m_pApplyTempl->eType )
5373
0
            {
5374
0
                case SfxStyleFamily::Para:
5375
0
                    if( (( SelectionType::Text | SelectionType::Table )
5376
0
                         & eSelection ) && !rSh.HasReadonlySel() )
5377
0
                    {
5378
0
                        rSh.SetTextFormatColl( m_pApplyTempl->aColl.pTextColl );
5379
0
                        m_pApplyTempl->nUndo =
5380
0
                            std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5381
0
                        bCallBase = false;
5382
0
                        if ( m_pApplyTempl->aColl.pTextColl )
5383
0
                            aStyleName = m_pApplyTempl->aColl.pTextColl->GetName();
5384
0
                    }
5385
0
                    break;
5386
0
                case SfxStyleFamily::Char:
5387
0
                    if( (( SelectionType::Text | SelectionType::Table )
5388
0
                         & eSelection ) && !rSh.HasReadonlySel() )
5389
0
                    {
5390
0
                        rSh.SetAttrItem( SwFormatCharFormat(m_pApplyTempl->aColl.pCharFormat) );
5391
0
                        rSh.UnSetVisibleCursor();
5392
0
                        rSh.EnterStdMode();
5393
0
                        rSh.SetVisibleCursor(aDocPt);
5394
0
                        m_pApplyTempl->nUndo =
5395
0
                            std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5396
0
                        bCallBase = false;
5397
0
                        if ( m_pApplyTempl->aColl.pCharFormat )
5398
0
                            aStyleName = m_pApplyTempl->aColl.pCharFormat->GetName();
5399
0
                    }
5400
0
                    break;
5401
0
                case SfxStyleFamily::Frame :
5402
0
                {
5403
0
                    const SwFrameFormat* pFormat = rSh.GetFormatFromObj( aDocPt );
5404
0
                    if(dynamic_cast<const SwFlyFrameFormat*>( pFormat) )
5405
0
                    {
5406
0
                        rSh.SetFrameFormat( m_pApplyTempl->aColl.pFrameFormat, false, &aDocPt );
5407
0
                        m_pApplyTempl->nUndo =
5408
0
                            std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5409
0
                        bCallBase = false;
5410
0
                        if( m_pApplyTempl->aColl.pFrameFormat )
5411
0
                            aStyleName = m_pApplyTempl->aColl.pFrameFormat->GetName();
5412
0
                    }
5413
0
                    break;
5414
0
                }
5415
0
                case SfxStyleFamily::Page:
5416
                    // no Undo with page templates
5417
0
                    rSh.ChgCurPageDesc( *m_pApplyTempl->aColl.pPageDesc );
5418
0
                    if ( m_pApplyTempl->aColl.pPageDesc )
5419
0
                        aStyleName = m_pApplyTempl->aColl.pPageDesc->GetName();
5420
0
                    m_pApplyTempl->nUndo =
5421
0
                        std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5422
0
                    bCallBase = false;
5423
0
                    break;
5424
0
                case SfxStyleFamily::Pseudo:
5425
0
                    if( !rSh.HasReadonlySel() )
5426
0
                    {
5427
0
                        rSh.SetCurNumRule( *m_pApplyTempl->aColl.pNumRule,
5428
0
                                           false,
5429
0
                                           m_pApplyTempl->aColl.pNumRule->GetDefaultListId() );
5430
0
                        bCallBase = false;
5431
0
                        m_pApplyTempl->nUndo =
5432
0
                            std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount());
5433
0
                        if( m_pApplyTempl->aColl.pNumRule )
5434
0
                            aStyleName = m_pApplyTempl->aColl.pNumRule->GetName();
5435
0
                    }
5436
0
                    break;
5437
0
                default: break;
5438
0
            }
5439
5440
0
            uno::Reference< frame::XDispatchRecorder > xRecorder =
5441
0
                    m_rView.GetViewFrame().GetBindings().GetRecorder();
5442
0
            if ( !aStyleName.isEmpty() && xRecorder.is() )
5443
0
            {
5444
0
                SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView );
5445
0
                if ( pSfxShell )
5446
0
                {
5447
0
                    SfxRequest aReq(m_rView.GetViewFrame(), SID_STYLE_APPLY);
5448
0
                    aReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aStyleName.toString() ) );
5449
0
                    aReq.AppendItem( SfxUInt16Item( SID_STYLE_FAMILY, static_cast<sal_uInt16>(m_pApplyTempl->eType) ) );
5450
0
                    aReq.Done();
5451
0
                }
5452
0
            }
5453
0
        }
5454
5455
0
    }
5456
0
    ReleaseMouse();
5457
    // Only processed MouseEvents arrive here; only at these this mode can
5458
    // be reset.
5459
0
    m_bMBPressed = false;
5460
5461
    // Make this call just to be sure. Selecting has finished surely by now.
5462
    // Otherwise the timeout's timer could give problems.
5463
0
    EnterArea();
5464
0
    g_bNoInterrupt = false;
5465
5466
0
    if (bCallBase)
5467
0
        Window::MouseButtonUp(rMEvt);
5468
5469
    // tdf#161717 - Track changes: Clicking on change in document should highlight related change
5470
    // in "Manage Changes" window/sidebar
5471
0
    if (m_rView.GetWrtShell().GetCurrRedline())
5472
0
    {
5473
0
        SwDocShell* pDocSh = m_rView.GetDocShell();
5474
0
        if (pDocSh)
5475
0
            pDocSh->Broadcast(SfxHint(SfxHintId::SwRedlineContentAtPos));
5476
0
    }
5477
5478
0
    if (!(pSdrView && rMEvt.GetClicks() == 1 && comphelper::LibreOfficeKit::isActive()))
5479
0
        return;
5480
5481
    // When tiled rendering, single click on a shape text starts editing already.
5482
0
    SdrViewEvent aViewEvent;
5483
0
    SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aViewEvent);
5484
0
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
5485
0
    if (eHit == SdrHitKind::TextEditObj && rMarkList.GetMarkCount() == 1)
5486
0
    {
5487
0
        if (SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj())
5488
0
        {
5489
0
            EnterDrawTextMode(pObj->GetLogicRect().Center());
5490
0
            if ( auto pSwDrawTextShell = dynamic_cast< SwDrawTextShell *>( m_rView.GetCurShell() ) )
5491
0
                pSwDrawTextShell->Init();
5492
0
        }
5493
0
    }
5494
0
}
5495
5496
/**
5497
 * Apply template
5498
 */
5499
void SwEditWin::SetApplyTemplate(const SwApplyTemplate &rTempl)
5500
0
{
5501
0
    static bool bIdle = false;
5502
0
    m_pApplyTempl.reset();
5503
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
5504
5505
0
    if(rTempl.m_pFormatClipboard)
5506
0
    {
5507
0
        m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
5508
0
        m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5509
0
        SetPointer( PointerStyle::Fill );//@todo #i20119# maybe better a new brush pointer here in future
5510
0
        rSh.NoEdit( false );
5511
0
        bIdle = rSh.GetViewOptions()->IsIdle();
5512
0
        rSh.GetViewOptions()->SetIdle( false );
5513
0
    }
5514
0
    else if(rTempl.nColor)
5515
0
    {
5516
0
        m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
5517
0
        m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5518
0
        SetPointer( PointerStyle::Fill );
5519
0
        rSh.NoEdit( false );
5520
0
        bIdle = rSh.GetViewOptions()->IsIdle();
5521
0
        rSh.GetViewOptions()->SetIdle( false );
5522
0
    }
5523
0
    else if( rTempl.eType != SfxStyleFamily::None )
5524
0
    {
5525
0
        m_pApplyTempl.reset(new SwApplyTemplate( rTempl ));
5526
0
        m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount();
5527
0
        SetPointer( PointerStyle::Fill  );
5528
0
        rSh.NoEdit( false );
5529
0
        bIdle = rSh.GetViewOptions()->IsIdle();
5530
0
        rSh.GetViewOptions()->SetIdle( false );
5531
0
    }
5532
0
    else
5533
0
    {
5534
0
        SetPointer( PointerStyle::Text );
5535
0
        rSh.UnSetVisibleCursor();
5536
5537
0
        rSh.GetViewOptions()->SetIdle( bIdle );
5538
0
        if ( !rSh.IsSelFrameMode() )
5539
0
            rSh.Edit();
5540
0
    }
5541
5542
0
    static const sal_uInt16 aInva[] =
5543
0
    {
5544
0
        SID_STYLE_WATERCAN,
5545
0
        SID_ATTR_CHAR_COLOR_EXT,
5546
0
        SID_ATTR_CHAR_COLOR_BACKGROUND_EXT,
5547
0
        0
5548
0
    };
5549
0
    m_rView.GetViewFrame().GetBindings().Invalidate(aInva);
5550
0
}
5551
5552
/**
5553
 * Ctor
5554
 */
5555
SwEditWin::SwEditWin(vcl::Window *pParent, SwView &rMyView):
5556
4.08k
    DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
5557
4.08k
    DropTargetHelper( this ),
5558
4.08k
    DragSourceHelper( this ),
5559
5560
4.08k
    m_aTimer("SwEditWin"),
5561
4.08k
    m_nTimerCalls(0),
5562
4.08k
    m_aKeyInputFlushTimer("SwEditWin m_aKeyInputFlushTimer"),
5563
4.08k
    m_eBufferLanguage(LANGUAGE_DONTKNOW),
5564
4.08k
    m_eScrollSizeMode(ScrollSizeMode::ScrollSizeMouseSelection),
5565
4.08k
    m_aTemplateTimer("SwEditWin m_aTemplateTimer"),
5566
4.08k
    m_pUserMarkerObj( nullptr ),
5567
5568
4.08k
    m_rView( rMyView ),
5569
5570
4.08k
    m_aActHitType(SdrHitKind::NONE),
5571
4.08k
    m_nDropFormat( SotClipboardFormatId::NONE ),
5572
4.08k
    m_nDropAction( 0 ),
5573
4.08k
    m_nDropDestination( SotExchangeDest::NONE ),
5574
5575
4.08k
    m_eBezierMode(SID_BEZIER_INSERT),
5576
4.08k
    m_nInsFrameColCount( 1 ),
5577
4.08k
    m_eDrawMode(SdrObjKind::NONE),
5578
5579
4.08k
    m_bMBPressed(false),
5580
4.08k
    m_bInsDraw(false),
5581
4.08k
    m_bInsFrame(false),
5582
4.08k
    m_bIsInMove(false),
5583
4.08k
    m_bIsInDrag(false),
5584
4.08k
    m_bOldIdle(false),
5585
4.08k
    m_bOldIdleSet(false),
5586
4.08k
    m_bChainMode(false),
5587
4.08k
    m_bWasShdwCursor(false),
5588
4.08k
    m_bLockInput(false),
5589
4.08k
    m_bIsRowDrag(false),
5590
4.08k
    m_bUseInputLanguage(false),
5591
4.08k
    m_bObjectSelect(false),
5592
4.08k
    mbIsDragSidebar(false),
5593
4.08k
    m_nKS_NUMDOWN_Count(0),
5594
4.08k
    m_nKS_NUMINDENTINC_Count(0),
5595
4.08k
    m_pFrameControlsManager(new SwFrameControlsManager(this))
5596
4.08k
{
5597
4.08k
    set_id(u"writer_edit"_ustr);
5598
4.08k
    SetHelpId(HID_EDIT_WIN);
5599
4.08k
    EnableChildTransparentMode();
5600
4.08k
    SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
5601
5602
4.08k
    m_bMBPressed = m_bInsDraw = m_bInsFrame =
5603
4.08k
    m_bIsInDrag = m_bOldIdle = m_bOldIdleSet = m_bChainMode = m_bWasShdwCursor = false;
5604
    // initially use the input language
5605
4.08k
    m_bUseInputLanguage = true;
5606
5607
4.08k
    SetMapMode(MapMode(MapUnit::MapTwip));
5608
5609
4.08k
    SetPointer( PointerStyle::Text );
5610
4.08k
    m_aTimer.SetInvokeHandler(LINK(this, SwEditWin, TimerHandler));
5611
5612
4.08k
    m_aKeyInputFlushTimer.SetTimeout( 20 );
5613
4.08k
    m_aKeyInputFlushTimer.SetInvokeHandler(LINK(this, SwEditWin, KeyInputFlushHandler));
5614
5615
    // TemplatePointer for colors should be reset without
5616
    // selection after single click, but not after double-click (tdf#122442)
5617
4.08k
    m_aTemplateTimer.SetTimeout(GetSettings().GetMouseSettings().GetDoubleClickTime());
5618
4.08k
    m_aTemplateTimer.SetInvokeHandler(LINK(this, SwEditWin, TemplateTimerHdl));
5619
5620
    // temporary solution!!! Should set the font of the current
5621
    // insert position at every cursor movement!
5622
4.08k
    if( !rMyView.GetDocShell()->IsReadOnly() )
5623
4.08k
    {
5624
4.08k
        SetInputContext( InputContext(vcl::Font(), InputContextFlags::Text |
5625
4.08k
                                            InputContextFlags::ExtText ) );
5626
4.08k
    }
5627
4.08k
}
Unexecuted instantiation: SwEditWin::SwEditWin(vcl::Window*, SwView&)
SwEditWin::SwEditWin(vcl::Window*, SwView&)
Line
Count
Source
5556
4.08k
    DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
5557
4.08k
    DropTargetHelper( this ),
5558
4.08k
    DragSourceHelper( this ),
5559
5560
4.08k
    m_aTimer("SwEditWin"),
5561
4.08k
    m_nTimerCalls(0),
5562
4.08k
    m_aKeyInputFlushTimer("SwEditWin m_aKeyInputFlushTimer"),
5563
4.08k
    m_eBufferLanguage(LANGUAGE_DONTKNOW),
5564
4.08k
    m_eScrollSizeMode(ScrollSizeMode::ScrollSizeMouseSelection),
5565
4.08k
    m_aTemplateTimer("SwEditWin m_aTemplateTimer"),
5566
4.08k
    m_pUserMarkerObj( nullptr ),
5567
5568
4.08k
    m_rView( rMyView ),
5569
5570
4.08k
    m_aActHitType(SdrHitKind::NONE),
5571
4.08k
    m_nDropFormat( SotClipboardFormatId::NONE ),
5572
4.08k
    m_nDropAction( 0 ),
5573
4.08k
    m_nDropDestination( SotExchangeDest::NONE ),
5574
5575
4.08k
    m_eBezierMode(SID_BEZIER_INSERT),
5576
4.08k
    m_nInsFrameColCount( 1 ),
5577
4.08k
    m_eDrawMode(SdrObjKind::NONE),
5578
5579
4.08k
    m_bMBPressed(false),
5580
4.08k
    m_bInsDraw(false),
5581
4.08k
    m_bInsFrame(false),
5582
4.08k
    m_bIsInMove(false),
5583
4.08k
    m_bIsInDrag(false),
5584
4.08k
    m_bOldIdle(false),
5585
4.08k
    m_bOldIdleSet(false),
5586
4.08k
    m_bChainMode(false),
5587
4.08k
    m_bWasShdwCursor(false),
5588
4.08k
    m_bLockInput(false),
5589
4.08k
    m_bIsRowDrag(false),
5590
4.08k
    m_bUseInputLanguage(false),
5591
4.08k
    m_bObjectSelect(false),
5592
4.08k
    mbIsDragSidebar(false),
5593
4.08k
    m_nKS_NUMDOWN_Count(0),
5594
4.08k
    m_nKS_NUMINDENTINC_Count(0),
5595
4.08k
    m_pFrameControlsManager(new SwFrameControlsManager(this))
5596
4.08k
{
5597
4.08k
    set_id(u"writer_edit"_ustr);
5598
4.08k
    SetHelpId(HID_EDIT_WIN);
5599
4.08k
    EnableChildTransparentMode();
5600
4.08k
    SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
5601
5602
4.08k
    m_bMBPressed = m_bInsDraw = m_bInsFrame =
5603
4.08k
    m_bIsInDrag = m_bOldIdle = m_bOldIdleSet = m_bChainMode = m_bWasShdwCursor = false;
5604
    // initially use the input language
5605
4.08k
    m_bUseInputLanguage = true;
5606
5607
4.08k
    SetMapMode(MapMode(MapUnit::MapTwip));
5608
5609
4.08k
    SetPointer( PointerStyle::Text );
5610
4.08k
    m_aTimer.SetInvokeHandler(LINK(this, SwEditWin, TimerHandler));
5611
5612
4.08k
    m_aKeyInputFlushTimer.SetTimeout( 20 );
5613
4.08k
    m_aKeyInputFlushTimer.SetInvokeHandler(LINK(this, SwEditWin, KeyInputFlushHandler));
5614
5615
    // TemplatePointer for colors should be reset without
5616
    // selection after single click, but not after double-click (tdf#122442)
5617
4.08k
    m_aTemplateTimer.SetTimeout(GetSettings().GetMouseSettings().GetDoubleClickTime());
5618
4.08k
    m_aTemplateTimer.SetInvokeHandler(LINK(this, SwEditWin, TemplateTimerHdl));
5619
5620
    // temporary solution!!! Should set the font of the current
5621
    // insert position at every cursor movement!
5622
4.08k
    if( !rMyView.GetDocShell()->IsReadOnly() )
5623
4.08k
    {
5624
4.08k
        SetInputContext( InputContext(vcl::Font(), InputContextFlags::Text |
5625
4.08k
                                            InputContextFlags::ExtText ) );
5626
4.08k
    }
5627
4.08k
}
5628
5629
SwEditWin::~SwEditWin()
5630
4.08k
{
5631
4.08k
    disposeOnce();
5632
4.08k
}
5633
5634
void SwEditWin::dispose()
5635
4.08k
{
5636
4.08k
    m_pShadCursor.reset();
5637
5638
4.08k
    if( s_pQuickHlpData->m_bIsDisplayed && m_rView.GetWrtShellPtr() )
5639
0
        s_pQuickHlpData->Stop( m_rView.GetWrtShell() );
5640
4.08k
    g_bExecuteDrag = false;
5641
4.08k
    m_pApplyTempl.reset();
5642
5643
4.08k
    m_rView.SetDrawFuncPtr(nullptr);
5644
5645
4.08k
    m_pUserMarker.reset();
5646
5647
4.08k
    m_pAnchorMarker.reset();
5648
5649
4.08k
    m_pFrameControlsManager->dispose();
5650
4.08k
    m_pFrameControlsManager.reset();
5651
5652
4.08k
    DragSourceHelper::dispose();
5653
4.08k
    DropTargetHelper::dispose();
5654
4.08k
    vcl::Window::dispose();
5655
4.08k
}
5656
5657
/**
5658
 * Turn on DrawTextEditMode
5659
 */
5660
void SwEditWin::EnterDrawTextMode( const Point& aDocPos )
5661
0
{
5662
0
    if ( m_rView.EnterDrawTextMode(aDocPos) )
5663
0
    {
5664
0
        if (m_rView.GetDrawFuncPtr())
5665
0
        {
5666
0
            m_rView.GetDrawFuncPtr()->Deactivate();
5667
0
            m_rView.SetDrawFuncPtr(nullptr);
5668
0
            m_rView.LeaveDrawCreate();
5669
0
        }
5670
0
        m_rView.NoRotate();
5671
0
        m_rView.AttrChangedNotify(nullptr);
5672
0
    }
5673
0
}
5674
5675
/**
5676
 * Turn on DrawMode
5677
 */
5678
bool SwEditWin::EnterDrawMode(const MouseEvent& rMEvt, const Point& aDocPos)
5679
0
{
5680
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
5681
0
    SdrView *pSdrView = rSh.GetDrawView();
5682
5683
0
    if ( m_rView.GetDrawFuncPtr() )
5684
0
    {
5685
0
        if (rSh.IsDrawCreate())
5686
0
            return true;
5687
5688
0
        bool bRet = m_rView.GetDrawFuncPtr()->MouseButtonDown( rMEvt );
5689
0
        m_rView.AttrChangedNotify(nullptr);
5690
0
        return bRet;
5691
0
    }
5692
5693
0
    if ( pSdrView && pSdrView->IsTextEdit() )
5694
0
    {
5695
0
        bool bUnLockView = !rSh.IsViewLocked();
5696
0
        rSh.LockView( true );
5697
5698
0
        rSh.EndTextEdit(); // clicked aside, end Edit
5699
0
        rSh.SelectObj( aDocPos );
5700
0
        if ( !rSh.GetSelectedObjCount() && !rSh.IsFrameSelected() )
5701
0
            rSh.LeaveSelFrameMode();
5702
0
        else
5703
0
        {
5704
0
            SwEditWin::s_nDDStartPosY = aDocPos.Y();
5705
0
            SwEditWin::s_nDDStartPosX = aDocPos.X();
5706
0
            g_bFrameDrag = true;
5707
0
        }
5708
0
        if( bUnLockView )
5709
0
            rSh.LockView( false );
5710
0
        m_rView.AttrChangedNotify(nullptr);
5711
0
        return true;
5712
0
    }
5713
0
    return false;
5714
0
}
5715
5716
bool SwEditWin::IsDrawSelMode() const
5717
0
{
5718
0
    return IsObjectSelect();
5719
0
}
5720
5721
void SwEditWin::GetFocus()
5722
0
{
5723
0
    if ( m_rView.GetPostItMgr()->HasActiveSidebarWin() )
5724
0
    {
5725
0
        m_rView.GetPostItMgr()->GrabFocusOnActiveSidebarWin();
5726
0
    }
5727
0
    else
5728
0
    {
5729
0
        m_rView.GotFocus();
5730
0
        Window::GetFocus();
5731
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
5732
0
        m_rView.GetWrtShell().InvalidateAccessibleFocus();
5733
0
#endif
5734
0
    }
5735
0
}
5736
5737
void SwEditWin::LoseFocus()
5738
0
{
5739
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
5740
0
    if (m_rView.GetWrtShellPtr())
5741
0
        m_rView.GetWrtShell().InvalidateAccessibleFocus();
5742
0
#endif
5743
0
    Window::LoseFocus();
5744
0
    if( s_pQuickHlpData && s_pQuickHlpData->m_bIsDisplayed )
5745
0
        s_pQuickHlpData->Stop( m_rView.GetWrtShell() );
5746
0
}
5747
5748
bool SwEditWin::IsViewReadonly() const
5749
0
{
5750
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
5751
0
    SfxViewShell* pNotifySh = rSh.GetSfxViewShell();
5752
0
    return (m_rView.GetDocShell()->IsReadOnly() && rSh.IsCursorReadonly()) || (pNotifySh && pNotifySh->IsLokReadOnlyView());
5753
0
}
5754
5755
void SwEditWin::Command( const CommandEvent& rCEvt )
5756
0
{
5757
0
    if (isDisposed())
5758
0
    {
5759
        // If ViewFrame dies shortly, no popup anymore!
5760
0
        Window::Command(rCEvt);
5761
0
        return;
5762
0
    }
5763
5764
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
5765
5766
    // The command event is send to the window after a possible context
5767
    // menu from an inplace client has been closed. Now we have the chance
5768
    // to deactivate the inplace client without any problem regarding parent
5769
    // windows and code on the stack.
5770
0
    SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient();
5771
0
    bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() );
5772
0
    if ( bIsOleActive && ( rCEvt.GetCommand() == CommandEventId::ContextMenu ))
5773
0
    {
5774
0
        rSh.FinishOLEObj();
5775
0
        return;
5776
0
    }
5777
5778
0
    bool bCallBase      = true;
5779
5780
0
    switch ( rCEvt.GetCommand() )
5781
0
    {
5782
0
    case CommandEventId::ContextMenu:
5783
0
    {
5784
0
            const sal_uInt16 nId = SwInputChild::GetChildWindowId();
5785
0
            SwInputChild* pChildWin = static_cast<SwInputChild*>(GetView().GetViewFrame().
5786
0
                                                GetChildWindow( nId ));
5787
5788
0
            if (m_rView.GetPostItMgr()->IsHit(rCEvt.GetMousePosPixel()))
5789
0
                return;
5790
5791
0
            Point aDocPos( PixelToLogic( rCEvt.GetMousePosPixel() ) );
5792
0
            if ( !rCEvt.IsMouseEvent() )
5793
0
                aDocPos = rSh.GetCharRect().Center();
5794
5795
            // Don't trigger the command on a frame anchored to header/footer is not editing it
5796
0
            FrameControlType eControl;
5797
0
            bool bOverFly = false;
5798
0
            bool bPageAnchored = false;
5799
0
            bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored );
5800
            // !bOverHeaderFooterFly doesn't mean we have a frame to select
5801
0
            if ( !bPageAnchored && rCEvt.IsMouseEvent( ) &&
5802
0
                 ( ( rSh.IsHeaderFooterEdit( ) && !bOverHeaderFooterFly && bOverFly ) ||
5803
0
                   ( !rSh.IsHeaderFooterEdit( ) && bOverHeaderFooterFly ) ) )
5804
0
            {
5805
0
                return;
5806
0
            }
5807
5808
0
            if((!pChildWin || pChildWin->GetView() != &m_rView) &&
5809
0
                !rSh.IsDrawCreate() && !IsDrawAction())
5810
0
            {
5811
0
                CurrShell aCurr( &rSh );
5812
0
                if (!m_pApplyTempl)
5813
0
                {
5814
0
                    if (g_bNoInterrupt)
5815
0
                    {
5816
0
                        ReleaseMouse();
5817
0
                        g_bNoInterrupt = false;
5818
0
                        m_bMBPressed = false;
5819
0
                    }
5820
0
                    if ( rCEvt.IsMouseEvent() )
5821
0
                    {
5822
0
                        SelectMenuPosition(rSh, rCEvt.GetMousePosPixel());
5823
0
                        m_rView.StopShellTimer();
5824
0
                    }
5825
0
                    const Point aPixPos = LogicToPixel( aDocPos );
5826
5827
0
                    if ( m_rView.GetDocShell()->IsReadOnly() )
5828
0
                    {
5829
0
                        SwReadOnlyPopup aROPopup(aDocPos, m_rView);
5830
5831
0
                        ui::ContextMenuExecuteEvent aEvent;
5832
0
                        aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
5833
0
                        aEvent.ExecutePosition.X = aPixPos.X();
5834
0
                        aEvent.ExecutePosition.Y = aPixPos.Y();
5835
0
                        rtl::Reference<VCLXPopupMenu> xMenu;
5836
0
                        rtl::Reference<VCLXPopupMenu> xMenuInterface = aROPopup.CreateMenuInterface();
5837
0
                        if (GetView().TryContextMenuInterception(xMenuInterface, u"private:resource/ReadonlyContextMenu"_ustr, xMenu, aEvent))
5838
0
                        {
5839
0
                            if (xMenu.is())
5840
0
                            {
5841
0
                                css::uno::Reference<css::awt::XWindowPeer> xParent(aEvent.SourceWindow, css::uno::UNO_QUERY);
5842
0
                                sal_uInt16 nExecId = xMenu->execute(xParent, css::awt::Rectangle(aPixPos.X(), aPixPos.Y(), 1, 1),
5843
0
                                                                    css::awt::PopupMenuDirection::EXECUTE_DOWN);
5844
0
                                if (!::ExecuteMenuCommand(xMenu, m_rView.GetViewFrame(), nExecId))
5845
0
                                    aROPopup.Execute(this, nExecId);
5846
0
                            }
5847
0
                            else
5848
0
                                aROPopup.Execute(this, aPixPos);
5849
0
                        }
5850
0
                    }
5851
0
                    else if (!m_rView.ExecSpellPopup(aDocPos, rCEvt.IsMouseEvent()))
5852
0
                        SfxDispatcher::ExecutePopup(this, &aPixPos);
5853
0
                }
5854
0
                else if (m_pApplyTempl->nUndo < rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount())
5855
0
                {
5856
                    // Undo until we reach the point when we entered this context.
5857
0
                    rSh.Do(SwWrtShell::UNDO);
5858
0
                }
5859
0
                bCallBase = false;
5860
0
            }
5861
0
    }
5862
0
    break;
5863
5864
0
    case CommandEventId::Wheel:
5865
0
    case CommandEventId::StartAutoScroll:
5866
0
    case CommandEventId::AutoScroll:
5867
0
            if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
5868
0
            {
5869
0
                GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
5870
0
                m_pSavedOutlineFrame = nullptr;
5871
0
            }
5872
0
            m_pShadCursor.reset();
5873
0
            bCallBase = !m_rView.HandleWheelCommands( rCEvt );
5874
0
            break;
5875
5876
0
    case CommandEventId::GestureZoom:
5877
0
    {
5878
0
        if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
5879
0
        {
5880
0
            GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
5881
0
            m_pSavedOutlineFrame = nullptr;
5882
0
        }
5883
0
        m_pShadCursor.reset();
5884
0
        bCallBase = !m_rView.HandleGestureZoomCommand(rCEvt);
5885
0
        break;
5886
0
    }
5887
5888
0
    case CommandEventId::GesturePan:
5889
0
    {
5890
0
        if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
5891
0
        {
5892
0
            GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
5893
0
            m_pSavedOutlineFrame = nullptr;
5894
0
        }
5895
0
        m_pShadCursor.reset();
5896
0
        bCallBase = !m_rView.HandleGesturePanCommand(rCEvt);
5897
0
        break;
5898
0
    }
5899
5900
0
    case CommandEventId::GestureLongPress:
5901
0
    case CommandEventId::GestureSwipe: //nothing yet
5902
0
            break;
5903
5904
0
    case CommandEventId::StartExtTextInput:
5905
0
    {
5906
0
        bool bIsViewReadOnly = IsViewReadonly();
5907
0
        if(!bIsViewReadOnly)
5908
0
        {
5909
0
            if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
5910
0
            {
5911
0
                bCallBase = false;
5912
0
                rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
5913
0
            }
5914
0
            else
5915
0
            {
5916
0
                if( rSh.HasSelection() )
5917
0
                    rSh.DelRight();
5918
5919
0
                bCallBase = false;
5920
0
                LanguageType eInputLanguage = GetInputLanguage();
5921
0
                rSh.CreateExtTextInput(eInputLanguage);
5922
0
            }
5923
0
        }
5924
0
        break;
5925
0
    }
5926
0
    case CommandEventId::EndExtTextInput:
5927
0
    {
5928
0
        bool bIsViewReadOnly = IsViewReadonly();
5929
5930
0
        if(!bIsViewReadOnly)
5931
0
        {
5932
0
            if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
5933
0
            {
5934
0
                bCallBase = false;
5935
0
                rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
5936
0
            }
5937
0
            else
5938
0
            {
5939
0
                bCallBase = false;
5940
0
                OUString sRecord = rSh.DeleteExtTextInput();
5941
0
                uno::Reference< frame::XDispatchRecorder > xRecorder =
5942
0
                        m_rView.GetViewFrame().GetBindings().GetRecorder();
5943
5944
0
                if ( !sRecord.isEmpty() )
5945
0
                {
5946
                    // convert quotes in IME text
5947
                    // works on the last input character, this is especially in Korean text often done
5948
                    // quotes that are inside of the string are not replaced!
5949
0
                    const sal_Unicode aCh = sRecord[sRecord.getLength() - 1];
5950
0
                    SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
5951
0
                    SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
5952
0
                    if(pACorr &&
5953
0
                        (( pACorr->IsAutoCorrFlag( ACFlags::ChgQuotes ) && ('\"' == aCh ))||
5954
0
                        ( pACorr->IsAutoCorrFlag( ACFlags::ChgSglQuotes ) && ( '\'' == aCh))))
5955
0
                    {
5956
0
                        rSh.DelLeft();
5957
0
                        rSh.AutoCorrect( *pACorr, aCh );
5958
0
                    }
5959
5960
0
                    if ( xRecorder.is() )
5961
0
                    {
5962
                        // determine Shell
5963
0
                        SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView );
5964
                        // generate request and record
5965
0
                        if (pSfxShell)
5966
0
                        {
5967
0
                            SfxRequest aReq(m_rView.GetViewFrame(), FN_INSERT_STRING);
5968
0
                            aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, sRecord ) );
5969
0
                            aReq.Done();
5970
0
                        }
5971
0
                    }
5972
0
                }
5973
0
            }
5974
0
        }
5975
0
    }
5976
0
    break;
5977
0
    case CommandEventId::ExtTextInput:
5978
0
    {
5979
0
        bool bIsViewReadOnly = IsViewReadonly();
5980
5981
0
        if (!bIsViewReadOnly && !rSh.HasReadonlySel())
5982
0
        {
5983
0
            if( s_pQuickHlpData->m_bIsDisplayed )
5984
0
                s_pQuickHlpData->Stop( rSh );
5985
5986
0
            if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
5987
0
            {
5988
0
                bCallBase = false;
5989
0
                rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
5990
0
            }
5991
0
            else
5992
0
            {
5993
0
                const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
5994
0
                if( pData )
5995
0
                {
5996
0
                    bCallBase = false;
5997
0
                    rSh.SetExtTextInputData( *pData );
5998
0
                }
5999
0
            }
6000
0
            uno::Reference< frame::XDispatchRecorder > xRecorder =
6001
0
                        m_rView.GetViewFrame().GetBindings().GetRecorder();
6002
0
            if(!xRecorder.is())
6003
0
            {
6004
0
                SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
6005
0
                if (!rACfg.IsAutoTextTip() || !ShowAutoText(rSh.GetChunkForAutoText()))
6006
0
                {
6007
0
                    SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
6008
0
                    if (pACorr && pACorr->GetSwFlags().bAutoCompleteWords)
6009
0
                        ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr);
6010
0
                }
6011
0
            }
6012
0
        }
6013
6014
0
        if (rSh.HasReadonlySel())
6015
0
        {
6016
            // Inform the user that the request has been ignored.
6017
0
            rSh.InfoReadOnlyDialog(true);
6018
0
        }
6019
0
    }
6020
0
    break;
6021
0
    case CommandEventId::CursorPos:
6022
        // will be handled by the base class
6023
0
        break;
6024
6025
0
    case CommandEventId::PasteSelection:
6026
0
        if( !m_rView.GetDocShell()->IsReadOnly() )
6027
0
        {
6028
0
            TransferableDataHelper aDataHelper(
6029
0
                        TransferableDataHelper::CreateFromPrimarySelection());
6030
0
            if( !aDataHelper.GetXTransferable().is() )
6031
0
                break;
6032
6033
0
            SotExchangeDest nDropDestination = GetDropDestination( rCEvt.GetMousePosPixel() );
6034
0
            if( nDropDestination == SotExchangeDest::NONE )
6035
0
                break;
6036
0
            SotClipboardFormatId nDropFormat;
6037
0
            sal_uInt8 nEventAction, nDropAction;
6038
0
            SotExchangeActionFlags nActionFlags;
6039
0
            nDropAction = SotExchange::GetExchangeAction(
6040
0
                                aDataHelper.GetDataFlavorExVector(),
6041
0
                                nDropDestination, EXCHG_IN_ACTION_COPY,
6042
0
                                EXCHG_IN_ACTION_COPY, nDropFormat,
6043
0
                                nEventAction,
6044
0
                                SotClipboardFormatId::NONE, nullptr,
6045
0
                                &nActionFlags );
6046
0
            if( EXCHG_INOUT_ACTION_NONE != nDropAction )
6047
0
            {
6048
0
                const Point aDocPt( PixelToLogic( rCEvt.GetMousePosPixel() ) );
6049
0
                SwTransferable::PasteData( aDataHelper, rSh, nDropAction, nActionFlags,
6050
0
                                    nDropFormat, nDropDestination, false,
6051
0
                                    false, &aDocPt, EXCHG_IN_ACTION_COPY,
6052
0
                                    true );
6053
0
            }
6054
0
        }
6055
0
        break;
6056
0
        case CommandEventId::ModKeyChange :
6057
0
        {
6058
0
            const CommandModKeyData* pCommandData = rCEvt.GetModKeyData();
6059
0
            if (!pCommandData->IsDown() && pCommandData->IsMod1() && !pCommandData->IsMod2())
6060
0
            {
6061
0
                sal_uInt16 nSlot = 0;
6062
0
                if(pCommandData->IsLeftShift() && !pCommandData->IsRightShift())
6063
0
                    nSlot = SID_ATTR_PARA_LEFT_TO_RIGHT;
6064
0
                else if(!pCommandData->IsLeftShift() && pCommandData->IsRightShift())
6065
0
                    nSlot = SID_ATTR_PARA_RIGHT_TO_LEFT;
6066
0
                if(nSlot && SvtCTLOptions::IsCTLFontEnabled())
6067
0
                    GetView().GetViewFrame().GetDispatcher()->Execute(nSlot);
6068
0
            }
6069
0
        }
6070
0
        break;
6071
0
        case CommandEventId::InputLanguageChange :
6072
            // i#42732 - update state of fontname if input language changes
6073
0
            g_bInputLanguageSwitched = true;
6074
0
            SetUseInputLanguage( true );
6075
0
        break;
6076
0
        case CommandEventId::SelectionChange:
6077
0
        {
6078
0
            const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
6079
0
            rSh.SttCursorMove();
6080
0
            rSh.GoStartSentence();
6081
0
            rSh.GetCursor()->GetPoint()->AdjustContent(sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetStart()));
6082
0
            rSh.SetMark();
6083
0
            rSh.GetCursor()->GetMark()->AdjustContent(sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetEnd() - pData->GetStart()));
6084
0
            rSh.EndCursorMove( true );
6085
0
        }
6086
0
        break;
6087
0
        case CommandEventId::PrepareReconversion:
6088
0
        if( rSh.HasSelection() )
6089
0
        {
6090
0
            SwPaM *pCursor = rSh.GetCursor();
6091
6092
0
            if( rSh.IsMultiSelection() )
6093
0
            {
6094
0
                if (pCursor && !pCursor->HasMark() &&
6095
0
                    pCursor->GetPoint() == pCursor->GetMark())
6096
0
                {
6097
0
                    rSh.GoPrevCursor();
6098
0
                    pCursor = rSh.GetCursor();
6099
0
                }
6100
6101
                // Cancel all selections other than the last selected one.
6102
0
                while( rSh.GetCursor()->GetNext() != rSh.GetCursor() )
6103
0
                    delete rSh.GetCursor()->GetNext();
6104
0
            }
6105
6106
0
            if( pCursor )
6107
0
            {
6108
0
                SwNodeOffset nPosNodeIdx = pCursor->GetPoint()->GetNodeIndex();
6109
0
                const sal_Int32 nPosIdx = pCursor->GetPoint()->GetContentIndex();
6110
0
                SwNodeOffset nMarkNodeIdx = pCursor->GetMark()->GetNodeIndex();
6111
0
                const sal_Int32 nMarkIdx = pCursor->GetMark()->GetContentIndex();
6112
6113
0
                if( !rSh.GetCursor()->HasMark() )
6114
0
                    rSh.GetCursor()->SetMark();
6115
6116
0
                rSh.SttCursorMove();
6117
6118
0
                if( nPosNodeIdx < nMarkNodeIdx )
6119
0
                {
6120
0
                    rSh.GetCursor()->GetPoint()->Assign(nPosNodeIdx, nPosIdx);
6121
0
                    rSh.GetCursor()->GetMark()->Assign(nPosNodeIdx,
6122
0
                        rSh.GetCursor()->GetPointContentNode()->Len());
6123
0
                }
6124
0
                else if( nPosNodeIdx == nMarkNodeIdx )
6125
0
                {
6126
0
                    rSh.GetCursor()->GetPoint()->Assign(nPosNodeIdx, nPosIdx);
6127
0
                    rSh.GetCursor()->GetMark()->Assign(nMarkNodeIdx, nMarkIdx);
6128
0
                }
6129
0
                else
6130
0
                {
6131
0
                    rSh.GetCursor()->GetMark()->Assign(nMarkNodeIdx, nMarkIdx);
6132
0
                    rSh.GetCursor()->GetPoint()->Assign(nMarkNodeIdx,
6133
0
                        rSh.GetCursor()->GetMarkContentNode()->Len());
6134
0
                }
6135
6136
0
                rSh.EndCursorMove( true );
6137
0
            }
6138
0
        }
6139
0
        break;
6140
0
        case CommandEventId::QueryCharPosition:
6141
0
        {
6142
0
            bool bVertical = rSh.IsInVerticalText();
6143
0
            const SwPosition& rPos = *rSh.GetCursor()->GetPoint();
6144
0
            SwDocShell* pDocSh = m_rView.GetDocShell();
6145
0
            SwDoc *pDoc = pDocSh->GetDoc();
6146
0
            SwExtTextInput* pInput = pDoc->GetExtTextInput( rPos.GetNode(), rPos.GetContentIndex() );
6147
0
            if ( pInput )
6148
0
            {
6149
0
                const SwPosition& rStart = *pInput->Start();
6150
0
                const SwPosition& rEnd = *pInput->End();
6151
0
                sal_Int32 nSize = rEnd.GetContentIndex() - rStart.GetContentIndex();
6152
0
                vcl::Window& rWin = rSh.GetView().GetEditWin();
6153
0
                if ( nSize == 0 )
6154
0
                {
6155
                    // When the composition does not exist, use Caret rect instead.
6156
0
                    const SwRect& aCaretRect ( rSh.GetCharRect() );
6157
0
                    tools::Rectangle aRect( aCaretRect.Left(), aCaretRect.Top(), aCaretRect.Right(), aCaretRect.Bottom() );
6158
0
                    rWin.SetCompositionCharRect( &aRect, 1, bVertical );
6159
0
                }
6160
0
                else
6161
0
                {
6162
0
                    std::unique_ptr<tools::Rectangle[]> aRects(new tools::Rectangle[ nSize ]);
6163
0
                    int nRectIndex = 0;
6164
0
                    for ( sal_Int32 nIndex = rStart.GetContentIndex(); nIndex < rEnd.GetContentIndex(); ++nIndex )
6165
0
                    {
6166
0
                        const SwPosition aPos( rStart.GetNode(), rStart.GetNode().GetContentNode(), nIndex );
6167
0
                        SwRect aRect ( rSh.GetCharRect() );
6168
0
                        rSh.GetCharRectAt( aRect, &aPos );
6169
0
                        aRects[ nRectIndex ] = tools::Rectangle( aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom() );
6170
0
                        ++nRectIndex;
6171
0
                    }
6172
0
                    rWin.SetCompositionCharRect( aRects.get(), nSize, bVertical );
6173
0
                }
6174
0
            }
6175
0
            bCallBase = false;
6176
0
        }
6177
0
        break;
6178
0
        default:
6179
0
            SAL_WARN("sw.ui", "unknown command.");
6180
0
        break;
6181
0
    }
6182
0
    if (bCallBase)
6183
0
        Window::Command(rCEvt);
6184
0
}
6185
6186
/*  i#18686 select the object/cursor at the mouse
6187
    position of the context menu request */
6188
void SwEditWin::SelectMenuPosition(SwWrtShell& rSh, const Point& rMousePos )
6189
0
{
6190
0
    const Point aDocPos( PixelToLogic( rMousePos ) );
6191
0
    const bool bIsInsideSelectedObj( rSh.IsInsideSelectedObj( aDocPos ) );
6192
    //create a synthetic mouse event out of the coordinates
6193
0
    MouseEvent aMEvt(rMousePos);
6194
0
    SdrView *pSdrView = rSh.GetDrawView();
6195
0
    if ( pSdrView )
6196
0
    {
6197
        // no close of insert_draw and reset of
6198
        // draw mode, if context menu position is inside a selected object.
6199
0
        if ( !bIsInsideSelectedObj && m_rView.GetDrawFuncPtr() )
6200
0
        {
6201
6202
0
            m_rView.GetDrawFuncPtr()->Deactivate();
6203
0
            m_rView.SetDrawFuncPtr(nullptr);
6204
0
            m_rView.LeaveDrawCreate();
6205
0
            SfxBindings& rBind = m_rView.GetViewFrame().GetBindings();
6206
0
            rBind.Invalidate( SID_ATTR_SIZE );
6207
0
            rBind.Invalidate( SID_TABLE_CELL );
6208
0
        }
6209
6210
        // if draw text is active and there's a text selection
6211
        // at the mouse position then do nothing
6212
0
        if(rSh.GetSelectionType() & SelectionType::DrawObjectEditMode)
6213
0
        {
6214
0
            OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
6215
0
            ESelection aSelection = pOLV->GetSelection();
6216
0
            if(aSelection != ESelection())
6217
0
            {
6218
0
                SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
6219
0
                bool bVertical = pOutliner->IsVertical();
6220
0
                const EditEngine& rEditEng = pOutliner->GetEditEngine();
6221
0
                Point aEEPos(aDocPos);
6222
0
                const tools::Rectangle& rOutputArea = pOLV->GetOutputArea();
6223
                // regard vertical mode
6224
0
                if(bVertical)
6225
0
                {
6226
0
                    aEEPos -= rOutputArea.TopRight();
6227
                    //invert the horizontal direction and exchange X and Y
6228
0
                    tools::Long nTemp = -aEEPos.X();
6229
0
                    aEEPos.setX( aEEPos.Y() );
6230
0
                    aEEPos.setY( nTemp );
6231
0
                }
6232
0
                else
6233
0
                    aEEPos -= rOutputArea.TopLeft();
6234
6235
0
                ESelection aCompare(rEditEng.FindDocPosition(aEEPos));
6236
                // make it a forward selection - otherwise the IsLess/IsGreater do not work :-(
6237
0
                aSelection.Adjust();
6238
0
                if(!(aCompare < aSelection) && !(aCompare > aSelection))
6239
0
                {
6240
0
                    return;
6241
0
                }
6242
0
            }
6243
6244
0
        }
6245
6246
0
        if (pSdrView->MouseButtonDown( aMEvt, GetOutDev() ) )
6247
0
        {
6248
0
            pSdrView->MouseButtonUp( aMEvt, GetOutDev() );
6249
0
            rSh.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
6250
0
            return;
6251
0
        }
6252
0
    }
6253
0
    rSh.ResetCursorStack();
6254
6255
0
    if ( EnterDrawMode( aMEvt, aDocPos ) )
6256
0
    {
6257
0
        return;
6258
0
    }
6259
0
    if ( m_rView.GetDrawFuncPtr() && m_bInsFrame )
6260
0
    {
6261
0
        StopInsFrame();
6262
0
        rSh.Edit();
6263
0
    }
6264
6265
0
    UpdatePointer( aDocPos );
6266
6267
0
    if( !rSh.IsSelFrameMode() &&
6268
0
        !GetView().GetViewFrame().GetDispatcher()->IsLocked() )
6269
0
    {
6270
        // Test if there is a draw object at that position and if it should be selected.
6271
0
        bool bShould = rSh.ShouldObjectBeSelected(aDocPos);
6272
6273
0
        if(bShould)
6274
0
        {
6275
0
            m_rView.NoRotate();
6276
0
            rSh.HideCursor();
6277
6278
0
            bool bUnLockView = !rSh.IsViewLocked();
6279
0
            rSh.LockView( true );
6280
0
            bool bSelObj = rSh.SelectObj( aDocPos );
6281
0
            if( bUnLockView )
6282
0
                rSh.LockView( false );
6283
6284
0
            if( bSelObj )
6285
0
            {
6286
                // in case the frame was deselected in the macro
6287
                // just the cursor has to be displayed again.
6288
0
                if( FrameTypeFlags::NONE == rSh.GetSelFrameType() )
6289
0
                    rSh.ShowCursor();
6290
0
                else
6291
0
                {
6292
0
                    if (rSh.IsFrameSelected() && m_rView.GetDrawFuncPtr())
6293
0
                    {
6294
0
                        m_rView.GetDrawFuncPtr()->Deactivate();
6295
0
                        m_rView.SetDrawFuncPtr(nullptr);
6296
0
                        m_rView.LeaveDrawCreate();
6297
0
                        m_rView.AttrChangedNotify(nullptr);
6298
0
                    }
6299
6300
0
                    rSh.EnterSelFrameMode( &aDocPos );
6301
0
                    g_bFrameDrag = true;
6302
0
                    UpdatePointer( aDocPos );
6303
0
                    return;
6304
0
                }
6305
0
            }
6306
6307
0
            if (!m_rView.GetDrawFuncPtr())
6308
0
                rSh.ShowCursor();
6309
0
        }
6310
0
    }
6311
0
    else if ( rSh.IsSelFrameMode() &&
6312
0
              (m_aActHitType == SdrHitKind::NONE ||
6313
0
               !bIsInsideSelectedObj))
6314
0
    {
6315
0
        m_rView.NoRotate();
6316
0
        bool bUnLockView = !rSh.IsViewLocked();
6317
0
        rSh.LockView( true );
6318
6319
0
        if ( rSh.IsSelFrameMode() )
6320
0
        {
6321
0
            rSh.UnSelectFrame();
6322
0
            rSh.LeaveSelFrameMode();
6323
0
            m_rView.AttrChangedNotify(nullptr);
6324
0
        }
6325
6326
0
        bool bSelObj = rSh.SelectObj( aDocPos, 0/*nFlag*/ );
6327
0
        if( bUnLockView )
6328
0
            rSh.LockView( false );
6329
6330
0
        if( !bSelObj )
6331
0
        {
6332
            // move cursor here so that it is not drawn in the
6333
            // frame at first; ShowCursor() happens in LeaveSelFrameMode()
6334
0
            g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false));
6335
0
            rSh.LeaveSelFrameMode();
6336
0
            m_rView.LeaveDrawCreate();
6337
0
            m_rView.AttrChangedNotify(nullptr);
6338
0
        }
6339
0
        else
6340
0
        {
6341
0
            rSh.HideCursor();
6342
0
            rSh.EnterSelFrameMode( &aDocPos );
6343
0
            rSh.SelFlyGrabCursor();
6344
0
            rSh.MakeSelVisible();
6345
0
            g_bFrameDrag = true;
6346
0
            if( rSh.IsFrameSelected() &&
6347
0
                m_rView.GetDrawFuncPtr() )
6348
0
            {
6349
0
                m_rView.GetDrawFuncPtr()->Deactivate();
6350
0
                m_rView.SetDrawFuncPtr(nullptr);
6351
0
                m_rView.LeaveDrawCreate();
6352
0
                m_rView.AttrChangedNotify(nullptr);
6353
0
            }
6354
0
            UpdatePointer( aDocPos );
6355
0
        }
6356
0
    }
6357
0
    else if ( rSh.IsSelFrameMode() && bIsInsideSelectedObj )
6358
0
    {
6359
        // Object at the mouse cursor is already selected - do nothing
6360
0
        return;
6361
0
    }
6362
6363
0
    if ( rSh.IsGCAttr() )
6364
0
    {
6365
0
        rSh.GCAttr();
6366
0
        rSh.ClearGCAttr();
6367
0
    }
6368
6369
0
    bool bOverSelect = rSh.TestCurrPam( aDocPos );
6370
0
    bool bOverURLGrf = false;
6371
0
    if( !bOverSelect )
6372
0
        bOverURLGrf = bOverSelect = nullptr != rSh.IsURLGrfAtPos( aDocPos );
6373
6374
0
    if ( !bOverSelect )
6375
0
    {
6376
        // create only temporary move context because otherwise
6377
        // the query against the content form doesn't work!!!
6378
0
        SwMvContext aMvContext( &rSh );
6379
0
        if (rSh.HasSelection())
6380
0
            rSh.ResetSelect(&aDocPos, false, ScrollSizeMode::ScrollSizeDefault);
6381
0
        rSh.SwCursorShell::SetCursor(aDocPos, false, /*Block=*/false, /*FieldInfo=*/true);
6382
0
    }
6383
0
    if( !bOverURLGrf )
6384
0
    {
6385
0
        const SelectionType nSelType = rSh.GetSelectionType();
6386
0
        if( nSelType == SelectionType::Ole ||
6387
0
            nSelType == SelectionType::Graphic )
6388
0
        {
6389
0
            SwMvContext aMvContext( &rSh );
6390
0
            if( !rSh.IsFrameSelected() )
6391
0
                rSh.GotoNextFly();
6392
0
            rSh.EnterSelFrameMode();
6393
0
        }
6394
0
    }
6395
0
}
6396
6397
void SwEditWin::DrawCommentGuideLine(Point aPointPixel)
6398
0
{
6399
0
    const Point aPointLogic = PixelToLogic(aPointPixel);
6400
6401
0
    sw::sidebarwindows::SidebarPosition eSidebarPosition
6402
0
        = m_rView.GetPostItMgr()->GetSidebarPos(aPointLogic);
6403
0
    if (eSidebarPosition == sw::sidebarwindows::SidebarPosition::NONE) // should never happen
6404
0
        return;
6405
6406
0
    tools::Long nPosX;
6407
0
    sal_uInt16 nZoom = m_rView.GetWrtShell().GetViewOptions()->GetZoom();
6408
0
    if (eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT)
6409
0
    {
6410
0
        tools::Long nSidebarRectLeft
6411
0
            = LogicToPixel(m_rView.GetPostItMgr()->GetSidebarRect(aPointLogic).TopLeft()).X();
6412
0
        tools::Long nPxWidth = aPointPixel.X() - nSidebarRectLeft;
6413
0
        nPosX = nSidebarRectLeft + std::clamp<tools::Long>(nPxWidth, 1 * nZoom, 8 * nZoom);
6414
0
    }
6415
0
    else
6416
0
    {
6417
0
        tools::Long nSidebarRectRight
6418
0
            = LogicToPixel(m_rView.GetPostItMgr()->GetSidebarRect(aPointLogic).TopRight()).X();
6419
0
        tools::Long nPxWidth = nSidebarRectRight - aPointPixel.X();
6420
0
        nPosX = nSidebarRectRight - std::clamp<tools::Long>(nPxWidth, 1 * nZoom, 8 * nZoom);
6421
0
    }
6422
6423
6424
    // We need two InvertTracking calls here to "erase" the previous and draw the new position at each mouse move
6425
0
    InvertTracking(aLastCommentSidebarPos, ShowTrackFlags::Clip | ShowTrackFlags::Split);
6426
0
    const tools::Long nHeight = GetOutDev()->GetOutputSizePixel().Height();
6427
0
    aLastCommentSidebarPos
6428
0
        = tools::Rectangle(PixelToLogic(Point(nPosX, 0)), PixelToLogic(Point(nPosX, nHeight)));
6429
0
    InvertTracking(aLastCommentSidebarPos, ShowTrackFlags::Clip | ShowTrackFlags::Split);
6430
0
}
6431
6432
void SwEditWin::ReleaseCommentGuideLine()
6433
0
{
6434
0
    InvertTracking(aLastCommentSidebarPos, ShowTrackFlags::Clip | ShowTrackFlags::Split);
6435
0
    aLastCommentSidebarPos = tools::Rectangle();
6436
0
    mbIsDragSidebar = false;
6437
0
}
6438
6439
void SwEditWin::SetSidebarWidth(const Point& rPointPixel)
6440
0
{
6441
0
    if (aLastCommentSidebarPos.IsEmpty())
6442
0
        return;
6443
    // aLastCommentSidebarPos right and left positions are the same so either can be used here
6444
0
    m_rView.GetPostItMgr()->SetSidebarWidth(
6445
0
        Point(aLastCommentSidebarPos.Right(), PixelToLogic(rPointPixel).Y()));
6446
0
}
6447
6448
static SfxShell* lcl_GetTextShellFromDispatcher( SwView const & rView )
6449
0
{
6450
    // determine Shell
6451
0
    SfxShell* pShell;
6452
0
    SfxDispatcher* pDispatcher = rView.GetViewFrame().GetDispatcher();
6453
0
    for(sal_uInt16  i = 0; true; ++i )
6454
0
    {
6455
0
        pShell = pDispatcher->GetShell( i );
6456
0
        if( !pShell || dynamic_cast< const SwTextShell *>( pShell ) !=  nullptr )
6457
0
            break;
6458
0
    }
6459
0
    return pShell;
6460
0
}
6461
6462
IMPL_LINK_NOARG(SwEditWin, KeyInputFlushHandler, Timer *, void)
6463
0
{
6464
0
    FlushInBuffer();
6465
0
}
6466
6467
void SwEditWin::InitStaticData()
6468
9
{
6469
9
    s_pQuickHlpData = new QuickHelpData();
6470
9
}
6471
6472
void SwEditWin::FinitStaticData()
6473
9
{
6474
9
    delete s_pQuickHlpData;
6475
9
}
6476
/* i#3370 - remove quick help to prevent saving
6477
 * of autocorrection suggestions */
6478
void SwEditWin::StopQuickHelp()
6479
0
{
6480
0
    if( HasFocus() && s_pQuickHlpData && s_pQuickHlpData->m_bIsDisplayed  )
6481
0
        s_pQuickHlpData->Stop( m_rView.GetWrtShell() );
6482
0
}
6483
6484
IMPL_LINK_NOARG(SwEditWin, TemplateTimerHdl, Timer *, void)
6485
0
{
6486
0
    SetApplyTemplate(SwApplyTemplate());
6487
0
}
6488
6489
void SwEditWin::SetChainMode( bool bOn )
6490
0
{
6491
0
    if ( !m_bChainMode )
6492
0
        StopInsFrame();
6493
6494
0
    m_pUserMarker.reset();
6495
6496
0
    m_bChainMode = bOn;
6497
6498
0
    static const sal_uInt16 aInva[] =
6499
0
    {
6500
0
        FN_FRAME_CHAIN, FN_FRAME_UNCHAIN, 0
6501
0
    };
6502
0
    m_rView.GetViewFrame().GetBindings().Invalidate(aInva);
6503
0
}
6504
6505
rtl::Reference<comphelper::OAccessible> SwEditWin::CreateAccessible()
6506
0
{
6507
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
6508
0
    SolarMutexGuard aGuard;   // this should have happened already!!!
6509
0
    SwWrtShell *pSh = m_rView.GetWrtShellPtr();
6510
0
    OSL_ENSURE( pSh, "no writer shell, no accessible object" );
6511
0
    if( pSh )
6512
0
        return pSh->CreateAccessible();
6513
0
#endif
6514
0
    return {};
6515
0
}
6516
6517
void QuickHelpData::Move( QuickHelpData& rCpy )
6518
0
{
6519
0
    m_aHelpStrings.clear();
6520
0
    m_aHelpStrings.swap( rCpy.m_aHelpStrings );
6521
6522
0
    m_bIsDisplayed = rCpy.m_bIsDisplayed;
6523
0
    nCurArrPos = rCpy.nCurArrPos;
6524
0
    m_bAppendSpace = rCpy.m_bAppendSpace;
6525
0
    m_bIsTip = rCpy.m_bIsTip;
6526
0
    m_bIsAutoText = rCpy.m_bIsAutoText;
6527
0
}
6528
6529
void QuickHelpData::ClearContent()
6530
9
{
6531
9
    nCurArrPos = nNoPos;
6532
9
    m_bIsDisplayed = m_bAppendSpace = false;
6533
9
    nTipId = nullptr;
6534
9
    m_aHelpStrings.clear();
6535
9
    m_bIsTip = true;
6536
9
    m_bIsAutoText = true;
6537
9
}
6538
6539
void QuickHelpData::Start(SwWrtShell& rSh, const bool bRestart)
6540
0
{
6541
0
    if (bRestart)
6542
0
    {
6543
0
        nCurArrPos = 0;
6544
0
    }
6545
0
    m_bIsDisplayed = true;
6546
6547
0
    vcl::Window& rWin = rSh.GetView().GetEditWin();
6548
0
    if( m_bIsTip )
6549
0
    {
6550
0
        Point aPt( rWin.OutputToScreenPixel( rWin.LogicToPixel(
6551
0
                    rSh.GetCharRect().Pos() )));
6552
0
        aPt.AdjustY( -3 );
6553
0
        nTipId = Help::ShowPopover(&rWin, tools::Rectangle( aPt, Size( 1, 1 )),
6554
0
                        CurStr(),
6555
0
                        QuickHelpFlags::Left | QuickHelpFlags::Bottom);
6556
0
    }
6557
0
    else
6558
0
    {
6559
0
        OUString sStr(CurStr());
6560
0
        sStr = sStr.copy(CurLen());
6561
0
        sal_uInt16 nL = sStr.getLength();
6562
0
        const ExtTextInputAttr nVal = ExtTextInputAttr::DottedUnderline |
6563
0
                                ExtTextInputAttr::Highlight;
6564
0
        const std::vector<ExtTextInputAttr> aAttrs( nL, nVal );
6565
0
        CommandExtTextInputData aCETID( sStr, aAttrs.data(), nL,
6566
0
                                        0, false );
6567
6568
        //fdo#33092. If the current input language is the default
6569
        //language that text would appear in if typed, then don't
6570
        //force a language on for the ExtTextInput.
6571
0
        LanguageType eInputLanguage = rWin.GetInputLanguage();
6572
0
        if (lcl_isNonDefaultLanguage(eInputLanguage,
6573
0
            rSh.GetView(), sStr) == INVALID_HINT)
6574
0
        {
6575
0
            eInputLanguage = LANGUAGE_DONTKNOW;
6576
0
        }
6577
6578
0
        rSh.CreateExtTextInput(eInputLanguage);
6579
0
        rSh.SetExtTextInputData( aCETID );
6580
0
    }
6581
0
}
6582
6583
void QuickHelpData::Stop( SwWrtShell& rSh )
6584
0
{
6585
0
    if( !m_bIsTip )
6586
0
        rSh.DeleteExtTextInput( false );
6587
0
    else if( nTipId )
6588
0
    {
6589
0
        vcl::Window& rWin = rSh.GetView().GetEditWin();
6590
0
        Help::HidePopover(&rWin, nTipId);
6591
0
    }
6592
0
    ClearContent();
6593
0
}
6594
6595
void QuickHelpData::FillStrArr( SwWrtShell const & rSh, const OUString& rWord )
6596
0
{
6597
0
    enum Capitalization { CASE_LOWER, CASE_UPPER, CASE_SENTENCE, CASE_OTHER };
6598
6599
    // Determine word capitalization
6600
0
    const CharClass& rCC = GetAppCharClass();
6601
0
    const OUString sWordLower = rCC.lowercase( rWord );
6602
0
    Capitalization aWordCase = CASE_OTHER;
6603
0
    if ( !rWord.isEmpty() )
6604
0
    {
6605
0
        if ( rWord[0] == sWordLower[0] )
6606
0
        {
6607
0
            if ( rWord == sWordLower )
6608
0
                aWordCase = CASE_LOWER;
6609
0
        }
6610
0
        else
6611
0
        {
6612
            // First character is not lower case i.e. assume upper or title case
6613
0
            OUString sWordSentence = sWordLower.replaceAt( 0, 1, rtl::OUStringChar(rWord[0]) );
6614
0
            if ( rWord == sWordSentence )
6615
0
                aWordCase = CASE_SENTENCE;
6616
0
            else
6617
0
            {
6618
0
                if ( rWord == rCC.uppercase( rWord ) )
6619
0
                    aWordCase = CASE_UPPER;
6620
0
            }
6621
0
        }
6622
0
    }
6623
6624
0
    SwCalendarWrapper& rCalendar = s_getCalendarWrapper();
6625
0
    rCalendar.LoadDefaultCalendar( rSh.GetCurLang() );
6626
6627
    // Add matching calendar month and day names
6628
0
    for ( const auto& aNames : { rCalendar.getMonths(), rCalendar.getDays() } )
6629
0
    {
6630
0
        for ( const auto& rName : aNames )
6631
0
        {
6632
0
            const OUString& rStr( rName.FullName );
6633
            // Check string longer than word and case insensitive match
6634
0
            if( rStr.getLength() > rWord.getLength() &&
6635
0
                rCC.lowercase( rStr, 0, rWord.getLength() ) == sWordLower )
6636
0
            {
6637
0
                OUString sStr;
6638
6639
                //fdo#61251 if it's an exact match, ensure unchanged replacement
6640
                //exists as a candidate
6641
0
                if (rStr.startsWith(rWord))
6642
0
                    m_aHelpStrings.emplace_back(rStr, rWord.getLength());
6643
0
                else
6644
0
                    sStr = rStr; // to be added if no case conversion is performed below
6645
6646
0
                if ( aWordCase == CASE_LOWER )
6647
0
                    sStr = rCC.lowercase(rStr);
6648
0
                else if ( aWordCase == CASE_SENTENCE )
6649
0
                    sStr = rCC.lowercase(rStr).replaceAt(0, 1, rtl::OUStringChar(rStr[0]));
6650
0
                else if ( aWordCase == CASE_UPPER )
6651
0
                    sStr = rCC.uppercase(rStr);
6652
6653
0
                if (!sStr.isEmpty())
6654
0
                    m_aHelpStrings.emplace_back(sStr, rWord.getLength());
6655
0
            }
6656
0
        }
6657
0
    }
6658
6659
    // Add matching current date in ISO 8601 format, for example 2016-01-30
6660
0
    OUString rStrToday;
6661
6662
    // do not suggest for single years, for example for "2016",
6663
    // only for "201" or "2016-..." (to avoid unintentional text
6664
    // insertion at line ending, for example typing "30 January 2016")
6665
0
    if (!rWord.isEmpty() && rWord.getLength() != 4 && rWord[0] == '2')
6666
0
    {
6667
0
        rStrToday = utl::toISO8601(DateTime(Date(Date::SYSTEM)).GetUNODateTime());
6668
0
        if (rStrToday.startsWith(rWord))
6669
0
            m_aHelpStrings.emplace_back(rStrToday, rWord.getLength());
6670
0
    }
6671
6672
    // Add matching words from AutoCompleteWord list
6673
0
    const SwAutoCompleteWord& rACList = SwEditShell::GetAutoCompleteWords();
6674
0
    std::vector<OUString> strings;
6675
6676
0
    if ( !rACList.GetWordsMatching( rWord, strings ) )
6677
0
        return;
6678
6679
0
    for (const OUString & aCompletedString : strings)
6680
0
    {
6681
        // when we have a matching current date, avoid to suggest
6682
        // other words with the same matching starting characters,
6683
        // for example 2016-01-3 instead of 2016-01-30
6684
0
        if (!rStrToday.isEmpty() && aCompletedString.startsWith(rWord))
6685
0
            continue;
6686
6687
0
        OUString sStr;
6688
6689
        //fdo#61251 if it's an exact match, ensure unchanged replacement
6690
        //exists as a candidate
6691
0
        if (aCompletedString.startsWith(rWord))
6692
0
            m_aHelpStrings.emplace_back(aCompletedString, rWord.getLength());
6693
0
        else
6694
0
            sStr = aCompletedString; // to be added if no case conversion is performed below
6695
6696
0
        if (aWordCase == CASE_LOWER)
6697
0
            sStr = rCC.lowercase(aCompletedString);
6698
0
        else if (aWordCase == CASE_SENTENCE)
6699
0
            sStr = rCC.lowercase(aCompletedString)
6700
0
                       .replaceAt(0, 1, rtl::OUStringChar(aCompletedString[0]));
6701
0
        else if (aWordCase == CASE_UPPER)
6702
0
            sStr = rCC.uppercase(aCompletedString);
6703
6704
0
        if (!sStr.isEmpty())
6705
0
            m_aHelpStrings.emplace_back(aCompletedString, rWord.getLength());
6706
0
    }
6707
0
}
6708
6709
namespace {
6710
6711
class CompareIgnoreCaseAsciiFavorExact
6712
{
6713
    const OUString &m_rOrigWord;
6714
public:
6715
    explicit CompareIgnoreCaseAsciiFavorExact(const OUString& rOrigWord)
6716
0
        : m_rOrigWord(rOrigWord)
6717
0
    {
6718
0
    }
6719
6720
    bool operator()(const std::pair<OUString, sal_uInt16>& s1,
6721
                    const std::pair<OUString, sal_uInt16>& s2) const
6722
0
    {
6723
0
        int nRet = s1.first.compareToIgnoreAsciiCase(s2.first);
6724
0
        if (nRet == 0)
6725
0
        {
6726
            //fdo#61251 sort stuff that starts with the exact rOrigWord before
6727
            //another ignore-case candidate
6728
0
            int n1StartsWithOrig = s1.first.startsWith(m_rOrigWord) ? 0 : 1;
6729
0
            int n2StartsWithOrig = s2.first.startsWith(m_rOrigWord) ? 0 : 1;
6730
0
            return n1StartsWithOrig < n2StartsWithOrig;
6731
0
        }
6732
0
        return nRet < 0;
6733
0
    }
6734
};
6735
6736
struct EqualIgnoreCaseAscii
6737
{
6738
    bool operator()(const std::pair<OUString, sal_uInt16>& s1,
6739
                    const std::pair<OUString, sal_uInt16>& s2) const
6740
0
    {
6741
0
        return s1.first.equalsIgnoreAsciiCase(s2.first);
6742
0
    }
6743
};
6744
6745
} // anonymous namespace
6746
6747
// TODO Implement an i18n aware sort
6748
void QuickHelpData::SortAndFilter(const OUString &rOrigWord)
6749
0
{
6750
0
    std::sort( m_aHelpStrings.begin(),
6751
0
               m_aHelpStrings.end(),
6752
0
               CompareIgnoreCaseAsciiFavorExact(rOrigWord) );
6753
6754
0
    const auto it
6755
0
        = std::unique(m_aHelpStrings.begin(), m_aHelpStrings.end(), EqualIgnoreCaseAscii());
6756
0
    m_aHelpStrings.erase( it, m_aHelpStrings.end() );
6757
6758
0
    nCurArrPos = 0;
6759
0
}
6760
6761
// For a given chunk of typed text between 3 and 9 characters long that may start at a word boundary
6762
// or in a whitespace and may include whitespaces, SwEditShell::GetChunkForAutoTextcreates a list of
6763
// possible candidates for long AutoText names. Let's say, we have typed text "lorem ipsum  dr f";
6764
// and the cursor is right after the "f". SwEditShell::GetChunkForAutoText would take "  dr f",
6765
// since it's the longest chunk to the left of the cursor no longer than 9 characters, not starting
6766
// in the middle of a word. Then it would create this list from it (in this order, longest first):
6767
//     "  dr f"
6768
//      " dr f"
6769
//       "dr f"
6770
// It cannot add "r f", because it starts in the middle of the word "dr"; also it cannot give " f",
6771
// because it's only 2 characters long.
6772
// Now the result of SwEditShell::GetChunkForAutoText is passed here to SwEditWin::ShowAutoText, and
6773
// then to SwGlossaryList::HasLongName, where all existing autotext entries' long names are tested
6774
// if they start with one of the list elements. The matches are sorted according the position of the
6775
// candidate that matched first, then alphabetically inside the group of suggestions for a given
6776
// candidate. Say, if we have these AutoText entry long names:
6777
//    "Dr Frodo"
6778
//    "Dr Credo"
6779
//    "Or Bilbo"
6780
//    "dr foo"
6781
//    "  Dr Fuzz"
6782
//    " dr Faust"
6783
// the resulting list would be:
6784
//    "  Dr Fuzz" -> matches the first (longest) item in the candidates list
6785
//    " dr Faust" -> matches the second candidate item
6786
//    "Dr Foo" -> first item of the two matching the third candidate; alphabetically sorted
6787
//    "Dr Frodo" -> second item of the two matching the third candidate; alphabetically sorted
6788
// Each of the resulting suggestions knows the length of the candidate it replaces, so accepting the
6789
// first suggestion would replace 6 characters before cursor, while tabbing to and accepting the
6790
// last suggestion would replace only 4 characters to the left of cursor.
6791
bool SwEditWin::ShowAutoText(const std::vector<OUString>& rChunkCandidates)
6792
0
{
6793
0
    s_pQuickHlpData->ClearContent();
6794
0
    if (!rChunkCandidates.empty())
6795
0
    {
6796
0
        SwGlossaryList* pList = ::GetGlossaryList();
6797
0
        pList->HasLongName(rChunkCandidates, s_pQuickHlpData->m_aHelpStrings);
6798
0
    }
6799
6800
0
    if (!s_pQuickHlpData->m_aHelpStrings.empty())
6801
0
    {
6802
0
        s_pQuickHlpData->Start(m_rView.GetWrtShell(), true);
6803
0
    }
6804
0
    return !s_pQuickHlpData->m_aHelpStrings.empty();
6805
0
}
6806
6807
void SwEditWin::ShowAutoCorrectQuickHelp(
6808
        const OUString& rWord, SvxAutoCorrect& rACorr )
6809
0
{
6810
0
    if (rWord.isEmpty())
6811
0
        return;
6812
0
    SwWrtShell& rSh = m_rView.GetWrtShell();
6813
0
    s_pQuickHlpData->ClearContent();
6814
6815
0
    if( s_pQuickHlpData->m_aHelpStrings.empty() &&
6816
0
        rACorr.GetSwFlags().bAutoCompleteWords )
6817
0
    {
6818
0
        s_pQuickHlpData->m_bIsAutoText = false;
6819
0
        s_pQuickHlpData->m_bIsTip = rACorr.GetSwFlags().bAutoCmpltShowAsTip;
6820
6821
        // Get the necessary data to show help text.
6822
0
        s_pQuickHlpData->FillStrArr( rSh, rWord );
6823
0
    }
6824
6825
0
    if( !s_pQuickHlpData->m_aHelpStrings.empty() )
6826
0
    {
6827
0
        s_pQuickHlpData->SortAndFilter(rWord);
6828
0
        s_pQuickHlpData->Start(rSh, true);
6829
0
    }
6830
0
}
6831
6832
bool SwEditWin::IsInHeaderFooter( const Point &rDocPt, FrameControlType &rControl ) const
6833
0
{
6834
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
6835
0
    const SwPageFrame* pPageFrame = rSh.GetLayout()->GetPageAtPos( rDocPt );
6836
6837
0
    if ( pPageFrame && pPageFrame->IsOverHeaderFooterArea( rDocPt, rControl ) )
6838
0
        return true;
6839
6840
0
    if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Header ) || rSh.IsShowHeaderFooterSeparator( FrameControlType::Footer ) )
6841
0
    {
6842
0
        SwFrameControlsManager &rMgr = rSh.GetView().GetEditWin().GetFrameControlsManager();
6843
0
        Point aPoint( LogicToPixel( rDocPt ) );
6844
6845
0
        if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Header ) )
6846
0
        {
6847
0
            SwFrameControlPtr pControl = rMgr.GetControl( FrameControlType::Header, pPageFrame );
6848
0
            if ( pControl && pControl->Contains( aPoint ) )
6849
0
            {
6850
0
                rControl = FrameControlType::Header;
6851
0
                return true;
6852
0
            }
6853
0
        }
6854
6855
0
        if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Footer ) )
6856
0
        {
6857
0
            SwFrameControlPtr pControl = rMgr.GetControl( FrameControlType::Footer, pPageFrame );
6858
0
            if ( pControl && pControl->Contains( aPoint ) )
6859
0
            {
6860
0
                rControl = FrameControlType::Footer;
6861
0
                return true;
6862
0
            }
6863
0
        }
6864
0
    }
6865
6866
0
    return false;
6867
0
}
6868
6869
bool SwEditWin::IsOverHeaderFooterFly( const Point& rDocPos, FrameControlType& rControl, bool& bOverFly, bool& bPageAnchored ) const
6870
0
{
6871
0
    bool bRet = false;
6872
0
    Point aPt( rDocPos );
6873
0
    SwWrtShell &rSh = m_rView.GetWrtShell();
6874
0
    SwPaM aPam( *rSh.GetCurrentShellCursor().GetPoint() );
6875
0
    rSh.GetLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aPt, nullptr, true );
6876
6877
0
    const SwStartNode* pStartFly = aPam.GetPoint()->GetNode().FindFlyStartNode();
6878
0
    if ( pStartFly )
6879
0
    {
6880
0
        bOverFly = true;
6881
0
        SwFrameFormat* pFlyFormat = pStartFly->GetFlyFormat( );
6882
0
        if ( pFlyFormat )
6883
0
        {
6884
0
            const SwNode* pAnchorNode = pFlyFormat->GetAnchor( ).GetAnchorNode( );
6885
0
            if ( pAnchorNode )
6886
0
            {
6887
0
                bool bInHeader = pAnchorNode->FindHeaderStartNode( ) != nullptr;
6888
0
                bool bInFooter = pAnchorNode->FindFooterStartNode( ) != nullptr;
6889
6890
0
                bRet = bInHeader || bInFooter;
6891
0
                if ( bInHeader )
6892
0
                    rControl = FrameControlType::Header;
6893
0
                else if ( bInFooter )
6894
0
                    rControl = FrameControlType::Footer;
6895
0
            }
6896
0
            else
6897
0
                bPageAnchored = pFlyFormat->GetAnchor( ).GetAnchorId( ) == RndStdIds::FLY_AT_PAGE;
6898
0
        }
6899
0
    }
6900
0
    else
6901
0
        bOverFly = false;
6902
0
    return bRet;
6903
0
}
6904
6905
void SwEditWin::SetUseInputLanguage( bool bNew )
6906
0
{
6907
0
    if ( bNew || m_bUseInputLanguage )
6908
0
    {
6909
0
        SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
6910
0
        rBind.Invalidate( SID_ATTR_CHAR_FONT );
6911
0
        rBind.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
6912
0
    }
6913
0
    m_bUseInputLanguage = bNew;
6914
0
}
6915
6916
OUString SwEditWin::GetSurroundingText() const
6917
0
{
6918
0
    SwWrtShell& rSh = m_rView.GetWrtShell();
6919
6920
0
    if (rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit())
6921
0
        return rSh.GetDrawView()->GetTextEditOutlinerView()->GetSurroundingText();
6922
6923
0
    OUString sReturn;
6924
0
    if( rSh.HasSelection() && !rSh.IsMultiSelection() && rSh.IsSelOnePara() )
6925
0
        rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR  );
6926
0
    else if( !rSh.HasSelection() )
6927
0
    {
6928
0
        bool bUnLockView = !rSh.IsViewLocked();
6929
0
        rSh.LockView(true);
6930
6931
        // store shell state *before* Push
6932
0
        ::std::optional<SwCallLink> aLink(std::in_place, rSh);
6933
0
        rSh.Push();
6934
6935
        // disable accessible events for internal-only helper cursor
6936
0
        const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents();
6937
0
        rSh.SetSendAccessibleCursorEvents(false);
6938
6939
        // get the sentence around the cursor
6940
0
        rSh.HideCursor();
6941
0
        rSh.GoStartSentence();
6942
0
        rSh.SetMark();
6943
0
        rSh.GoEndSentence();
6944
0
        rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR  );
6945
6946
0
        rSh.Pop(SwCursorShell::PopMode::DeleteCurrent, aLink);
6947
0
        rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld);
6948
0
        rSh.HideCursor();
6949
6950
0
        if (bUnLockView)
6951
0
            rSh.LockView(false);
6952
0
    }
6953
6954
0
    return sReturn;
6955
0
}
6956
6957
Selection SwEditWin::GetSurroundingTextSelection() const
6958
0
{
6959
0
    SwWrtShell& rSh = m_rView.GetWrtShell();
6960
6961
0
    if (rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit())
6962
0
        return rSh.GetDrawView()->GetTextEditOutlinerView()->GetSurroundingTextSelection();
6963
6964
0
    if( rSh.HasSelection() )
6965
0
    {
6966
0
        OUString sReturn;
6967
0
        rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR  );
6968
0
        const SwCursor* pCursor = rSh.GetCursor();
6969
0
        if (pCursor && *pCursor->GetPoint() < *pCursor->GetMark())
6970
0
            return Selection(sReturn.getLength(), 0);
6971
0
        else
6972
0
            return Selection(0, sReturn.getLength());
6973
0
    }
6974
6975
0
    if (rSh.GetCursor()->GetPoint()->GetNode().GetTextNode())
6976
0
    {
6977
0
        bool bUnLockView = !rSh.IsViewLocked();
6978
0
        rSh.LockView(true);
6979
6980
        // Return the position of the visible cursor in the sentence
6981
        // around the visible cursor.
6982
0
        TextFrameIndex const nPos(rSh.GetCursorPointAsViewIndex());
6983
6984
        // store shell state *before* Push
6985
0
        ::std::optional<SwCallLink> aLink(std::in_place, rSh);
6986
0
        rSh.Push();
6987
6988
        // disable accessible events for internal-only helper cursor
6989
0
        const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents();
6990
0
        rSh.SetSendAccessibleCursorEvents(false);
6991
6992
0
        rSh.HideCursor();
6993
0
        rSh.GoStartSentence();
6994
0
        TextFrameIndex const nStartPos(rSh.GetCursorPointAsViewIndex());
6995
6996
0
        rSh.Pop(SwCursorShell::PopMode::DeleteCurrent, aLink);
6997
0
        rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld);
6998
0
        rSh.ShowCursor();
6999
7000
0
        if (bUnLockView)
7001
0
            rSh.LockView(false);
7002
7003
0
        return Selection(sal_Int32(nPos - nStartPos), sal_Int32(nPos - nStartPos));
7004
0
    }
7005
7006
0
    return Selection(0, 0);
7007
0
}
7008
7009
bool SwEditWin::DeleteSurroundingText(const Selection& rSelection)
7010
0
{
7011
0
    SwWrtShell& rSh = m_rView.GetWrtShell();
7012
7013
0
    if (rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit())
7014
0
        return rSh.GetDrawView()->GetTextEditOutlinerView()->DeleteSurroundingText(rSelection);
7015
7016
0
    if (rSh.HasSelection())
7017
0
        return false;
7018
7019
    // rSelection is relative to the start of the sentence, so find that and
7020
    // adjust the range by it
7021
0
    rSh.Push();
7022
7023
    // disable accessible events for internal-only helper cursor
7024
0
    const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents();
7025
0
    rSh.SetSendAccessibleCursorEvents(false);
7026
7027
0
    rSh.HideCursor();
7028
0
    rSh.GoStartSentence();
7029
0
    TextFrameIndex const nStartPos(rSh.GetCursorPointAsViewIndex());
7030
7031
0
    rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
7032
0
    rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld);
7033
0
    rSh.ShowCursor();
7034
7035
0
    if (rSh.SelectTextView(nStartPos + TextFrameIndex(rSelection.Min()), nStartPos + TextFrameIndex(rSelection.Max())))
7036
0
    {
7037
0
        rSh.Delete(false);
7038
0
        return true;
7039
0
    }
7040
7041
0
    return false;
7042
0
}
7043
7044
void SwEditWin::LogicInvalidate(const tools::Rectangle* pRectangle)
7045
0
{
7046
0
    SfxLokHelper::notifyInvalidation(&m_rView, pRectangle);
7047
0
}
7048
7049
void SwEditWin::SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool bClearMark)
7050
0
{
7051
0
    if (SdrView* pSdrView = m_rView.GetWrtShell().GetDrawView())
7052
0
    {
7053
        // Editing shape text, then route the call to editeng.
7054
0
        if (pSdrView->GetTextEditObject())
7055
0
        {
7056
0
            EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
7057
0
            rEditView.SetCursorLogicPosition(rPosition, bPoint, bClearMark);
7058
0
            return;
7059
0
        }
7060
0
    }
7061
7062
0
    if (m_rView.GetPostItMgr())
7063
0
    {
7064
0
        if (sw::annotation::SwAnnotationWin* pWin = m_rView.GetPostItMgr()->GetActiveSidebarWin())
7065
0
        {
7066
            // Editing postit text.
7067
0
            pWin->SetCursorLogicPosition(rPosition, bPoint, bClearMark);
7068
0
            return;
7069
0
        }
7070
0
    }
7071
7072
    // Not an SwWrtShell, as that would make SwCursorShell::GetCursor() inaccessible.
7073
0
    SwEditShell& rShell = m_rView.GetWrtShell();
7074
7075
0
    bool bCreateSelection = false;
7076
0
    {
7077
0
        SwMvContext aMvContext(&rShell);
7078
0
        if (bClearMark)
7079
0
            rShell.ClearMark();
7080
0
        else
7081
0
            bCreateSelection = !rShell.HasMark();
7082
7083
0
        if (bCreateSelection)
7084
0
            m_rView.GetWrtShell().SttSelect();
7085
7086
        // If the mark is to be updated, then exchange the point and mark before
7087
        // and after, as we can't easily set the mark.
7088
0
        if (!bPoint)
7089
0
            rShell.getShellCursor(/*bBlock=*/false)->Exchange();
7090
0
        rShell.SetCursor(rPosition);
7091
0
        if (!bPoint)
7092
0
            rShell.getShellCursor(/*bBlock=*/false)->Exchange();
7093
0
    }
7094
7095
0
    if (bCreateSelection)
7096
0
        m_rView.GetWrtShell().EndSelect();
7097
0
}
7098
7099
void SwEditWin::SetGraphicTwipPosition(bool bStart, const Point& rPosition)
7100
0
{
7101
0
    if (bStart)
7102
0
    {
7103
0
        MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
7104
0
        MouseButtonDown(aClickEvent);
7105
0
        MouseEvent aMoveEvent(Point(rPosition.getX() + MIN_MOVE + 1, rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
7106
0
        MouseMove(aMoveEvent);
7107
0
    }
7108
0
    else
7109
0
    {
7110
0
        MouseEvent aMoveEvent(Point(rPosition.getX() - MIN_MOVE - 1, rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
7111
0
        MouseMove(aMoveEvent);
7112
0
        MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
7113
0
        MouseButtonUp(aClickEvent);
7114
0
    }
7115
0
}
7116
7117
SwFrameControlsManager& SwEditWin::GetFrameControlsManager()
7118
25.6k
{
7119
25.6k
    return *m_pFrameControlsManager;
7120
25.6k
}
7121
7122
void SwEditWin::ToggleOutlineContentVisibility(const size_t nOutlinePos, const bool bSubs)
7123
0
{
7124
    // bSubs purpose is to set all sub level outline content to the same visibility as
7125
    // nOutlinePos outline content visibility is toggled. It is only applicable when not treating
7126
    // sub outline levels as content.
7127
0
    SwWrtShell& rSh = GetView().GetWrtShell();
7128
7129
0
    if (GetView().GetDrawView()->IsTextEdit())
7130
0
        rSh.EndTextEdit();
7131
0
    if (GetView().IsDrawMode())
7132
0
        GetView().LeaveDrawCreate();
7133
0
    rSh.EnterStdMode();
7134
7135
0
    if (!bSubs || rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
7136
0
    {
7137
0
        SwNode* pNode = rSh.GetNodes().GetOutLineNds()[nOutlinePos];
7138
0
        bool bVisible = pNode->GetTextNode()->GetAttrOutlineContentVisible();
7139
0
        pNode->GetTextNode()->SetAttrOutlineContentVisible(!bVisible);
7140
0
    }
7141
0
    else if (bSubs)
7142
0
    {
7143
        // also toggle sub levels to the same content visibility
7144
0
        SwOutlineNodes::size_type nPos = nOutlinePos;
7145
0
        SwOutlineNodes::size_type nOutlineNodesCount
7146
0
                = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
7147
0
        int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
7148
0
        bool bVisible = rSh.IsOutlineContentVisible(nOutlinePos);
7149
0
        do
7150
0
        {
7151
0
            if (rSh.IsOutlineContentVisible(nPos) == bVisible)
7152
0
                rSh.GetNodes().GetOutLineNds()[nPos]->GetTextNode()->SetAttrOutlineContentVisible(!bVisible);
7153
0
        } while (++nPos < nOutlineNodesCount
7154
0
                 && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel);
7155
0
    }
7156
7157
0
    rSh.InvalidateOutlineContentVisibility();
7158
0
    rSh.GotoOutline(nOutlinePos);
7159
0
    rSh.SetModified();
7160
0
    GetView().GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged));
7161
0
}
7162
7163
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */