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