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